feat: real hierarchical 2-level arbiter, real N=16 timing WNS -0.913ns -> -0.646ns (EXP-0094)

sdram_arbiter_hier.v: fixes EXP-0093's own real, traced P&R timing
failure (flat 21-way req_wdata mux, route-delay-dominated). Reuses
sdram_arbiter_n.v unmodified, twice: 4 leaf instances (NUM_REQ=5, one
per group) + 1 top instance (NUM_REQ=5: 4 groups + host, host
bypassed/unpipelined), one real pipeline register stage between
levels. Isolated verification (tb_sdram_arbiter_hier.v): 23/23 PASS.

Two real bugs found and fixed via signal tracing: a testbench helper
not waiting for grant before firing req, and a genuine RTL lost-pulse
bug at the leaf-to-top boundary (a transient one-shot request could be
dropped if the top level was busy with a different group) -- fixed
with a sticky per-group pending_req_r latch.

Wired into n16_system_ddr3_top.v (drop-in). Real, full P&R re-run:
WNS improved -0.913ns -> -0.646ns, TNS -690ns -> -97.5ns, failing
endpoints 3021 -> 771 -- substantial, measured improvement, confirming
the arbiter was correctly root-caused (bottleneck moved elsewhere:
neural_processor_packed.v's own already-thin-margin MAC datapath,
eroded by N=16's higher overall congestion). Functional xsim still
32/32 PASS. Timing not yet fully closed -- real next steps documented,
not yet attempted without further direction.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MUG92aM9m68TRc4rG55BcC
This commit is contained in:
2026-09-21 02:25:44 +02:00
co-authored by Claude Sonnet 5
parent 50c940a41d
commit 9e1f16db47
7 changed files with 840 additions and 19 deletions
+57 -12
View File
@@ -659,7 +659,7 @@ specifically to document where/how it breaks rather than to succeed):
---
### 5.6 [Functionally DONE, TIMING NOT YET CLOSED — EXP-0089/0090/0091/0092/0093] Hybrid systolic scaling: 4 groups × 4-PE weight-stationary chains
### 5.6 [Functionally DONE, TIMING SUBSTANTIALLY IMPROVED BUT NOT YET CLOSED — EXP-0089/0090/0091/0092/0093/0094] Hybrid systolic scaling: 4 groups × 4-PE weight-stationary chains
Captured from a 2026-09-20 brainstorming session as a purely exploratory
idea; the same day, per the user's own explicit reprioritization, the real
@@ -732,17 +732,62 @@ hardware at the target clock. This does not invalidate the functional/
connectivity results; timing closure is a genuinely separate gate. N=2
(EXP-0088) remains the real, trustworthy, deployable signoff.
**Not yet done, real and disclosed, real options for closing timing**
(need a real decision on direction before committing more RTL effort):
(1) pipeline `sdram_arbiter_n.v`'s own req_wdata/req_addr mux by one
real cycle — adds one cycle of real arbitration latency per request,
likely acceptable given DDR3's own already-dominant real latency
(EXP-0087); probably the most direct fix, targets the exact real
critical path found above. (2) a real, hierarchical 2-level arbiter
(e.g. 4 groups' own 5-way sub-arbiters feeding one real 4-way top
arbiter) instead of one flat 20/21-way mux. (3) lower the real target
clock for the N=16 variant specifically (a real, unquantified
throughput tradeoff against N=2). See EXP-0093's own `next_action`.
- **Real, hierarchical 2-level arbiter (EXP-0094)**: `sdram_arbiter_
hier.v`, reusing `sdram_arbiter_n.v` unmodified, twice — 4 real LEAF
instances (NUM_REQ=5, one per group, physically local to their own
PEs) + 1 real TOP instance (NUM_REQ=5: 4 groups' own pipelined output
+ 1 host, host bypassed/unpipelined since it was never the real
bottleneck), with a real pipeline register stage between the two
levels — the direct, targeted fix for EXP-0093's own real, traced
route-delay-dominated critical path. Isolated verification (new
`tb_sdram_arbiter_hier.v`, real `burst_mem_model32.v`): **23/23
PASS**, including cross-group and mixed host+group worst-case
contention. Two real bugs found and fixed via signal tracing before
a trustworthy result was possible: a testbench helper not waiting for
grant before firing req (fixed to match `act_tile_fetch.v`'s own real
S_MEMWAIT discipline), and a genuine RTL lost-pulse bug at the
leaf-to-top boundary (a transient one-shot request pulse could be
dropped if the top level was still busy with a different group —
fixed with a real, sticky per-group `pending_req_r` latch). Wired
into `n16_system_ddr3_top.v` as a drop-in replacement.
- **Real re-verification with the new arbiter**: functional xsim
(`tb_n16_system_ddr3.v`) still **32/32 PASS, 0 errors**. Real, full
P&R re-run: utilization essentially unchanged (128 DSP48E1/53.33%).
**Real timing: WNS improved from 0.913ns to 0.646ns, TNS from
690.085ns to 97.541ns, failing endpoints from 3021 to 771** — a
real, substantial, measured improvement, confirming the arbiter was
correctly root-caused and fixed (the bottleneck demonstrably moved
elsewhere). **Timing is still not fully met.**
**Real, honest current bottleneck (traced via the actual new worst
violated path, not guessed)**: the new critical path is inside
`neural_processor_packed.v`'s own DSP48E1 MAC datapath (`GEN_MAC_
PACKED`→`prodb1_reg`), logic-dominated (79%), not route — a
pre-existing module, unchanged since N=2, where it closed with an
already razor-thin real margin (WNS=+0.099962ns, EXP-0088). Real,
coherent interpretation: N=16's real overall die utilization (31% LUT)
increases general placement congestion enough, on its own, to erode
that already-thin margin — a different, more diffuse problem than the
arbiter's own single structural bottleneck, without an equally obvious
single-point fix.
**Current real status**: N=16 is **functionally correct (EXP-0092,
re-confirmed EXP-0094) with a real, substantially improved but still
NOT fully closed timing result (EXP-0094)** — honestly not yet ready
for real hardware at the target clock. N=2 (EXP-0088) remains the
real, trustworthy, deployable signoff.
**Not yet done, real and disclosed, real options for closing the
remaining gap** (need a real decision on direction before committing
more RTL effort — `neural_processor_packed.v` is the compute core
shared by every real PE in this project): (1) real pipelining inside
`neural_processor_packed.v`'s own MAC datapath at the specific
`GEN_MAC_PACKED`/`prodb1_reg` boundary (fork-before-promote, N=2's own
signoff must stay protected). (2) a real, measured lower target clock
for the N=16 variant specifically (unquantified throughput trade-off
against N=2). (3) real Vivado placement/timing directives (e.g. a
`PBLOCK` per group to reduce congestion) as a lower-RTL-risk first
attempt. See EXP-0094's own `next_action`.
**The problem it targets**: plain N=16 independent cores (§5.5's own
"documentary, expected to break" framing) means 16 independent DDR3