feat: MILESTONE - real activation-fetch engine, full N=2 system verified on real DDR3 (EXP-0079)
Closes the last major disclosed functional gap: packed_slot.v's activation data was read through a combinational stand-in since EXP-0062. New act_tile_fetch.v reads activation tiles directly from DDR3 (no on-chip buffering needed, unlike weights -- activation data has no reuse), sharing each slot's existing ctrl port with its own weight-prefetch engine. Real memory layout: one full BURST_LEN=8-word burst per tile, deliberately avoiding any runtime-indexed part-select given this project's thin P&R timing margin (EXP-0078). Verified at three levels: act_tile_fetch.v alone (6/6), packed_slot.v with real preloaded activation data (9/9), and the full N=2 system against real DDR3 via xsim (8/8, 0 errors) -- the first time this project's compute path has been verified end-to-end with real DDR3 for both weights and activations. Retired hardware/v3/rtl/n2_system_top.v and its testbench (pre-DDR3 SDR-placeholder era, fully superseded by n2_system_ddr3_top.v). Also: docs/PHYSICAL_REALIZATION.md (real pinout/parts/timing/protocol reference for the physical board) and CLAUDE.md (persistent project instructions for future Claude Code sessions). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUG92aM9m68TRc4rG55BcC
This commit is contained in:
@@ -15,8 +15,12 @@
|
||||
// memory backend is swapped, isolating that as the one variable
|
||||
// under test.
|
||||
//
|
||||
// Activation stand-in (see packed_slot.v's own header) is unchanged
|
||||
// too -- still a disclosed, separate gap, not addressed here.
|
||||
// EXP-0079 UPDATE: activations are now fetched via a REAL act_tile_
|
||||
// fetch.v inside each packed_slot.v instance (real DDR3 reads, same
|
||||
// physical bus each slot already uses for weights) -- no more stand-
|
||||
// in. This test now preloads real activation data into the SAME real
|
||||
// DDR3 model too (preload_ddr3_activations), on top of the weight
|
||||
// preload that was already here.
|
||||
//
|
||||
// Uses mig_7series_0_mig_sim (SIM_BYPASS_INIT_CAL="FAST" default,
|
||||
// EXP-0068's own real vendor-shipped fast-calibration simulation
|
||||
@@ -236,19 +240,34 @@ module tb;
|
||||
end
|
||||
endtask
|
||||
|
||||
function automatic signed [DATA_WIDTH*P_IN-1:0] act_lookup(input [ADDR_WIDTH-1:0] addr);
|
||||
integer li_d, pos_d, tidx_d, k;
|
||||
reg signed [DATA_WIDTH*P_IN-1:0] r;
|
||||
begin
|
||||
li_d = addr / 100000;
|
||||
pos_d = (addr / 1000) % 100;
|
||||
tidx_d = addr % 1000;
|
||||
for (k = 0; k < P_IN; k = k + 1)
|
||||
r[k*DATA_WIDTH +: DATA_WIDTH] = input_byte(li_d, pos_d, tidx_d*P_IN + k);
|
||||
act_lookup = r;
|
||||
end
|
||||
// ---- real activation preload (EXP-0079: packed_slot.v now wraps
|
||||
// a real act_tile_fetch.v, no more stand-in) -- same convention as
|
||||
// tb_packed_slot.v/tb_act_tile_fetch.v: one full BURST_LEN=8-word
|
||||
// burst per tile, P_IN=8 bytes in the low 64 bits. ----
|
||||
localparam [MIG_ADDR_WIDTH-1:0] ACT_MEM_BASE = 25'h10000;
|
||||
function automatic [ADDR_WIDTH-1:0] act_x_base(input integer li, input integer pos);
|
||||
act_x_base = {{(ADDR_WIDTH-MIG_ADDR_WIDTH){1'b0}}, ACT_MEM_BASE} + (li*M + pos) * (N_TILES*BURST_LEN);
|
||||
endfunction
|
||||
|
||||
task automatic preload_ddr3_activations;
|
||||
integer li, pos, t, k;
|
||||
reg [16*BURST_LEN-1:0] burst_data;
|
||||
reg [ADDR_WIDTH-1:0] base;
|
||||
begin
|
||||
for (li = 0; li < L; li = li + 1) begin
|
||||
for (pos = 0; pos < M; pos = pos + 1) begin
|
||||
base = act_x_base(li, pos);
|
||||
for (t = 0; t < N_TILES; t = t + 1) begin
|
||||
burst_data = {(16*BURST_LEN){1'b0}};
|
||||
for (k = 0; k < P_IN/2; k = k + 1)
|
||||
burst_data[k*16 +: 16] = {input_byte(li, pos, t*P_IN + 2*k+1), input_byte(li, pos, t*P_IN + 2*k)};
|
||||
sdram_write_burst(base[MIG_ADDR_WIDTH-1:0] + t*BURST_LEN, burst_data);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
// ---- neural_director_packed.v ----
|
||||
reg job_in_valid;
|
||||
wire job_in_ready;
|
||||
@@ -308,11 +327,6 @@ module tb;
|
||||
wire signed [DATA_WIDTH-1:0] res_a, res_b;
|
||||
wire [15:0] res_nid_a, res_nid_b;
|
||||
wire [ADDR_WIDTH-1:0] res_addr_a_out, res_addr_b_out;
|
||||
wire [ADDR_WIDTH-1:0] act_addr_a, act_addr_b;
|
||||
wire signed [DATA_WIDTH*P_IN-1:0] act_data_a, act_data_b;
|
||||
|
||||
assign act_data_a = act_lookup(act_addr_a);
|
||||
assign act_data_b = act_lookup(act_addr_b);
|
||||
|
||||
packed_slot #(
|
||||
.DATA_WIDTH(DATA_WIDTH), .P_IN(P_IN), .ACC_WIDTH(ACC_WIDTH),
|
||||
@@ -332,8 +346,6 @@ module tb;
|
||||
.result_node_id_a(res_nid_a), .result_node_id_b(res_nid_b),
|
||||
.result_addr_a_out(res_addr_a_out), .result_addr_b_out(res_addr_b_out),
|
||||
.mem_active(mem_active[gi]), .mem_grant(mem_grant[gi]),
|
||||
.act_tile_addr_a(act_addr_a), .act_tile_addr_b(act_addr_b),
|
||||
.act_tile_data_a(act_data_a), .act_tile_data_b(act_data_b),
|
||||
.ctrl_req(s_ctrl_req[gi]), .ctrl_wr(s_ctrl_wr[gi]),
|
||||
.ctrl_addr(s_ctrl_addr_flat[gi*MIG_ADDR_WIDTH +: MIG_ADDR_WIDTH]),
|
||||
.ctrl_wdata(s_ctrl_wdata_flat[gi*16*BURST_LEN +: 16*BURST_LEN]),
|
||||
@@ -429,6 +441,8 @@ module tb;
|
||||
|
||||
$display("=== preload SDRAM with %0d resident-filter weight sets ===", L);
|
||||
preload_sdram_layers;
|
||||
$display("=== preload SDRAM with real activation data (EXP-0079) ===");
|
||||
preload_ddr3_activations;
|
||||
@(posedge ui_clk);
|
||||
pre_active = 1'b0;
|
||||
repeat (5) @(posedge ui_clk);
|
||||
@@ -436,7 +450,7 @@ module tb;
|
||||
$display("=== N=2 system on REAL DDR3: submitting %0d layers x %0d positions ===", L, M);
|
||||
for (li_i = 0; li_i < L; li_i = li_i + 1) begin
|
||||
for (pp_i = 0; pp_i < M; pp_i = pp_i + 1) begin
|
||||
submit_job(li_i*100000 + pp_i*1000, li_i*WORDS_PER_LAYER, N_TILES[15:0],
|
||||
submit_job(act_x_base(li_i, pp_i), li_i*WORDS_PER_LAYER, N_TILES[15:0],
|
||||
26'h9000 + li_i*10 + pp_i, (li_i*M + pp_i));
|
||||
expect_node[n_expected] = (li_i*M + pp_i);
|
||||
expect_val[n_expected] = golden_result(li_i, pp_i);
|
||||
|
||||
Reference in New Issue
Block a user