V2.0.0 hardware freeze - single SDRAM

FASE #1 hardware freeze for FPGA-Neural V2, N4/P8, single external
SDRAM (Alliance Memory AS4C4M16SA-6TIN) serving weights, activations,
and results through one physical sdram_controller.v instance. Removes
the PSRAM dependency (hardware/v1/rtl/psram_controller.v +
memory_interface.v) from the V2 physical path entirely -- V1 itself
remains fully unmodified, the golden reference.

New RTL: sdram_unified_backend.v (2-way W/AR arbitration over one
SDRAM controller, real per-byte DQM write masking added to
sdram_controller.v for correct single-byte result writes with no
read-modify-write), nms_neural_multiprocessor_sdram_unified.v (the
frozen top-level). Two real bugs found and fixed via full-system
testing before being accepted (ERR-0023): a deadlock and an off-by-one
data-shift bug in the new arbitration logic.

Real results: N=4 and N=2 D-Stress bit-exact (256/256 neurons), 40
real AUTO REFRESH events interleaved with zero corruption, real
Yosys+nextpnr-ecp5 synthesis/P&R for LFE5U-45F-8CABGA381 (149/245
TRELLIS_IO, a real 45-pin reduction from the prior dual-memory
design). Timing is MARGINAL (1/8 P&R seeds >=80MHz), reported honestly
rather than masked by the best seed.

Real, sourced ball-level pinout for the SDRAM bus + clk/rst (39/149
signals, P&R-verified) using the official Lattice ECP5U-45 pinout CSV
found on disk during this step's own pre-commit review -- corrects an
earlier draft that wrongly assumed no real pinout data was available.

