docs: capture exploratory 4x4 hybrid systolic scaling direction (not built)
Brainstorming session outcome: instead of flat N=16 independent DDR3 requesters, group cores into 4 weight-stationary systolic chains of 4 PEs each - reduces independent DDR3 contenders from 16 to 4 while preserving task-level parallelism across the 4 groups. Captured as docs/ARCHITECTURE_ANALYSIS.md S5.6, explicitly marked exploratory/not decided/not built - revisit after the 32-bit channel widening and real N=2/4/8 flat-core scaling tests produce real numbers. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUG92aM9m68TRc4rG55BcC
This commit is contained in:
@@ -483,6 +483,72 @@ 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
|
||||||
|
|
||||||
|
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.**
|
||||||
|
|
||||||
|
**The problem it targets**: plain N=16 independent cores (§5.5's own
|
||||||
|
"documentary, expected to break" framing) means 16 independent DDR3
|
||||||
|
requesters contending for one arbitrated channel — real congestion that
|
||||||
|
neither §5.1 (packing) nor §5.4 (32-bit widening) alone removes, since both
|
||||||
|
attack bytes-per-MAC or raw bandwidth, not the *number of independent
|
||||||
|
consumers*.
|
||||||
|
|
||||||
|
**The idea**: instead of 16 flat, independent `packed_slot.v` instances,
|
||||||
|
group them into **4 systolic chains of 4 PEs each**. Within a chain: the
|
||||||
|
weight tile stays resident (loaded once, same "weight-stationary" pattern
|
||||||
|
`layer_prefetch_ctrl.v`/`layer_weight_buffer.v` already implement for the
|
||||||
|
existing A/B lane reuse — this is a direct extension to 4 positions instead
|
||||||
|
of 2, not a new mechanism), and activation data streams through the chain
|
||||||
|
position by position, fetched from DDR3 once per chain rather than once per
|
||||||
|
PE. Between the 4 chains (groups), full task-level parallelism is
|
||||||
|
preserved — each group can run an independent job, same as today's model.
|
||||||
|
|
||||||
|
**Why weight-stationary specifically (not activation-broadcast)**: chosen
|
||||||
|
because it generalizes to any layer type (FC, conv-via-im2col, attention —
|
||||||
|
anything reducible to "same weight matrix, many activation vectors") without
|
||||||
|
assuming a specific model's channel count or convolution overlap pattern —
|
||||||
|
important since this is a general-purpose accelerator, not built for one
|
||||||
|
fixed network.
|
||||||
|
|
||||||
|
**Real, quantifiable rationale** (order-of-magnitude, not yet measured —
|
||||||
|
flagged explicitly as a projection):
|
||||||
|
- DSP48E1: 16 cores × 8 DSP/core = 128/240 (53%) — real, fits with margin.
|
||||||
|
- DDR3 requesters: drops from 16 (flat) to 4 (one per chain) — a real 4×
|
||||||
|
reduction in the number of independent contenders for the arbitrated
|
||||||
|
channel, on top of (not instead of) §5.1's packing and §5.4's widening.
|
||||||
|
- Combined with §5.4's 32-bit widening (2× physical ceiling), the
|
||||||
|
available-bandwidth-to-demand ratio improves by roughly 8× versus the
|
||||||
|
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.
|
||||||
|
|
||||||
|
**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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 6. Summary table: what's real vs. what's a calculation
|
## 6. Summary table: what's real vs. what's a calculation
|
||||||
|
|
||||||
| Claim | Status |
|
| Claim | Status |
|
||||||
|
|||||||
Reference in New Issue
Block a user