Files
FPGA-Neural/hardware/v2/constraints/v2_board_top.lpf
T
micheleandClaude Sonnet 5 7d6311bce3 feat: two-flash programming architecture, FPGA_DATA_READY, real JTAG/config pinout
Establishes the real ESP32<->ECP5 programming architecture: flash #1
(neural-network data, existing V1 subsystem, ball reserved not yet
wired into V2) stays separate from flash #2 (boot bitstream, MSPI
auto-boot, CFG[2:0]=[0,1,0]); ESP32 talks JTAG only (bit-banged, no
hardware JTAG-master peripheral on S3/C6), updating flash #2 through
the ECP5's own internal sysCONFIG-to-SPI bridge, never driving the
flash pins directly -- zero bus contention, confirmed against the real
Lattice hardware checklist and sysCONFIG user guide.

Adds real, verified ball assignments (official Lattice CABGA381 CSV +
Project Trellis iodb.json) for JTAG, PROGRAMN/INITN/DONE, CFG[2:0],
and the MSPI dedicated pins -- all written to docs/pinouts.md.

Implements FPGA_DATA_READY as real RTL: a system-idle detector
(dependency_manager's any_pending OR neural_director's !queue_empty OR
any active slot), sticky on the busy->idle edge, self-clearing on new
work -- not a per-neuron completion pulse, which was confirmed too
fine-grained. Bit-exact regression re-verified at N_SLOTS=4 and 8
(zero cycle-count change), new explicit data_ready assertion check
added to the D-Stress testbench (PASS both configs), and a fresh
Yosys+nextpnr-ecp5 placement check (0 errors, data_ready placed at G3).

Also fixes a real, independently-found bug while editing an adjacent
file: nms_neural_multiprocessor_sdram_unified.v's own sdram_a port was
still [11:0] (12 bits), stale from before the 64MB/13-bit memory
upgrade. Not exercised by the real board-level top (which wires SDRAM
directly, bypassing this wrapper) but WAS silently truncating A12 in
every D-Stress simulation this session, including today's earlier
ERR-0029 verification runs. Assessed impact: all D-Stress test
addresses used this session decode to rows under 4096 (bit 12 never
actually needed), so no false-positive PASS is believed to have
resulted -- but the full 64MB space was never actually exercised
through this wrapper. Fixed; re-verified bit-exact with identical
cycle counts.

See decisions.log DEC-0041 for full detail.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-07 12:46:00 +02:00

113 lines
6.7 KiB
Plaintext

