From 95f9d61ba876820260880af92f5f5cdd295627ea Mon Sep 17 00:00:00 2001 From: bunnie Date: Wed, 7 Dec 2022 12:25:48 +0800 Subject: [PATCH] fix cycle delay + make range logic generic across configs The mux was actually delayed by one cycle, but this didn't show up in my earlier testbench because I was simply counting up while writing data. I now have a "random" (actually LFSR) write, sequential read test bench that is passing and it picked up this bug. The fix was to hoist the demux computation into the case statement, so it slightly increases that critical path but I think it's probably OK. I also formatted the demux_val priming logic so it is no longer specific to my system config, it's now generic so this could be considered a PR for mainlining. --- litex/soc/interconnect/stream.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/litex/soc/interconnect/stream.py b/litex/soc/interconnect/stream.py index 94014de21..71894115b 100644 --- a/litex/soc/interconnect/stream.py +++ b/litex/soc/interconnect/stream.py @@ -355,7 +355,7 @@ class _UpConverter(Module): # Control path demux_cnt = Signal(max=ratio) # counts how many cycles we've cycled demux_val = Signal(max=ratio) # tracks the actual value of the demux; may be primed with non-zero value - prime_demux = Signal(reset=1) + prime_demux = Signal(reset=1) # indicates that the demux should be primed wit the current address value load_data = Signal() load_addr = Signal() strobe_all = Signal() @@ -367,8 +367,6 @@ class _UpConverter(Module): ] demux_last = ((demux_cnt == (ratio - 1)) | sink.last) - # 0-3 should mux to the even channel - # 4-7 should mux to the odd channel self.sync += [ If(sink.last, prime_demux.eq(1), @@ -380,7 +378,8 @@ class _UpConverter(Module): If(source.ready, strobe_all.eq(0)), If(load_addr, If(prime_demux, - demux_val.eq( (self.aw & 7) < 4 ), + # pluck the range of bits from the source addr that correspond to the byte lane offset in the destination data path + demux_val.eq( self.aw[log2_int(nbits_from // 8):log2_int(nbits_from // 8) + log2_int(ratio)] ), ).Else( demux_val.eq(demux_val + 1), ), @@ -415,7 +414,12 @@ class _UpConverter(Module): self.sync += If( load_data, source.data.eq(0), - Case(demux_val, cases) + Case( + # This is demux_val, but re-computed here so we can have it one cycle earlier + prime_demux & ( self.aw[log2_int(nbits_from // 8):log2_int(nbits_from // 8) + log2_int(ratio)] ) | + ~prime_demux & (demux_val + 1), + cases + ) ) # Valid token count self.sync += If(load_data, source.valid_token_count.eq(demux_cnt + 1))