Files
TeslaRel410/emulator/firmware-decomp/FPGA-RECONSTRUCTION.md
T
CydandClaude Opus 4.8 ba7c657dd9 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>
2026-07-19 07:54:34 -05:00

98 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.