// FPGA-Neural V2 -- FINAL board-level top constraints (STEP-final).
// Target: fpga_neural_v2_top (N_SLOTS=2 default in this file's own
// simulation-facing top; the frozen hardware reference is N_SLOTS=4,
// synthesized separately at that parameter value -- see the synthesis
// log for the actual instantiation used for these P&R runs).
// FPGA: LFE5U-45F-8BG381, package CABGA381, speed grade -8
//
// This supersedes hardware/v2/constraints/v2_unified.lpf (which
// constrained the OLDER nms_neural_multiprocessor_sdram_unified.v
// simulation-facing top, with its raw 110-pin reg_* bus and an
// assumed-already-80MHz `clk` input). The board-level top has NO
// reg_* ports at all -- job registration is via 4 real SPI pins,
// and the input clock is a real 16MHz oscillator feeding a real
// EHXPLLL (ecp5_pll_sys_clk.v), not a pre-generated 80MHz.
//
// Every ball below is real, sourced from the official Lattice
// pinout CSV (FPGA-SC-02034-3-0-ECP5U-45-Pinout.csv rev 3.0,
// ~/Downloads/, cross-referenced against docs/pinouts.md) -- none
// invented. osc_clk/ext_rst_n reuse the SAME real balls (H5/B4) as
// V1's own validated spi_neuron_top.lpf and the previous v2_unified
// .lpf (same physical clock/reset pins on this package regardless of
// which V2 top-level is programmed). The 4 SPI pins and pll_locked
// are NEW real balls from banks 6/7 (plain GPIO, dual function "-"
// in the CSV, not previously used by the 37-signal SDRAM bus).
BLOCK ASYNCPATHS;
BLOCK RESETPATHS;
// Real 16MHz board oscillator (external to the FPGA; EHXPLLL inside
// the design generates the internal 64MHz system clock -- see
// ecp5_pll_sys_clk.v's own FREQUENCY_PIN_CLKI/CLKOP attributes,
// which nextpnr-ecp5 reads automatically for the generated-clock
// domain; no separate LPF entry is needed for the internal 64MHz net).
FREQUENCY PORT "osc_clk" 16 MHZ;
LOCATE COMP "osc_clk" SITE "H5";
IOBUF PORT "osc_clk" IO_TYPE=LVCMOS33;
LOCATE COMP "ext_rst_n" SITE "B4";
IOBUF PORT "ext_rst_n" IO_TYPE=LVCMOS33;
// ---- real SPI host interface (4 pins, banks 6/7) ----
LOCATE COMP "spi_sclk" SITE "L3"; IOBUF PORT "spi_sclk" IO_TYPE=LVCMOS33;
LOCATE COMP "spi_mosi" SITE "M3"; IOBUF PORT "spi_mosi" IO_TYPE=LVCMOS33;
LOCATE COMP "spi_miso" SITE "L2"; IOBUF PORT "spi_miso" IO_TYPE=LVCMOS33;
LOCATE COMP "spi_cs_n" SITE "N2"; IOBUF PORT "spi_cs_n" IO_TYPE=LVCMOS33;
// ---- PLL lock status (debug/bring-up signal, real ball) ----
LOCATE COMP "pll_locked" SITE "L1"; IOBUF PORT "pll_locked" IO_TYPE=LVCMOS33;
// ---- SDRAM interface (37 signals), unchanged from v2_unified.lpf,
// real balls, banks 6/7 ----
LOCATE COMP "sdram_cke" SITE "B5"; IOBUF PORT "sdram_cke" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_cs_n" SITE "C5"; IOBUF PORT "sdram_cs_n" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_ras_n" SITE "C4"; IOBUF PORT "sdram_ras_n" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_cas_n" SITE "A3"; IOBUF PORT "sdram_cas_n" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_we_n" SITE "B3"; IOBUF PORT "sdram_we_n" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_ba[0]" SITE "E4"; IOBUF PORT "sdram_ba[0]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_ba[1]" SITE "C3"; IOBUF PORT "sdram_ba[1]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_a[0]" SITE "D5"; IOBUF PORT "sdram_a[0]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_a[1]" SITE "D3"; IOBUF PORT "sdram_a[1]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_a[2]" SITE "F4"; IOBUF PORT "sdram_a[2]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_a[3]" SITE "E5"; IOBUF PORT "sdram_a[3]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_a[4]" SITE "E3"; IOBUF PORT "sdram_a[4]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_a[5]" SITE "F5"; IOBUF PORT "sdram_a[5]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_a[6]" SITE "A2"; IOBUF PORT "sdram_a[6]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_a[7]" SITE "B1"; IOBUF PORT "sdram_a[7]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_a[8]" SITE "C2"; IOBUF PORT "sdram_a[8]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_a[9]" SITE "C1"; IOBUF PORT "sdram_a[9]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_a[10]" SITE "D2"; IOBUF PORT "sdram_a[10]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_a[11]" SITE "D1"; IOBUF PORT "sdram_a[11]" IO_TYPE=LVCMOS33;
// sdram_a[12]: NEW pin, required by the AS4C32M16SA-7TIN memory
// upgrade (13 row address bits, one more than the previous
// AS4C4M16SA-6TIN's 12). Real, free, plain-GPIO ball (bank 6,
// official Lattice pinout CSV rev 3.0, CABGA381 column) -- not
// previously used by this LPF's own 44-signal set.
LOCATE COMP "sdram_a[12]" SITE "F1"; IOBUF PORT "sdram_a[12]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[0]" SITE "E1"; IOBUF PORT "sdram_dq[0]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[1]" SITE "G5"; IOBUF PORT "sdram_dq[1]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[2]" SITE "H3"; IOBUF PORT "sdram_dq[2]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[3]" SITE "J5"; IOBUF PORT "sdram_dq[3]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[4]" SITE "K3"; IOBUF PORT "sdram_dq[4]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[5]" SITE "K2"; IOBUF PORT "sdram_dq[5]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[6]" SITE "H1"; IOBUF PORT "sdram_dq[6]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[7]" SITE "J1"; IOBUF PORT "sdram_dq[7]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[8]" SITE "K1"; IOBUF PORT "sdram_dq[8]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[9]" SITE "K4"; IOBUF PORT "sdram_dq[9]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[10]" SITE "L4"; IOBUF PORT "sdram_dq[10]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[11]" SITE "L5"; IOBUF PORT "sdram_dq[11]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[12]" SITE "M5"; IOBUF PORT "sdram_dq[12]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[13]" SITE "M4"; IOBUF PORT "sdram_dq[13]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[14]" SITE "N4"; IOBUF PORT "sdram_dq[14]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dq[15]" SITE "N5"; IOBUF PORT "sdram_dq[15]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dqm[0]" SITE "P5"; IOBUF PORT "sdram_dqm[0]" IO_TYPE=LVCMOS33;
LOCATE COMP "sdram_dqm[1]" SITE "N3"; IOBUF PORT "sdram_dqm[1]" IO_TYPE=LVCMOS33;
// data_ready (FPGA_DATA_READY, to ESP32): free bank-7 ball, dual-
// function PCLKT7_1 not needed as a PLL input here, reused as plain
// GPIO output -- real ball, verified free (not in any other LOCATE
// COMP in this file) via the Trellis iodb.json + official CSV.
LOCATE COMP "data_ready" SITE "G3"; IOBUF PORT "data_ready" IO_TYPE=LVCMOS33;
// All 17 top-level ports of fpga_neural_v2_top are now real-ball
// assigned: osc_clk, ext_rst_n, spi_sclk, spi_mosi, spi_miso,
// spi_cs_n, sdram_cke, sdram_cs_n, sdram_ras_n, sdram_cas_n,
// sdram_we_n, sdram_ba[1:0], sdram_a[12:0], sdram_dq[15:0],
// sdram_dqm[1:0], data_ready, pll_locked -- no placeholders remain in
// THIS LPF. (sdram_a corrected from a stale [11:0] comment -- the
// real port has been [12:0] since the 64MB memory upgrade.)