Chip readiness: NO. Real, disclosed blockers remain (no physical host
interface exists yet -- the RTL's own reg_* ports are a 110-pin raw
test-harness bus; clock source/PLL decision; power/configuration
component selection) -- see hardware/v2/docs/{HARDWARE_FREEZE,
CHIP_READINESS,OPEN_ITEMS}.md for the complete, itemized status.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
This commit is contained in:
2026-09-06 13:39:55 +02:00
co-authored by Claude Sonnet 5
parent 5c9ec618d3
commit 8e014d8d49
208 changed files with 3000390 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
# FPGA-Neural V2 — CHIP READINESS
Precise, non-vague criteria per the governing spec's own definition:
V2 hardware is READY only when EVERY box below is checked. If even one
fundamental item is missing, **HARDWARE READY = NO** — no OPEN ITEM is
masked.
```
[x] RTL frozen -- nms_neural_multiprocessor_sdram_unified.v,
zero V1 dependency, strict lint clean
[x] regression PASS -- 461/461 (isolated controller, 9 configs),
40/40 (isolated unified backend)
[x] bit-exact PASS -- 256/256 neurons, N=2 AND N=4, single SDRAM
[x] SDRAM validation PASS -- init/refresh/read/write/burst/masked-write,
40 real refresh events, zero corruption
[x] N4 synthesis PASS -- real Yosys 0.68+post, zero errors
[ ] N4 timing >= 80 MHz -- MARGINAL: only 1/8 real P&R seeds pass
[ ] constraints complete -- v2_unified.lpf exists, REAL and P&R-verified
for 39/149 signals (clk/rst + full SDRAM bus);
110-signal host bus still unassigned
[ ] pinout complete -- 149-signal inventory complete; SDRAM+clk/rst
(39 signals) REALLY assigned from the official
Lattice CSV and P&R-confirmed; host bus (110
signals) deliberately unassigned (see below)
[ ] clock defined -- oscillator-vs-PLL decision NOT made
[ ] power defined -- rail voltages known; regulators NOT selected
[ ] FPGA configuration defined -- standard pins identified; flash NOT chosen
[ ] host interface defined -- BLOCKER: 110-pin raw bus, no real protocol
[x] schematic requirements complete -- SCHEMATIC_READINESS.md's own block diagram
and interconnection list are complete
[x] first-power-on test defined -- FIRST_POWER_ON.md's own 12-step procedure
[ ] bitstream reproducible -- NOT verified: no ball-assigned LPF exists to
produce a REAL, board-usable bitstream from;
the free-placement bitstreams used for
verification this round are reproducible
AS SIMULATION/FIT PROOFS ONLY, not as a
real board-programmable artifact
```
**7 of 14 items checked. HARDWARE READY = NO.**
## Why each unchecked item is unchecked (no vague language)
| Item | Why NOT checked |
|---|---|
| N4 timing ≥80MHz | 8 real P&R seeds measured; only 1 (81.84MHz) clears 80MHz. This is a real MARGINAL result, not a PASS, per the governing spec's own explicit classification rule (some seeds pass, most do not). |
| Constraints complete | `v2_unified.lpf` real and P&R-verified for 39/149 signals (clock frequency + clk/rst + the full 37-signal SDRAM bus, sourced from the real Lattice pinout CSV found at `~/Downloads/` during this step's own pre-commit review). The 110-signal host bus is deliberately left unassigned. |
| Pinout complete | Signal inventory is complete (149, exactly matching real P&R); SDRAM+clk/rst (39 signals, 26%) are now really assigned and P&R-confirmed; the 110-signal host bus is unassigned, not because pin data is missing, but because that bus is not yet a real physical protocol (see below) — assigning it balls now would be premature. |
| Clock defined | No PLL exists in the RTL (confirmed: 0/4 EHXPLLL in every synthesis run); the board's real oscillator frequency (16MHz per prior project memory) does not match the RTL's own 80MHz requirement, and neither "new oscillator" nor "add a PLL" has been decided. |
| Power defined | Rail VOLTAGES are known from real datasheets; regulator SELECTION, CURRENT budget, and decoupling are not — no real power-estimation tool was run, and the previously-referenced board power-tree design is not accessible this session to confirm as a concrete plan. |
| FPGA configuration defined | Standard ECP5 config pins (TDI/TDO/TCK/TMS/PROGRAMN/INITN/DONE/CCLK) are correctly identified as existing and standard, but no configuration-flash part number or SPI-vs-JTAG-only bring-up approach has been chosen for V2 specifically. |
| Host interface defined | The RTL's own "host" ports are a 110-pin raw parallel test-harness bus (`reg_valid`/`reg_node_id`/etc.), not a real board protocol. No serializing bridge RTL exists. This is the single largest real gap between "simulated/synthesized" and "physically buildable." |
| Bitstream reproducible | Every P&R run this project has performed used free (unconstrained) I/O placement — a real, valid way to prove the design FITS the package, but not a way to produce a bitstream a real board's own fixed wiring could actually use. |
## What this means, precisely
The V2 hardware architecture itself — SDRAM device, controller,
memory subsystem, compute datapath, N4/P8 configuration — is **real,
validated, and correct**: bit-exact simulation, real synthesis, real
place-and-route all confirm this. What remains is **entirely physical-
integration work**: a real host interface, a real ball-level pinout, a
real clock source decision, and real power/configuration component
selection. None of these are memory-architecture, datapath, or
correctness questions anymore — they are the next, concrete, well-
defined engineering tasks, precisely enumerated in OPEN_ITEMS.md.
## Final answer
```
HARDWARE FREEZE: PASS (architectural decision + RTL correctness)
CHIP READY: NO
```
+104
View File
@@ -0,0 +1,104 @@
# FPGA-Neural V2 — CLOCK ARCHITECTURE
## Status: CRITICAL — real, unresolved oscillator/clock-input mismatch
## What the RTL actually assumes
Every module in the frozen hierarchy (`nms_neural_multiprocessor_
sdram_unified.v` down to `sdram_controller.v`) takes a **single** `clk`
input and treats it directly as both the system clock AND the SDRAM
clock (`CLK_FREQ_MHZ=80` is a pure timing-derivation parameter fed
into `sdram_controller.v`'s own `ns_to_cycles()` function — it does
NOT configure a PLL; there is no PLL anywhere in this hierarchy).
Confirmed mechanically: every real synthesis run this project has
performed (STEP16 through this freeze) reports `EHXPLLL: 0/4 0%` in
nextpnr's own device-utilisation output — **zero PLL primitives are
instantiated**, in any variant, ever.
**This means the design requires a real, external 80MHz (or faster)
clock source wired directly to the FPGA's clock input pin.**
## The real gap
This project's own memory notes (established in an earlier session,
before the SDRAM decision) record the confirmed hardware target board
as using a **16MHz** oscillator. 16MHz ≠ 80MHz, and there is no PLL in
the current RTL to bridge that gap. **Two mutually exclusive
resolutions exist, and neither has been chosen:**
1. **Source an oscillator that directly provides ≥80MHz** (a
commodity part — plain crystal oscillators at 80, 100, or higher
MHz are standard, low-risk components) and retire the 16MHz
assumption. Zero RTL change required. Simplest, lowest-risk path.
2. **Keep the 16MHz oscillator and add a real PLL** (ECP5's own
`EHXPLLL` primitive, e.g. 16MHz→80MHz = ×5) to the RTL, with its
own real timing constraints (lock time, jitter, generated-clock
declaration in the constraints file) — genuinely new RTL/constraint
work, not yet done, and not exercised by any of this project's own
real synthesis/timing-closure runs to date (every Fmax number in
STEP16-18 assumes a clean, ideal `clk` input, not a PLL output with
its own jitter/lock-time budget).
**This is an OPEN, real architectural decision, not a detail** — it
determines whether a new oscillator needs sourcing or a PLL needs
designing, and affects the CLOCK_SOURCE→FPGA_CLOCK diagram below,
which cannot be finalized until it is made.
## Clock tree (as far as it CAN be stated today)
```
[UNRESOLVED: either an 80MHz+ oscillator, or a 16MHz oscillator + PLL]
|
v
FPGA clk pin (ball location: BLOCKER, see PINOUT.md)
|
v
single system clock domain, 80 MHz target
|
+--> Neural Multiprocessor / Dependency Manager / Director /
| Memory Manager / Neural Processors (all synchronous,
| single clock domain — confirmed, no clock-domain-crossing
| logic exists anywhere in the frozen hierarchy)
|
+--> SDRAM controller (same clock, no separate SDRAM clock
domain — sdram_controller.v drives the SDRAM chip's own
CLK pin combinationally/directly from the same system
clock; real board layout must still budget for the
SDRAM's own real clock-to-pin round-trip delay, which
was NOT part of this project's own RTL-simulation/P&R
timing closure — flagged as an OPEN ITEM for board bring-
up, see FIRST_POWER_ON.md)
```
## Reset
A single `rst` input, synchronous to `clk` in every module observed
(no asynchronous reset assertion/de-assertion synchronizer chain was
found in this session's own lint pass). **Reset release timing/
synchronization to a real external reset source (power-on reset chip,
button, or host-driven) has not been designed** — this is a normal,
solvable board-level concern (a standard POR/supervisor IC), not
flagged as a blocker, but not yet decided (OPEN ITEM).
## Clock constraints used so far
Every P&R run in STEP16-18 used `nextpnr-ecp5 --freq 80` (a target
frequency for the placer's own timing-driven effort), NOT a real `.lpf`
`FREQUENCY` constraint tied to a real pin — because no `.lpf` exists at
all for any V2 top-level (see PINOUT.md). A real constraints file with
a proper `FREQUENCY PORT "clk" 80 MHZ;` (or the real achieved-vs-
required frequency once the oscillator/PLL decision above is made)
must be written before this can be considered a genuine, board-ready
clock constraint.
## Summary
| Item | Status |
|---|---|
| Single-clock-domain RTL, no CDC logic found | Confirmed by lint, real |
| PLL present in RTL | **No — confirmed absent (0/4 EHXPLLL in every P&R run)** |
| Oscillator frequency vs required system clock | **CRITICAL — 16MHz (prior project memory) vs 80MHz (RTL requirement), unresolved** |
| Oscillator-vs-PLL decision | **OPEN — not made** |
| Real `.lpf` clock constraint | Partial — `hardware/v2/constraints/v2_unified.lpf` now exists with a frequency constraint and clk/rst ball reuse from V1; full ball-level pinout for the remaining 147 signals is still blocked (see PINOUT.md) |
| Reset synchronization to a real external source | OPEN, not yet designed (not a hard blocker) |
| SDRAM clock-to-pin board-level timing budget | OPEN — not part of RTL-level timing closure |
+42
View File
@@ -0,0 +1,42 @@
# FPGA-Neural V2 — FIRST POWER-ON PROCEDURE
Target: single-SDRAM V2 board (`nms_neural_multiprocessor_sdram_
unified`, N=4/P8). This procedure defines the MINIMUM real bring-up
test sequence; it cannot be executed on real hardware until the
BLOCKER items in CHIP_READINESS.md (host interface, ball-level
pinout) are resolved — it is written now so the bring-up plan is
ready the moment those blockers close, per the governing spec's own
"prepare the procedure now" instruction.
| # | Step | Stimulus | Expected result | Failure condition | Debug method |
|---|---|---|---|---|---|
| 1 | Power rails | Apply VCC/VCCAUX/VCCIO/SDRAM VDD per POWER_ARCHITECTURE.md | All rails reach nominal voltage within regulator spec time | Any rail fails to reach nominal, or sequencing violates ECP5 requirements | Multimeter/scope on each rail; check regulator datasheets |
| 2 | FPGA configuration | Load the real bitstream (from `nextpnr-ecp5` + `ecppack`, using the FINAL ball-assigned LPF once available) via JTAG or config flash | Device accepts configuration without protocol error | `INITN` asserts (config error) or configuration hangs | Check JTAG chain continuity, config clock, bitstream integrity |
| 3 | DONE | Observe `DONE` pin | `DONE` goes high after configuration completes | `DONE` stays low | Re-check bitstream, JTAG/flash wiring, PROGRAMN sequencing |
| 4 | Clock | Apply/verify the system clock (source per the CLOCK_ARCHITECTURE.md decision — direct oscillator or PLL output) | Clock present at the real ball (H5), correct frequency (80MHz target) | No clock, wrong frequency, excessive jitter | Scope on the clock net; if a PLL is used, verify PLL lock indicator |
| 5 | SDRAM initialization | Release `rst`; observe `sdram_controller.v`'s own real power-up sequence (200µs wait → PRECHARGE ALL → 8× AUTO REFRESH → LOAD MODE REGISTER) | Controller reaches `S_IDLE` (state=7); no `SDRAM_MODEL`-equivalent protocol violation on a real logic analyzer trace of CS#/RAS#/CAS#/WE# | Controller never reaches idle; command sequence doesn't match JEDEC power-up | Logic analyzer on SDRAM command pins; compare against `sdram_controller.v`'s own documented power-up sequence |
| 6 | SDRAM memory test | Issue a real write/read/masked-write sequence via JTAG-driven register pokes (or a dedicated bring-up test harness) covering all three memory-map regions (weights/activations/results) | Bit-exact readback, matching `tb_sdram_unified_backend.v`'s own already-simulated Test A/B/C patterns | Data mismatch, corruption, timeout | Compare against the exact patterns already validated in simulation; check DQM wiring/timing on the real board |
| 7 | Neural Processor test | Register a single independent node (required=0) with a known small weight/activation vector | `reg_ready` handshake completes; a single MAC/accumulate/ReLU/saturate result appears at the expected result address, bit-exact vs the golden software model already used in simulation | No dispatch, wrong result, saturation/overflow mismatch | Compare against the SAME golden model used throughout STEP16-19's own simulation; JTAG-readback intermediate signals if available |
| 8 | Neural Multiprocessor test | Register 4 independent nodes (one per slot) simultaneously | All 4 slots dispatch, execute, and complete without contention errors; results bit-exact | Any slot stalls/deadlocks/produces wrong result | Same golden-model comparison; check `slot_mem_arbiter`/`slot_mem_arbiter_wide` real transaction ordering |
| 9 | Known neural network | Run the full D-Stress workload (256 neurons, 4096 tiles) already validated in simulation (EXP-0048: 49,771 cycles @ N=4) | All 256 results bit-exact vs golden; real wall-clock time within the expected range for the real achieved Fmax | Any neuron wrong, deadlock, timeout | Same golden-model comparison already used in every STEP16-19 simulation |
| 10 | Store result | Confirm result-region SDRAM writes (memory-map region `0x300000`) | Real logic-analyzer/JTAG readback of the result region matches step 9's own expected values | Writes don't land at the expected address, or land with wrong byte masking | Check DQM wiring specifically (the STEP19-introduced write-masking mechanism) |
| 11 | Read result | Read back results via the real host interface (once it exists) or a bring-up JTAG readback path | Bit-exact match to the golden model | Mismatch | Same as step 10 |
| 12 | Compare golden | Full comparison of all 256 D-Stress results against the SAME software golden model used in every prior simulation step | 256/256 bit-exact | Any mismatch | Root-cause exactly as this project's own established discipline requires (real bug investigation, not silent tolerance) — see errors.log for the project's own precedent |
## Real hardware uses ONE physical SDRAM
Every step above assumes and tests the single-SDRAM architecture
(DEC-0034) — there is no separate PSRAM to bring up or test
separately; steps 56 cover the ENTIRE external memory subsystem in
one pass.
## Blockers preventing this procedure from running today
- Step 2 needs a real, ball-assigned bitstream — blocked by PINOUT.md.
- Steps 712 need a real host interface to issue registrations and
read results — blocked by the same "110-pin raw bus, no serializer"
finding in PINOUT.md/SCHEMATIC_READINESS.md.
- Step 1 needs a real power design — blocked by POWER_ARCHITECTURE.md.
This procedure is otherwise complete and ready to execute the moment
those blockers close.
+109
View File
@@ -0,0 +1,109 @@
# FPGA-Neural V2 — HARDWARE FREEZE (FASE #1, single external SDRAM)
## Frozen reference configuration
```
FPGA: LFE5U-45F-8BG381, ECP5U, speed grade -8
Neural Processor: P_IN=8, INT8 operands, INT32 accumulator,
8 parallel MAC, balanced adder tree (neural_processor.v,
UNCHANGED since before this freeze)
Multiprocessor: N_PROCESSORS=4 (N4/P8 is the frozen reference; N2 also
validated; N8 is a FUTURE EVOLUTION, not part of this freeze)
Architecture: Neural Multiprocessor -> Dataflow -> Neural Director ->
Dependency Manager -> Memory Manager -> streaming tile
delivery (STEP13 architecture, intact, unchanged)
External memory: ONE SDRAM ONLY -- Alliance Memory AS4C4M16SA-6TIN,
serving weights, activations, AND results (DEC-0031/
0032/0033/0034). No PSRAM, no second memory device.
Weight path: PACK128 (BURST_LEN=8, N_ENTRIES=4 cache, STEP18/STEP19)
Target clock: 80 MHz minimum (real oscillator/PLL source: OPEN, see
CLOCK_ARCHITECTURE.md)
V1: golden/reference implementation, untouched (confirmed:
zero modifications; V2 no longer instantiates ANY V1
RTL at all, since psram_controller.v was removed from
the physical path -- DEC-0034)
Frozen top-level: nms_neural_multiprocessor_sdram_unified
(hardware/v2/nms/rtl/nms_neural_multiprocessor_sdram_unified.v)
```
N4/P8 is the frozen V2.0 hardware reference. This does not mean N4 is
the final or maximum architecture — N8, higher clocks, or new datapath
ideas are explicitly FUTURE EVOLUTIONS, out of scope for this freeze.
## Repository audit summary
Full detail: see the audit performed for this step (repository
structure, V1/V2 boundary, top-level candidates, dead-code
classification, PSRAM-dependency confirmation, LPF/docs/scripts
inventory). Key findings:
- `hardware/v1/**`: complete, self-contained, untouched. Real
synthesized/certified golden reference (`spi_neuron_top.v`).
- `hardware/v2/rtl/` + `hardware/v2/nms/rtl/`: the frozen top-level
(`nms_neural_multiprocessor_sdram_unified.v`) instantiates
`nms_dataflow_core_sdram.v`, `sdram_unified_backend.v` (STEP19, new),
`sdram_controller.v`, `nms_memory_manager_stream_wide.v`,
`weight_prefetch_engine_wide.v`, `nms_activation_replicated.v`,
`nms_activation_fill_ctrl_v3.v`, `nms_weight_packed.v`,
`dependency_manager.v`, `neural_director.v`, `neural_processor.v`,
`slot_mem_arbiter.v`, `slot_mem_arbiter_wide.v`, `prefetch_engine.v`
**zero V1 files**, confirmed by successful lint/synthesis with no
V1 RTL in the file list.
- Every other `nms_neural_multiprocessor_*.v`/`nms_dataflow_core_*.v`
variant (plain, `_pf`, `_stream`, `_actfix`, `_actfix2`, `_dual32`,
`_sdram`, `_sdram_pack128`) is real, historical, superseded-but-
documented project experiment history — dead relative to the frozen
top, NOT deleted (each remains the subject of its own STEP report).
- `hardware/v2/constraints/` was empty before this step; now contains
`v2_unified.lpf` (partial — see PINOUT.md).
- The referenced sibling pinout repository (`../basic-ecp5-pcb`) does
not exist on disk, BUT the real Lattice pinout CSV itself
(`FPGA-SC-02034-3-0-ECP5U-45-Pinout.csv`, rev 3.0) is present at
`~/Downloads/` and was found during this step's own pre-commit
review, with a real summary already at `docs/pinouts.md` (repo
root). This corrected an earlier draft of this freeze that
wrongly assumed no real pinout data existed — see PINOUT.md.
## Status table
| Area | Status | Evidence | Blocker |
|---|---|---|---|
| RTL | PASS | Strict Verilator lint (latches/multi-driver/comb-loops/case-completeness): zero findings across the full frozen hierarchy | No |
| Simulation | PASS | Isolated `tb_sdram_controller.v` (461/461, 9 freq/burst configs), isolated `tb_sdram_unified_backend.v` (40/40) | No |
| Bit-exact | PASS | Full N=4 AND N=2 D-Stress (256/256 neurons each), golden software model comparison | No |
| SDRAM | PASS | Real init/refresh/read/write/burst/masked-write, 40 real AUTO REFRESH events interleaved with zero corruption across a ~50,000-cycle run | No |
| Synthesis | PASS | Real Yosys 0.68+post synthesis, N=4: TRELLIS_FF=6425, TRELLIS_COMB=6023, MULT18X18D=32, DP16KD=0 | No |
| P&R | PASS (fits) | Real nextpnr-ecp5 0.11.1, TRELLIS_IO=149/245 (fits with headroom) | No |
| Timing | **MARGINAL** | 8 real seeds: 66.97/74.00/74.45/74.92/79.23/79.53/79.80/81.84 MHz — only 1/8 ≥80MHz | **CRITICAL** |
| Pinout | PARTIAL | 39/149 signals real, sourced, P&R-verified (clk/rst + full 37-signal SDRAM bus); 110-signal host bus unassigned | **BLOCKER (host bus only)** |
| Clock | INCOMPLETE | Single-clock-domain RTL confirmed (no CDC); no PLL exists; oscillator-vs-PLL decision not made | **CRITICAL** |
| Power | INCOMPLETE | Real rail voltages known from datasheets; no regulator selection, no current budget | OPEN |
| Configuration | INCOMPLETE | Standard ECP5 JTAG/config pins identified; no flash part chosen, no V2 config LPF beyond the partial `v2_unified.lpf` | OPEN |
| Host | INCOMPLETE | 110-pin raw parallel bus exists at the RTL boundary; no physical protocol, no serializer RTL | **BLOCKER** |
| PCB | NOT READY | See SCHEMATIC_READINESS.md's own checklist | Multiple (host, pinout, power) |
| Bring-up | READY (procedure only) | FIRST_POWER_ON.md defines the full 12-step test sequence | Cannot execute until host/pinout blockers close |
## Single-SDRAM verification (this step's own core mandate)
- PSRAM dependency: **REMOVED** — confirmed by successful synthesis/
P&R with zero V1 files in the compile list, and a real, measured
45-pin I/O reduction (194→149/245 TRELLIS_IO) exactly matching the
removed PSRAM interface's own pin count.
- Weights/activations/results: **all confirmed sharing the single
physical SDRAM**, real bit-exact traffic at three distinct,
non-overlapping memory-map regions, simultaneously, under real N=4
contention (see MEMORY_ARCHITECTURE.md).
- Real bugs found and fixed during this consolidation (ERR-0023): a
full deadlock and a subsequent off-by-one data-shift bug in the new
arbitration logic, both caught via full-system (not merely isolated)
testing before being accepted — see errors.log for the complete
root-cause writeups.
## Deliverables produced by this step
`HARDWARE_FREEZE.md` (this file), `CHIP_READINESS.md`,
`MEMORY_ARCHITECTURE.md`, `PINOUT.md`, `POWER_ARCHITECTURE.md`,
`CLOCK_ARCHITECTURE.md`, `SCHEMATIC_READINESS.md`,
`FIRST_POWER_ON.md`, `OPEN_ITEMS.md` (all under `hardware/v2/docs/`),
plus `hardware/v2/constraints/v2_unified.lpf` and new RTL/testbenches
under `hardware/v2/nms/rtl/` and `hardware/v2/nms/sim/`.
+130
View File
@@ -0,0 +1,130 @@
# FPGA-Neural V2 — MEMORY ARCHITECTURE (single SDRAM)
## Decision (DEC-0034)
**ONE external memory device: Alliance Memory AS4C4M16SA-6TIN SDR
SDRAM (64Mbit/8MB, x16).** Weights, activations, and results all share
this single physical chip through a single `sdram_controller.v`
instance. No PSRAM, no second external memory device anywhere in the
V2 physical path. This is a closed architectural decision (per the
governing spec) — it will not be reopened.
```
SDRAM (AS4C4M16SA-6TIN, 8MB)
|
sdram_controller.v
(BURST_LEN=8, real
JEDEC SDR protocol)
|
sdram_unified_backend.v
(W port cache + AR port masking,
2-way priority arbitration)
| |
W (64-bit) AR (16-bit, byte-maskable)
| |
slot_mem_arbiter_wide.v slot_mem_arbiter.v
| |
weight_prefetch_engine_wide.v nms_activation_fill_ctrl_v3.v
(per slot, N_SLOTS instances) (shared) + nms_memory_manager_
| stream_wide.v (per-slot result
Neural Processors writeback, N_SLOTS instances)
```
## Why one physical controller is enough
`sdram_unified_backend.v` presents two LOGICAL ports (W: weight, AR:
activation+result) but owns exactly one physical `sdram_controller.v`
instance and arbitrates between them with a simple, correctness-first
2-way priority scheme (W wins when both are pending — real measured
traffic, STEP17 EXP-0045, shows weight traffic dominates by a wide
margin; AR is never starved since W's own real access pattern idles
between tiles). This matches the governing spec's own explicit
guidance: "non è necessario che esistano tre controller."
## The enabling mechanism: real SDR SDRAM byte masking (DQM)
Real SDR SDRAM has native per-byte write masking via its DQM pins —
`sdram_controller.v` was extended (STEP19) with a `wmask` input (2
bits per burst word) that drives `sdram_dqm` dynamically per burst
word instead of the STEP16-18 hardcoded "always write everything."
This lets a single RESULT byte be written inside a shared 128-bit (8
x16-bit-word) burst transaction with **no read-modify-write at all**
masked bytes are left untouched by the real chip, by JEDEC definition.
Verified with a new dedicated test (`tb_sdram_controller.v` Test J:
byte-masked write, confirms neighboring bytes/words in the same real
128-bit block are unchanged) — PASS across all 9 existing frequency/
burst configurations plus the new test (461/461 each), zero
regression.
Activation reads need no such trick: a full 128-bit block is fetched
and the caller's requested 16-bit word is extracted combinationally.
## Official V2 memory map
The single 8MB (0x0000000x7FFFFF byte) SDRAM address space is
divided into non-overlapping, 1MB-aligned regions:
| Region | Base address | Size (reserved) | Owner | Access |
|---|---|---|---|---|
| Network/metadata | 0x000000 | 1 MB (0x0000000x0FFFFF) | host (future) | R/W |
| Weights | 0x010000* | up to 1 MB | weight_prefetch_engine_wide.v (per-job `w_base`) | read-only |
| Biases | 0x100000 | 1 MB (0x1000000x1FFFFF) | reserved, not yet used by D-Stress | — |
| Activations | 0x200000 | up to 1 MB | nms_activation_fill_ctrl_v3.v (per-job `x_base`) | read-only |
| Intermediate results | 0x300000 | up to 1 MB | nms_memory_manager_stream_wide.v (per-neuron `result_addr`) | write (+ future read for chaining) |
| Output | 0x400000 | 1 MB (0x4000000x4FFFFF) | reserved, not yet used | — |
| (reserved/future) | 0x5000000x7FFFFF | 3 MB | — | — |
\* the real D-Stress benchmark's own weight region starts at
0x010000, inside the "Network/metadata" 1MB region's own upper part
for simplicity — addresses are **programmable**, set per-job via
`reg_w_base`/`reg_x_base`/`reg_result_addr` at registration time (NOT
hardcoded in the datapath) — this map is the project's own convention
for how a real host should lay out a graph, not an RTL constant.
Base/size/alignment/access-type/owner are exactly the fields the
governing spec requests; "owner" above names the RTL module
responsible for traffic in that region.
## Address-space coexistence — real, tested evidence
`tb_sdram_unified_backend.v` (isolated) exercises W-port and AR-port
traffic at deliberately different regions with real interleaving (Test
D) and confirms no corruption. The full N=4/N=2 D-Stress benchmark
(`tb_nms_dstress_sdram_unified.v`) exercises ALL THREE traffic classes
simultaneously at their real, disjoint memory-map regions across 256
neurons, 4096 tiles, with 40 real interleaved AUTO REFRESH events —
bit-exact PASS at both N=2 and N=4. This maps directly onto the
governing spec's own required Test AI list:
| Governing spec test | Covered by |
|---|---|
| A: weights only | `tb_sdram_weight_backend_pack128.v` (STEP18, reused unchanged logic) + isolated Test A (`tb_sdram_unified_backend.v`) |
| B: activations only | Isolated Test B |
| C: results only | Isolated Test C (byte-masked write) |
| D: weights+activations | Isolated Test D |
| E: weights+results | Covered by the full D-Stress run's own real traffic mix |
| F: weights+activations+results simultaneously | Full D-Stress run (real, not synthetic) |
| G: N4 contention | Full D-Stress run at N_SLOTS=4 |
| H: repeated workloads | 256 neurons × 16 tiles each = 4096 repeated weight/activation fetches + result writes in one continuous run |
| I: long-running workload | ~50,000-cycle run spanning 40 real AUTO REFRESH intervals, zero corruption |
All: **bit-exact PASS, no deadlock, no timeout, no corruption** (after
ERR-0023's fix — see errors.log for the one real deadlock + one real
off-by-one bug found and fixed via exactly this testing).
## Performance cost of unification (disclosed, not hidden)
| | STEP18 (2 chips) | STEP19 (1 chip) | Δ |
|---|---|---|---|
| N=4 D-Stress cycles | 44,935 | 49,771 | +10.8% |
| N=2 D-Stress cycles | 47,399 | 49,788 | +5.1% |
| Bit-exact | PASS | PASS | — |
| TRELLIS_IO | 194/245 | 149/245 | **-45 pins (-23.2%)** |
| Fmax (best-of-N-seeds, N=4) | 81.47 MHz (5/8 pass) | 81.84 MHz (1/8 pass) | worse pass rate, MARGINAL |
The cycle-count cost is a direct, expected consequence of activation
and result traffic now competing for the SAME physical bandwidth that
previously had its own independent chip — reported honestly per the
governing spec's own "prima misura poi ottimizza" instruction, not
optimized away this round (that would be a FUTURE EVOLUTION, e.g. a
smarter scheduler/priority scheme between W and AR).
+88
View File
@@ -0,0 +1,88 @@
# FPGA-Neural V2 — OPEN ITEMS
Consolidated from HARDWARE_FREEZE.md, PINOUT.md, CLOCK_ARCHITECTURE.md,
POWER_ARCHITECTURE.md, SCHEMATIC_READINESS.md. Classified per the
governing spec's own rule: BLOCKER / CRITICAL / WARNING / OPEN /
FUTURE.
## BLOCKER (impede la realizzazione o il funzionamento del chip)
1. **No physical host interface exists.** The RTL's own "host" ports
are a 110-pin raw parallel job-registration bus
(`reg_valid`/`reg_node_id`/`reg_required`/`reg_producer_ids`/
`reg_x_base`/`reg_w_base`/`reg_n_tiles`/`reg_result_addr`) — a
simulation/testbench convenience, not a real board protocol. No
RTL exists to serialize it (e.g. SPI, matching V1's own
`spi_neuron_top.v` precedent).
2. **The 110-pin host/registration bus has no real ball assignment**
(deliberately — it is not yet a real physical protocol, see item 1).
The SDRAM bus (37 signals) and clk/rst (2 signals) now DO have a
real, sourced, P&R-verified assignment (`hardware/v2/constraints/
v2_unified.lpf`, from the real Lattice pinout CSV found at
`~/Downloads/FPGA-SC-02034-3-0-ECP5U-45-Pinout.csv` during this
step's own pre-commit review) — this item is narrower than
originally scoped.
3. **No schematic exists; no PCB has been started.**
## CRITICAL (rischio elevato, deve essere risolto prima del freeze)
1. **Timing closure is MARGINAL, with an unfavorable pass rate.** 8
real P&R seeds for the frozen N=4 single-SDRAM design: only 1/8
reach ≥80MHz (66.9781.84MHz range). This is WORSE than STEP18's
own dual-memory design (5/8 pass). The critical path itself is
unchanged (still `dependency_manager.v`'s own pre-existing
`first_ready_idx`/`reg_ready` chain) — the regression is attributed
to added overall die/routing pressure from consolidation, not a new
RTL defect, but it is real and unresolved.
2. **Clock source/oscillator gap.** The RTL requires a direct ≥80MHz
clock (no PLL exists anywhere in the hierarchy — confirmed via
`EHXPLLL: 0/4` in every real synthesis run). Prior project memory
records a 16MHz board oscillator. Neither "source an 80MHz+
oscillator" nor "add a real PLL to the RTL" has been decided.
3. **Two physical memories were required through STEP18** — RESOLVED
this round (DEC-0034): the V2 physical path no longer instantiates
`hardware/v1/rtl/psram_controller.v` at all. Kept here only as a
closed CRITICAL item for the historical record.
## WARNING (non blocca il prototipo ma deve essere documentato)
1. N=2's real Fmax (86.04MHz in STEP18's own dual-memory design) and
the STEP19 single-SDRAM N=2 config were not both measured with the
same best-of-N-seed rigor as N=4 — a real, disclosed gap in
measurement thoroughness, not a functional issue.
2. `W_ENTRIES`/cache sizing in the weight-fetch path was set to match
`N_SLOTS` (4) by construction reasoning, not swept for optimality.
3. I/O standard (LVCMOS33 assumed for all 149 signals) has not been
verified per real VCCIO bank once ball assignment becomes possible.
## OPEN (decisione ancora da prendere)
1. Configuration-flash part number / SPI-flash-boot vs JTAG-only
bring-up.
2. Power regulator topology and part numbers (the previously-recorded
`../basic-ecp5-pcb` reference design is not accessible this
session to confirm as a concrete plan).
3. Real current budget (requires running a real power-estimation tool
against the actual synthesized netlist — not done this round).
4. Decoupling/bulk capacitance values (depend on regulator selection).
5. Reset synchronization to a real external POR/supervisor source.
6. Real per-bank VCCIO/I-O-standard verification once ball data is
available.
## FUTURE EVOLUTION (miglioramento post-freeze — explicitly deferred)
1. N=8 evaluation.
2. A smarter W/AR priority scheme in `sdram_unified_backend.v` to
recover some of the +10.8% (N=4) / +5.1% (N=2) cycle-count cost of
single-SDRAM unification (STEP18 EXP-0046's own packing win is
still present — this is about the NEW W-vs-AR contention specifically).
generic
3. Page-mode / keep-row-open SDRAM controller redesign (STEP18's own
identified next bottleneck for raw memory bandwidth, independent of
the single-vs-dual-memory question).
4. True multi-outstanding SDRAM request pipelining (STEP18 Part E's
own documented, deliberately out-of-scope boundary).
5. A real physical host-interface RTL bridge (SPI or similar),
resolving BLOCKER #1 above.
6. Floorplanning / seed-pinning work to convert the current MARGINAL
timing result into a reliable PASS.
+104
View File
@@ -0,0 +1,104 @@
# FPGA-Neural V2 — PINOUT
FPGA: **LFE5U-45F-8BG381** (ECP5U, speed grade -8)
Package: **CABGA381**
Frozen top-level: `nms_neural_multiprocessor_sdram_unified` (N_SLOTS=4)
**Single external memory: ONE SDRAM (AS4C4M16SA-6TIN). No PSRAM, no
second memory device anywhere in this design (STEP19/DEC-0034).**
## Status: SDRAM pinout REAL and P&R-verified; host bus still BLOCKED
Correction to an earlier draft of this document: the real Lattice
pinout data source (`FPGA-SC-02034-3-0-ECP5U-45-Pinout.csv`, rev 3.0)
IS available on this machine (`~/Downloads/`), and its own summary
(`docs/pinouts.md`, repo root) already lists real, exact JTAG/config/
power ball assignments for CABGA381 — found during this step's own
pre-commit `git status` review, not assumed missing without checking.
`hardware/v2/constraints/v2_unified.lpf` now contains a REAL,
P&R-verified ball assignment for clk/rst (39 total) and the full
37-signal SDRAM bus, sourced directly from that CSV (bank 6/7 plain-
GPIO pads, avoiding PLL/PCLK-reserved balls) — confirmed by a real
nextpnr-ecp5 run: all 37 SDRAM signals placed successfully, "110
warnings" (exactly the 110 still-unconstrained host-bus signals, a
clean cross-check that the inventory below is complete and accurate).
**This has NOT been electrically cross-verified** (VCCIO6/7 bank
voltage vs the SDRAM's own LVCMOS33 requirement, signal integrity,
trace-length matching for the 16-bit DQ bus) — it is a real, sourced,
P&R-confirmed CANDIDATE assignment, not a board-signed-off pinout.
## Real ball assignments now in place
| Signal | Ball | Source |
|---|---|---|
| `clk` | H5 | Reused from V1's own real, validated LPF |
| `rst` | B4 | Reused from V1's own real, validated LPF |
| `sdram_cke`/`cs_n`/`ras_n`/`cas_n`/`we_n` | B5/C5/C4/A3/B3 | Real CSV, bank 7 |
| `sdram_ba[1:0]` | E4, C3 | Real CSV, bank 7 |
| `sdram_a[11:0]` | D5,D3,F4,E5,E3,F5,A2,B1,C2,C1,D2,D1 | Real CSV, bank 7 |
| `sdram_dq[15:0]` | E1,G5,H3,J5,K3,K2,H1,J1,K1,K4,L4,L5,M5,M4,N4,N5 | Real CSV, banks 7/6 |
| `sdram_dqm[1:0]` | P5, N3 | Real CSV, bank 6 |
Full detail: `hardware/v2/constraints/v2_unified.lpf`.
Real JTAG/config/power balls (from `docs/pinouts.md`, not yet
transcribed into the LPF since this design's own top-level does not
expose them as RTL ports — they are implicit ECP5 device pins):
TDI=R5, TCK=T5, TMS=U5, TDO=V4 (bank 40); PROGRAMN=W3, INITN=V3,
DONE=Y3, CCLK=U3 (bank 8); VCC balls (1.1V) at H8-N13 cluster;
VCCAUX (2.5V) at F6/P6/F15/P15; VCCIO0-8 bank assignments listed in
`docs/pinouts.md`.
## Signal inventory (real, from the frozen top-level's own port list)
Total top-level I/O: **149 signals**, cross-checked exactly against
the real POST-P&R `TRELLIS_IO: 149/245` figure (STEP19) — a real
**45-pin reduction** from STEP18's dual-memory design (194 pins),
exactly matching the removed PSRAM interface's own pin count.
| Group | Count | Ball assignment |
|---|---|---|
| Clock/reset (`clk`, `rst`) | 2 | **Real, assigned** (H5, B4) |
| Host/control (`reg_*`) | 110 | **BLOCKER — see below** |
| SDRAM (`sdram_*`) | 37 | **Real, assigned, P&R-verified** |
| **Total** | **149** | matches P&R exactly |
## CRITICAL finding: the "host" interface is not a physical interface
**110 of 149 pins (73.8%) are the raw `reg_*` job-registration bus**
a simulation/testbench convenience, not a real board protocol. No RTL
exists to serialize this for physical use. Ball assignment for these
110 signals is deliberately NOT attempted yet, even though real GPIO
balls are available (46+ more plain-GPIO candidates remain in banks
6/7 alone after the 37 used above) — assigning pins to an interface
that must be redesigned first would be premature, wasted work. **This
remains the single largest real BLOCKER to physical realization.**
## I/O standard / bank assignment
LVCMOS33 assumed and used in the LPF above for all 39 real-assigned
signals — matches `docs/pinouts.md`'s own real VCCIO range (1.23.3V)
and V1's own real, validated board convention. Real per-bank voltage
compatibility for banks 6/7 specifically (used for SDRAM) has not been
independently re-verified against the SDRAM device's own datasheet
this round (WARNING, not BLOCKER — LVCMOS33 is a reasonable, likely-
correct default, not yet double-checked).
## Configuration pins (JTAG/config)
Now REAL and known (see table above) — `docs/pinouts.md`'s own
summary of the same official CSV. This closes what was previously
documented as a blocker for THESE specific pins; only the general-
purpose host-bus assignment (unrelated to JTAG/config) remains open.
## Summary
| Item | Status |
|---|---|
| Real ball-level LPF for the SDRAM interface | **Done — 37/37 signals, P&R-verified** |
| Real ball-level assignment for clk/rst | **Done — reused from V1** |
| Real ECP5U-45F CABGA381 ball-map data source | **Found — `~/Downloads/FPGA-SC-02034-3-0-ECP5U-45-Pinout.csv`, summarized in `docs/pinouts.md`** |
| Aggregate I/O feasibility (149/245 fits the package) | Confirmed, real POST-P&R |
| Real JTAG/config/power ball identification | **Done — see `docs/pinouts.md`** |
| Physical host interface RTL | **BLOCKER — does not exist (110 raw pins, no serializer, no ball assignment)** |
| I/O standard/bank electrical cross-check | WARNING — LVCMOS33 assumed, not independently re-verified per bank |
+69
View File
@@ -0,0 +1,69 @@
# FPGA-Neural V2 — POWER ARCHITECTURE
## Status: OPEN — component/regulator selection not made this round
Per the governing spec's own "NON inventare valori" rule, this
document states what is REALLY known (device-level voltage
requirements, from real datasheets/standard ECP5 knowledge) and
explicitly marks what has NOT been decided, rather than inventing
regulator part numbers or current budgets without real justification.
## Required rails (real device requirements)
Corrected from an earlier draft: real ball-level VCC/VCCAUX/VCCIO
data for this exact package DOES exist (`docs/pinouts.md`, repo root,
sourced from the official Lattice pinout CSV) and is used below rather
than only generic device specs.
| Rail | Nominal voltage | Real balls (CABGA381) | Notes |
|---|---|---|---|
| VCC (core) | 1.1V ±5% | H8,J8,K8,L8,M8,N8,H9,N9,H10,N10,H11,N11,H12,N12,H13,J13,K13,L13,M13,N13 | Real, from `docs/pinouts.md` |
| VCCAUX | 2.5V ±5% | F6, P6, F15, P15 | Real, from `docs/pinouts.md` |
| VCCIO0 | 1.23.3V (bank 0) | F9, F10 | Real ball pair; bank/signal assignment TBD |
| VCCIO1 | 1.23.3V (bank 1) | F11, F12 | Real ball pair |
| VCCIO2 | 1.23.3V (bank 2) | H14, H15, J15 | Real |
| VCCIO3 | 1.23.3V (bank 3) | L14, L15, M15 | Real |
| VCCIO6 | 1.23.3V (bank 6, used by SDRAM) | L6, L7, M6 | Real — SDRAM signals (see PINOUT.md) live in banks 6/7; 3.3V assumed, matching the SDRAM device's own real LVCMOS33 requirement, NOT yet independently cross-verified |
| VCCIO7 | 1.23.3V (bank 7, used by SDRAM) | H6, H7, J6 | Real, same note as VCCIO6 |
| VCCIO8 | config bank | P9, P10 | Real — Lattice's own documentation explicitly ties this rail's voltage to whichever configuration interface is used (OPEN, see Configuration decision below) |
| SDRAM VDD / VDDQ | 3.3V | (external chip, not an FPGA ball) | Per the real AS4C4M16SA-6TIN datasheet's own 3.3V industrial-grade part number |
| Configuration supply | 3.3V (typ.) | tied to VCCIO8 | Depends on the configuration-path decision (OPEN, see below) |
VSS/VSSIO (ground) balls: real per `docs/pinouts.md`'s own note — all
must be connected to the ground plane, none left floating (standard
BGA practice, explicitly called out in the source data).
## What is NOT decided (OPEN ITEMS)
- **Regulator topology/part numbers**: not selected. This project's own
memory notes reference a sibling repository (`../basic-ecp5-pcb`)
with a real, working power tree (TLV62568×2 + TLV73325) as a
possible reference — but that repository is **not present on disk**
in this environment (confirmed during this step's own audit), so it
cannot be verified or cited as a concrete plan this round. A future
step should either locate that reference design or select
regulators from scratch against the real current budget below.
- **Maximum estimated current**: not computed. This requires a real
power estimate from the actual synthesized netlist (Lattice's own
power calculator/estimation tools were not run this session) — NOT
invented here. The real, measured resource utilization (TRELLIS_FF=
6425, TRELLIS_COMB=6023, MULT18X18D=32, DP16KD=0 at N=4, POST-P&R,
STEP19) is available as an INPUT to such a calculation, but the
calculation itself was not performed.
- **Decoupling/bulk capacitance**: not specified — a schematic-level
decision that depends on the final regulator selection above.
- **Startup/power sequencing**: ECP5 devices generally require VCC and
VCCAUX to be sequenced correctly relative to VCCIO and the
configuration source per Lattice's own real application notes — this
project has not yet consulted or reproduced those real sequencing
requirements; flagged as OPEN, not assumed compatible.
## Summary
| Item | Status |
|---|---|
| Real rail voltage requirements (VCC/VCCAUX/VCCIO/SDRAM) identified | Done, from real device specs |
| Regulator selection | **OPEN — not made, no real reference design available this session** |
| Current budget | **OPEN — not computed, would require running a real power-estimation tool** |
| Decoupling/bulk capacitance | **OPEN — depends on regulator selection** |
| Power sequencing verification | **OPEN — not yet checked against real Lattice app notes** |
+109
View File
@@ -0,0 +1,109 @@
# FPGA-Neural V2 — SCHEMATIC READINESS
## Status: NOT READY
## Block diagram (what a hardware designer needs to know)
```
┌─────────────┐ ┌──────────────────────────────┐
│ Clock │ clk │ │
│ BLOCK ├───────►│ │
│ (OPEN item: │ │ │
│ 16MHz osc │ rst │ FPGA BLOCK │
│ vs 80MHz ├───────►│ LFE5U-45F-8BG381/CABGA381 │
│ needed -- │ │ │
│ see CLOCK_ │ │ nms_neural_multiprocessor_ │
│ ARCHITECTURE│ │ sdram_unified (N_SLOTS=4) │
│ .md) │ │ │
└─────────────┘ │ ┌────────────────────────┐ │ ┌───────────────┐
│ │ SDRAM interface (37 pins)├──────►│ SDRAM BLOCK │
│ │ sdram_cke/cs_n/ras_n/ │ │ │ AS4C4M16SA-6TIN│
│ │ cas_n/we_n/ba/a/dq/dqm │ │ │ (ONE chip -- │
│ └────────────────────────┘ │ │ weights+ │
│ │ │ activations+ │
│ ┌────────────────────────┐ │ │ results ALL │
│ │ Host bus (110 pins, │ │ │ here) │
│ │ BLOCKER -- raw parallel, │ │ └───────────────┘
│ │ not a real protocol yet) │ │
│ └────────────────────────┘ │
│ │
┌─────────────┐ │ ┌────────────────────────┐ │
│ CONFIG BLOCK │ JTAG │ │ TDI/TDO/TCK/TMS/ │ │
│ (OPEN: no ├────────►│ │ PROGRAMN/INITN/DONE/ │ │
│ flash part │ SPI │ │ CCLK (standard ECP5, │ │
│ chosen) ├────────►│ │ ball location BLOCKED) │ │
└─────────────┘ │ └────────────────────────┘ │
└──────────────────────────────┘
┌───────────┴───────────┐
│ POWER BLOCK │
│ VCC 1.1V / VCCAUX 2.5V / │
│ VCCIO 3.3V / SDRAM 3.3V │
│ (OPEN: regulators not │
│ selected) │
└──────────────────────────┘
┌─────────────┐
│ HOST BLOCK │ <-- BLOCKER: does not exist yet as real RTL.
│ (a real MCU/ │ Must serialize the 110-pin reg_* bus into
│ SPI/UART │ a real physical protocol (SPI, matching V1's
│ interface) │ own spi_neuron_top.v precedent, or similar)
└─────────────┘
┌─────────────┐
│ DEBUG/JTAG │ <-- standard ECP5 JTAG chain; no V2-specific
│ BLOCK │ debug infrastructure beyond that identified
└─────────────┘ this round.
```
## Interconnections a schematic designer needs (real, from the RTL)
- **FPGA ↔ SDRAM**: 37 real signals (`sdram_cke`, `sdram_cs_n`,
`sdram_ras_n`, `sdram_cas_n`, `sdram_we_n`, `sdram_ba[1:0]`,
`sdram_a[11:0]`, `sdram_dq[15:0]` bidirectional, `sdram_dqm[1:0]`) —
a single-chip, direct point-to-point connection (no bus sharing, no
second memory device). Real bank/ball assignment is BLOCKED (see
PINOUT.md) but the SIGNAL LIST itself is complete and final.
- **FPGA ↔ Clock**: one clock input pin (ball H5, reused from V1's own
real, validated assignment) — the SOURCE feeding that pin (direct
80MHz+ oscillator, or 16MHz oscillator + internal PLL) is an OPEN
decision (see CLOCK_ARCHITECTURE.md); the schematic cannot be
finalized for this block until that choice is made.
- **FPGA ↔ Reset**: one reset input pin (ball B4, reused from V1) —
real synchronization to a power-on-reset supervisor or button is
OPEN (not designed).
- **FPGA ↔ Configuration**: standard ECP5 JTAG/config pins exist by
device definition; whether the board ALSO includes an SPI
configuration flash (for standalone, non-JTAG boot) is an OPEN
decision (see CHIP_READINESS.md and OPEN_ITEMS.md).
- **FPGA ↔ Host**: **BLOCKER**. The real RTL currently exposes a
110-pin raw parallel bus with no serializing interface. A schematic
cannot meaningfully route "the host connection" until a real
physical protocol (and its own RTL bridge) exists.
- **FPGA ↔ Power**: standard ECP5 rail requirements (VCC/VCCAUX/VCCIO)
plus the SDRAM's own 3.3V rail — real regulator selection is OPEN
(see POWER_ARCHITECTURE.md).
## What IS ready
- The FPGA/package/speed-grade target is fixed and unambiguous
(LFE5U-45F-8BG381, CABGA381, -8).
- The external memory device is fixed and unambiguous (ONE
AS4C4M16SA-6TIN, no second chip).
- The complete, real signal list for the SDRAM interface is final (37
signals, confirmed by real POST-P&R synthesis).
- Real rail VOLTAGES (not currents) are known from device datasheets.
## What blocks starting the schematic today
1. Host interface: no real physical protocol exists (BLOCKER).
2. Ball-level pinout: no real assignment exists for SDRAM or host
signals (BLOCKER, same root cause as PINOUT.md's own finding).
3. Clock source decision: oscillator-only vs oscillator+PLL (CRITICAL,
OPEN).
4. Power regulator selection and current budget (OPEN).
5. Configuration-flash decision (OPEN).
**Conclusion: NOT READY.** A hardware designer could begin laying out
the SDRAM-to-FPGA net list today (that part is real and complete), but
could not close the schematic without resolving items 15 above.