diff --git a/CLAUDE.md b/CLAUDE.md index 9b241b5..81908bf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -121,6 +121,71 @@ The FPGA must be in a configurable state before loading the proxy. Issue `JPROGRAM` first to reset, then `CFG_IN` + shift the bitstream, then `JSTART` and check `DONE`. +## Extending to other FPGA families (design note) + +Not yet implemented — captured here so the design is ready when needed. +Targets in mind: small Lattice MachXO2/MachXO3 (PSU sequencing/glue) and +Microsemi/Microchip IGLOO2 / SmartFusion2. + +**Key difference from Xilinx.** Our Xilinx path programs an *external* +SPI flash via a BSCAN proxy bitstream. Both Lattice MachXO2/3 and +Microsemi IGLOO2 instead hold their config in *internal* flash, +programmed *directly over JTAG* — no external flash, no proxy. So +`bscan_spi/` and `spi_flash/` do **not** apply to them; they need a +different programming backend. + +**What already generalises (reuse as-is):** +- probe drivers, `jtag_core`, and the `bscan_set_ir` / `bscan_shift_dr` + primitives in `bscan_spi/` — vendor-neutral, and exactly what any + JTAG programming sequence drives; +- IDCODE detection + BSDL load (BSDL is a standard); +- the `fpga_target` registry concept and the script-command framework. + +**Two strategies for the programming backend:** + +1. **Native per-family backend.** Implement the vendor's JTAG flow on + top of our IR/DR primitives. + - *Lattice MachXO2/3*: the IEEE 1532 / ISC sequence — `ISC_ENABLE` → + `ISC_ERASE` → `LSC_INIT_ADDRESS` → `LSC_PROG_INCR_NV` (page loop) → + `ISC_PROGRAM_DONE`, with BUSY polling. Well documented (Lattice + TN1204, IEEE 1532 BSDL `ISC_*` attributes) → very feasible. Needs a + `.jed` parser for the payload. + - *Microsemi IGLOO2*: the on-chip programming algorithm is + proprietary and complex (sys-services, eNVM/fabric) — reimplementing + it natively is a large, fragile effort. Not recommended. + +2. **Generic SVF / STAPL player (higher leverage).** Execute the JTAG + programming file the vendor tool exports, instead of re-deriving the + algorithm. The vendor's algorithm is *baked into the file*. + - **SVF** = a flat list of `SIR`/`SDR`/`RUNTEST` ops → a small player + on `bscan_set_ir`/`bscan_shift_dr` covers it; vendor-neutral + (Lattice, Microsemi, Altera all export SVF). + - **STAPL** (`.stp`/`.jam`) = a full language (loops, conditionals) → + needs an interpreter, more work, but it's Microsemi's/Lattice's + native portable format. + - **For IGLOO2 this is the pragmatic route**: let Libero/FlashPro + export SVF (or STAPL) and just play it. One player → many vendors. + + Recommendation: an **SVF player** is the single highest-value + addition — it unlocks IGLOO2 *and* most other JTAG parts at once, + with the vendor owning the algorithm. Add native Lattice ISC only if + a self-contained `.jed` flow (no vendor export step) is wanted. + +**Registry / dispatch adjustments:** +1. `fpga_target` is Xilinx-flavoured today (`ir_cfg_in`, `ir_user1`, + `ir_jprogram`, …). Generalise it — per-family opcode sets, or a small + "programming method" tag (`proxy_spi` / `lattice_isc` / `svf`) that + selects the backend. +2. The existing `family` enum is the natural dispatch point + (`FPGA_FAMILY_XILINX_*`, add `FPGA_FAMILY_LATTICE_*`, + `FPGA_FAMILY_MICROSEMI_*`). An SVF player is family-agnostic and + needs no per-part opcodes at all. + +**Scope caveat.** Lattice MachXO2/3 and IGLOO2/SmartFusion2 are genuinely +JTAG-programmable. iCE40 is usually programmed over SPI directly (or +one-time NVCM) with minimal JTAG — out of scope for this JTAG-centric +tool. + ## External references - **BSCAN proxy bitstreams**: `quartiq/bscan_spi_bitstreams` (MIT).