1 from migen
.fhdl
.std
import *
2 from migen
.bank
.description
import *
3 from migen
.genlib
.fifo
import SyncFIFO
4 from migen
.genlib
.fsm
import FSM
, NextState
6 from miscope
.std
import *
8 class RunLengthEncoder(Module
, AutoCSR
):
9 def __init__(self
, width
, length
=1024):
13 self
.sink
= rec_dat(width
)
14 self
.source
= rec_dat(width
)
16 self
._r
_enable
= CSRStorage()
20 enable
= self
._r
_enable
.storage
22 sink_d
= rec_dat(width
)
23 self
.sync
+= If(self
.sink
.stb
, sink_d
.eq(self
.sink
))
25 cnt
= Signal(max=length
)
36 self
.comb
+= cnt_max
.eq(cnt
== length
)
39 self
.comb
+= change
.eq(self
.sink
.stb
& (self
.sink
.dat
!= sink_d
.dat
))
41 fsm
= FSM(reset_state
="BYPASS")
42 self
.submodules
+= fsm
45 sink_d
.connect(self
.source
),
47 If(enable
& ~change
& self
.sink
.stb
, NextState("COUNT"))
51 cnt_inc
.eq(self
.sink
.stb
),
52 If(change | cnt_max | ~enable
,
53 self
.source
.stb
.eq(1),
54 self
.source
.dat
[width
-1].eq(1), # Set RLE bit
55 self
.source
.dat
[:flen(cnt
)].eq(cnt
),
60 class Recorder(Module
, AutoCSR
):
61 def __init__(self
, width
, depth
):
64 self
.trig_sink
= rec_hit()
65 self
.dat_sink
= rec_dat(width
)
67 self
._r
_trigger
= CSR()
68 self
._r
_length
= CSRStorage(bits_for(depth
))
69 self
._r
_offset
= CSRStorage(bits_for(depth
))
70 self
._r
_done
= CSRStatus()
72 self
._r
_read
_en
= CSR()
73 self
._r
_read
_empty
= CSRStatus()
74 self
._r
_read
_dat
= CSRStatus(width
)
78 fifo
= InsertReset(SyncFIFO(width
, depth
))
79 self
.submodules
+= fifo
81 fsm
= FSM(reset_state
="IDLE")
82 self
.submodules
+= fsm
86 self
._r
_read
_empty
.status
.eq(~fifo
.readable
),
87 self
._r
_read
_dat
.status
.eq(fifo
.dout
),
91 If(self
._r
_trigger
.re
& self
._r
_trigger
.r
,
92 NextState("PRE_HIT_RECORDING"),
95 fifo
.re
.eq(self
._r
_read
_en
.re
& self
._r
_read
_en
.r
),
96 self
._r
_done
.status
.eq(1)
99 fsm
.act("PRE_HIT_RECORDING",
100 fifo
.we
.eq(self
.dat_sink
.stb
),
101 fifo
.din
.eq(self
.dat_sink
.dat
),
103 fifo
.re
.eq(fifo
.level
>= self
._r
_offset
.storage
),
105 If(self
.trig_sink
.stb
& self
.trig_sink
.hit
, NextState("POST_HIT_RECORDING"))
108 fsm
.act("POST_HIT_RECORDING",
109 fifo
.we
.eq(self
.dat_sink
.stb
),
110 fifo
.din
.eq(self
.dat_sink
.dat
),
112 If(~fifo
.writable |
(fifo
.level
>= self
._r
_length
.storage
), NextState("IDLE"))