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

5.1 KiB
Raw Blame History

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.