From 0303aacb9fa58b32af59265c415b8705dd11f4d6 Mon Sep 17 00:00:00 2001 From: manvalan Date: Tue, 22 Sep 2026 01:15:15 +0200 Subject: [PATCH] docs: consolidate N=16 to N=8's own level of rigor (EXP-0098) -- whole family real and closed N=2 re-verified with the same shared pipelined neural_processor_packed.v (EXP-0097's fix): real functional xsim 8/8 PASS (identical completion time to the pre-fix baseline), real full P&R WNS=+0.389ns (up from +0.099962ns), 0 failing endpoints, 16 DSP48E1 -- no regression. Real, consolidated family state, all sharing the same pipelined core: N=2: WNS=+0.389ns, 16 DSP48E1, 8/8 functional PASS N=8: WNS=+0.108ns, 64 DSP48E1, 16/16 functional PASS N=16: WNS=+0.269ns, 128 DSP48E1, 32/32 functional PASS Updated the project's own primary real docs (docs/PHYSICAL_REALIZATION.md S3, docs/ARCHITECTURE_ANALYSIS.md S5.6) to the same depth EXP-0096 gave N=8 alone -- not just the docs/latex/ deliverables. Clear two-track framing throughout: the physically fabricated board still uses N=8's original, unmodified core (WNS=0.000ns exact); this consolidated, improved family lives on the isolated n16-timing-closure branch, pending a real hardware decision on whether/when to adopt it. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01MUG92aM9m68TRc4rG55BcC --- docs/ARCHITECTURE_ANALYSIS.md | 104 +++++++++++++++++++++++++------ docs/PHYSICAL_REALIZATION.md | 102 +++++++++++++++++++----------- hardware/v2/logs/experiments.log | 49 +++++++++++++++ 3 files changed, 198 insertions(+), 57 deletions(-) diff --git a/docs/ARCHITECTURE_ANALYSIS.md b/docs/ARCHITECTURE_ANALYSIS.md index e87929b..c826a67 100644 --- a/docs/ARCHITECTURE_ANALYSIS.md +++ b/docs/ARCHITECTURE_ANALYSIS.md @@ -1,15 +1,16 @@ # FPGA-Neural V3 — Architecture Analysis: Timing, Bottlenecks, and Recommended Interventions Scope: the current, real, P&R-verified V3 design (`hardware/v3/`, branch -`v3-artix7`), updated through EXP-0095/0096 (N=8 hybrid systolic, real, -closed timing — the current, definitive real deployment target, chosen -by the user after a real, measured N=4/8/16 timing curve). The current -real, trustworthy *timing* signoff is now EXP-0095/0096 -(`n8_system_ddr3_top.v`, 32-bit DDR3, 155.039MHz, WNS 0.000ns, 8 real -parallel PEs), replacing EXP-0088's own N=2 pointer (which itself -replaced EXP-0086's, which replaced EXP-0083's 16-bit-era one). See §5.6 -for the full real story, including N=16's own real RTL (functionally -verified but NOT timing-closed, kept as documented future work). Every +`v3-artix7` for the physically-fabricated board; branch +`n16-timing-closure` for the real, consolidated follow-up below), +updated through EXP-0097/0098 (a real MAC-pipeline fix that closes +timing for the WHOLE real family — N=2/N=8/N=16 — not just N=8). The +board **currently in physical fabrication** uses N=8's own original, +unmodified EXP-0095/0096 signoff (`n8_system_ddr3_top.v`, 32-bit DDR3, +155.039MHz, WNS=0.000ns exact, 8 real parallel PEs). Separately, on an +isolated real branch, EXP-0097/0098 found that one shared-core fix +closes N=16 too (WNS=+0.269ns) and improves N=2 (+0.389ns) and N=8 +(+0.108ns) as well — see §5.6 for the full real story. Every number in this document is either directly measured (real simulation trace, real P&R report) or a calculation built from directly-measured building blocks — the two are labeled @@ -664,7 +665,7 @@ specifically to document where/how it breaks rather than to succeed): --- -### 5.6 [N=8 IS THE REAL, DEFINITIVE DEPLOYMENT TARGET — `n8_system_ddr3_top.v`, EXP-0089…0096] Hybrid systolic scaling: up to 4 groups × 4-PE weight-stationary chains +### 5.6 [WHOLE FAMILY CLOSED — N=2/N=8/N=16, EXP-0089…0098] Hybrid systolic scaling: up to 4 groups × 4-PE weight-stationary chains Captured from a 2026-09-20 brainstorming session as a purely exploratory idea; the same day, per the user's own explicit reprioritization, the real @@ -857,16 +858,79 @@ lanes exercised exactly once): **real functional xsim, 16/16 PASS, 0 errors** — closes the real, disclosed functional-verification gap this section previously flagged for N=8 specifically. -**Current real status: N=8 (`n8_system_ddr3_top.v`) is BOTH -functionally verified AND timing-closed under its own permanent real -name — the definitive deployment target.** N=2 (`n2_system_ddr3_top.v`, -EXP-0088) remains documented as a real, valid, simpler fallback. N=16 -(`n16_system_ddr3_top.v`) remains real, functionally-verified RTL, not -abandoned, just not timing-closed and not the current target. Real, -disclosed caveat carried forward: N=8's WNS=0.000ns is an exact-zero -margin — any future RTL change touching this top-level or its -dependents needs a fresh real P&R (same `Explore`/`ExtraNetDelay_high`/ -`AggressiveExplore` directive stack) before trusting timing again. +**Current real status (physical board): N=8 (`n8_system_ddr3_top.v`) +is BOTH functionally verified AND timing-closed under its own +permanent real name — the configuration currently in physical +fabrication.** N=2 (`n2_system_ddr3_top.v`, EXP-0088) remains +documented as a real, valid, simpler fallback. Real, disclosed caveat: +N=8's original WNS=0.000ns is an exact-zero margin — any future RTL +change touching this top-level or its dependents needs a fresh real +P&R before trusting timing again. **This exact-zero margin is what +motivated EXP-0097/0098 below.** + +#### 5.6.1 [DONE, EXP-0097/0098] The whole family closes: a real MAC-pipeline fix, branch `n16-timing-closure` + +**Context**: N=16's own real, traced remaining bottleneck (after the +hierarchical arbiter + P&R directive tuning already closed most of the +gap, WNS −0.913ns → −0.338ns, EXP-0094) was inside `neural_processor_ +packed.v`'s own DSP48E1 MAC datapath — a pre-existing, N=2-era design +(unchanged since EXP-0059) with an already razor-thin real margin +(+0.099962ns) that N=16's own higher real die congestion eroded past +zero, and that N=8's own real signoff (§5.6, EXP-0095/0096) closed at +an exact zero with no slack to spare. + +**Real root cause** (traced to the exact register-to-register hop, not +guessed): the critical path ran from a DSP48E1's own (Vivado-auto- +retimed) product register, straight through the real carry-heavy +INT8-unpack logic (`pb_comb`'s own shift + conditional +1 +carry-propagate add, CARRY4-dominated), into `proda1`/`prodb1` in a +SINGLE real cycle. + +**Real fix**: split the original single pipeline stage into two real +stages — Stage 1a registers the RAW DSP48E1 product with zero logic in +between (a real, explicit register boundary immediately after the +multiply); Stage 1b does the carry-heavy unpack FROM the already- +registered value (unchanged real math, now one real cycle later). Real, +deliberate consequence: end-to-end per-tile latency grows by exactly +ONE real clock cycle; throughput is unaffected (real valid/ready +handshaking throughout, no fixed-latency assumption anywhere +downstream). + +**Real bug found and fixed in the testbench first** (not an RTL bug): +`tb_neural_processor_packed.v`'s own comparison logic required all +three cores (2 real reference `neural_processor.v` instances + the +DUT) to assert `result_valid` simultaneously — correct only when all +three share the exact same real pipeline depth, no longer true once +the DUT is deliberately one real cycle deeper. Fixed by latching each +core's own result independently the cycle its own `result_valid` +first pulses, then comparing the three LATCHED values. + +**Real, consolidated result — EVERY real top-level this project has, +same shared pipelined core, real functional xsim + real, full P&R**: + +| Target | Real WNS | Real DSP48E1 | Real functional test | +|---|---|---|---| +| N=2 (`n2_system_ddr3_top.v`) | +0.389ns (up from +0.099962ns) | 16 (6.67%) | 8/8 PASS | +| N=8 (`n8_system_ddr3_top.v`) | +0.108ns (up from 0.000ns exact) | 64 (26.7%) | 16/16 PASS | +| N=16 (`n16_system_ddr3_top.v`) | **+0.269ns** (up from −0.338ns FAILED) | 128 (53.3%) | 32/32 PASS | + +A real margin-hunt attempt for even more N=16 headroom (alternate P&R +directives) gave a WORSE real result (+0.168ns vs. the original ++0.269ns) — confirms real P&R run-to-run variance, not a further +systematic gain available without touching more RTL (the new N=16 +worst path, after this fix, moved to `neural_director_grouped.v`'s own +queue update logic, still real route-dominated — not pursued further, +current margin already comfortable). + +**Decision**: this fix is a pure, unconditional real improvement +across the whole real family — no regression anywhere, real margin +improves at every N, N=16 goes from real FAILING to real CLOSED. It is +**not yet applied to the physically fabricated board** (which uses the +original, unmodified N=8 core) — adopting it (and/or moving to N=16) +for a future board revision is a real, open hardware decision, not an +RTL blocker. A real Vivado incremental-synthesis quirk was also found +and fixed along the way (a parameter binding silently carried forward +from an earlier `-generic` run despite `reset_run` — see CLAUDE.md). **The problem it targets**: plain N=16 independent cores (§5.5's own "documentary, expected to break" framing) means 16 independent DDR3 diff --git a/docs/PHYSICAL_REALIZATION.md b/docs/PHYSICAL_REALIZATION.md index 6c98638..22f2051 100644 --- a/docs/PHYSICAL_REALIZATION.md +++ b/docs/PHYSICAL_REALIZATION.md @@ -165,25 +165,39 @@ these from an ESP32 doing real JTAG bit-banging (TAP state machine, IR/DR shifting) rather than a bench programmer — that firmware is separate, software-side work, not covered here. -## 3. Real timing signoff (EXP-0095/0096, the current, definitive target — N=8 hybrid systolic, `n8_system_ddr3_top.v`, CLOSED) +## 3. Real timing signoff — N=8 in physical fabrication; N=2/N=8/N=16 all real, closed on branch `n16-timing-closure` (EXP-0095…0098) -**This is the real, definitive deployment target as of 2026-09-21** -(the user's own explicit decision, after a real, measured N=4/8/16 -timing curve found N=8 to be the largest real configuration that -closes timing cleanly — see `docs/ARCHITECTURE_ANALYSIS.md` §5.6 for -the full real story). Top-level RTL: `hardware/v3/rtl/ -n8_system_ddr3_top.v` — 2 groups × 4 PEs, shared-weight-broadcast -systolic architecture (`systolic_group.v`/`packed_pe.v`, -`neural_director_grouped.v`, `sdram_arbiter_hier.v`'s own real -hierarchical 2-level arbiter), same real DDR3/SPI/flash bridge as -every other real V3 top-level. Real in-context Vivado place-and-route -(not out-of-context, not estimated): +**Real, current, two-track status (2026-09-22)**: the **physical board +currently being fabricated** uses **N=8** (`hardware/v3/rtl/ +n8_system_ddr3_top.v`, unmodified, EXP-0095/0096 signoff below) — this +was the real, definitive decision made on 2026-09-21 after a real, +measured N=4/8/16 timing curve found N=8 the largest configuration +that closed cleanly at the time. Separately, on an isolated real +development branch (`n16-timing-closure`, does NOT affect the board +already in fabrication), a real fix (EXP-0097 — an extra real pipeline +stage in `neural_processor_packed.v`'s own MAC datapath, see +`docs/ARCHITECTURE_ANALYSIS.md` §5.6) has since **closed real timing +for N=16 too, and improved N=2's and N=8's own margins** — the whole +real product family (N=2/N=8/N=16) now closes with positive margin +under that fix. Whether/when to adopt this fix for a future board +revision (potentially N=16) is a real, open hardware decision, not an +RTL blocker — see `docs/ARCHITECTURE_ANALYSIS.md` §5.6 for the full +story. + +### 3.0 N=8, in physical fabrication (`n8_system_ddr3_top.v`, EXP-0095/0096, unmodified core) + +Top-level RTL: `hardware/v3/rtl/n8_system_ddr3_top.v` — 2 groups × 4 +PEs, shared-weight-broadcast systolic architecture +(`systolic_group.v`/`packed_pe.v`, `neural_director_grouped.v`, +`sdram_arbiter_hier.v`'s own real hierarchical 2-level arbiter), same +real DDR3/SPI/flash bridge as every other real V3 top-level. Real +in-context Vivado place-and-route (not out-of-context, not estimated): | Metric | Value | |---|---| | DDR3 PHY clock (sys_clk_p/n) | **310.078 MHz** (3.225ns period) | | Compute domain clock (ui_clk/clk_pll_i, PLL-derived 2:1 from sys_clk) | **155.039 MHz** | -| WNS (setup slack) | **0.000 ns** — real, closed, 0 failing setup endpoints (EXP-0095/0096). Re-verify with a fresh P&R after ANY further logic addition — this margin is exactly zero, no slack to spare. | +| WNS (setup slack) | **0.000 ns** — real, closed, 0 failing setup endpoints (EXP-0095/0096). This is the exact RTL physically being fabricated. | | WHS (hold slack) | +0.017 ns | | Failing endpoints | 0 of 63212 (setup), 0 of 63209 (hold) | | LUTs used | 12535 / 63400 (19.77%) | @@ -200,20 +214,31 @@ real, closed, but with zero slack. Re-run a real P&R (same ExtraNetDelay_high` / `phys_opt_design -directive AggressiveExplore` / `route_design -directive AggressiveExplore` directive stack used to reach this result, EXP-0094/0095) after ANY further RTL change before -trusting timing again — do not assume it still holds. +trusting timing again — do not assume it still holds. This zero-margin +result is exactly why EXP-0097's own pipeline fix (below) was pursued. -**Superseded, real predecessor signoff (N=2, flat architecture, -`n2_system_ddr3_top.v`, EXP-0088)** — kept below for reference; still -a real, valid, simpler fallback target if N=8's zero-margin closure -ever proves too fragile in practice: +### 3.0.1 The real, consolidated family — EXP-0097/0098, branch `n16-timing-closure` (not yet on the fabricated board) -| Metric | Value | -|---|---| -| WNS (setup slack) | +0.099962 ns | -| WHS (hold slack) | +0.036275 ns | -| LUTs used | 6642 / 63400 (10.48%) | -| DSP48E1 used | 16 / 240 (6.67%) — 8 per compute core × 2 cores | -| Real parallelism | 2 real parallel processing elements | +A single real fix (`neural_processor_packed.v`, an extra real pipeline +stage in the packed-MAC datapath — full real root-cause story in +`docs/ARCHITECTURE_ANALYSIS.md` §5.6) applies identically to every +real top-level in the family (it's the SAME shared compute core). Real +functional xsim + real, full P&R, every real configuration this +project has a dedicated top-level for: + +| Target | Top-level | Real WNS | Real DSP48E1 | Real functional test | +|---|---|---|---|---| +| N=2 | `n2_system_ddr3_top.v` | **+0.389 ns** (up from +0.100ns) | 16/240 (6.67%) | 8/8 PASS | +| N=8 | `n8_system_ddr3_top.v` | **+0.108 ns** (up from 0.000ns exact) | 64/240 (26.7%) | 16/16 PASS | +| N=16 | `n16_system_ddr3_top.v` | **+0.269 ns** (up from −0.338ns FAILED) | 128/240 (53.3%) | 32/32 PASS | + +**Real, honest takeaway**: this fix is a pure, unconditional +improvement across the whole real family — no regression found +anywhere, real margin improves at every N, and N=16 goes from real +FAILING to real CLOSED. It is not yet applied to the physically +fabricated board (which uses the original, unmodified N=8 core, +§3.0) — that board's own real signoff (WNS=0.000ns) remains accurate +for the hardware actually being built. Signoff history (every real change, in-context P&R): @@ -230,7 +255,10 @@ Signoff history (every real change, in-context P&R): | 0088 (+result-writeback engine, `result_writeback.v`) | N=2 | +0.100 (CLOSED) | 6642 | 16 | | 0093 (hybrid systolic, flat 21-way arbiter) | N=16 | -0.913 (FAILED) | 19751 | 128 | | 0094 (+hierarchical 2-level arbiter, +P&R directive tuning) | N=16 | -0.338 (still FAILED) | 19936 | 128 | -| 0095/0096 (`n8_system_ddr3_top.v`, hybrid systolic) | **N=8** | **0.000 (CLOSED)** | 12535 | 64 | +| 0095/0096 (`n8_system_ddr3_top.v`, hybrid systolic — **in physical fabrication**) | **N=8** | **0.000 (CLOSED)** | 12535 | 64 | +| 0097/0098 (+MAC pipeline fix, branch `n16-timing-closure`) | N=2 | +0.389 (CLOSED) | 6645 | 16 | +| 0097/0098 (+MAC pipeline fix, branch `n16-timing-closure`) | N=8 | +0.108 (CLOSED) | 12536 | 64 | +| 0097/0098 (+MAC pipeline fix, branch `n16-timing-closure`) | **N=16** | **+0.269 (CLOSED)** | 19903 | 128 | ### 3.1 Real 32-bit DDR3 widening — functionally verified AND timing CLOSED (EXP-0084 → EXP-0086) @@ -397,17 +425,17 @@ when it actually fires, instead of polling every loop iteration. ## 7. Known-open items (honestly disclosed, not hidden) -- Scaling past N=2 compute cores: **RESOLVED, real N=8 is now the - definitive deployment target** (§3, EXP-0095/0096, `n8_system_ddr3_ - top.v`, a real hybrid systolic shared-weight-broadcast architecture, - 2 groups × 4 PEs, WNS=0.000ns CLOSED). Real N=4/8/16 P&R curve - measured: N=4 −0.005ns (2 failing endpoints, essentially at the - edge), N=8 **0.000ns (CLOSED)**, N=16 −0.338ns (still failing even - after a real hierarchical-arbiter fix + P&R directive tuning, EXP- - 0093/0094) — see `docs/ARCHITECTURE_ANALYSIS.md` §5.6 for the full - real story. N=16 remains real, functionally verified RTL - (`n16_system_ddr3_top.v`), just not yet timing-closed; not the - current real deployment target. +- Scaling past N=2 compute cores: **RESOLVED, N=8 is the configuration + in physical fabrication** (§3.0, EXP-0095/0096, `n8_system_ddr3_ + top.v`, WNS=0.000ns CLOSED). **UPDATE (EXP-0097/0098)**: a real MAC- + pipeline fix, developed on an isolated branch (`n16-timing-closure`, + does not affect the board in fabrication), closes real timing for + N=16 too (WNS=+0.269ns) and improves N=2's and N=8's own margins + (+0.389ns, +0.108ns respectively) — see §3.0.1 and + `docs/ARCHITECTURE_ANALYSIS.md` §5.6 for the full real story. N=16 + is no longer blocked by a real timing problem; whether to adopt it + for a future board revision is now a real hardware decision, not an + RTL one. - `sys_rst` has only a *tentative* real pin (G13, bank 15, EXP-0084 — chosen just to unblock real P&R, not a final board decision) — assign its real, permanent location once the rest of the board layout (reset diff --git a/hardware/v2/logs/experiments.log b/hardware/v2/logs/experiments.log index 541f84e..1c8f6ca 100644 --- a/hardware/v2/logs/experiments.log +++ b/hardware/v2/logs/experiments.log @@ -6962,3 +6962,52 @@ N=8 design, unaffected), and/or (2) actually build the NEXT physical board as N=16 instead of N=8, given N=16 is now real, functionally verified, AND timing-closed with a real, comfortable margin -- a real, consequential hardware decision, not an RTL one. + +EXP-0098 -- consolidating N=16 to the same real rigor as N=8: N=2 +re-verified too (the pipelined MAC core is SHARED across the whole +real family), full real family state now closed at every N +(2026-09-22, user's own explicit direction: "consolidare N=16 come +faccio con N=8") + +CONTEXT: EXP-0097 verified the pipelined `neural_processor_packed.v` +against N=8 and N=16, but never against N=2 -- a real, disclosed gap, +since N=2 (`n2_system_ddr3_top.v`) is the SAME shared core and remains +this project's own documented real fallback signoff (EXP-0088). +Consolidating N=16 to N=8's own level of rigor means confirming the +WHOLE real family, not just the two configurations directly asked +about. + +REAL RESULT: functional xsim (`tb_n2_system_ddr3.v`, real DDR3 model): +**8/8 PASS, 0 errors**, `$finish` at the EXACT SAME real completion +time as the pre-fix baseline (101204.9335ns) -- zero observable +end-to-end effect at this scale, same as N=16's own real finding. +Real, full P&R (`n2_system_ddr3_top.v`, real XC7A100T-CSG324-2, same +directive stack): **WNS=+0.389ns (up from the original real ++0.099962ns), WHS=+0.017ns, 0 failing endpoints, 16 DSP48E1 (6.67%), +6645 LUTs (10.48%)** -- a real, substantial margin improvement, no +regression. + +REAL, CONSOLIDATED FAMILY STATE (branch `n16-timing-closure`, all +three real top-levels sharing the SAME pipelined `neural_processor_ +packed.v`, all real, functionally verified AND timing-closed): + + N=2 (`n2_system_ddr3_top.v`): WNS=+0.389ns, 16 DSP48E1, 8/8 functional PASS + N=8 (`n8_system_ddr3_top.v`): WNS=+0.108ns, 64 DSP48E1, 16/16 functional PASS + N=16 (`n16_system_ddr3_top.v`): WNS=+0.269ns, 128 DSP48E1, 32/32 functional PASS + +DECISION: the real MAC-pipeline fix (EXP-0097) is a pure, unconditional +improvement across the entire real product family -- every real +configuration this project has ever built a dedicated top-level for +now closes with real, comfortable, positive margin, not just N=16. No +real regression found anywhere. This is now a real, trustworthy, +fully-consolidated state for this branch, at the same level of rigor +EXP-0096 established for N=8 alone. + +next_action: update the project's own primary real docs +(`docs/PHYSICAL_REALIZATION.md` §3, `docs/ARCHITECTURE_ANALYSIS.md` +§5.6 and its own top-of-document pointer) on this branch to reflect +this consolidated real family state -- not yet done, the LaTeX +deliverables (`docs/latex/*.tex`) were updated first per the user's +own more immediate request, but the markdown docs are this project's +own real, authoritative source of truth per CLAUDE.md's own "Read +first" section and deserve the same update.