Commit Graph

2 Commits

Author SHA1 Message Date
Roflin abab26232b Fix the +1 descriptor offset: drop the arbiter's response register
SPRAMArbiter latched the SPRAM word into rsp_buf and raised exi_rsp_valid a
cycle later.  BBARegisterFile already took the response the cycle it arrived,
so the buffer bought nothing and cost a 24 MHz cycle (~42 ns) inside a deadline
that was short by about that much.  Both are now combinational in the cycle
SPRAM's output is valid.  The data sampling is unchanged -- the old code read
spram_dout in that same cycle, it just registered it before handing it over --
so only the handoff moved.

bba_top T9 goes from 1/6 to 6/6 byte-exact at EXI_HALF=1, and stays 6/6 at 2
and 8.  The whole suite passes at the hardware rate.  Nothing else changed:
BBARegisterFile is untouched.

Found by measuring instead of guessing, after four falsified attempts.  A
counter in ExiCapture recording tx_load & ~tx_fifo.r_rdy, with a shift-register
history of which byte boundary underran, showed good and bad reads BOTH
underrun at pop 3 (harmless, mid-header) while a bad read adds pop 4 -- the pop
that loads data slot 0.  So the late byte is the FIRST data byte, which rules
out every "prefetch further ahead" idea, because byte 0's request cannot be
issued before RHDR_LO where the low address byte arrives.  That makes the
deadline arithmetic with no contention in it: rx CDC ~125ns + arbiter 42 + SPRAM
42 + rsp_buf 42 + tx CDC ~110 = ~361ns against a 296ns byte time.  Over budget
idle, which is why fair arbitration changed nothing -- ETH contention was only
what pushed a marginal path over on some frames.

Two further changes were implemented, measured and then removed as unnecessary:
issuing byte 1's request during the pad byte, and two requests in flight with a
3-deep response hold.  With rsp_buf gone, T9 is 6/6 with both removed, with
either alone, and with the register file reverted completely.  They were real
pipelining but not the constraint, and they cost logic on sync, the binding
timing domain.  CLAUDE.md records them as do-not-re-add, along with the trap
that sank the earlier 2-outstanding attempt: incrementing `outstanding` in the
FSM and decrementing it in the response handler are two m.d.sync assignments
that Amaranth resolves by PRIORITY, not arithmetic, so the increment is
silently discarded when both fire in one cycle.

Arbiter TB updated (the response is a cycle earlier) and mutation-tested:
re-registering the response fails T1/T2/T4, swapping the byte lanes fails
T1/T2.  New T4 pins exi_rsp_valid to exactly one cycle.

Not yet confirmed on hardware; netboot's reader still probes both offsets.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-10 09:53:55 +02:00
Dennis Brentjes 8d0ab1d948 Added full design created with Claude 2026-06-13 18:35:38 +02:00