feat(v2): M10 Optimization - data-driven findings, completes the V2 roadmap

Final milestone of docs/v2-description.md's §33 roadmap, scoped
exactly to its own mandate: optimize only on data already gathered in
M1-M9, across the pipeline/P_IN/processor-count/scheduling/memory
axes - no speculative new features.

Three concrete, data-driven results:

1. N_SLOTS=8 (numero processor axis): real synthesis + nextpnr-ecp5
   P&R for dataflow_core at N_SLOTS=8, extending M7's N_SLOTS=2/4
   sweep to the real DSP ceiling DEC-0005 predicted. 92.63 MHz
   POST-P&R, PASS at 80MHz, DSP 64/72 (88.9%). DEC-0012 recommends
   N_SLOTS=8 as the practical ceiling for P_IN=8 on the
   LFE5U-45F-8BG381.

2. ACC_WIDTH 24 vs 32 (pipeline axis): a real 6-seed nextpnr-ecp5
   placement sweep (reusing already-synthesized netlists, no new
   synthesis needed) resolves EXP-0002's single-seed
   inconclusiveness. ACC_WIDTH=24 wins on both mean Fmax (+6.2%,
   180.71 vs 170.12 MHz) and seed-to-seed variance (~3.4x tighter),
   on top of its already-known resource advantage. DEC-0013
   recommends ACC_WIDTH=24 as the new default.

3. Stall %/utilization (scheduling/memory axes): testbench-only cycle
   counters added to tb_neural_multiprocessor.v (no RTL touched)
   close DEC-0011's deferred measurement gap with real data - shared
   PSRAM port 81.7% utilized, slot 0 95.2%, slot 1 65.2%, no
   conclusive evidence of harmful fixed-priority starvation at this
   scale.

The 10-milestone V2 roadmap (docs/v2-description.md §33) is now
complete end-to-end: real Verilator simulation, real Yosys synthesis,
real nextpnr-ecp5 place & route for every milestone, fully logged
(EXP-0001..EXP-0013, DEC-0001..DEC-0013, ERR-0001..ERR-0008) with no
invented results (§30) and V1 kept frozen and untouched throughout
(§1/§34).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
This commit is contained in:
2026-09-05 18:58:10 +02:00
co-authored by Claude Sonnet 5
parent 84794a3d25
commit 91bbbe2fe5
9 changed files with 367 additions and 1 deletions
@@ -121,8 +121,32 @@ module tb;
integer errors, tests;
integer i, wd;
// ---- M10 addition (decisions.log DEC-0011 closure): real
// cycle-accounting instrumentation, TESTBENCH-ONLY (no RTL
// touched) -- counts, from the moment node registration begins
// (measure_en) to $finish, how many cycles the shared PSRAM port
// is actually busy (slot_mem_arbiter's own `owner` field != NONE)
// and how many cycles each slot's memory_manager is busy (state
// != MM_IDLE), giving real SIMULATED stall %/utilization numbers
// for the exact same EXP-0009 scenario instead of leaving them
// unmeasured. ----
reg measure_en;
integer measured_cycles;
integer psram_busy_cycles;
integer slot0_busy_cycles, slot1_busy_cycles;
always @(posedge clk) begin
if (measure_en) begin
measured_cycles <= measured_cycles + 1;
if (u_nmp.u_arbiter.owner != 0) psram_busy_cycles <= psram_busy_cycles + 1;
if (u_nmp.u_dataflow_core.GEN_SLOT[0].u_mm.state != 3'd0) slot0_busy_cycles <= slot0_busy_cycles + 1;
if (u_nmp.u_dataflow_core.GEN_SLOT[1].u_mm.state != 3'd0) slot1_busy_cycles <= slot1_busy_cycles + 1;
end
end
initial begin
errors = 0; tests = 0;
measure_en = 1'b0; measured_cycles = 0; psram_busy_cycles = 0;
slot0_busy_cycles = 0; slot1_busy_cycles = 0;
rst = 1; reg_valid = 0; reg_node_id = 0; reg_required = 0; reg_producer_ids = 0;
reg_x_base = 0; reg_w_base = 0; reg_n_tiles = 0; reg_result_addr = 0;
repeat(5) @(posedge clk);
@@ -132,6 +156,7 @@ module tb;
// requirement/convention as tb_memory_manager.v (M4).
wait (u_nmp.u_psram_ctrl.state == u_nmp.u_psram_ctrl.STATE_IDLE);
@(posedge clk);
measure_en = 1'b1;
for (i = 0; i < 8; i = i + 1) begin
poke_byte(23'h10+i, 8'sd2); poke_byte(23'h20+i, 8'sd3); // node0: x=2,w=3
@@ -178,6 +203,17 @@ module tb;
errors = errors + 1;
end else $display("PASS node2: result=40, dispatched only after BOTH producers genuinely completed, real PSRAM end-to-end");
measure_en = 1'b0;
$display("========================================");
$display("M10 cycle-accounting (DEC-0011 closure, real SIMULATED data):");
$display(" measured cycles (from first registration to completion): %0d", measured_cycles);
$display(" shared PSRAM port busy: %0d/%0d cycles (%0.1f%% utilization, %0.1f%% idle)",
psram_busy_cycles, measured_cycles,
100.0*psram_busy_cycles/measured_cycles, 100.0*(measured_cycles-psram_busy_cycles)/measured_cycles);
$display(" slot 0 (memory_manager) busy: %0d/%0d cycles (%0.1f%% utilization)",
slot0_busy_cycles, measured_cycles, 100.0*slot0_busy_cycles/measured_cycles);
$display(" slot 1 (memory_manager) busy: %0d/%0d cycles (%0.1f%% utilization)",
slot1_busy_cycles, measured_cycles, 100.0*slot1_busy_cycles/measured_cycles);
$display("========================================");
if (errors == 0)
$display("ALL %0d TESTS PASSED (neural_multiprocessor, real V1 PSRAM chain shared across N_SLOTS=%0d via slot_mem_arbiter)", tests, N_SLOTS);