fix: make flash SPI bus electrically independent, drop USRMCLK/CCLK reuse (Phase F7)
The flash subsystem's SCLK previously reused the boot config-SPI's CCLK pad via the ECP5 USRMCLK primitive to save one pin. This made the "exclusive flash bus" claim misleading (SCLK still depended on the config engine's own pad electrically) and carried an unresolved verification gap (USRMCLKTS pad-enable timing never checked against the primary Lattice sysCONFIG Usage Guide). flash_sclk is now a genuine 4th ordinary GPIO pin (E3, bank 7), added purely additively to the real .lpf (git diff: one new line, no existing ball moved). The flash bus is now 4 fully independent wires (sclk/mosi/miso/cs_n), zero pins shared with any ECP5 config primitive -- confirmed by the full-system synthesis reporting USRMCLK 0/1 (0%) utilisation. All 33 project testbenches re-run clean after the port rename (no functional change, only sclk_sim -> sclk). Full-system real synthesis re-verified: 0 constraint errors, Fmax 67.91MHz (up slightly from 66.68MHz, same critical path, not a regression). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
This commit is contained in:
@@ -15,8 +15,9 @@ Yosys+nextpnr-ecp5), test avversari oltre al caso positivo, tracciabilità delle
|
||||
## `rtl/spi_flash_master.v` — master SPI verso la flash (F1)
|
||||
|
||||
**Cosa è coperto**: RDID, READ, WREN, PP (incl. la regola "solo AND, mai OR" del datasheet),
|
||||
SE, RDSR-1; gestione USRMCLK per CCLK post-configurazione; opcode non implementato non causa
|
||||
hang.
|
||||
SE, RDSR-1; opcode non implementato non causa hang. **Revisionato in Fase F7 (2026-09-04)**:
|
||||
`sclk` è ora GPIO ordinaria sempre presente (non più dietro `USRMCLK`/CCLK-reuse — vedi
|
||||
`WORKLOG.md` Fase F7 per il perché), bus a 4 fili genuinamente indipendente.
|
||||
|
||||
**Come**: `sim/spi_flash_master_tb.v`, 5 test contro `sim/flash_model.v`.
|
||||
|
||||
@@ -31,13 +32,15 @@ ingenuo che passerebbe un test più debole.
|
||||
nessun hang, il master shifta un numero fisso di bit indipendentemente dalla semantica.
|
||||
|
||||
**Sintesi reale**: `yosys synth_ecp5` (0 problemi) + `nextpnr-ecp5` reale, modulo isolato:
|
||||
Fmax 181.72 MHz (PASS a 80MHz), `USRMCLK` 1/1 piazzata.
|
||||
Fmax 181.36 MHz (PASS a 80MHz, ri-misurato in Fase F7 dopo la rimozione di `USRMCLK` —
|
||||
181.72 MHz il numero precedente, differenza nel rumore di piazzamento), `USRMCLK` **0/1
|
||||
(0%)** — conferma diretta che la primitiva non è più usata.
|
||||
|
||||
**NON coperto (§A.6)**: nessun test di power-loss (arriva a livello catalogo, F4); nessun
|
||||
timeout RDSR a questo livello (responsabilità del chiamante, F3); nessuna verifica
|
||||
elettrica/analogica reale (setup/hold, rise/fall) — solo comportamentale; polarità di
|
||||
`USRMCLKTS` basata sulla convenzione open-source comune, non verificata contro la Technical
|
||||
Note Lattice primaria (non presente nel set documentale locale).
|
||||
elettrica/analogica reale (setup/hold, rise/fall) — solo comportamentale. Il gap di
|
||||
verifica su `USRMCLKTS` (mai verificato contro la Technical Note Lattice primaria) è stato
|
||||
**chiuso rimuovendo la dipendenza stessa** in Fase F7, non colmando la verifica mancante.
|
||||
|
||||
---
|
||||
|
||||
@@ -226,6 +229,20 @@ Occupazione (sistema completo): `TRELLIS_IO` 56/245 (22%), `TRELLIS_FF` 4855/438
|
||||
`TRELLIS_COMB` 9060/43848 (20%), `DP16KD` 2/108, `MULT18X18D` 16/72, `USRMCLK` 1/1 (100%) —
|
||||
nessuna pressione sulle risorse del dispositivo.
|
||||
|
||||
**Fase F7 (2026-09-04, stesso giorno): bus flash reso indipendente, ri-sintetizzato.**
|
||||
Rimosso `USRMCLK`/riuso di CCLK per SCLK (richiesta esplicita dell'utente: il bus deve essere
|
||||
esclusivo anche elettricamente, non solo di controllo — vedi `WORKLOG.md` Fase F7 per il
|
||||
razionale completo). `flash_sclk` è ora una 4ª ball GPIO ordinaria (`E3`, banco 7), aggiunta
|
||||
in modo puramente additivo (`git diff` sul `.lpf`: solo 1 riga in più, nessuna ball esistente
|
||||
spostata). Ri-sintesi completa del sistema: **0 errori di vincolo**, `TRELLIS_IO` 57/245
|
||||
(23%), **`USRMCLK` 0/1 (0%)** — conferma diretta che la primitiva non è più usata affatto.
|
||||
Fmax **67.91 MHz** (leggermente meglio dei 66.68MHz precedenti, rumore di piazzamento, non
|
||||
regressione), percorso critico confermato ancora identico (nessun modulo flash coinvolto).
|
||||
Regressione completa dei 33 testbench del progetto ripetuta da zero dopo il fix: tutti PASS,
|
||||
incluso il test end-to-end mandatorio con lo stesso output atteso (126) e le stesse latenze
|
||||
misurate (ERASE≈400.003ms, SAVE≈403.004ms, LOAD=1.743ms — invariate, la rinomina del pin non
|
||||
tocca la temporizzazione).
|
||||
|
||||
---
|
||||
|
||||
## Scoperta trasversale: limite reale di `WRITE_RAM`/`READ_RAM` (non specifica alla flash)
|
||||
|
||||
@@ -72,11 +72,11 @@ Signal budget this design actually needs:
|
||||
| Application SPI (`sclk/mosi/miso/cs_n`) | 4 |
|
||||
| `clk`, `rst` | 2 |
|
||||
| Host attention (`irq_n`, `data_ready_n`, added 2026-09-03 — §7) | 2 |
|
||||
| Config SPI (to onboard FLASH) | 3 (`flash_mosi`/`flash_miso`/`flash_cs_n` — SCLK shared via `USRMCLK`, no dedicated pin, confirmed against yosys's own `cells_bb.v` blackbox; implemented Phases F1-F6) |
|
||||
| Flash runtime SPI bus (`flash_sclk`/`flash_mosi`/`flash_miso`/`flash_cs_n` — fully independent, all ordinary GPIO, no config-primitive shared; implemented Phases F1-F7) | 4 |
|
||||
| JTAG (recommended, for bring-up/debug) | 4 |
|
||||
| **Total** | **~59** |
|
||||
| **Total** | **~60** |
|
||||
|
||||
~59 of ~232 usable I/O used (56 actually placed and place&route-verified
|
||||
~60 of ~232 usable I/O used (57 actually placed and place&route-verified
|
||||
in the flash-subsystem synthesis, `synth/ecp5/spi_neuron_top_flash/
|
||||
nextpnr.log`) — **plenty of headroom** (~170+ spare
|
||||
pins) for LEDs, buttons, a debug PMOD-style header, or a second SPI
|
||||
@@ -280,16 +280,28 @@ usage: 53/245 (21%) — still confirms the §2 headroom estimate.
|
||||
`WORKLOG.md`) added 3 real pins (`flash_mosi`, `flash_miso`, `flash_cs_n`
|
||||
— bank 7, generated additively by `tools/pinout/gen_lpf.py`, confirmed via
|
||||
`git diff` on `synth/ecp5/spi_neuron_top.lpf` to leave every existing ball
|
||||
unchanged; no dedicated flash SCLK pin — it reuses the same `USRMCLK`
|
||||
primitive already driving the application-SPI/config path, per §7):
|
||||
full-system real Yosys+nextpnr-ecp5 synthesis (`synth/ecp5/
|
||||
unchanged). Full-system real Yosys+nextpnr-ecp5 synthesis (`synth/ecp5/
|
||||
spi_neuron_top_flash/nextpnr.log`), **0 constraint errors**, full route
|
||||
completes, Fmax **66.68 MHz**. The critical path is confirmed
|
||||
unchanged from the pre-existing `neuron_parallel` accumulator carry chain
|
||||
(no flash-subsystem module appears in the reported critical path) — the
|
||||
66.68 vs 73.88 MHz difference is attributed to placement/routing
|
||||
noise from the added I/O and logic, not a new bottleneck. TRELLIS_IO
|
||||
usage: 56/245 (23%).
|
||||
completes, Fmax **66.68 MHz**. TRELLIS_IO usage: 56/245 (23%).
|
||||
|
||||
**Superseded again the same day (Phase F7)**: the flash bus's SCLK
|
||||
originally reused the boot `CCLK` pad via the ECP5 `USRMCLK` primitive
|
||||
(no dedicated pin) — dropped after the user pointed out this made the
|
||||
"exclusive flash bus" claim electrically misleading (SCLK still
|
||||
depended on the same pad as the config engine) and it carried an
|
||||
unresolved verification gap (`USRMCLKTS` pad-enable timing never
|
||||
checked against the primary Lattice sysCONFIG Usage Guide,
|
||||
FPGA-TN-02039, absent from this project's document set). `flash_sclk`
|
||||
is now a 4th ordinary GPIO ball (`E3`, bank 7), added purely additively
|
||||
(`git diff` confirms only the new line, no existing ball moved) — the
|
||||
flash bus is now 4 independent wires (`sclk`/`mosi`/`miso`/`cs_n`), zero
|
||||
pins shared with any ECP5 config primitive. Re-verified with a fresh
|
||||
full-system synthesis: **0 constraint errors**, Fmax **67.91 MHz**
|
||||
(slightly better than 66.68, placement noise, not a regression),
|
||||
critical path confirmed unchanged (`neuron_parallel` accumulator carry
|
||||
chain, no flash module involved), `USRMCLK` utilisation now **0/1
|
||||
(0%)** — direct confirmation the primitive is no longer used at all.
|
||||
TRELLIS_IO usage: 57/245 (23%). See `WORKLOG.md`'s Phase F7 entry.
|
||||
|
||||
**Cross-checked against the real Lattice datasheet (2026-09-03, user-
|
||||
provided `FPGA-DS-02012-3-4-ECP5-ECP5G-Family-Data-Sheet.pdf`)**: its §4.3.2
|
||||
@@ -374,9 +386,10 @@ the exact rationale):
|
||||
| `irq_n` | C4 | 7 | low while `graph_engine`'s load-time guard has tripped (mirrors STATUS.bit2 / §7 of the network-engine spec); clears only on RESET or a fresh graph `run_start`, NOT on a plain STATUS read |
|
||||
|
||||
**Flash subsystem — runtime SPI to the onboard W25Q128JV** (added
|
||||
2026-09-04, Phases F1-F6 — `rtl/spi_flash_master.v`, `WORKLOG.md`; ordinary
|
||||
GPIO, generated the same additive way as every other row here, confirmed
|
||||
by `git diff` against the pre-flash `.lpf` to leave every existing ball
|
||||
2026-09-04, Phases F1-F6, made fully independent in Phase F7 same day —
|
||||
`rtl/spi_flash_master.v`, `WORKLOG.md`; all 4 signals ordinary GPIO,
|
||||
generated the same additive way as every other row here, confirmed by
|
||||
`git diff` against the pre-flash `.lpf` to leave every existing ball
|
||||
unchanged):
|
||||
|
||||
| Signal | Ball | Bank | Note |
|
||||
@@ -384,12 +397,23 @@ unchanged):
|
||||
| `flash_cs_n` | E4 | 7 | |
|
||||
| `flash_miso` | D5 | 7 | |
|
||||
| `flash_mosi` | D3 | 7 | |
|
||||
| `flash_sclk` | E3 | 7 | added Phase F7 — see below |
|
||||
|
||||
No `flash_sclk` ball: SCLK is driven through the `USRMCLK` primitive,
|
||||
reclaiming the same physical CCLK net already used for bitstream boot —
|
||||
see §6/§9 for the board-level wiring implication (the flash chip's
|
||||
DI/DO/CS pins must be dual-wired to both the dedicated sysCONFIG pins and
|
||||
these 3 ordinary balls).
|
||||
**Phase F7 (2026-09-04): `flash_sclk` is now a real, independent GPIO
|
||||
ball, not a CCLK/`USRMCLK` reuse.** An earlier version drove SCLK
|
||||
through the ECP5 `USRMCLK` primitive, reclaiming the same physical CCLK
|
||||
net already used for bitstream boot, to save one pin. Dropped: it made
|
||||
the "exclusive flash bus" claim electrically misleading (SCLK still
|
||||
depended on the config engine's own pad) and carried an unresolved
|
||||
verification gap (`USRMCLKTS` pad-enable timing never checked against
|
||||
the primary Lattice sysCONFIG Usage Guide, FPGA-TN-02039, absent from
|
||||
this project's document set). Re-synthesized full system: `USRMCLK`
|
||||
utilisation now 0/1 (0%), directly confirming the primitive is no
|
||||
longer used at all. See §6/§9 for the board-level wiring implication
|
||||
(the flash chip's DI/DO/CS/CLK pins must be dual-wired to both the
|
||||
dedicated sysCONFIG pins and these 4 ordinary balls — a board-level
|
||||
duplication inherent to using one physical chip for both boot and
|
||||
runtime persistence, not something Phase F7 changed).
|
||||
|
||||
**PSRAM address:**
|
||||
|
||||
@@ -485,9 +509,10 @@ sizes are decided.
|
||||
real Lattice datasheet (§7, matches on 6/7 banks exactly). Fmax
|
||||
54.58 MHz when this pinout was first verified, 75.30 MHz
|
||||
after the `neuron_parallel` timing-closure work, 73.88 MHz
|
||||
after adding the host-attention pins, and **66.68 MHz** for
|
||||
the current full system including the flash subsystem (§7,
|
||||
2026-09-04) — see §7 for the full history and why each change is
|
||||
after adding the host-attention pins, 66.68 MHz after adding
|
||||
the flash subsystem, and **67.91 MHz** for the current full
|
||||
system after making the flash SPI bus fully independent (Phase F7,
|
||||
§7, 2026-09-04) — see §7 for the full history and why each change is
|
||||
pin-placement noise, not a regression.
|
||||
**Config-SPI and JTAG ball numbers are still not pinned down**
|
||||
(§7) — confirmed by reading the full real datasheet that it has
|
||||
@@ -504,21 +529,21 @@ sizes are decided.
|
||||
in-progress KiCad work, not something this repo's synthesis
|
||||
flow needs to resolve.
|
||||
**Distinct from this open item** (do not conflate the two): the
|
||||
flash subsystem's own runtime SPI pins (`flash_mosi`, `flash_miso`,
|
||||
`flash_cs_n` — Phases F1-F6, `WORKLOG.md`) **are** real, pinned,
|
||||
place&route-verified ordinary GPIO on bank 7 (`flash_mosi`=D3,
|
||||
flash subsystem's own runtime SPI pins (`flash_sclk`, `flash_mosi`,
|
||||
`flash_miso`, `flash_cs_n` — Phases F1-F6, made fully independent
|
||||
in Phase F7, `WORKLOG.md`) **are** real, pinned, place&route-
|
||||
verified ordinary GPIO on bank 7 (`flash_sclk`=E3, `flash_mosi`=D3,
|
||||
`flash_miso`=D5, `flash_cs_n`=E4), generated the same way as every
|
||||
other signal in this table. Only SCLK is shared with the dedicated
|
||||
config-boot clock, reclaimed post-configuration via the `USRMCLK`
|
||||
primitive (confirmed against yosys's own `cells_bb.v` blackbox) —
|
||||
it needs no `.lpf` entry of its own, same reasoning as the
|
||||
dedicated pins discussed above. §5's PCB-level implication: the
|
||||
W25Q128JV's DI/DO/CS pins must be wired to *both* the dedicated
|
||||
sysCONFIG pins (for boot) *and* these 3 ordinary GPIO balls (for
|
||||
other signal in this table — **no pin shared with any ECP5 config
|
||||
primitive** (Phase F7 removed the earlier `USRMCLK`/CCLK reuse for
|
||||
SCLK; `USRMCLK` utilisation in the current full-system synthesis
|
||||
is 0/1, confirming it). §5's PCB-level implication: the
|
||||
W25Q128JV's DI/DO/CS/CLK pins must be wired to *both* the dedicated
|
||||
sysCONFIG pins (for boot) *and* these 4 ordinary GPIO balls (for
|
||||
runtime access after configuration completes) — a board-level
|
||||
dual-wiring the same shape as the CCLK-reuse workaround already
|
||||
noted above, not yet reflected in a schematic since none exists
|
||||
yet (see the KiCad item below).
|
||||
duplication inherent to using one physical chip for both roles,
|
||||
not yet reflected in a schematic since none exists yet (see the
|
||||
KiCad item below).
|
||||
- [ ] Confirm PSRAM/SPI signal integrity at whatever clock is
|
||||
actually fitted (§4) — no signal integrity analysis done yet
|
||||
- [ ] JTAG header footprint choice (blocked on the JTAG ball question
|
||||
|
||||
@@ -556,9 +556,18 @@ flash sector (sector 0) — no dynamic allocation, no garbage collection.
|
||||
|
||||
**Layering** (each level reusable/testable on its own):
|
||||
- `rtl/spi_flash_master.v` — raw SPI master toward the flash chip
|
||||
(RDID/READ/WREN/PP/SE/RDSR-1), owns the ECP5 `USRMCLK` primitive
|
||||
internally (the flash's SCLK is not a normal I/O pin post-configuration
|
||||
— see that file's own header for the full citation trail).
|
||||
(RDID/READ/WREN/PP/SE/RDSR-1). All 4 pins (`sclk`/`mosi`/`miso`/`cs_n`)
|
||||
are ordinary GPIO (`flash_sclk`/`flash_mosi`/`flash_miso`/`flash_cs_n`
|
||||
at the top level) — a **fully independent** SPI bus, no pin shared
|
||||
with the dedicated boot config-SPI path, no ECP5 config-primitive
|
||||
involved. **Revised 2026-09-04**: an earlier version reused the
|
||||
boot `CCLK` pad via the `USRMCLK` primitive to save one pin — dropped
|
||||
because it made the "exclusive flash bus" claim electrically
|
||||
misleading (SCLK depended on the same pad as the config engine) and
|
||||
carried an unresolved verification gap (`USRMCLKTS` pad-enable timing
|
||||
was never checked against the primary Lattice sysCONFIG Usage Guide,
|
||||
FPGA-TN-02039, not present in this project's local document set).
|
||||
See `WORKLOG.md`'s Phase F7 entry.
|
||||
- `rtl/flash_copy_engine.v` — block-streaming engine on top: flash→PSRAM
|
||||
(`DIR_LOAD`), PSRAM→flash with internal erase-before-write + ≤256B
|
||||
Page Program loop + WIP polling (`DIR_SAVE`), standalone sector erase
|
||||
|
||||
Reference in New Issue
Block a user