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
+8 -2
View File
@@ -142,8 +142,14 @@ module n16_system_ddr3_top #(
wire [NUM_REQ*4*BURST_LEN-1:0] req_wmask;
wire [NUM_REQ*32*BURST_LEN-1:0] req_rdata;
sdram_arbiter_n #(
.NUM_REQ(NUM_REQ), .ADDR_WIDTH(MEM_ADDR_WIDTH), .BURST_LEN(BURST_LEN)
// EXP-0094: real, hierarchical 2-level arbiter (fixes EXP-0093's own
// real, measured P&R timing failure on the flat 21-way version --
// see sdram_arbiter_hier.v's own header). Drop-in replacement: same
// real external port shape/NUM_REQ/slot-index convention this
// module's own surrounding req_active/req_grant/etc wiring already
// uses, no other change needed here.
sdram_arbiter_hier #(
.N_GROUPS(N_GROUPS), .PES_PER_GROUP(4), .ADDR_WIDTH(MEM_ADDR_WIDTH), .BURST_LEN(BURST_LEN)
) u_arb (
.clk(ui_clk), .rst(ui_clk_sync_rst),
.req_active(req_active), .req_grant(req_grant),