Files
FPGA-Neural/docs/FPGA-Neural-Hardware-Design.md
T
micheleandClaude Sonnet 5 f6edc01613 docs: Phase 7 placement-seed sweep + hardware design document
Phase 7 (docs/FPGA-NeuralNetwork-Engine.md): re-ran nextpnr-ecp5 on
the already-synthesized Phase 5 spi_neuron_top netlists (top.json
reused, only placement re-seeded) at --seed 1/2/3 for both P8 and P2.
Both land in a tight band regardless of seed (P8: 39.5-40.6 MHz,
2.6% spread; P2: 42.5-45.0 MHz, 5.8% spread) -- confirms the Phase 5
timing shortfall is a real structural bottleneck, not placement
noise, unlike the much smaller same-tier benchmark design (<2%
utilization, huge placer freedom, genuinely noisy). Corrected the
earlier "pipeline the saturate stage" candidate fix, which targeted
Phase 4's critical path and not the one Phase 5's logic actually
shifted to; block RAM for x_mem/w_mem remains the leading candidate,
not yet implemented.

New docs/FPGA-Neural-Hardware-Design.md: draft hardware design doc
for a board carrying the project's actual target device
(LFE5U-45F-8BG381C) plus the parallel PSRAM rtl/psram_controller.v
is written for. Covers: why not the basic-ecp5-pcb reference board
(wrong package/speed grade, no RAM), a real I/O pin budget from
Lattice's own CABGA381 pinout table, a researched PSRAM part
(ISSI IS66WVE4M16EBLL-70BLI -- 70ns access matches the controller's
timing assumption exactly, with a note on the byte/word address
shift in int8_memory_access.v so the chip's top address line is
correctly left as spare headroom, not a wiring error), clock
(16 MHz, no PLL exists yet so CLK_FREQ_MHZ must match whatever
oscillator is fitted), power/config reusing the reference board's
proven circuitry and errata (config-SPI pin can't double as the
application SPI interface), and a BOM/open-items list.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WQV3vS9TXaGDJ5cRfnfidt
2026-09-02 20:54:52 +02:00

11 KiB
Raw Blame History

FPGA-Neural — Hardware Design Document

Status: draft, pre-schematic. Component choices below are researched against current distributor listings (2026-09-02) but not yet ordered/prototyped. No PCB layout exists yet.

Goal: a board carrying the project's actual target device (LFE5U-45F-8BG381C) plus the parallel PSRAM the current RTL (rtl/psram_controller.v) is written for, so real hardware exists to run everything already synthesized/benchmarked in this repo.


1. Why a new board (not basic-ecp5-pcb)

