1 from migen
.fhdl
.std
import *
2 from migen
.flow
.actor
import *
3 from migen
.flow
.network
import *
4 from migen
.fhdl
.specials
import Memory
5 from migen
.bus
import csr
6 from migen
.bank
import description
, csrgen
7 from migen
.bank
.description
import *
8 from migen
.actorlib
.fifo
import SyncFIFO
10 class RunLenghEncoder(Module
, AutoCSR
):
11 def __init__(self
, width
, length
):
15 self
.sink
= Sink([("d", width
)])
16 self
.source
= Source([("d", width
)])
18 self
._r
_enable
= CSRStorage()
21 enable
= self
._r
_enable
.storage
23 dat_i
= self
.sink
.payload
.d
28 dat_i_d
= Signal(width
)
37 comb
= [diff
.eq(stb_i
& (~enable |
(dat_i_d
!= dat_i
)))]
40 change_rising
= Signal()
41 self
.sync
+= change_d
.eq(change
)
42 self
.comb
+= change_rising
.eq(change
& ~change_d
)
45 rle_cnt
= Signal(max=length
)
48 comb
+=[If(rle_cnt
== length
, rle_max
.eq(enable
))]
54 rle_cnt
.eq(rle_cnt
+ 1)
58 # Mux RLE word and data
59 stb_o
= self
.source
.stb
60 dat_o
= self
.source
.payload
.d
61 ack_o
= self
.source
.ack
64 If(change_rising
& ~rle_max
,
67 dat_o
[:flen(rle_cnt
)].eq(rle_cnt
)
68 ).Elif(change_d | rle_max
,
79 class Recorder(Module
, AutoCSR
):
80 def __init__(self
, width
, depth
):
83 self
.sink
= Sink([("hit", 1), ("d", width
)])
85 self
._r
_trigger
= CSR()
86 self
._r
_length
= CSRStorage(bits_for(depth
))
87 self
._r
_offset
= CSRStorage(bits_for(depth
))
88 self
._r
_done
= CSRStatus()
90 self
._r
_read
_en
= CSR()
91 self
._r
_read
_empty
= CSRStatus()
92 self
._r
_read
_dat
= CSRStatus(width
)
96 length
= self
._r
_length
.storage
97 offset
= self
._r
_offset
.storage
98 done
= Signal(reset
=1)
101 cnt
= Signal(max=depth
)
103 fifo
= SyncFIFO([("d", width
)], depth
)
104 self
.submodules
+= fifo
106 # Write fifo is done only when done = 0
107 # Fifo must always be pulled by software between
108 # acquisition (Todo: add a flush funtionnality)
110 fifo
.sink
.stb
.eq(self
.sink
.stb
& ~done
),
111 fifo
.sink
.payload
.d
.eq(self
.sink
.payload
.d
),
116 # 0, 0 : Storage triggered but hit was not yet seen
117 # Data are recorded to fifo, if "offset" datas
118 # in the fifo, ack is set on fifo.source to
119 # store only "offset" datas.
121 # 0, 1 : Hit was seen, ack is no longer set on fifo.source
122 # we are storing "length"-"offset" data in this
125 # 1, 0 : We have stored "length" datas in fifo. Write to
127 # Software must now read data from the fifo until
132 If(self
._r
_trigger
.re
& self
._r
_trigger
.r
, done
.eq(0)
133 ).Elif(cnt
==length
, done
.eq(1)),
135 If(self
.sink
.stb
& self
.sink
.payload
.hit
& ~done
, ongoing
.eq(1)
136 ).Elif(done
, ongoing
.eq(0)),
139 # fifo ack & csr connection
141 If(~done
& ~ongoing
& (cnt
>= offset
), fifo
.source
.ack
.eq(1)
142 ).Else(fifo
.source
.ack
.eq(self
._r
_read
_en
.re
& self
._r
_read
_en
.r
)),
143 self
._r
_read
_empty
.status
.eq(~fifo
.source
.stb
),
144 self
._r
_read
_dat
.status
.eq(fifo
.source
.payload
.d
),
145 self
._r
_done
.status
.eq(done
)
152 ).Elif(fifo
.sink
.stb
& fifo
.sink
.ack
& ~
(fifo
.source
.stb
& fifo
.source
.ack
),