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
+32
View File
@@ -166,3 +166,35 @@ Osservazioni (tutte da dati reali sopra, nessun numero inventato):
- BRAM=0 per V2 riflette una scelta di scope esplicita (M3 non ancora
collegato, DEC-0009), non un vantaggio architetturale reale -- un
confronto onesto lo nota piuttosto che nasconderlo.
[2026-09-05] M10 -- Optimization, closing M9's deferred gaps with real
data (§32/DEC-0011 follow-up)
Stall %/utilization (EXP-0013, real SIMULATED data, N_SLOTS=2, 3-node
DAG scenario, replacing M9's "NOT MEASURED" placeholder for V2 -- V1's
own equivalent instrumentation was not built this session, still NOT
MEASURED for V1):
| Metric | V2 (SIMULATED, real) |
|------------------------------------|------------------------|
| shared PSRAM port utilization | 81.7% (18.3% idle) |
| slot 0 (memory_manager) utilization| 95.2% |
| slot 1 (memory_manager) utilization| 65.2% |
N_SLOTS sweep, extended to the real DSP ceiling (EXP-0008/EXP-0011):
| N_SLOTS | Fmax (POST-P&R) | DSP used/total |
|-----------|-------------------|------------------|
| 2 | 165.15 MHz | 16/72 (22%) |
| 4 | 133.19 MHz | 32/72 (44%) |
| 8 | 92.63 MHz | 64/72 (89%) |
All three PASS at 80MHz; N_SLOTS=8 recommended as the practical
ceiling for P_IN=8 on this chip (DEC-0012).
ACC_WIDTH 6-seed real placement sweep (EXP-0012, resolves EXP-0002's
single-seed inconclusiveness):
| ACC_WIDTH | mean Fmax | min | max | stdev |
|-------------|-------------|-------|-------|---------|
| 32 | 170.12 MHz | 145.73| 183.96| 14.16 |
| 24 | 180.71 MHz | 175.16| 185.49| 4.21 |
ACC_WIDTH=24 recommended as the new default (DEC-0013): higher mean
Fmax, much tighter variance, fewer resources, same bit-exact
correctness.
+126
View File
@@ -649,3 +649,129 @@ than M9 scope creep.
STATUS:
ACCEPTED
DEC-0012
DATE: 2026-09-05
DECISION:
For the LFE5U-45F-8BG381 target at P_IN=8, N_SLOTS=8 is the
recommended practical ceiling for dataflow_core's processor count (the
"numero processor" axis of M10). Beyond N_SLOTS=8, DSP usage would
exceed the chip's 72 total MULT18X18D (N_SLOTS=8 already uses 64/72 =
88.9%; N_SLOTS=9 would need 72/72 = 100%, leaving zero margin for any
other DSP use and very likely failing placement given routing
congestion already visibly eating into Fmax margin well before that
point).
WHY:
Real P&R data across the full N_SLOTS sweep now run (EXP-0003 at the
neural_processor_array level for M2, EXP-0008/EXP-0011 at the
dataflow_core level for M7/M10) shows TWO real, independent trends
converging on the same conclusion: (1) DSP usage scales exactly
linearly at 8 per slot (matches P_IN=8), hitting 88.9% at N_SLOTS=8 --
consistent with DEC-0005's original finding that DSP, not LUT/FF, is
the first resource to saturate; (2) Fmax falls monotonically and
non-linearly as N_SLOTS grows (165.15 -> 133.19 -> 92.63 MHz for
N_SLOTS=2/4/8), meaning routing congestion around the shared
neural_director/dependency_manager hub is ALREADY compounding with DSP
pressure well before the hard resource ceiling is reached. N_SLOTS=8
is therefore not merely "the largest N_SLOTS that fits" but close to
where BOTH constraints (DSP budget and real routing congestion)
become simultaneously binding -- a genuinely data-driven ceiling, not
an assumed one.
EVIDENCE:
timing.log/synthesis.log EXP-0008 (N_SLOTS=2: 165.15 MHz, 16/72 DSP;
N_SLOTS=4: 133.19 MHz, 32/72 DSP) and EXP-0011 (N_SLOTS=8: 92.63 MHz,
PASS at 80MHz but with a much thinner margin, 64/72 DSP) -- all real
nextpnr-ecp5 place&route measurements via harness_dataflow_core.v.
ALTERNATIVES:
1. Recommend a smaller N_SLOTS (e.g. 4) for a larger Fmax safety
margin. Rejected as a BLANKET recommendation: whether 133.19 MHz's
larger margin over 133.19 vs 92.63 MHz's thinner one actually
matters depends on the target application's own real timing needs,
which M9's benchmark did not fix to a specific number beyond
"PASS at 80MHz" -- both configurations real-measure as passing.
N_SLOTS=8 remains the data-driven CEILING; choosing a smaller
N_SLOTS for a specific deployment is a downstream product decision,
not something this session can make on the target's behalf.
2. Reduce P_IN below 8 to allow more slots within the same DSP budget
(e.g. P_IN=4, N_SLOTS=16 -> still 64 DSP). Rejected as untested:
no real data exists yet on Fmax/throughput for P_IN=4 slots at any
N_SLOTS -- this is a real, open experiment for a FUTURE session,
not something to recommend without having actually measured it
(§30).
RESULT:
N_SLOTS=8 (P_IN=8) is the data-driven practical ceiling on the
LFE5U-45F-8BG381 for dataflow_core/neural_multiprocessor. Smaller
N_SLOTS values remain valid, real-measured configurations trading
Fmax margin for less concurrency; a P_IN<8 exploration for even higher
N_SLOTS is explicitly flagged as untested future work, not assumed.
STATUS:
ACCEPTED
DEC-0013
DATE: 2026-09-05
DECISION:
ACC_WIDTH=24 is the recommended default for neural_processor.v's
accumulator width (the "pipeline" axis of M10), replacing EXP-0002's
original single-seed, inconclusive finding.
WHY:
A 6-seed real placement sweep (EXP-0012: default seed plus 5 explicit
--seed values, same two already-synthesized netlists, real
nextpnr-ecp5 P&R only -- no re-synthesis needed) shows ACC_WIDTH=24
has a HIGHER mean Fmax (180.71 vs 170.12 MHz, +6.2%) AND a much
tighter seed-to-seed spread (stdev 4.21 vs 14.16 MHz) than
ACC_WIDTH=32. EXP-0002's original single-seed result (176.21 <
183.12 MHz, suggesting ACC=24 was WORSE) is now understood as
placement-seed noise, not a real trend -- exactly the kind of mistake
a single-seed measurement risks, which is why §30/§31 call for
experimentally exploring configurations rather than trusting one
placement run. Combined with EXP-0001/EXP-0002's already-known
resource advantage (ACC_WIDTH=24: LUT=49/FF=509/CCU2C=88 vs
ACC_WIDTH=32: LUT=55/FF=533/CCU2C=96 -- fewer of every resource) and
both being bit-exact-correct against the same 7-test regression
(EXP-0001/EXP-0002), ACC_WIDTH=24 dominates ACC_WIDTH=32 on every real
axis measured for a plain INT8 perceptron whose products/partial sums
never need more than 24 bits of headroom for P_IN=8 (8 x int8 x int8
products, worst case magnitude fits well under 2^24).
EVIDENCE:
timing.log EXP-0012 (6-seed Fmax data for both configs, computed
mean/min/max/stdev); synthesis.log EXP-0001/EXP-0002 (resource
counts, already logged); simulation.log EXP-0001/EXP-0002 (both
configs bit-exact-correct against V1, 7/7 PASS).
ALTERNATIVES:
1. Keep ACC_WIDTH=32 as the default (matches V1's own mac_unit.v
accumulator width, "when in doubt, match the frozen baseline").
Rejected: real multi-seed data now shows ACC_WIDTH=24 is strictly
better on Fmax, resource usage, AND correctness for this specific
P_IN=8 INT8 configuration -- there is no real axis left on which
ACC_WIDTH=32 wins for THIS workload. V1 itself is a separate, frozen
baseline (§1/§34) and is not required to match V2's own internal
width choices.
2. Run more than 6 seeds per config for a tighter confidence interval.
Deferred, not rejected: 6 seeds already show a clear, consistent
direction (ACC=24 wins on both mean and variance) -- diminishing
returns for this decision's purposes; a future session could extend
the sweep if ACC_WIDTH ever becomes a live bottleneck again.
RESULT:
ACC_WIDTH default changed to 24 going forward for any NEW V2 module
instantiating neural_processor.v at P_IN=8 (no existing committed
module needs to be edited retroactively purely for this -- M1-M9's own
modules already default to ACC_WIDTH=32 via their own parameter
defaults and remain correct either way, since both widths are
bit-exact verified; this is a recommendation for future configuration
choices, not a mandate to re-synthesize already-logged results).
STATUS:
ACCEPTED
+32
View File
@@ -252,3 +252,35 @@ decision: vedi decisions.log DEC-0011 (stall %/utilization non
rimandata a M10 dove diventa direttamente utile).
next_action: M10 -- Optimization, sulla base dei dati reali raccolti
in M1-M9.
[2026-09-05] M10 -- Optimization (finale della roadmap V2, §33)
reason: roadmap M10 -- ottimizzare SOLO sulla base dei dati reali
raccolti in M1-M9, sugli assi: pipeline, P_IN, numero processor,
buffer, FIFO, scheduling, prefetch, routing, memoria.
result: tre azioni concrete, tutte basate su dati reali gia' raccolti
o su nuove misure reali mirate a colmare lacune gia' documentate:
(1) N_SLOTS=8 sintetizzato e P&R reale (92.63 MHz, PASS @80MHz,
DSP 64/72=88.9%) -- conferma e completa il limite gia' previsto da
DEC-0005, formalizzato come DEC-0012 (N_SLOTS=8 tetto pratico per
P_IN=8 su questo chip). (2) Sweep reale a 6 seed di piazzamento per
ACC_WIDTH 24 vs 32 (riusando i netlist gia' sintetizzati) -- risolve
l'inconcludenza a singolo seed di EXP-0002: ACC_WIDTH=24 vince sia
in Fmax medio (+6.2%) che in varianza (~3.4x piu' stretta),
formalizzato come DEC-0013 (ACC_WIDTH=24 nuovo default
raccomandato). (3) Strumentazione di conteggio cicli aggiunta al
testbench M8 (nessun RTL toccato) -- chiude la lacuna di
DEC-0011 con dati reali SIMULATED: porta PSRAM condivisa
utilizzata all'81.7%, slot0 al 95.2%, slot1 al 65.2% (nessuna prova
conclusiva di starvation dannosa su un test cosi' piccolo).
errors: nessuno.
decision: vedi decisions.log DEC-0012 e DEC-0013.
next_action: nessuna prevista dal mandato (§33 termina a M10) -- la
roadmap V2 a 10 milestone e' ora completa end-to-end, da M1 (singolo
neural_processor) a M9 (benchmark completo V1 vs V2) a M10 (risultati
di ottimizzazione basati sui dati). Elementi ancora aperti restano
tutti esplicitamente rimandati dalle proprie DEC entry (non
dimenticanze): riuso slot in dependency_manager (DEC-0008),
fairness dell'arbitro sotto contesa piu' estesa (DEC-0010), sweep
P_IN<8 per N_SLOTS ancora piu' alto (DEC-0012 alternativa #2), riuso
dei buffer M3 come cache condivisa (DEC-0009), strumentazione
stall%/utilization anche lato V1 (DEC-0011).
+50
View File
@@ -463,3 +463,53 @@ next_action: M10 -- Optimization, using the REAL data gathered in M1-
fairness question (DEC-0010) -- plus building the stall %/
utilization instrumentation DEC-0011 deferred, since M10 is exactly
where that data becomes actionable.
[2026-09-05] EXP-0011/EXP-0012/EXP-0013 -- M10 Optimization, only on
data already gathered (docs/v2-description.md M10: "Solo sulla base
dei dati: pipeline; P_IN; numero processor; buffer; FIFO; scheduling;
prefetch; routing; memoria.")
test/result summary (full detail in synthesis.log/timing.log/
simulation.log/benchmark.log under the same EXP numbers):
EXP-0011 ("numero processor" axis): dataflow_core N_SLOTS=8 real
synthesis+P&R (via harness_dataflow_core.v) -- 92.63 MHz POST-P&R,
PASS at 80MHz, DSP 64/72 (88.9%). Extends M7's N_SLOTS=2/4 sweep
to the real ceiling DEC-0005 predicted. See decisions.log DEC-0012
(N_SLOTS=8 recommended practical ceiling for P_IN=8).
EXP-0012 ("pipeline" axis): ACC_WIDTH 24-vs-32, 6 real placement
seeds each (reusing already-synthesized netlists, nextpnr-ecp5
P&R only) -- ACC_WIDTH=24 wins on both mean Fmax (+6.2%) and
variance (~3.4x tighter), resolving EXP-0002's single-seed
inconclusiveness. See decisions.log DEC-0013 (ACC_WIDTH=24
recommended new default).
EXP-0013 ("scheduling"/"memoria" axes): testbench-only cycle-
accounting instrumentation added to tb_neural_multiprocessor.v (no
RTL touched) -- closes decisions.log DEC-0011's deferred stall %/
utilization gap with real SIMULATED numbers (shared PSRAM port
81.7% utilized, slot 0 95.2%, slot 1 65.2%, N_SLOTS=2 3-node DAG).
No conclusive evidence of harmful fixed-priority starvation in
this small a test (slot 0's higher utilization is at least partly
explained by serving 2 sequential jobs vs slot 1's 1) --
decisions.log DEC-0010's arbiter fairness question remains
correctly deferred pending a larger, longer-running workload.
simulator: Verilator 5.050 (--binary --timing) for EXP-0013; Yosys +
real nextpnr-ecp5 for EXP-0011/EXP-0012 (no new simulation needed,
reused already-verified netlists/functional results).
PASS/FAIL: EXP-0013 4/4 PASS (unchanged from EXP-0009, instrumentation
is additive-only). EXP-0011/EXP-0012 are synthesis/P&R measurements,
not functional tests -- 0 synthesis problems, all P&R runs PASS at
80MHz.
errors: none this milestone.
decision: see decisions.log DEC-0012 (N_SLOTS=8 ceiling) and DEC-0013
(ACC_WIDTH=24 new default).
next_action: none mandated by docs/v2-description.md's own roadmap
(§33 ends at M10) -- the 10-milestone V2 roadmap is now complete
end-to-end, from M1's single neural_processor through M9's full
V1-vs-V2 benchmark to M10's data-driven optimization findings.
Remaining open items (all explicitly deferred by their own DEC
entries, not oversights): dependency_manager node-slot reclamation
(DEC-0008), slot_mem_arbiter fairness under sustained/larger
contention (DEC-0010, now informed by EXP-0013's small-scale data),
a P_IN<4 sweep at higher N_SLOTS (DEC-0012's alternative #2), M3
buffer reuse as a shared cache once real bandwidth pressure is
measured (DEC-0009), and V1-side stall%/utilization instrumentation
to complete the M9 table's V1 column (DEC-0011).
+23
View File
@@ -95,3 +95,26 @@ PASS/FAIL: 4/4 PASS after fixing a real dropped-request bug in the
regression: hardware/v2/sim/tb_memory_manager.v (M4) re-run unchanged
(no M4 file touched) -- still 3/3 PASS, identical cycle counts
(446/166/728), confirming slot_mem_arbiter.v is purely additive.
[2026-09-05] EXP-0013 -- hardware/v2/sim/tb_neural_multiprocessor.v,
M10 cycle-accounting instrumentation (closes decisions.log DEC-0011's
deferred stall %/utilization gap with real data, testbench-only
addition, no RTL touched)
test: same EXP-0009 scenario (3-node DAG, N_SLOTS=2, real V1 PSRAM
chain, real slot_mem_arbiter contention), instrumented with cycle
counters (shared PSRAM port busy cycles via
u_nmp.u_arbiter.owner!=0, each slot's memory_manager busy cycles via
its own state!=MM_IDLE), measured from the first node registration
to test completion.
simulator: Verilator 5.050 (--binary --timing)
PASS/FAIL: 4/4 PASS (unchanged from EXP-0009), plus real measured
data: 684 total cycles measured; shared PSRAM port busy 559/684
(81.7% utilization, 18.3% idle); slot 0 (memory_manager) busy
651/684 (95.2%); slot 1 (memory_manager) busy 446/684 (65.2%).
note: slot 0's higher utilization is at least partly explained by it
serving TWO sequential jobs in this run (node0, then whichever slot
frees first serves node2 -- likely slot 0, first-free/lowest-index)
while slot 1 only ever serves node1 -- NOT conclusive evidence of
harmful priority starvation on its own; see decisions.log DEC-0010's
original fairness deferral, now informed by this real (if small)
data point.
+11
View File
@@ -76,3 +76,14 @@ $_TBUF_=16 (tri-state buffers for the bidirectional psram_dq bus,
from V1's own unmodified psram_controller.v)
CHECK: 0 problems (same 32 benign "multiple conflicting drivers for
...neural_processor.\gi" warnings documented since EXP-0001).
[2026-09-05] EXP-0011 -- dataflow_core N_SLOTS=8 (M10, "numero
processor" axis, via harness_dataflow_core.v, extending M7's own
N_SLOTS=2/4 sweep to the real DSP ceiling predicted by DEC-0005)
LUT4=6439 CCU2C=996 TRELLIS_FF=9053 MULT18X18D=64 (64/72=88.9% of
the LFE5U-45F's total DSP budget -- matches DEC-0005's M2-era
prediction almost exactly, since dataflow_core's per-slot DSP cost
is just neural_processor's own P_IN=8 DSP cost x N_SLOTS)
DP16KD=0 (expected, DEC-0009). CHECK: 0 problems (same benign
"multiple conflicting drivers" warnings as every other neural_processor
instantiation since EXP-0001).
+31
View File
@@ -70,3 +70,34 @@ configs still clear the 80MHz target with real margin.
standalone synthesis, no harness needed), real nextpnr-ecp5 --45k
--package CABGA381 --speed 8 --freq 80 --lpf-allow-unconstrained
Fmax: 142.45 MHz -- PASS at 80MHz (real place&route measurement)
[2026-09-05] EXP-0011 -- dataflow_core N_SLOTS=8 (via
harness_dataflow_core.v), real nextpnr-ecp5 --45k --package CABGA381
--speed 8 --freq 80 --lpf-allow-unconstrained
Fmax: 92.63 MHz -- PASS at 80MHz (real place&route measurement), but
with a much thinner margin than N_SLOTS=2 (165.15 MHz) or N_SLOTS=4
(133.19 MHz) -- Fmax falls monotonically with N_SLOTS (165.15 ->
133.19 -> 92.63 MHz for N_SLOTS=2/4/8) as routing congestion around
the shared neural_director/dependency_manager hub grows, while DSP
usage (88.9% at N_SLOTS=8) approaches its hard ceiling at the same
time -- see decisions.log DEC-0012.
[2026-09-05] EXP-0012 -- ACC_WIDTH 24 vs 32 real placement-seed sweep
(M10, "pipeline" axis, resolving EXP-0002's single-seed
inconclusiveness), 5 additional real nextpnr-ecp5 seeds (1-5) plus the
original default-seed run (EXP-0001/EXP-0002), same synthesized
netlists (hardware/v2/synthesis/neural_processor_p8/top.json and
neural_processor_p8_acc24/top.json), --45k --package CABGA381 --speed
8 --freq 80 --lpf-allow-unconstrained
ACC_WIDTH=32: seeds [default,1,2,3,4,5] -> [183.12, 164.85, 174.25,
168.83, 183.96, 145.73] MHz. n=6, mean=170.12 MHz, min=145.73 MHz,
max=183.96 MHz, stdev=14.16 MHz.
ACC_WIDTH=24: seeds [default,1,2,3,4,5] -> [176.21, 183.72, 180.57,
183.08, 185.49, 175.16] MHz. n=6, mean=180.71 MHz, min=175.16 MHz,
max=185.49 MHz, stdev=4.21 MHz.
Conclusion: over 6 real placement seeds, ACC_WIDTH=24 has a HIGHER
mean Fmax (+10.6 MHz, +6.2%) AND a much lower seed-to-seed variance
(stdev 4.21 vs 14.16 MHz, ~3.4x tighter) than ACC_WIDTH=32 --
EXP-0002's single-seed result (176.21 < 183.12, i.e. ACC=24 looked
WORSE) was placement-seed noise, not a real trend. See decisions.log
DEC-0013.