A reference ECP5 dev board (Matt Venn's basic-ecp5-pcb, OSHWA-approved, in this workspace at ../basic-ecp5-pcb) exists and is a useful source of proven power/config circuitry — but it carries the wrong chip for this project and has no RAM at all:

basic-ecp5-pcb This project's target
Device LFE5U-45F-6BG256C LFE5U-45F-8BG381C
Package 256-ball CABGA 381-ball CABGA
Speed grade -6 (slowest ECP5 grade) -8 (fastest ECP5 grade)
RAM none (6 PMODs, no memory chip) parallel PSRAM required

Same die (LFE5U-45F, same 44K LUT / 72 DSP), different package and a materially slower speed grade. All Fmax numbers measured so far in this repo (docs/FPGA-NeuralNetwork-Engine.md §15 "Phase 7 — Optimization") target the -8 grade; they do not directly transfer to a -6 part.

What we reuse from it anyway: the power tree and bitstream-config approach (§4, §5) are package-independent and already validated on real, shipped hardware — no reason to redesign those from scratch.


2. I/O pin budget (real ball data, CABGA381)

Extracted from Lattice's own ECP5-45 pinout table (../basic-ecp5-pcb/docs/ECP5Upinouts.ods, sheet ECP5U45Pinout, CABGA381 column) — not estimated:

Bank Usable I/O balls
0 29
1 35
2 35
3 36
6 36
7 35
8 22
40 (config-related) 4
Total usable ~232
Power/ground/NC (remaining of 381 balls) 149

Signal budget this design actually needs:

Function Pins
PSRAM (psram_a 22b worst case, psram_dq 16b, ce_n/oe_n/we_n/lb_n/ub_n/zz_n 6b) up to 44 (real usage likely less — see §3, address lines can be trimmed to match actual chip density)
Application SPI (sclk/mosi/miso/cs_n) 4
clk, rst 2
Config SPI (to onboard FLASH) 4
JTAG (recommended, for bring-up/debug) 4
Total ~58

~58 of ~232 usable I/O used — plenty of headroom (~170+ spare pins) for LEDs, buttons, a debug PMOD-style header, or a second SPI host, without any pin-count pressure. This board does not need to be pin-constrained the way a 256-ball/PMOD-only design would.


3. PSRAM subsystem (the piece basic-ecp5-pcb doesn't have)

rtl/psram_controller.v implements a plain asynchronous parallel interface — address bus, 16-bit data bus, ce_n/oe_n/we_n and byte-lane lb_n/ub_n, plus zz_n — and its timing already hardcodes a 70 ns access latency assumption (ACCESS_CYCLES = ceil(70ns × CLK_FREQ_MHZ / 1000)). This is a classic async-SRAM-style bus, not QSPI — most "PSRAM" sold today (including what's on typical ESP32 boards) is serial/QSPI and will not plug into this controller without a rewrite.

Recommended part: ISSI IS66WVE4M16EBLL-70BLI

  • 64 Mbit (4M × 16), parallel pseudo-SRAM, async, 70 ns access — matches the controller's timing assumption exactly, no RTL change needed.
  • TSOP-44/48 package — hand-solderable-adjacent, real distributor listings (DigiKey, Mouser) at time of writing.
  • Address bus note: the chip is 4M×16 words (8 MB total, needs a real 22-bit word address, A0A21). The current RTL's ADDR_WIDTH=22 is a byte address (4 MiB space) that int8_memory_access.v right-shifts by 1 (addr >> 1) into a word address before it reaches psram_controller — so only 21 word-address bits are actually driven today. Wire all 22 chip address balls, but the chip's topmost line (A21) stays unused/tied low until ADDR_WIDTH is widened to 23 to use the chip's full 8 MB instead of today's 4 MiB. Free headroom, not a defect.

Fallback: ISSI IS61WV6416DBLL / IS61WV102416BLL (true async SRAM, not pseudo-SRAM) — electrically drop-in on the same ce_n/oe_n/we_n/lb_n/ub_n signals, no internal refresh (so zz_n can just be tied inactive), faster than needed (~10 ns), useful if the ISSI PSRAM specifically is out of stock. Smaller density (116 Mbit depending on exact part) — fine for this project's current memory footprint (weights/biases/activations for the networks exercised so far are well under 1 MB).

Real part numbers, not yet ordered — verify current stock/pricing before BOM lock.


4. Clock

basic-ecp5-pcb uses a fixed 16 MHz MEMS oscillator (SiTime SiT2001B family) — no crystal driver on the ECP5, the clock input must come from an oscillator IC into a PCLK pad.

Recommendation: keep 16 MHz, same SiT2001B family (or SiT1602/SiT8008, same vendor, also in stock). Rationale, not just "reuse what worked":

  • No PLL exists anywhere in this project's RTL yet — CLK_FREQ_MHZ is a timing parameter, not a clock generator. Whatever oscillator is fitted drives clk directly.
  • Every Fmax measured so far for the full integrated system (spi_neuron_top, Phase 5) sits at 39.545 MHz across a seed sweep (docs/FPGA-NeuralNetwork-Engine.md §15 "Phase 7 — Optimization") — confirmed structural, not placement luck. 16 MHz sits well under that with real margin.
  • CLK_FREQ_MHZ must be set to match whatever oscillator is actually fitted (16, if this recommendation is taken) — it feeds the PSRAM access-timing formulas directly (§3); using the RTL's default of 80 with a 16 MHz real clock would under-time the PSRAM by 5×.

A higher oscillator (e.g. 25 or 32 MHz) is possible with margin to spare, but revisit once the Phase 7 timing-closure work (docs/FPGA-NeuralNetwork-Engine.md) lands rather than guessing a number now.


5. Power

Reuse basic-ecp5-pcb's proven three-rail tree as-is (same device family, same rail requirements regardless of package):

Rail Value Part Load Status
Core 1.1 V TLV62568 (buck) ≥600 mA Confirmed in production, DigiKey/Mouser listed
I/O 3.3 V TLV62568 (buck) 1 A (all banks + PSRAM + PMODs share this) Confirmed in production
Auxiliary 2.5 V TLV73325 (LDO) 10 mA Confirmed in production

Decoupling: one cap per I/O bank minimum, per Lattice's ECP5 Hardware Checklist (referenced by basic-ecp5-pcb, not re-derived here).


6. Configuration (bitstream load)

Reuse basic-ecp5-pcb's SPI-FLASH-boot approach:

  • W25Q128JV SPI NOR flash (16 MB) — confirmed in production, multiple package options (WSON, SOIC) currently listed.
  • ECP5 reads its bitstream from this flash at power-on (sysCONFIG SPI master mode); no external programmer needed for normal power-up, only for the initial flash write.

Lessons reused from basic-ecp5-pcb's errata (do not re-discover these the hard way):

  • Config-mode select pins should tie directly to GND, not through a 10 k resistor — the ECP5 test point is ~1 V, too close to the 3.3 V bank's input threshold through a resistor divider.
  • Not every SPI flash that claims QSPI actually has a usable QE (quad-enable) bit in practice — basic-ecp5-pcb hit this with an IS25LP016D and switched to the W25Q12x family instead. Stick with W25Q128JV rather than substituting on price alone.
  • The dedicated config-SPI clock pin cannot be reused as a general input post-configuration without extra board-level workaround (basic-ecp5-pcb needed a bodge wire to let a Raspberry Pi talk SPI to the FPGA over the same physical pin used for flash boot). This project's application SPI (spi_neuron_top's sclk/mosi/miso/cs_n, the host-facing protocol in docs/FPGA-NeuralNetwork-Engine.md §8.1) must land on separate, ordinary I/O pins — never the config-SPI pins — precisely to avoid needing that same workaround.

7. Signal map (draft — not yet a real LPF)

No .lpf pin constraints exist for this device/package combination yet (all .lpf files in synth/ are currently empty — nextpnr has been auto-placing I/O for every synthesis run so far, fine for Fmax/resource benchmarking, not sufficient for a real board). Before schematic capture, someone needs to:

  1. Pick actual CABGA381 ball numbers for each signal below from the pinout table referenced in §2 (bank-aware: keep the PSRAM data/ address bus in one or two adjacent banks to ease layout and timing).
  2. Write a real .lpf with those assignments and re-run nextpnr-ecp5 with it (current benchmark runs deliberately skipped this — see tools/fpga_benchmark.py).
  3. Confirm bank voltage compatibility (all banks are 3.3 V I/O in this design, per §5 — fine for both the PSRAM candidates in §3 and standard SPI-level signaling).
Signal group Port(s) Count Target bank (TBD)
PSRAM address psram_a[21:0] 22 one bank
PSRAM data psram_dq[15:0] 16 same or adjacent bank
PSRAM control psram_ce_n/oe_n/we_n/lb_n/ub_n/zz_n 6 same bank as above
Application SPI sclk/mosi/miso/cs_n 4 any bank, NOT the config-SPI bank (§6)
Clock/reset clk, rst 2 clk must land on a PCLK-capable pad
Config SPI to onboard flash 4 dedicated config bank (bank "40" balls, §2)
JTAG (debug) TCK/TMS/TDI/TDO 4 dedicated JTAG balls

8. Bill of materials (draft)

Ref Part Function Availability
U1 LFE5U-45F-8BG381C FPGA Already the project's confirmed target (see main docs, price/stock table)
U2 ISSI IS66WVE4M16EBLL-70BLI Parallel PSRAM, 64Mb, 70ns Verified listed, DigiKey/Mouser
U3, U4 TLV62568 Buck converter, core + IO rails Confirmed in production
U5 TLV73325 LDO, 2.5V aux rail Confirmed in production
U6 W25Q128JV SPI NOR flash, config Confirmed in production, multiple packages
Y1 SiT2001B, 16 MHz System clock oscillator Confirmed in production

Not yet specified: exact package/footprint per part, decoupling cap values, JTAG header, PSRAM address-bus trim if a smaller/cheaper density than 4M×16 turns out to be sufficient once real network sizes are decided.


9. Open items before schematic capture

  • Decide real PSRAM density needed (drives whether ADDR_WIDTH stays 22 or can shrink, and whether the fallback true-SRAM part in §3 is sufficient instead of the pseudo-SRAM)
  • Real .lpf pin assignment (§7) and a synthesis run against it (current benchmark results all use auto-placed I/O)
  • Confirm PSRAM/SPI signal integrity at whatever clock is actually fitted (§4) — no signal integrity analysis done yet
  • JTAG header footprint choice
  • KiCad (or other) schematic capture — none exists yet for this device/package combination