V2.0.0 hardware freeze - single SDRAM
FASE #1 hardware freeze for FPGA-Neural V2, N4/P8, single external SDRAM (Alliance Memory AS4C4M16SA-6TIN) serving weights, activations, and results through one physical sdram_controller.v instance. Removes the PSRAM dependency (hardware/v1/rtl/psram_controller.v + memory_interface.v) from the V2 physical path entirely -- V1 itself remains fully unmodified, the golden reference. New RTL: sdram_unified_backend.v (2-way W/AR arbitration over one SDRAM controller, real per-byte DQM write masking added to sdram_controller.v for correct single-byte result writes with no read-modify-write), nms_neural_multiprocessor_sdram_unified.v (the frozen top-level). Two real bugs found and fixed via full-system testing before being accepted (ERR-0023): a deadlock and an off-by-one data-shift bug in the new arbitration logic. Real results: N=4 and N=2 D-Stress bit-exact (256/256 neurons), 40 real AUTO REFRESH events interleaved with zero corruption, real Yosys+nextpnr-ecp5 synthesis/P&R for LFE5U-45F-8CABGA381 (149/245 TRELLIS_IO, a real 45-pin reduction from the prior dual-memory design). Timing is MARGINAL (1/8 P&R seeds >=80MHz), reported honestly rather than masked by the best seed. Real, sourced ball-level pinout for the SDRAM bus + clk/rst (39/149 signals, P&R-verified) using the official Lattice ECP5U-45 pinout CSV found on disk during this step's own pre-commit review -- corrects an earlier draft that wrongly assumed no real pinout data was available. Chip readiness: NO. Real, disclosed blockers remain (no physical host interface exists yet -- the RTL's own reg_* ports are a 110-pin raw test-harness bus; clock source/PLL decision; power/configuration component selection) -- see hardware/v2/docs/{HARDWARE_FREEZE, CHIP_READINESS,OPEN_ITEMS}.md for the complete, itemized status. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
# NMS Activation Fill Controller Timing (STEP14 Part B)
|
||||
|
||||
Status: fixed, real post-P&R verified, bit-exact, adopted. Full data:
|
||||
`hardware/v2/reports/step14_activation_timing.csv`. Full narrative:
|
||||
`hardware/v2/logs/experiments.log` (EXP-0029, 0030, 0031),
|
||||
`decisions.log` (DEC-0026, DEC-0027).
|
||||
|
||||
## B1 — Exact critical path (not assumed)
|
||||
|
||||
Mined directly from the real nextpnr-ecp5 P&R report for
|
||||
`nms_neural_multiprocessor_stream.v` at N_SLOTS=4
|
||||
(Fmax=55.22 MHz, FAIL @ 80 MHz). Full path, 18.11 ns total (6.25 ns
|
||||
logic + 11.85 ns routing):
|
||||
|
||||
```
|
||||
SOURCE: u_act_fill.resident_tag[11] (register Q)
|
||||
-> COMBINATIONAL, chained, NO register in between:
|
||||
(1) max_n_tiles computation, nms_activation_fill_ctrl.v:92
|
||||
(N_SLOTS-wide running-max fold, each iteration gated by a
|
||||
23-bit tag-equality check) -- long CCU2C carry chain
|
||||
(2) resident_count < max_n_tiles comparison, line 165
|
||||
(the ST_IDLE refill/continue decision) -- ANOTHER 16-bit
|
||||
magnitude-comparison carry chain, feeding directly off (1)
|
||||
in the SAME cycle
|
||||
(3) into pf_start's own next-state logic
|
||||
DESTINATION: u_act_fill.pf_addr's clock-enable (CE) pin
|
||||
```
|
||||
|
||||
Two full 16-bit magnitude comparisons sit in **one** combinational
|
||||
cone across **one** clock edge. This confirms, at the exact RTL-line
|
||||
level, the failure class DEC-0016/EXP-0022 predicted analytically
|
||||
("O(N_SLOTS) unpipelined combinational scan feeding directly into a
|
||||
control decision") — but precisely localizes it to the comparison
|
||||
logic (lines 92 and 165), *not* the priority-encoder
|
||||
(`desired_valid`/`desired_x_base`, lines 77-86), which does not appear
|
||||
in this critical path at all.
|
||||
|
||||
## B2 — Scaling behavior
|
||||
|
||||
The bottleneck is the `max_n_tiles` running-max fold: an imperative
|
||||
`for` loop creates a data dependency between iterations (`max_n_tiles`
|
||||
after iteration *i* depends on iteration *i-1*), which Yosys
|
||||
synthesizes as a sequentially-chained carry structure — inherently
|
||||
O(N_SLOTS) deep, not O(log N_SLOTS). At N_SLOTS=4 the chain reached
|
||||
6.25 ns logic + 11.85 ns routing; at N_SLOTS=8 it doubles again (see
|
||||
below).
|
||||
|
||||
## B3 — Minimum fix (two iterations, evidence-driven)
|
||||
|
||||
**v2** (one pipeline stage: register `max_n_tiles` before its use in
|
||||
the `resident_count` comparison): Fmax 55.22 → 72.78 MHz (+31.8%) —
|
||||
real improvement, still fails 80 MHz. Re-tracing showed the *remaining*
|
||||
critical path was entirely inside `max_n_tiles`'s own computation
|
||||
(now feeding its own register), confirming the fix needed to go one
|
||||
level deeper.
|
||||
|
||||
**v3** (second stage: register each slot's tag-equality/masking result
|
||||
first — independent per-slot work, no N_SLOTS-dependent chain — *then*
|
||||
fold the already-registered, already-masked values): Fmax 55.22 →
|
||||
**106.81 MHz** (+93.4%). **PASSES** 80 MHz with real margin. Resource
|
||||
cost: LUT4 -5.5%, FF +1.4% (2 added pipeline registers), CCU2C
|
||||
unchanged.
|
||||
|
||||
## B4 — No serialization reintroduced
|
||||
|
||||
Verified directly: N_SLOTS=2 bit-exact regression test (D-Stress, real
|
||||
V1 PSRAM chain) gives **numerically identical** cycle count and
|
||||
sustained MAC/cycle before and after the fix (185270/185270 cycles,
|
||||
0.1769/0.1769 MAC/cycle). The 3 total cycles of added latency apply
|
||||
only to the rare, tile-refill-boundary-only decision — never to the
|
||||
real-time per-tile consumption path (already fully decoupled by
|
||||
STEP13's own streaming manager). Higher Fmax, zero throughput cost —
|
||||
satisfying B4's explicit requirement.
|
||||
|
||||
## N=8 (exploratory)
|
||||
|
||||
`nms_activation_fill_ctrl_v3.v` at N_SLOTS=8: DSP=64/72 (89%, FEASIBLE),
|
||||
LUT4=4653, FF=10855 (both comfortably FEASIBLE). **Fmax=52.25 MHz,
|
||||
FAILS 80 MHz** — the v3 fix's second stage (the max-fold itself) is
|
||||
still O(N_SLOTS)-deep; at N=8 it is twice as deep as at N=4 and becomes
|
||||
dominant again. This is expected: v3 shifted the crossover point, it
|
||||
did not eliminate the underlying dependency. A genuine balanced-tree
|
||||
reduction (or a pipeline scaling with log₂(N_SLOTS) rather than a flat
|
||||
2-stage split) would be required for N=8 — not undertaken this round
|
||||
(N=8 is explicitly exploratory; the limiting resource (Fmax, not
|
||||
DSP/LUT/FF/BRAM) is precisely identified and quantified, per spec).
|
||||
|
||||
## Adoption
|
||||
|
||||
`nms_activation_fill_ctrl_v3.v` is adopted as the reference activation
|
||||
fill controller for N_SLOTS≥4 configurations (DEC-0027). The original
|
||||
and the insufficient v2 are preserved for reference.
|
||||
Reference in New Issue
Block a user