storage: simplify run length encoder...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Thu, 22 May 2014 16:13:27 +0000 (18:13 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Thu, 22 May 2014 16:13:27 +0000 (18:13 +0200)
miscope/storage.py

index 82a1c2d20b154be55b1f3a96220debc6da6f6137..bff03ae9057cbeb9b30372a32c69d264382275da 100644 (file)
@@ -18,56 +18,44 @@ class RunLengthEncoder(Module, AutoCSR):
                ###
 
                enable = self._r_enable.storage
-               stb_i = self.sink.stb
-               dat_i = self.sink.dat
+                       
+               fsm = FSM(reset_state="BYPASS")
+               self.submodules += fsm
+
+               sink_d = rec_dat(width)
+               self.sync += If(self.sink.stb, sink_d.eq(self.sink))
 
-               # Register Input
-               stb_i_d = Signal()
-               dat_i_d = Signal(width)
+               cnt = Signal(max=length)
+               cnt_inc = Signal()
+               cnt_reset = Signal()
+               cnt_max = Signal()
 
                self.sync += \
-                       If(stb_i,
-                               dat_i_d.eq(dat_i),
-                               stb_i_d.eq(stb_i)
+                       If(cnt_reset,
+                               cnt.eq(1),
+                       ).Elif(cnt_inc,
+                               cnt.eq(cnt+1)
                        )
+               self.comb += cnt_max.eq(cnt == length)
 
-               # Detect change
                change = Signal()
-               self.comb += change.eq(stb_i & (~enable | (dat_i_d != dat_i)))
-
-               change_d = Signal()
-               change_rising = Signal()
-               self.sync += If(stb_i, change_d.eq(change))
-               self.comb += change_rising.eq(stb_i & (change & ~change_d))
-
-               # Generate RLE word
-               rle_cnt  = Signal(max=length)
-               rle_max  = Signal()
+               self.comb += change.eq(self.sink.stb & (self.sink.dat != sink_d.dat))
 
-               self.comb += If(rle_cnt == length, rle_max.eq(enable))
-
-               self.sync += \
-                       If(change | rle_max,
-                               rle_cnt.eq(0)
-                       ).Else(
-                               rle_cnt.eq(rle_cnt + 1)
-                       )
+               fsm.act("BYPASS",
+                       sink_d.connect(self.source),
+                       cnt_reset.eq(1),
+                       If(enable & ~change & self.sink.stb, NextState("COUNT"))
+               )
 
-               # Mux RLE word and data
-               stb_o = self.source.stb
-               dat_o = self.source.dat
-
-               self.comb += \
-                       If(change_rising & ~rle_max,
-                               stb_o.eq(1),
-                               dat_o[width-1].eq(1),
-                               dat_o[:flen(rle_cnt)].eq(rle_cnt)
-                       ).Elif(change_d | rle_max,
-                               stb_o.eq(stb_i_d),
-                               dat_o.eq(dat_i_d)
-                       ).Else(
-                               stb_o.eq(0),
+               fsm.act("COUNT",
+                       cnt_inc.eq(self.sink.stb),
+                       If(change | cnt_max | ~enable,
+                               self.source.stb.eq(1),
+                               self.source.dat[width-1].eq(1), # Set RLE bit
+                               self.source.dat[:flen(cnt)].eq(cnt),
+                               NextState("BYPASS")
                        )
+               ),
 
 class Recorder(Module, AutoCSR):
        def __init__(self, width, depth):