Fixes review comments.

This commit is contained in:
Dennis Brentjes
2026-07-31 11:46:07 +02:00
parent 5828d6a388
commit 7d7ab34bff
23 changed files with 15412 additions and 7499 deletions
+34 -8
View File
@@ -75,9 +75,28 @@ icepll -i 12 -o 54 # confirms DIVR=0 DIVF=71 DIVQ=4 → 54 MHz (capture domai
The `exi_bba/` module tree is **fully implemented** with simulation testbenches.
All modules elaborate without errors and pass their unit tests. The full design
**synthesizes, places, routes, and meets timing** on the iCE40UP5K
(`python -m exi_bba.synth`): `capture` closes ~70 MHz (target 54) and `exi`/
`sync` close ~36 MHz (target 24) — both PASS.
synthesizes, places and routes on the iCE40UP5K, but **capture-domain timing is
seed-dependent and only closes on a minority of seeds** — you MUST sweep.
Measured 2026-07-31, full build (`BBATopSynth(status_panel=True,
uart_console=True)`, 47% LC), `python -m exi_bba.synth --seeds 8`:
| domain | target | result |
|---|---|---|
| `clk` (exi/sync) | 24 MHz | 35.438.4 MHz — **PASS on every seed** |
| `capture_clk` | 54.02 MHz | 49.755.7 MHz — **PASS on only 2 of 8 seeds** (3 and 6) |
Best seed 3 = 55.69 MHz, margin +1.67 MHz (3%). Seed 1 — the default when you
run without `--seeds`**FAILS at 53.08 MHz**. So `python -m exi_bba.synth`
with no arguments produces a bitstream that does not meet timing; always pass
`--seeds 8` (or more) and flash the reported best seed from
`build/seed<N>/top.bin`.
There is essentially no margin: assume any added logic breaks capture timing
until a sweep proves otherwise. The earlier "~70 MHz, both PASS" figure in this
file was wrong — it came from a sweep that silently never ran (see the
`_prepared` note in `synth.py`) and from misreading nextpnr's PRE-routing
placement estimate, which runs ~8 MHz optimistic.
### `exi_bba/` module status
@@ -98,10 +117,15 @@ All modules elaborate without errors and pass their unit tests. The full design
**Bring-up status panel (optional):** `BBATop(status_panel=True)` adds a
`StatusPanel` driving onboard iCEbreaker LEDs + button (dedicated pins, so it
coexists with EXI + W5100). `synth.py` enables it: **LEDG=heartbeat**,
**LEDR=EXI activity** (the GC is talking), **RGB red=rx / green=tx / blue=ready**
**LEDR=EXI activity** (the GC is talking), **RGB red=rx / green=tx / ready**
(via `SB_RGBA_DRV` on pins 39/40/41), **BTN_N=manual re-init**. All 5 panel
LEDs are now mapped on the iCEbreaker. The full EXI + W5100 + panel build
synthesizes and meets timing (slow ~35≥24, capture ~64≥54, 44% LC).
LEDs are now mapped on the iCEbreaker. For this build's timing see the seed
table above — it does NOT close on every seed.
On the **re-bba-rb board** the third RGB element (`led[4]`, "ready", pin 41) is
**D13 = YELLOW** (LCSC C2287), not blue — `synth.py`'s comment still calls it
blue, which describes the iCEbreaker dev board, not this PCB. D11=RED (rx) and
D12=GREEN (tx) are correct on both.
**Ethernet back-end is selectable:** `BBATop(eth="w5100")` (default — indirect
parallel bus, reaches the ~27 Mbit/s EXI ceiling) or `BBATop(eth="w5500")` (SPI,
@@ -124,8 +148,10 @@ python -m exi_bba.bba_top # end-to-end EXI integration test (W5100 RX loo
```
### Pending work
- **Synthesis/timing**: ✅ done — `python -m exi_bba.synth` synthesizes, P&Rs,
and meets timing on both clock domains (capture ~68≥54, slow ~40≥24).
- **Synthesis/timing**: ⚠️ partially — synthesizes and P&Rs, `clk` closes with
wide margin, but `capture_clk` closes on only **2 of 8 seeds** and the default
seed 1 FAILS (53.08 < 54.02). Always `--seeds 8`. Reducing capture-domain
logic to get a real margin is still open work — see the seed table above.
- **W5500 init/TX/RX**: ✅ done — `W5500SPIMaster` has a real Mode-0 byte engine,
a generic register-transaction engine (header + wbuf/stream payload), the full
init sequence (MR reset, SHAR, S0_MR MACRAW, S0_CR OPEN, S0_IMR), MACRAW TX