FPGA reconstruction design note: block-by-block feasibility + the three-retarget plan
The governing insight: specification is the bottleneck, not substrate -- igc_exec.py is the golden reference model every port (RTL or GPU) validates against. EMC array = natural FPGA target (208KB BRAM + ~50k LUT full-parallel, or 8:1 muxed); IGC = reimplementation from our cracked ISA; i860 = software (emu860 as executable spec); wire-identical boot via the blind boot-from-link property. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
# Reconstructing the VelociRender in hardware — FPGA design note (2026-07-19)
|
||||
|
||||
Companion to HARDWARE-ARCHITECTURE.md and IGC-ENCODING-DERIVATION.md. Scope:
|
||||
what a faithful FPGA reconstruction of the Division VelociRender (double-stacked
|
||||
EISA, T425 + i860 XP + PXPL IGC 5.2 + EMC array) would take, what already
|
||||
exists, and how the current software work feeds it.
|
||||
|
||||
## The governing insight
|
||||
|
||||
The bottleneck is **specification, not substrate**. The IGC/EMC behaviour we
|
||||
are still deriving (the last eof opcodes, the TXDN texture-fetch protocol) is
|
||||
required identically by an RTL build — you cannot synthesize what you cannot
|
||||
specify. `igc_exec.py` is therefore built as the **golden reference model**:
|
||||
any RTL (or GPU) port validates frame-for-frame against it, and it validates
|
||||
against the real firmware's captured streams.
|
||||
|
||||
## The beautiful property: wire-identical boot
|
||||
|
||||
The board is blind-loaded every cold boot — the transputer streams
|
||||
VRENDMON.BTL + VREND.MNG down the link with **no version check** (see
|
||||
board-boot notes). A reconstructed card that implements the link + CCB
|
||||
handshake accepts the *real firmware from the real host software* and is
|
||||
indistinguishable on the wire. The whole wire protocol is known
|
||||
(VELOCIRENDER_PROTOCOL.md); the boot handshake is implemented in our emulator.
|
||||
|
||||
## Block-by-block
|
||||
|
||||
### EMC array — the natural FPGA target
|
||||
- Per tile: 64×128 = 8,192 PEs, 208 bits pixel memory each (PXPL5002.DOC bit
|
||||
allocations; DIVPXMAP.H field map), 1-bit enable, shared linear-expression
|
||||
tree (eval = int(Ax+By+C) per pixel), bit-serial ALU (~2 bits/clock per the
|
||||
len+115 cycle counts in the instruction words).
|
||||
- FPGA budget (one tile, fully parallel): 8,192 × 26B = **208 KB pixel RAM**
|
||||
(~52 BRAM36) + 8,192 serial ALUs (~5-8 LUT each ≈ 40-65k LUT) + the tree
|
||||
evaluator (DSP adders). Fits a mid-range part (Artix-7 100T tight,
|
||||
Kintex/UltraScale+ comfortable). Time-multiplexing 8:1 makes it tiny — the
|
||||
original ran ~40 MHz; 200 MHz fabric has 5× headroom before parallelism.
|
||||
- The original processed the frame's 52 tiles (832×512 / 64×128) sequentially
|
||||
per renderer — an FPGA build does the same with one physical tile.
|
||||
|
||||
### IGC sequencer — reimplementation from our ISA spec
|
||||
- Custom UNC Pixel-Planes 5-lineage silicon. No netlist, no HDL, no docs in
|
||||
the dump. The instruction set is the one we cracked:
|
||||
`addr | op<<8 | aux<<16 | (len+115)<<23 | S1<<31`, op table in
|
||||
IGC-ENCODING-DERIVATION.md (named via ADDR + DUMP + expanded compiler
|
||||
output). An RTL IGC = a decoder + micro-sequencer driving the EMC controls —
|
||||
straightforward ONCE the op table is complete. **Open items = the same
|
||||
spec gaps the emulator has** (a handful of eof ops, SCMEMA/FCMEMA seed
|
||||
semantics, carry/latch details).
|
||||
|
||||
### DMA engine
|
||||
- Descriptor format fully known (DMAENGN.H + live captures): 64-bit
|
||||
{addr, count|opcode} pairs, SEND/SENDE/TILE/TXDN/GOTO/FLUSH/WAIT/STOP,
|
||||
127-longword chunking, GOTO-chained binchunks. Trivial RTL.
|
||||
- **Open item: the TXDN texture-fetch path** (texels stream to the EMC io
|
||||
port, bits 24+, via nested download programs at 0x8018000+) — being mapped
|
||||
now; needed by every substrate.
|
||||
|
||||
### i860 XP — the mountain, and how to route around it
|
||||
- No mature open i860 core known to us (fact-check welcome). The chip's
|
||||
exposed pipelines (3-stage FP adder, 2/3-stage multiplier, KR/KI/T, DIM,
|
||||
delay-slot annulment) are exactly what we had to model in emu860 — which is
|
||||
now MAME-validated + capture-validated and constitutes an executable spec
|
||||
for any future RTL attempt.
|
||||
- Pragmatic architecture: **i860 in software** — a C/JIT port of emu860 (the
|
||||
original is ~40 MHz dual-issue; a modern host or a Zynq hard-core reaches
|
||||
real-time comfortably), feeding the FPGA raster side through the same DMA
|
||||
queue interface the real firmware uses. i860 RTL is a separate multi-month
|
||||
project nobody needs for either goal.
|
||||
|
||||
### T425 transputer
|
||||
- Open T4xx cores exist; but the transputer is boot/comms only. For a
|
||||
wire-identical card, implement the link + iserver handshake + CCB mailbox
|
||||
(all documented/emulated already) — a small FSM, not necessarily a full
|
||||
transputer.
|
||||
|
||||
### Video out
|
||||
- 832×512 native (dPL3), ADV7150 DAC on the original; standard timing + the
|
||||
ramp/texmode LUT stage (output colour = ramp(texu) — pvision model). The
|
||||
ramp tables come over the wire; the LUT is a BRAM.
|
||||
|
||||
## Three retargets of one spec
|
||||
|
||||
| Goal | Substrate | Note |
|
||||
|---|---|---|
|
||||
| DOSBox renderer (ship as software) | **GPU compute** | EMC pixel = GPU thread; 1:1 mapping; real-time trivial |
|
||||
| Physical pod card / preservation | **FPGA raster + software i860** | wire-identical boot; EISA/link adapter |
|
||||
| The spec itself | `igc_exec.py` (now) | golden model both validate against |
|
||||
|
||||
## Sequencing
|
||||
1. Finish the spec (TXDN protocol, last ops) in the emulator — in progress.
|
||||
2. Restructure `igc_exec` so the op table + tile semantics are a clean,
|
||||
portable core (parser / semantics / readout separated).
|
||||
3. First retarget: GPU compute for the DOSBox goal (smallest step, biggest
|
||||
payoff for the project's stated aim).
|
||||
4. FPGA raster side when/if a physical build is wanted — this note is its
|
||||
starting brief.
|
||||
Reference in New Issue
Block a user