fix(v2): resolve ERR-0025 Part B - SRAM read timing bug in weight/activation memory

Root-causes and fixes the real, disclosed defect left open at the end
of the previous STEP20 commit: the board-level SPI host interface
produced wrong compute results when jobs were dispatched with
realistic (widely time-separated) pacing, even though job registration
itself was already confirmed correct at the dependency_manager
handshake.

Root cause: nms_weight_packed.v and nms_activation_replicated.v both
used a REGISTERED SRAM read (rd_data_reg <= mem[addr], one full clock
of latency), but nms_memory_manager_stream_wide.v's own read-ahead
pipeline (its `rd_pending` bit) is designed around a COMBINATIONAL
read -- a request issued this cycle produces data already valid to
capture the very next cycle. A busy, multi-tile job (e.g. the STEP19
D-Stress regression, 16 tiles/neuron) never exposes the mismatch,
since its own weight/activation prefetch always runs far enough ahead
that any given tile has been sitting stable in the SRAM for many
cycles by the time it's actually consumed. An uncontested single-tile
job has zero such margin: its one tile's read fires on the exact edge
the data nominally becomes ready, landing squarely on the missing
cycle and permanently latching stale/zero data.

Fixed by making both SRAMs' reads combinational, with an explicit
same-cycle fill/read address-match bypass for the one hazard a plain
combinational read alone would still miss. No FSM, arbiter, or SDRAM
controller logic was touched.

Verified (Verilator, per this project's own standing DEC-0004
protocol):
- tb_fpga_neural_v2_top_smoke.v: 11/11 PASS -- single job, back-to-back
  jobs, a realistic ~85us-gap job pair, and a parametric sweep of
  inter-job gaps (100ns/5000ns/50000ns).
- STEP19 D-Stress N=2: 49788 cycles, 256/256 bit-exact -- identical
  cycle count to before this fix (zero regression).
- STEP19 D-Stress N=4: 49771 cycles, 256/256 bit-exact -- identical
  cycle count to before this fix (zero regression).
- tb_sdram_unified_backend.v (40/40) and tb_spi_host_bridge.v (18/18)
  reconfirmed unaffected.

The physical SPI host interface is now verified correct end-to-end.
Real synthesis/P&R of the board-level top (fpga_neural_v2_top.v) is
the deliberate next step, not yet performed this round.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
This commit is contained in:
2026-09-06 17:33:45 +02:00
co-authored by Claude Sonnet 5
parent 18bf038ed5
commit 68f3c5e403
7 changed files with 329 additions and 97 deletions
+33
View File
@@ -2107,3 +2107,36 @@ deliberately NOT attempted this round -- doing so before the
functional defect is resolved would produce a real bitstream/timing
report for RTL known to compute wrong answers under realistic host
timing, which is not a meaningful use of that real toolchain work.
DEC-0037
DATE: 2026-09-06
DECISION:
ERR-0025 Part B (real, downstream defect blocking the physical SPI
host interface's own end-to-end correctness) is RESOLVED. The fix
(combinational reads in nms_weight_packed.v / nms_activation_
replicated.v, see errors.log's own "ERR-0025 Part B -- RESOLUTION"
entry for the full root-cause writeup) is verified to introduce ZERO
regression against the STEP19 baseline (N=2/N=4 D-Stress, identical
cycle counts, still bit-exact) while making the NEW STEP20 board-level
integration path (SPI -> dependency_manager -> compute -> SDRAM ->
result) correct under both tight and realistic-gap job dispatch.
This REVISES DEC-0036's own "V2 HARDWARE RELEASE: FAIL" conclusion:
the single blocking item DEC-0036 identified is now closed. The
physical SPI host interface is no longer just "protocol-correct in
isolation" -- it is now verified correct end-to-end, matching the same
bit-exact standard already established for the raw reg_* interface.
NEXT STEP (not yet performed this round, per the governing spec's own
explicit sequencing -- "prepara il repository per il passo successivo:
synthesis/P&R del vero fpga_neural_v2_top... NON eseguire benchmark
finche' ERR-0025 Part B non e' completamente chiuso e la V2 non ha
superato synthesis/P&R"): real synthesis and P&R of fpga_neural_v2_top.v
against a real, ball-assigned LPF, to determine the real, achievable
operating frequency for the board-level top (including the SPI bridge
and the new host-arb arbitration layer) -- this was deliberately not
attempted before now, since running the real toolchain against RTL
known to compute wrong answers would not have been a meaningful
result. That reason no longer applies.