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:
@@ -327,9 +327,17 @@ module tb;
|
||||
.dir_state(dir_state), .dir_error(dir_error), .queue_empty(queue_empty)
|
||||
);
|
||||
|
||||
// ---- real 20-way arbiter (4 groups' own weight-fetch + 16 PEs' own
|
||||
// activation-fetch+writeback) + 4x systolic_group.v ----
|
||||
localparam NUM_REQ = N_GROUPS + N_PES; // 4 + 16 = 20
|
||||
// ---- EXP-0094: real, hierarchical 2-level arbiter (4 groups' own
|
||||
// weight-fetch + 16 PEs' own activation-fetch+writeback + 1 host
|
||||
// slot, matching n16_system_ddr3_top.v's own real, fixed topology
|
||||
// exactly -- sdram_arbiter_hier.v always includes a host slot, so
|
||||
// this testbench ties it off inactive (it doesn't instantiate
|
||||
// host_mem_bridge.v at all, same real precedent as
|
||||
// tb_n2_system_ddr3.v never instantiating spi_host_bridge_v3.v) --
|
||||
// was a real 20-way flat sdram_arbiter_n.v; replaced after EXP-0093
|
||||
// found the flat 21-way version's own real P&R timing failure. ----
|
||||
localparam NUM_REQ = N_GROUPS + N_PES + 1; // 4 + 16 + 1 = 21
|
||||
localparam HOST_SLOT = NUM_REQ - 1; // 20, tied off inactive below
|
||||
|
||||
wire [NUM_REQ-1:0] req_active, req_grant, req_req, req_wr;
|
||||
wire [NUM_REQ-1:0] req_ready, req_busy;
|
||||
@@ -338,8 +346,15 @@ module tb;
|
||||
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(MIG_ADDR_WIDTH), .BURST_LEN(BURST_LEN)
|
||||
assign req_active[HOST_SLOT] = 1'b0;
|
||||
assign req_req[HOST_SLOT] = 1'b0;
|
||||
assign req_wr[HOST_SLOT] = 1'b0;
|
||||
assign req_addr[HOST_SLOT*MIG_ADDR_WIDTH +: MIG_ADDR_WIDTH] = {MIG_ADDR_WIDTH{1'b0}};
|
||||
assign req_wdata[HOST_SLOT*32*BURST_LEN +: 32*BURST_LEN] = {(32*BURST_LEN){1'b0}};
|
||||
assign req_wmask[HOST_SLOT*4*BURST_LEN +: 4*BURST_LEN] = {(4*BURST_LEN){1'b0}};
|
||||
|
||||
sdram_arbiter_hier #(
|
||||
.N_GROUPS(N_GROUPS), .PES_PER_GROUP(4), .ADDR_WIDTH(MIG_ADDR_WIDTH), .BURST_LEN(BURST_LEN)
|
||||
) u_arb (
|
||||
.clk(ui_clk), .rst(ui_clk_sync_rst),
|
||||
.req_active(req_active), .req_grant(req_grant),
|
||||
|
||||
Reference in New Issue
Block a user