From: Florent Kermarrec Date: Thu, 22 May 2014 16:13:27 +0000 (+0200) Subject: storage: simplify run length encoder... X-Git-Tag: 24jan2021_ls180~2575^2~75 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9a059336bfb76085941dc545e443dd414d525d0e;p=litex.git storage: simplify run length encoder... --- diff --git a/miscope/storage.py b/miscope/storage.py index 82a1c2d2..bff03ae9 100644 --- a/miscope/storage.py +++ b/miscope/storage.py @@ -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):