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.
This commit is contained in:
bunnie 2022-12-07 12:25:48 +08:00
parent b1ea804520
commit 95f9d61ba8
1 changed files with 9 additions and 5 deletions

View File

@ -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))