feat: real DDRManager re-measurement at 32-bit channel + BOM/pinout docs (EXP-0087)

Re-measured ddr_prefetch_mgr.v's (EXP-0083) real benefit against the
now-closed 32-bit DDR3 channel (EXP-0086), per this project's own
standing plan. Real result: the 2.86% benefit measured at the old
16-bit channel is GONE at 32-bit (WITH: 100663.1335ns vs WITHOUT:
100656.6835ns -- a 0.0064% regression, statistically a wash). The
wider channel's lower per-tile latency already absorbs the gap the
look-ahead prefetch used to hide. Kept wired in for correctness/
timing-neutrality (real P&R already signs off with it included), but
it's no longer a real performance win. Updated docs/ARCHITECTURE_
ANALYSIS.md and docs/PHYSICAL_REALIZATION.md accordingly.

Found and fixed 3 real testbench/simulation-setup bugs along the way:
- tb_n2_system_ddr3.v and tb_mig_native_adapter.v still had a stale
  CLKIN_PERIOD=2900 (the FAILED EXP-0084 clock period) instead of the
  current real, closed 3225ps (EXP-0086).
- tb_n2_system_ddr3.v used SystemVerilog-only $signed(8'(...)) cast
  syntax, invalid for xvlog's default plain-Verilog mode -- fixed via
  an intermediate 8-bit reg.
- Building a fresh sim_1 fileset needs the real MIG simulation
  dependency set added explicitly (mig_7series_0_mig.v is marked
  USED_IN_SIMULATION=0 in the project since testbenches bypass the
  public wrapper); verilog_define is a fileset-level property, not
  per-file, in this Vivado version.

New measurement-only fork (not part of the real synthesis target, per
fork-before-promote discipline): packed_slot_noprefetch.v +
tb_n2_system_ddr3_noprefetch.v, reproducing the pre-EXP-0083 direct
per-tile activation-fetch sequencing for a fair A/B baseline.

Also adds docs/BOM.md and docs/PINOUT.md: a real component list (DDR3
x2, flash, FPGA already verified; clk_ref oscillator and an ESP32-S3-
WROOM-1 module newly verified in-stock on LCSC; sys_clk oscillator
flagged as needing a custom-programmed order, no off-the-shelf SKU at
the required 310.077MHz) and a consolidated, board-layout-ready pinout
extract of PHYSICAL_REALIZATION.md's own pin tables.

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 18:37:41 +02:00
co-authored by Claude Sonnet 5
parent 678caa9bce
commit 344e798ad5
9 changed files with 1276 additions and 48 deletions
+71 -30
View File
@@ -9,11 +9,13 @@ directly measured (real simulation trace, real P&R report) or a calculation
built from directly-measured building blocks — the two are labeled
explicitly throughout. Nothing here is guessed.
**Status note (post EXP-0086)**: §5.1 (denser activation packing) is
**Status note (post EXP-0087)**: §5.1 (denser activation packing) is
**DONE and real-P&R-verified** (EXP-0081/0082); §5.2 (DDRManager) phase 1
is **DONE and real-measured** (EXP-0083, a genuinely modest ~2.9% real
benefit, measured against the OLD 16-bit signoff — re-measurement against
the now-closed 32-bit channel is a real next step); §5.4 (32-bit widening)
is **DONE, built, and RE-MEASURED against the closed 32-bit channel**
(EXP-0083's original modest ~2.9% real benefit was measured only at the
OLD 16-bit signoff — real re-measurement, EXP-0087, found the benefit is
now ~0%/a wash at 32-bit, kept wired in for correctness/timing-neutrality
only, not performance); §5.4 (32-bit widening)
is **fully DONE — real-verified AND real timing-closed** (EXP-0084
functional + EXP-0086 timing closure; honest intermediate story: the first
timing attempt failed because of a SEPARATE, stacked clock speedup, not the
@@ -41,7 +43,7 @@ DDR3 channel.
| → DDR3 can sustain, post-EXP-0081/0082 packing (2 tiles/burst, DONE) | **~50%** of one core's peak compute throughput | §3.2, current, real |
| Real P&R timing margin (WNS), current trustworthy (32-bit, CLOSED) | **+0.096 ns** | measured, EXP-0086 real P&R |
| Real DDR3 physical bandwidth ceiling, 32-bit channel (closed timing) | **~2.48 GB/s** | measured, real P&R signoff, EXP-0086 — 2× EXP-0083's 16-bit ~1.24 GB/s, real not projected |
| DDRManager phase 1 (single-slot look-ahead prefetch) real benefit | **2.86%** reduction in total real simulated time | measured, real xsim A/B on `tb_n2_system_ddr3.v` (§5.2, EXP-0083) — measured against the OLD 16-bit signoff; modest, honestly reported, not oversold; re-measurement against the closed 32-bit channel is a real next step |
| DDRManager phase 1 (single-slot look-ahead prefetch) real benefit | **~0% (0.0064% regression)** at the closed 32-bit channel | measured, real xsim A/B on `tb_n2_system_ddr3.v` (§5.2, EXP-0087) — the old 16-bit-only 2.86% figure (EXP-0083) does not survive the wider channel; kept wired in (timing-neutral, real P&R already signs off with it) but no longer a real performance win |
| DSP48E1 headroom for scaling | 224/240 free (93%) | measured, real P&R utilization |
The DSP headroom is real and large. The memory-bandwidth ceiling is real,
@@ -60,9 +62,10 @@ stacked an ADDITIONAL clock speedup (`ui_clk` +11.2%) in the same wizard
session, which an unrelated, pre-existing compute-pipeline path couldn't
absorb (§5.4.1) — width and clock rate turned out to be separable levers,
and reverting just the clock period closed timing with the width gain
intact. The DDRManager (§5.2) remains complementary — hides latency,
doesn't raise the physical ceiling — and its own real benefit should now be
re-measured against this closed, wider channel (not yet done).
intact. The DDRManager (§5.2) was re-measured against this now-closed,
wider channel (EXP-0087): its real benefit is gone (~0%, a 0.0064%
regression) — the wider channel's own lower per-tile latency already
absorbed the gap the look-ahead used to hide.
---
@@ -311,7 +314,7 @@ burst, new-burst crossing, back-to-back alternation), `tb_packed_slot.v`
`tb_n2_system_ddr3.v` (8/8 PASS, real xsim against real `ddr3_model.sv`,
JEDEC trace confirmed to show no more half-burst zero-padding).
### 5.2 [Complementary, addresses latency not bandwidth] DDRManager with orchestrator-driven prefetch (user's proposal) — **phase 1 DONE (EXP-0083), real benefit smaller than the original hypothesis below predicted**
### 5.2 [Complementary, addresses latency not bandwidth] DDRManager with orchestrator-driven prefetch (user's proposal) — **phase 1 DONE (EXP-0083); real benefit at the closed 32-bit channel is now ZERO (EXP-0087)**
**The original hypothesis** (written before building anything, now corrected
by real measurement — kept here so the correction is visible, not silently
@@ -333,13 +336,15 @@ DDR3 fetch latency itself (which is dominated by row activation/precharge,
§3.3, and look-ahead cannot make a single fetch faster, only start it
earlier).
**Real, measured result** (`ddr_prefetch_mgr.v`, real P&R WNS +0.073ns, up
from EXP-0082's +0.068ns, LUTs 5644, DSP48E1 16 unchanged):
**Real, measured result at the OLD 16-bit channel** (`ddr_prefetch_mgr.v`,
real P&R WNS +0.073ns, up from EXP-0082's +0.068ns, LUTs 5644, DSP48E1 16
unchanged):
- Real apples-to-apples comparison on the **real DDR3 backend**
(`tb_n2_system_ddr3.v` via real xsim, same N=2/8-position workload,
before vs after, same `ddr3_model.sv`): **2.86% reduction in total real
simulated time** (108370.88ns → 105268.43ns). This is the trustworthy
headline number.
simulated time** (108370.88ns → 105268.43ns) — EXP-0083's own headline
number, but see EXP-0087 below: this figure does NOT survive the 32-bit
channel and should not be quoted as the current real benefit.
- On the fast SDR placeholder backend (used for isolated glue-logic
testing, `tb_ddr_prefetch_mgr.v`): 0.9% reduction in a row-switch-heavy
scenario, and -1.4% (i.e. not faster) in an isolated same-row best case —
@@ -348,6 +353,35 @@ from EXP-0082's +0.068ns, LUTs 5644, DSP48E1 16 unchanged):
cleanly isolate the mechanism the real DDR3 backend's own row/bank timing
does. Full detail: EXP-0083 in `hardware/v2/logs/experiments.log`.
**Real RE-measurement at the closed 32-bit channel (EXP-0087) — the
benefit is now GONE**: EXP-0083's 2.86% figure was only ever measured
against the OLD 16-bit/155MHz channel. Once the 32-bit channel's own real
timing closed (EXP-0086), this project's own standing plan
("re-measure once the wider channel's timing actually closes") was
carried out: a real, fair A/B on the SAME 32-bit/3225ps config, comparing
the current, committed `packed_slot.v` (with `ddr_prefetch_mgr.v`) against
a measurement-only fork reproducing the pre-EXP-0083 direct-fetch
sequencing (`hardware/v3/sim/packed_slot_noprefetch.v`, not part of the
real synthesis target). Real result, both runs 8/8 PASS, 0 errors,
identical golden data:
- WITH `ddr_prefetch_mgr.v`: $finish at 100663.1335 ns
- WITHOUT `ddr_prefetch_mgr.v`: $finish at 100656.6835 ns
- **WITH is 6.45ns SLOWER — a 0.0064% real regression**, statistically a
wash, definitively NOT a benefit any more.
**Real, honest interpretation**: the 32-bit widening already halves the
real per-tile DDR3 round-trip latency. EXP-0083's own real finding
already showed the achievable benefit was capped by
`neural_processor_packed.v`'s fixed one-operand-per-cycle consumption
rate, not DDR3 latency, even at 16-bit — the wider channel shrinks the
real per-tile wait below whatever small gap the look-ahead could still
hide, leaving effectively nothing left to overlap. `ddr_prefetch_mgr.v`
stays wired into the real, committed `packed_slot.v` (real P&R already
signs off with it included, EXP-0086, and it causes zero real harm) —
but its justification is now "real, correct, timing-neutral", not "real
performance win". Building the larger multi-slot scheduler sketched below
is **not justified** by this real result.
**What it does NOT solve** (this part of the original reasoning holds):
§3.2's bandwidth ceiling is a hard physical limit (bytes/second the DDR3
channel can physically move) — prefetching earlier doesn't move more bytes
@@ -366,13 +400,17 @@ selection uses a registered index bit at both fill and read time, same
"known long before the data it gates" discipline as `act_tile_fetch.v`'s
own EXP-0081 layout — confirmed timing-safe by real P&R, not asserted.
**Full multi-slot / whole-Director-queue scheduler — still NOT built,
and now a more deliberate call, not just deferred**: given phase 1's real
measured benefit was modest, the cost/benefit case for the larger design
below should be re-examined against the 32-bit-widened channel's real
numbers (§5.4) before committing more engineering time to it — building it
now, on the still-16-bit channel, risks the same gap between hypothesis and
measurement this phase-1 experiment just corrected.
**Full multi-slot / whole-Director-queue scheduler — still NOT built, and
now real-disconfirmed, not just deferred**: the re-examination against the
32-bit channel's real numbers (EXP-0087, above) has now happened, and the
result is that phase 1's own benefit is gone entirely at this core count
— there is no real cost/benefit case left for the larger design below
until a NEW real bottleneck reintroduces DDR3-latency-bound behavior
(e.g. a higher core count where the shared bus is contended again, or a
workload with heavier row-switching than this experiment's own test
pattern). Revisit only if/when N=4/8/16 scaling (§5.5) reveals DDR3
latency, not `neural_processor_packed.v`'s own consumption rate, as the
real limiting factor again.
**Concrete design sketch for the full version** (informed by what already
exists in this codebase; kept for when it's revisited):
@@ -537,18 +575,21 @@ specifically to document where/how it breaks rather than to succeed):
EXP-0086 real timing closure, WNS=+0.096ns). Doubles the physical
ceiling itself (real, closed, ~2.48 GB/s), which §5.1 alone could not do.
3. §5.2 (DDRManager) — phase 1 (single-slot look-ahead prefetch) is
**DONE** (EXP-0083, real but modest ~2.9% benefit, measured on the OLD
16-bit channel). **Next real step**: re-measure this SAME real A/B
against the now-closed 32-bit channel (EXP-0086), since a wider channel
may change how much idle-channel time there is left to fill — only
build the larger multi-slot scheduler version if that re-measurement
justifies it, not on the original (now-corrected) hypothesis alone. Not
yet done.
**DONE and RE-MEASURED** (EXP-0083's original ~2.9% benefit was
measured on the OLD 16-bit channel; EXP-0087 re-measured the same real
A/B against the now-closed 32-bit channel and found the benefit is
gone, ~0%/a 0.0064% regression — the wider channel's lower per-tile
latency already absorbed the gap the look-ahead used to hide). Kept
wired in for correctness/timing-neutrality; the larger multi-slot
scheduler is **not justified** by this real result — revisit only if
N=4/8/16 scaling below reintroduces DDR3-latency-bound behavior.
4. Real N=2/4/8/16 tests, each with its own real P&R signoff (margin is
thin, §2 — do not assume a prior N's timing closure predicts the next).
N=8 is the real target configuration; N=16 is expected to expose real
bus/arbitration/timing limits and is built specifically to document that
breakdown, not to be a viable production configuration.
breakdown, not to be a viable production configuration. With DDR3
latency no longer the real bottleneck at N=2 (EXP-0087), this is now
the more promising real lever to pursue next.
---
@@ -697,6 +738,6 @@ design task, not yet scoped, and out of this repository's own RTL scope
| "~25% of peak sustainable" (pre-packing) / "~50%" (post-packing, current) | **Calculated** ratios; post-packing figure re-verified against real P&R (EXP-0082) and real simulation (§5.1) |
| I/O bank/DQS pin counts for XC7A100T-CSG324 (banks 14/15/16/34/35) | **Measured** — queried directly from the real Vivado part database for this exact part/package, used in §5.4's dual-channel-vs-widening analysis |
| Row-switch penalty as a fraction of real workloads | **Not measured** — depends on host-chosen memory layout, flagged as an open question, not asserted |
| DDRManager phase-1 real stall-reduction benefit (2.86%) | **Measured** — real xsim A/B on `tb_n2_system_ddr3.v`, real DDR3 backend, before vs after `ddr_prefetch_mgr.v` (EXP-0083), against the OLD 16-bit channel. Modest, not the larger figure the original hypothesis (§5.2) suggested before it was built. Re-measurement against the closed 32-bit channel (EXP-0086) is a real next step, not yet done. |
| Full multi-slot DDRManager's real benefit | **Not measured** not built; §5.2 recommends re-measuring phase 1 against the 32-bit-widened channel before deciding whether to build it |
| DDRManager phase-1 real stall-reduction benefit | **Measured** — real xsim A/B on `tb_n2_system_ddr3.v`, real DDR3 backend, before vs after `ddr_prefetch_mgr.v`. **2.86%** at the OLD 16-bit channel (EXP-0083); **~0% (0.0064% regression)** re-measured at the closed 32-bit channel (EXP-0087) — the benefit does not survive the wider channel, real and honestly reported, not oversold either direction. |
| Full multi-slot DDRManager's real benefit | **Not measured, not built, and now real-disconfirmed as a priority** — phase 1's own re-measurement against the closed 32-bit channel (EXP-0087) found ~0% benefit; §5.2 recommends against building the larger version unless N=4/8/16 scaling reintroduces DDR3-latency-bound behavior |
| 32-bit widening's real post-change bandwidth/timing numbers | **Measured** — real, closed P&R signoff (EXP-0086): WNS=+0.096ns, WHS=+0.036ns, 0 failing endpoints. The ~2.48 GB/s figure is now a real, closed-timing result, not a projection. |
+62
View File
@@ -0,0 +1,62 @@
# FPGA-Neural V3 — Bill of Materials
Real component list for the custom PCB (bare **XC7A100T-CSG324-2** + DDR3,
no dev board). Every line below is either **confirmed real and in-stock**
(part number + LCSC link, verified) or explicitly flagged as **needs the
user's own real sourcing check** — never a guessed/invented part number,
per this project's own standing discipline (CLAUDE.md: "verify real
component availability before committing to a part"). See
`docs/PINOUT.md` for how each part's pins map to the FPGA, and
`docs/PHYSICAL_REALIZATION.md` §1/§3 for the real, closed timing signoff
these frequency requirements are derived from (EXP-0086).
## Core, confirmed parts (verified in earlier sessions)
| # | Component | Part | Qty | Notes |
|---|---|---|---|---|
| 1 | FPGA | **XC7A100T-CSG324-2** | 1 | Speed grade -2. Real, closed timing signoff at this exact part (EXP-0086, WNS=+0.096ns). |
| 2 | DDR3 SDRAM | **Micron MT41J128M16JT-125:K** (2Gb, x16, DDR3-1600-rated) | **2** | Two chips ganged in parallel for the real 32-bit channel (EXP-0084/0086) — address/command/control shared, DQ/DQS/DM split 16 bits each. Verified in-stock on LCSC (earlier session). |
| 3 | Config flash | **Winbond W25Q32JVSSIQ** (32Mbit, SOIC-8) | 1 | Verified in-stock on LCSC (earlier session). Wired exclusively to the FPGA (no direct ESP32 connection). |
## Clocking — real, firm frequency requirements from the closed MIG config
| # | Component | Requirement | Status |
|---|---|---|---|
| 4 | `sys_clk_p/n` differential oscillator | **310.077 MHz**, differential (DIFF_SSTL15-compatible I/O, e.g. LVDS/LVPECL/HCSL) | **Not a stock catalog part at this exact frequency.** Real candidate family: **SiTime SiT9122** (220625 MHz MEMS oscillator, factory-programmable to any exact in-band frequency including 310.077 MHz) — but a custom-programmed frequency is order-to-spec, not an off-the-shelf SKU; typical low-MOQ, ~12 week lead time. **Needs the user's own real quote/order to get a firm LCSC SKU.** This exact frequency is a real, non-negotiable output of the Vivado MIG JEDEC/PLL calculator — do not substitute a different frequency without re-running the real MIG wizard (TimePeriod/InputClkFreq are tied together). |
| 5 | `clk_ref_p/n` differential oscillator | **200 MHz**, differential, LVDS (matches the LVDS_25 IOSTANDARD already assigned in the XDC) | **Confirmed real, in-stock**: **SiTime SiT9121AC-2CF-33E-200.00000**, LCSC **[C835051](https://lcsc.com/product-detail/programmable-oscillators_sitime-sit9121ac-2cf-33e-200-00000_C835051.html)**, 3.3V LVDS, factory-preset at exactly 200.000000 MHz, "In Stock". |
## Host MCU
| # | Component | Part | Status |
|---|---|---|---|
| 6 | ESP32 module (host/central processor) | **ESP32-S3-WROOM-1-N16R8** | **Confirmed real, in-stock**: LCSC **[C2913202](https://www.lcsc.com/product-detail/WiFi-Modules_Espressif-Systems-ESP32-S3-WROOM-1-N16R8_C2913202.html)**, ~8,375 units in stock at time of check, ~$5.09 ea. 45 GPIOs (real design needs only ~10: 4 for management SPI + sys_rst + data_ready_n + 4 for JTAG bit-banging, leaving generous headroom for debug UART etc.), 16MB flash + 8MB PSRAM, dual-core. No specific ESP32 module had been chosen anywhere in this project before now — this is a new real recommendation, not a previously-verified part. |
## DDR3 support (real design consideration, not yet a firm requirement)
| # | Component | Purpose | Status |
|---|---|---|---|
| 7 | VTT termination regulator (optional) | Sink/source termination for the DDR3 address/command/control/clock bus in fly-by topology — DQ/DQS lines use on-die termination and need no external parts. With 2 chips extending the fly-by chain, signal integrity margin may benefit from this. | Real, standard part for this role: **TI TPS51200**. Whether it's genuinely *needed* here is a **real, design-dependent judgment call** — depends on trace lengths, not established by this project's own work (no SI simulation has been done). One TPS51200 can typically supply 2 DDR3 chips sharing a rail per TI's own guidance, though thermal margin may favor one per chip. **Not confirmed in-stock this pass — treat as optional/TBD**, not a committed BOM line. |
## Power regulation (starting point only, not a full power-tree design)
| # | Component | Purpose | Status |
|---|---|---|---|
| 8 | VCCINT 1.0V regulator | FPGA core rail, the tightest-tolerance (~±5% per the Xilinx datasheet) and highest-current rail | Real, commonly-used candidate for Artix-7 designs: **Infineon IR38060** (integrated SupIRBuck, up to 6A) — appears in real Xilinx 7-series reference designs. **Stock not confirmed this pass.** |
| 9 | VCCAUX 1.8V, VCCO per-bank (1.5V DDR3 banks 34/35, 2.5V bank 14, 3.3V banks 15/16) | Remaining FPGA/DDR3 rails | **Not yet sourced** — only the tightest rail (VCCINT) was researched this pass; the rest of the power tree is a real, remaining task. |
## Known open items (honestly disclosed)
- **Line 4 (sys_clk oscillator)** is the real, highest-risk sourcing item —
no confirmed off-the-shelf SKU exists at the exact required frequency.
Get a real quote from SiTime (or an equivalent programmable-oscillator
vendor) before finalizing the BOM; a firm lead time affects build
scheduling.
- **Lines 7, 8, 9** need a real stock/price check before ordering — parts
named are real, plausible candidates, not yet individually confirmed
in-stock the way lines 13, 5, 6 are.
- Passive components (decoupling capacitors, pull-up/pull-down resistors
for the mode pins M[2:0]/CFGBVS, JTAG series resistors) are not itemized
here — standard values per the Xilinx UG470/UG483 reference design
guidance, not yet compiled into this BOM.
- This BOM does not include PCB fabrication, connectors, or enclosure
items — scope is components only.
+8 -5
View File
@@ -375,11 +375,14 @@ when it actually fires, instead of polling every loop iteration.
- ESP32-side JTAG bit-banging firmware (§5.1) does not exist yet — it's
software work on the host side, not part of this FPGA RTL.
- `ddr_prefetch_mgr.v` (DDRManager phase 1, EXP-0083) is real, built, and
timing-verified, but was only measured for benefit at the OLD 16-bit/
155MHz signoff (2.86% real reduction in total simulated time, modest —
see `docs/ARCHITECTURE_ANALYSIS.md` §5.2). The larger multi-slot
DDRManager is not built. Its own real benefit should now be re-measured
against the closed 32-bit channel (EXP-0086) — not yet done.
timing-verified. Its real performance benefit was 2.86% at the OLD
16-bit/155MHz signoff, but a real re-measurement against the closed
32-bit channel (EXP-0087) found the benefit is now GONE (~0%, a
0.0064% regression, statistically a wash) — see
`docs/ARCHITECTURE_ANALYSIS.md` §5.2. Kept wired into `packed_slot.v`
for correctness/timing-neutrality only, not performance. The larger
multi-slot DDRManager is not built and, per EXP-0087, is not currently
justified.
- `data_ready_n` (EXP-0085, user-requested active-low sticky IRQ) is real,
built, functionally verified (49/49 including 10 new checks,
`tb_spi_host_bridge_v3.v`), AND real P&R-verified at the closed EXP-0086
+136
View File
@@ -0,0 +1,136 @@
# FPGA-Neural V3 — Consolidated Pinout Reference
Single-source pinout for the custom PCB (bare **XC7A100T-CSG324-2**, no dev
board). This is a flattened, board-layout-ready extract of
`docs/PHYSICAL_REALIZATION.md` §2 — that document remains the authoritative,
narrated source (it explains *why* each pin was chosen and every real
conflict/fix found along the way); this file is the quick reference for
schematic capture. Every pin below comes from a real routed design
(`n2_system_ddr3_top_routed.dcp`, EXP-0086 signoff) or the MIG-generated
`mig_7series_0.xdc` — none of it is guessed. Re-generate this file if
`docs/PHYSICAL_REALIZATION.md` §2 ever changes.
## Bank summary
| Bank | Voltage (VCCO) | Standard | Used for |
|---|---|---|---|
| 0 | per board config rail | LVCMOS (per UG470) | FPGA configuration control (PROGRAM_B/INIT_B/DONE/mode pins/CFGBVS) |
| 14 | 2.5V | LVDS_25 | `clk_ref_p/n` only (differential IDELAYCTRL reference clock) |
| 15 | 3.3V | LVCMOS33 | Management SPI (ESP32↔FPGA), `sys_rst`, `data_ready_n` |
| 16 | 3.3V | LVCMOS33 | Config flash SPI (FPGA↔flash) |
| 34 | 1.5V | SSTL15 / DIFF_SSTL15 | DDR3 addr/ba/control/ck, `sys_clk_p/n` |
| 35 | 1.5V | SSTL15 / DIFF_SSTL15 | DDR3 dq/dqs/dm |
## DDR3 (bank 34/35 — two MT41J128M16JT-125:K chips in parallel, 32-bit channel)
Address/command/control fan out identically to BOTH chips (not duplicated
per chip); DQ/DQS/DM are split 16 bits per chip.
| Signal | Pin | Signal | Pin | Signal | Pin |
|---|---|---|---|---|---|
| ddr3_dq[0] | C5 | ddr3_dq[16] | F4 | ddr3_addr[0] | U3 |
| ddr3_dq[1] | B7 | ddr3_dq[17] | F3 | ddr3_addr[1] | U4 |
| ddr3_dq[2] | B6 | ddr3_dq[18] | E2 | ddr3_addr[2] | V1 |
| ddr3_dq[3] | D8 | ddr3_dq[19] | D2 | ddr3_addr[3] | U1 |
| ddr3_dq[4] | C7 | ddr3_dq[20] | C1 | ddr3_addr[4] | L5 |
| ddr3_dq[5] | E6 | ddr3_dq[21] | H1 | ddr3_addr[5] | L6 |
| ddr3_dq[6] | E5 | ddr3_dq[22] | G1 | ddr3_addr[6] | L4 |
| ddr3_dq[7] | E7 | ddr3_dq[23] | F1 | ddr3_addr[7] | K5 |
| ddr3_dq[8] | B4 | ddr3_dq[24] | F6 | ddr3_addr[8] | M2 |
| ddr3_dq[9] | A4 | ddr3_dq[25] | G4 | ddr3_addr[9] | M3 |
| ddr3_dq[10] | A3 | ddr3_dq[26] | G3 | ddr3_addr[10] | L3 |
| ddr3_dq[11] | B3 | ddr3_dq[27] | J3 | ddr3_addr[11] | K3 |
| ddr3_dq[12] | B2 | ddr3_dq[28] | J2 | ddr3_addr[12] | M1 |
| ddr3_dq[13] | D5 | ddr3_dq[29] | K2 | ddr3_addr[13] | L1 |
| ddr3_dq[14] | D4 | ddr3_dq[30] | K1 | ddr3_ba[0] | V5 |
| ddr3_dq[15] | E3 | ddr3_dq[31] | H6 | ddr3_ba[1] | V2 |
| ddr3_dm[0] | C6 | ddr3_dm[2] | C2 | ddr3_ba[2] | U2 |
| ddr3_dm[1] | C4 | ddr3_dm[3] | G6 | ddr3_cas_n | R3 |
| ddr3_dqs_p[0] | A6 (DIFF) | ddr3_dqs_n[0] | A5 (DIFF) | ddr3_cke[0] | P2 |
| ddr3_dqs_p[1] | B1 (DIFF) | ddr3_dqs_n[1] | A1 (DIFF) | ddr3_cs_n[0] | T5 |
| ddr3_dqs_p[2] | H2 (DIFF) | ddr3_dqs_n[2] | G2 (DIFF) | ddr3_odt[0] | R2 |
| ddr3_dqs_p[3] | J4 (DIFF) | ddr3_dqs_n[3] | H4 (DIFF) | ddr3_ras_n | V4 |
| ddr3_ck_p[0] | N2 (DIFF) | ddr3_ck_n[0] | N1 (DIFF) | ddr3_we_n | T3 |
| ddr3_reset_n | D7 (LVCMOS15) | | | | |
| **sys_clk_p** | **N5 (DIFF_SSTL15)** | **sys_clk_n** | **P5 (DIFF_SSTL15)** | real, required freq **310.077 MHz** | |
## Reference clock (bank 14)
| Signal | Pin | Standard | Notes |
|---|---|---|---|
| clk_ref_p | T14 | LVDS_25 (2.5V) | required freq **200 MHz**, differential |
| clk_ref_n | T15 | LVDS_25 (2.5V) | |
Bank 14 hosts ONLY `clk_ref_p/n` — the config-flash bus was moved out of
this bank (to bank 16, see below) specifically because it can't share a
VCCO with this signal (EXP-0084).
## Management SPI — ESP32 ↔ FPGA, FPGA is slave (bank 15, 3.3V)
| Signal | Pin | Direction (FPGA side) | Notes |
|---|---|---|---|
| sclk | A15 | input | |
| mosi | B16 | input | |
| miso | B17 | output | |
| cs_n | A16 | input | |
| sys_rst | G13 | input | tentative pin, not yet a final board decision (§7 of PHYSICAL_REALIZATION.md) |
| data_ready_n | D14 | output | active-low sticky IRQ (EXP-0085); tentative pin, same caveat as sys_rst |
## Config flash SPI — FPGA ↔ Winbond W25Q32JVSSIQ, FPGA is master (bank 16, 3.3V)
| Signal | Pin | Direction (FPGA side) | Notes |
|---|---|---|---|
| flash_mosi | D9 | output | connects to flash DI |
| flash_miso | D10 | input | connects to flash DO |
| flash_cs_n | C9 | output | connects to flash /CS |
| (CCLK) | E9 | output | **not a top-level RTL port** — internally driven via `STARTUPE2`; wire the flash's own CLK pin directly to package pin E9 |
No direct ESP32↔flash connection exists by design — the ESP32 can only
reach the flash by relaying bytes through the FPGA over the management SPI
bus (`FLASH_XFER` opcode 0x40, see §5/§6 of PHYSICAL_REALIZATION.md).
## FPGA configuration control (bank 0, fixed by the device, not negotiable)
| Signal | Pin | Purpose |
|---|---|---|
| PROGRAM_B | P9 | pulse low to force reconfiguration from flash |
| INIT_B | P7 | low during config; re-asserting can indicate a config error |
| DONE | P10 | goes high once configuration succeeds — good status-LED candidate |
| M0 | P12 | mode select — tie per the Master SPI boot setting below |
| M1 | P13 | mode select |
| M2 | P11 | mode select |
| CFGBVS | P8 | tie to match bank 0's own VCCO logic level (see UG470) |
**Master SPI boot mode pins**: `M[2:0] = 001` — tie via pull-up/pull-down
resistors on the board (static, not driven dynamically).
## JTAG (bank 0, always available)
| Signal | Pin |
|---|---|
| TCK | E10 |
| TDI | E11 |
| TMS | E12 |
| TDO | E13 |
Intended to be driven by the ESP32 bit-banging the TAP state machine
(factory programming, recovery, development) — see §5.1 of
`docs/ARCHITECTURE_ANALYSIS.md`; that firmware doesn't exist yet.
## Reserved / do-not-use (bank 14)
`L16` (EMCCLK), `R16` (RDWR_B), `V15` (CSI_B) — config-mode-reserved,
`PROHIBIT`ed in the project XDC (via `get_sites -of_objects`, not directly
on the `package_pin` objects — a real Vivado property gotcha, see
CLAUDE.md). Kept clear for any future Quad-SPI/BPI expansion; not used by
this design's own Master-SPI-only configuration scheme.
## Open items (not yet finalized — do not treat as final for PCB layout)
- `sys_rst` (G13) and `data_ready_n` (D14) are real, verified-free pins
chosen only to unblock P&R — not yet a final board decision pending the
rest of the layout (reset circuit, status LEDs).
- Bank 15/16 VCCO is *assumed* 3.3V in this pinout — confirm against the
real board power plan before finalizing.
- `sys_clk_p/n` and `clk_ref_p/n` oscillator part selection (real,
in-stock candidates) is tracked in `docs/BOM.md`.