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:
2026-09-20 08:13:15 +02:00
co-authored by Claude Sonnet 5
parent 78577dde59
commit 43a12379a5
11 changed files with 946 additions and 682 deletions
+98
View File
@@ -4933,3 +4933,101 @@ checkpoint. Remaining open work (scaling past N=2, a real activation-
fetch engine, PCB-specific pin constraints once the board layout is
underway, ESP32-side JTAG bootstrap firmware) is all disclosed and
outside this experiment's own scope.
EXP-0079 -- MILESTONE: real activation-fetch engine built, closing
the last major disclosed functional gap; full N=2 system re-verified
end-to-end with REAL DDR3 for BOTH weights and activations
(2026-09-20, same autonomous continuation, user's own explicit
request: "completiamo quello che manca per avere un codice ready to
use nell'hardware fisico")
CONTEXT: packed_slot.v's own header had disclosed, since EXP-0062,
that activation data was read through a combinational stand-in port
(act_tile_addr_a/b -> act_tile_data_a/b), with a real fetch engine
explicitly deferred. This was the single largest remaining gap between
"a verified compute architecture" and "a system that can actually run
on real data in real DDR3".
DESIGN: new hardware/v3/rtl/act_tile_fetch.v -- unlike the weight path
(prefetched once into an on-chip buffer, reused across many read-outs
per job), activation data has NO reuse (read exactly once per
position), so this engine reads DIRECTLY from DDR3 per tile, no
on-chip buffering. Reuses the SAME per-slot ctrl_req/addr/etc port
layer_prefetch_ctrl.v already owns (mutually exclusive in time by FSM
construction -- weight prefetch always fully completes before the
tile loop that needs activation data starts), muxed inside packed_slot.v
on a new act_mem_active signal. Two sequential burst reads per tile
request (lane A then lane B), with an explicit ctrl_busy wait between
them (mig_native_adapter.v's own S_DONE tail can keep busy asserted
one cycle past ready -- checked explicitly, not assumed safe).
MEMORY LAYOUT (a new, real, disclosed requirement): each tile occupies
its own full BURST_LEN=8-word burst slot (P_IN=8 bytes in the low 64
bits, upper 64 bits padding) -- deliberately 2x wasteful of DDR3
capacity, in exchange for needing ZERO runtime-indexed part-select in
the fetch logic (weight_tile_gather.v, EXP-0061, already flagged that
pattern as a real Fmax risk, and this project's P&R margin is
currently thin, EXP-0078 WNS +0.013ns -- not the moment to introduce a
new critical path). Documented in the new hardware/v3/constraints
physical doc for whoever prepares host-side data layout.
packed_slot.v's own S_TILEWAIT state was restructured into a real
two-source JOIN: latches (tile_seen/act_seen) independently track
whether the (fast, on-chip) weight tile and the (real-DDR3-latency)
activation tile have each arrived, proceeding to S_OPERAND only once
BOTH have been seen, correctly handling either arrival order (not just
the expected common case of weight-first).
VERIFICATION (three levels, matching this project's own "one variable
at a time" discipline):
1. hardware/v3/sim/tb_act_tile_fetch.v -- act_tile_fetch.v alone
against the SDR SDRAM placeholder: 6/6 PASS on the first real run
(no bugs found -- the nonblocking-assignment stimulus idiom,
already standard practice since EXP-0073/0075/0077, avoided the
testbench-race class that has bitten every PREVIOUS new module's
first draft in this project).
2. hardware/v3/sim/tb_packed_slot.v -- rewritten to preload REAL
activation data into the SDR placeholder (same technique already
used for weights) instead of a combinational lookup stand-in;
the OLD decimal-encoded x_base convention (li*100000+pos*1000)
was replaced by the new real word-address convention. 9/9 PASS,
0 errors, on the first real run after fixing one Verilog syntax
issue (can't part-select a function call's return value inline
in this dialect -- assign to a temp variable first).
3. hardware/v3/sim/tb_n2_system_ddr3.v -- the full real N=2 system
(Director + 2 packed_slot + arbiter + MIG + real ddr3_model.sv),
same update pattern, re-run via real xsim. **8/8 tests, 0 errors,
8/8 positions completed, bit-exact against the golden model --
the first time this project's compute path has been verified
end-to-end against REAL DDR3 for BOTH weights and activations,
not just weights.**
INTEGRATION: n2_system_ddr3_top.v (the real synthesis target) updated
to remove the old activation-stub top-level wiring entirely (the
free-running-counter stand-in from EXP-0074, itself a fix for an
earlier mistake of exposing act_addr/data as literal chip pins) --
activation fetch is now fully internal to each packed_slot instance,
using ports that already existed for other reasons. Net effect: FEWER
top-level signals than before, not more.
RETIRED (superseded, not fixed-in-place): hardware/v3/rtl/n2_system_top.v
and hardware/v3/sim/tb_np_director_n2_system.v (the pre-DDR3, SDR-
placeholder-era N=2 top/test, EXP-0066/0067) -- fully superseded by
n2_system_ddr3_top.v/tb_n2_system_ddr3.v, would have needed the exact
same class of update for zero forward benefit. Removed via `git rm`,
fully recoverable from git history if ever needed.
DECISION: this closes the last major disclosed FUNCTIONAL gap in the
V3 compute pipeline -- real DSP-packed cores, real weight-reuse
scheduling, real N-way arbitration, real DDR3 for BOTH weights and
activations, real host SPI protocol (jobs/registers/raw memory/config-
flash), all verified together end to end. What remains open (scaling
past N=2, PCB-specific pin finalization, ESP32 firmware) is genuinely
separate, disclosed, non-blocking work -- not a hidden correctness gap.
next_action: real in-context P&R re-verification (the activation
engine adds real logic on a path that matters -- EXP-0078's own margin
was already thin, +0.013ns, before this addition) -- must re-confirm
timing still closes before calling this "ready to use in physical
hardware". Also: finalize and commit docs/PHYSICAL_REALIZATION.md
(drafted this session, real pin/part/protocol/layout data).