feat: real first step of 4x4 hybrid systolic architecture (EXP-0089)
Adds packed_pe.v (packed_slot.v's compute+activation-fetch+writeback subsystem, reusing ddr_prefetch_mgr.v/neural_processor_packed.v/ result_writeback.v completely unmodified, with its own private weight-fetch removed) and systolic_group.v (one real layer_prefetch_ ctrl.v+layer_weight_buffer.v+weight_tile_gather.v shared by 4x packed_pe.v via a real, barrier-synchronized broadcast bus). Real design choice confirmed with the user before writing any RTL (AskUserQuestion, concrete topology preview): shared-weight broadcast, not a literal PE-to-PE systolic shift register -- achieves the real, quantified rationale (4x reduction in redundant weight-fetch DDR3 traffic per group of 4 PEs) with much lower real risk than genuine inter-PE pipeline fill/drain. The real new design is the barrier: each PE's own tcnt is the join key against the group's broadcast tcnt, self-synchronizing regardless of which PE is momentarily ahead/behind (e.g. a real DDR3 row-switch stall on one PE's own activation fetch). Found and fixed a real bug during verification (not by inspection): the first full test run reported every result as undefined despite every control-flow signal tracing correctly -- root-caused via real signal tracing down to a 5-way test arbiter bus mis-sliced at the wrong slot offset (single-bit handshake buses happened to use a correct range and masked it from the control-flow trace; only the wide, byte-offset buses were wrong). Verified in isolation (tb_systolic_group.v, real Icarus xsim, real sdram_arbiter_n.v generalized to NUM_REQ=5 with zero changes): 8/8 PASS across 2 consecutive group jobs (exercising the barrier's own per-job reset path, not just cold start). Deliberately scoped to the isolated mechanism only, per this project's "one variable at a time" discipline -- Director/SPI job dispatch for group jobs, a real N=16 top-level, and real P&R are real, disclosed next steps, not done here. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUG92aM9m68TRc4rG55BcC
This commit is contained in:
@@ -659,12 +659,18 @@ specifically to document where/how it breaks rather than to succeed):
|
||||
|
||||
---
|
||||
|
||||
### 5.6 [EXPLORATORY — captured, not decided, not built] Hybrid systolic scaling: 4 groups × 4-PE weight-stationary chains
|
||||
### 5.6 [First step DONE, EXP-0089] Hybrid systolic scaling: 4 groups × 4-PE weight-stationary chains
|
||||
|
||||
Captured from a 2026-09-20 brainstorming session (same continuation), before
|
||||
any N=4/8/16 scaling work starts, so the direction isn't lost. **Nothing in
|
||||
this subsection is implemented or committed to — it's a working hypothesis
|
||||
for a future architecture, explicitly not yet an RTL task.**
|
||||
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
|
||||
open design question below (shared-weight broadcast vs. a literal PE-to-PE
|
||||
systolic shift register) was resolved with the user directly (not guessed),
|
||||
and the **first real, isolated step is now built and verified**:
|
||||
`systolic_group.v` + `packed_pe.v` (EXP-0089) — one real group of 4 PEs
|
||||
sharing a single broadcast weight fetch, real barrier-synchronized, real
|
||||
xsim-verified (8/8 PASS across 2 consecutive group jobs). **Not yet done**:
|
||||
Director/SPI-level job dispatch for group jobs, a real N=16 (4-group)
|
||||
top-level, and any real P&R for this — see EXP-0089's own `next_action`.
|
||||
|
||||
**The problem it targets**: plain N=16 independent cores (§5.5's own
|
||||
"documentary, expected to break" framing) means 16 independent DDR3
|
||||
@@ -701,27 +707,32 @@ flagged explicitly as a projection):
|
||||
naive flat-N=16 baseline — a real, meaningful, but NOT a full solve by
|
||||
itself; still needs real measurement once anything is built.
|
||||
|
||||
**Real open questions, not resolved yet** (deliberately not designed
|
||||
further until the current in-flight work — §5.4's channel widening, N=2/4/8
|
||||
real testing — lands first, per this project's own "one variable at a time"
|
||||
discipline):
|
||||
- Intra-chain dataflow RTL (result propagation between adjacent PEs,
|
||||
pipeline drain/fill at chain boundaries) is a real, new design, not a
|
||||
trivial extension — needs its own isolated verification before wiring
|
||||
into anything real, same as every other module in this project.
|
||||
- Result collection actually gets SIMPLER under this model versus flat
|
||||
N=16 (4 chain-output events instead of 16 independent ones) — relevant
|
||||
to §5.3's result-writeback engine, worth designing writeback with this
|
||||
in mind rather than for flat N=16 if this direction is pursued.
|
||||
- Arbitration simplifies too: 4 group-level requesters instead of 16,
|
||||
though `sdram_arbiter_n.v`'s own NUM_REQ parameter already generalizes to
|
||||
either case without changes.
|
||||
**Real open question, RESOLVED (EXP-0089)**: intra-chain dataflow — the
|
||||
user was asked directly (`AskUserQuestion`, concrete side-by-side preview
|
||||
of both real topologies) rather than guessed, given how different their
|
||||
real risk/complexity profiles are. Chosen: **shared-weight broadcast** (one
|
||||
real weight fetch per group of 4 PEs, no inter-PE result/data propagation,
|
||||
each PE computes its own independent activation positions in parallel) —
|
||||
**not** a literal PE-to-PE systolic shift register. This achieves the real,
|
||||
quantified rationale above (4× reduction in redundant weight-fetch DDR3
|
||||
traffic per group) without the real complexity/risk of genuine pipeline
|
||||
fill/drain at chain boundaries, which the literal-systolic alternative
|
||||
would have required. Real result-writeback stays exactly as §5.3 already
|
||||
built it — `packed_pe.v` reuses `result_writeback.v` completely unmodified,
|
||||
one real DDR3 write per PE, not a new "4 chain-output events" model (that
|
||||
framing, from the original brainstorm, doesn't apply to the broadcast
|
||||
design actually built). Arbitration: confirmed real — `sdram_arbiter_n.v`'s
|
||||
own `NUM_REQ` parameter generalized to a 5-way arbiter (1 group weight-fetch
|
||||
+ 4 PE activation/writeback) in `tb_systolic_group.v` with zero changes to
|
||||
that module.
|
||||
|
||||
**Decision**: not decided. Revisit after §5.4 (32-bit widening) and the
|
||||
real N=2/4/8 flat-core scaling tests produce real numbers — those numbers
|
||||
will tell us whether flat scaling is "good enough" up to some N, making
|
||||
this restructuring unnecessary, or whether the real congestion at N=8/16
|
||||
justifies it.
|
||||
**Decision**: first real step DONE (EXP-0089) — build and verify the
|
||||
isolated group mechanism before any Director/SPI/top-level integration,
|
||||
per this project's own "one variable at a time" discipline. Full N=16
|
||||
integration (Director-level group job dispatch, SPI protocol extension,
|
||||
real top-level, real P&R) is real, disclosed, deliberately deferred work,
|
||||
not yet done — see EXP-0089's own `next_action` in
|
||||
`hardware/v2/logs/experiments.log`.
|
||||
|
||||
#### 5.6.1 [EXPLORATORY] Opportunistic BRAM cache for activation tiles
|
||||
|
||||
|
||||
Reference in New Issue
Block a user