FireStorm — FPGA
FireStorm is not a fixed "sound chip" or a simple video controller — it is a reconfigurable, multi-paradigm execution fabric at the heart of the Ant64, hosting the main CPU and the entire chipset on a single die.
Overview
FireStorm is built around the GoWin GW5AST-LV138PG676AC1/I0 FPGA (138K LUT4, 676-ball BGA). It hosts:
- The FireStorm Execution Engine — a 64-bit RV64GC-compatible RISC-V core with eight custom extensions, synthesised in FPGA fabric (a soft core, ~380 MHz)
- A hard RISC-V coprocessor — an 800 MHz 32-bit RISC-V core embedded in the FPGA silicon itself. Not user-programmable as an application target — it runs system / debug firmware that monitors FireStorm internals at silicon speed. See Hard RISC-V Coprocessor below.
- Blaze, the graphics chipset — layered display pipeline, blitter, copper, rasteriser, raycaster
- Tempest, the audio engine — 128+ voice synthesiser + mixer, with codec driven directly from the FPGA
- All bus arbiters, DMA controllers, and memory interfaces
The whole CPU-plus-chipset is one bitstream. Different bitstreams (personality cartridges) can change everything about the system — instruction set additions, chipset layouts, or even targeting a completely different ISA.
- Combined with a WM8960 codec (and an optional PCM3168A on the Studio I/O audio expansion) for audio I/O + optical digital audio out
- Runs various classic-machine personalities — Amiga, Atari STE, SNES, NES, C64, VIC-20, PacMan, Spectrum, MSX2 / Yamaha VDP — implemented either as EE code (software) or as alternative bitstreams (fabric)
Memory
- DDR3 SDRAM — 2.25GB on the Ant64 and 4.5GB on the Ant64C, 1.125GB on the entry Ant64S (user-upgradable to 4.5GB) — a 1Rx8, 72-bit SODIMM, DDR3-800; 72-bit wide (7.2 GB/s peak) — direct FPGA access via dedicated controller
- Wide-mode SRAM — up to 1M × 36-bit (~4.5MB) of pipeline-synchronous fast SRAM
- On-chip BSRAM — ~765KB (GW5AST-138; 6,120 Kbits Block SRAM + 1,080 Kbits Shadow SRAM)
- FPGA boot flash — config bitstream + read-only assets (system fonts, FM tables, wavetables, palette LUTs); shares its bus (clock + lower four IO lines) with the HyperRAM below, distinguished by a separate CS
- FPGA HyperRAM — two banks, 32 MB total (Infineon S70KL1282, 3 V HyperBus, 200 MHz DDR, ~400 MB/s each, ~70 ns first access). HyperRAM 1 (16 MB) shares the boot-flash MSPI bus (its own CS + upper IO + RWDS). HyperRAM 2 (16 MB) is a fully independent private bus in the FPGA I/O (pinout), adding a non-contending second lane for ~800 MB/s aggregate. Both banks are standard on every machine (Ant64 and eZX) → 32 MB. The private HyperRAM 2 carries live ROM (never contending with the flash); HyperRAM 1, sharing the boot bus, carries the burstier image-staging traffic — two lanes so those streams don't contend. Role: ROM / cartridge / disk images, parallel with DDR3 and SRAM; also native-mode scratch. See memory for the full treatment.
Display Inputs (Pulse MIPI + DeMon HDMI)
Two supervisors feed the FPGA's display compositor, over different links:
- Pulse — MIPI RX (a 4-lane-capable D-PHY receiver + differential clock, driven 2-lane by Pulse — 2 × 1.5 Gbps = 3 Gbps): the sequencer / mixer UI overlay layer.
- DeMon (CM5) — HDMI (2× HDMI into the fabric): HDMI0 carries the 720p over-plane; HDMI1 carries the under-plane video. CM↔FPGA data uses PCIe.
The FPGA has two 4-lane-capable MIPI D-PHY RX hardcells. With DeMon now on HDMI, only Pulse's is used for a supervisor feed; the second RX is spare and is routed out to the cartridge port as a full 4-lane input (up to ~6 Gbps), so an active cartridge — camera, capture, or a co-processor rendering a layer — can feed the compositor exactly as a supervisor does.
2nd HDMI data channel — arbitration. DeMon's second HDMI carries in-stream data (not video) by default. A ported emulator in
nativepresent mode instead sends its native-resolution guest framebuffer over this channel while foregrounded, with DeMon's data falling back to the PCIe link — one claimant at a time. A native-res guest layer isn't a fixed 720p, so FireStorm is also handed the frame geometry (width / height / pixel-aspect) as a small sideband over the register window (PCIe), so the compositor knows how to integer-scale it.
For the return direction (FireStorm → supervisor), the two differ. DeMon returns over the PCIe ×1 link to the CM's PCIe hard IP — the same bidirectional link that carries commands also carries the return: telemetry, audio buffers, bulk DDR3→CM transfers, compressed / reduced-resolution video readback. Pulse returns over OPI (8-bit SPI, with a Tempest data-ready interrupt) — mixer readback, telemetry, bulk data. Both replace the earlier LVDS-to-MIPI CSI bridge return, freeing the LVDS TX pins and dropping the external bridge chips; the return carries reduced / compressed data rather than raw frames.
Each input becomes a compositable layer within the chipset's display pipeline, alongside FireStorm's own native layers (tilemaps, sprites, command list, vectors, etc.). The same physical link is also used for bulk data transfer from each supervisor into FireStorm's DDR3 when the framebuffer feed has idle bandwidth.
Security
The FPGA supports both 128-bit AES encrypted and unencrypted bitstream images. The key is stored in a locked, write-once secure location — once set it cannot be read or overwritten. This allows encrypted personality cartridges whilst still permitting unencrypted community images.
The AES key will be set before distribution — if not set first, anyone could lock it with their own key.
DeMon (the CM5) programs FireStorm via JTAG at boot. While the FPGA is configuring, DeMon drives the keyboard touch TFT over MIPI with a boot UI or recovery interface — so the user sees something well before FireStorm is running; the main display picks up DeMon's HDMI overlay once FireStorm is compositing.
FPGA Comparison
| Feature | eZX Spectrum | Ant64S / Ant64 / Ant64C | Next (KS1) | Next (KS2) | Next (KS3) |
|---|---|---|---|---|---|
| Device | GW5AST-138 | GW5AST-138 | XC6LX9 | XC7A15T | XC7A35T |
| LUT4 | 138,240 | 138,240 | 9,152 | 16,640 | 33,380 |
| Shadow SRAM (Kbits) | 1,080 | 1,080 | 90 | 200 | 400 |
| Block SRAM (Kbits) | 6,120 | 6,120 | 576 | 900 | 1,800 |
| Number of BSRAM | 340 | 340 | ?? | 25 | 50 |
| DSP multipliers | 298 | 298 | 16 | 45 | 90 |
| EE soft core | enhanced RV64 — FireStorm (narrow + wide) | enhanced RV64 — FireStorm (narrow + wide) | — | — | — |
| Wide-mode SRAM bus | — | ✓ | — | — | — |
| Wide mode available | only with the DDR3 SODIMM fitted (no on-board wide-mode SRAM) | ✓ | — | — | — |
(Both Ant64 and eZX use the same ordering part, GW5AST-LV138PG676AC1/I0 — see Overview.)
The eZX Spectrum and every Ant64 model use the same FPGA. There is no smaller part and no fabric difference: identical LUT4, BSRAM, DSP and shadow-SRAM budgets, the same hard RISC-V coprocessor, the same SerDes, and — per Memory — the same 32 MB dual-bank HyperRAM.
The eZX is therefore not a constrained sibling in silicon. It is a different loaded image on the same device, and what separates the two machines is the board and the image, not the FPGA:
- The same EE. The eZX runs the identical enhanced RV64 FireStorm EE the Ant64 runs — same custom instruction families (
Xcrisp,Xmath,Xstack,Xlate,Xctx), sameXcond, sameXez. Not a parallel or scaled-down design; the eZX adopted the EE wholesale rather than maintaining its own RV32 profile alongside Ant64's RV64 one. See cpu for the eZX-board-specific CPU integration. - No wide-mode SRAM bank on the eZX board, so its wide mode depends on the optional DDR3 SODIMM being fitted (or the optional SRAM expansion daughter-board). Without either, the eZX runs entirely narrow from HyperRAM. See ezx.
- A smaller peripheral set, which is a carrier decision rather than a fabric one.
Why the eZX can be an Ant64 personality. Not because the Ant64 is a superset — the fabric is the same part — and not because of FireStorm, since a personality bitstream replaces the whole fabric and FireStorm is absent during an eZX session either way. It works because the device is identical and the Ant64 board provides at least the peripherals the eZX image expects — plus the on-board wide-mode SRAM bank the base eZX board doesn't carry, since Ant64 populates it by default. The remaining work is the pinout: the two carriers assign pins differently, so an eZX personality for the Ant64 is the same source re-placed for the Ant64's board, not the eZX's own bitstream loaded unchanged.
Hard RISC-V Coprocessor
Alongside the FireStorm EE (a soft core in FPGA fabric), the GW5AST-138 silicon contains a hard RISC-V CPU baked into the die itself.
Specifications
- 800 MHz clock speed
- 32-bit RISC-V architecture, base ISA + standard extensions
- Hardware multiplier and divider (RV-M)
- 32 KB I-cache + 32 KB D-cache, LRU replacement
- 64 KB ILM (Instruction Local Memory) + 64 KB DLM (Data Local Memory) — tightly-coupled single-cycle SRAM embedded with the core (separate from the caches); deterministic-latency tier for firmware code and hot working data
- Instruction address space: up to 256 MB
- Data address space: up to 2 GB
- XIP (eXecute In Place) — the core can fetch instructions directly from an attached SPI flash through its memory-mapped interface, with the 32 KB I-cache absorbing access latency. This makes running a real operating-system kernel (e.g. FreeRTOS) on the hard core practical: code lives in cheap, large SPI flash; ILM holds the hot path (ISRs, critical sections); DLM holds task control blocks and working state.
- Hardware Performance Monitors (HPM) — cycle, retired-instruction, cache-miss, branch-miss, and configurable event counters
- Memory Management Unit (MMU) — virtual-memory support (address translation, paging) for the firmware running on the core
- Physical Memory Protection (PMP) entries — region-based access control independent of the MMU
- Hardware stack protection extension — overflow detection in silicon
- Zero LUT cost — it occupies no programmable fabric; it's free silicon, already there
This is a fully-featured application-class RV32 CPU on silicon, not a stripped-down microcontroller. With XIP-from-flash for code, ILM for hot paths, DLM for state, and an MMU/PMP/HPM/stack-protection feature set, it's perfectly capable of hosting a real RTOS. The capability budget significantly exceeds what its current debug-and-monitor role on the Ant64 requires — there is substantial headroom for future expansion of the firmware's responsibilities.
Memory Hierarchy
The hard core has four distinct memory tiers:
-
Tightly-coupled local memory (ILM/DLM) — 64 KB instruction + 64 KB data, single-cycle access, deterministic latency. Used for the resident firmware's hot path (interrupt handlers, debug-packet assembly, ring buffers, performance-counter accumulators). Private to the hard core; does not appear in FireStorm's address space.
-
Cached local memory access — 32 KB I-cache + 32 KB D-cache (LRU) backing a wider address space (256 MB instruction / 2 GB data) for firmware too large for ILM. Code stored in FPGA flash can be fetched and cached; large diagnostic datasets — including chipset BSRAM and DDR3 contents — can live in caches over the wider memory window.
-
XIP from SPI flash — the core can execute directly from an attached SPI flash through its memory-mapped interface, with the I-cache absorbing fetch latency. This is the realistic home for a full firmware image: a complete FreeRTOS kernel + tasks fits easily, leaving ILM as a fast-path cache for ISRs and critical sections. SPI flash is cheap, dense, and a perfectly comfortable medium for firmware that doesn't need DDR3-scale storage.
-
Shared DDR3 (configurable) — the GW5AST-138 supports a Shared DDR3: Logic R/W Mode option that allows both the hard core ("MCU side") and FPGA fabric ("FireStorm side") to access DDR3 simultaneously through an arbiter. The address bus is 32-bit, giving the hard core access to DDR3 through its 32-bit data window. When this mode is enabled on the Ant64, the hard core can:
- Inspect FireStorm's DDR3-resident state in place — sample buffers, voice tables, frame-coherent debug snapshots — without round-tripping through QSPI
- Share large diagnostic regions with FireStorm (FireStorm writes a buffer, the hard core reads and analyses it; or vice versa)
- Hold large debug captures or telemetry buffers that wouldn't fit in DLM
The mode is disabled by default in the GoWin IP configurator and must be explicitly enabled in the bitstream configuration. When disabled, DDR3 is owned exclusively by the FPGA fabric (i.e. FireStorm), and the hard core is restricted to ILM/DLM + I-cache/D-cache + XIP flash. Shared mode adds bus contention with FireStorm's DDR3 accesses, but the hard core's bandwidth requirement is light (occasional reads for inspection), so the impact in practice is minimal.
Role
In the current Ant64 design the hard core is not a user-facing CPU. AntOS doesn't run there and user code can't target it directly. Its job is to run resident system / debug firmware with privileged visibility into FireStorm's internals — typically structured as a FreeRTOS image stored in SPI flash and executed via XIP, with multiple tasks coexisting under the RTOS scheduler:
- Voice-state monitoring task — which FireStorm voices are active, envelope states, DSP pipeline occupancy
- Performance counter task — audio DSP cycle budgets, rasteriser triangle throughput, memory bus utilisation across DDR3 / SRAM / BSRAM (the hard core's own HPM CSRs add another set of silicon-level counters for its firmware's own use)
- Error / assertion task — underruns, overflows, FIFO stalls, QSPI protocol errors, audio-engine assertion failures, configurable internal assertions that halt or flag specific voice states / timing violations / data-integrity issues
- Register inspection task — read or write any FireStorm chipset register from inside the FPGA, with no QSPI traffic, at silicon speed; responds to inspection requests from DeMon
- Debug stream task — assembles status packets and sends them to DeMon over a dedicated internal channel; DeMon forwards them to AntOS for display
- (Optional) Shared-DDR3 inspector task — when Shared DDR3 mode is enabled, walks DDR3-resident state on request without disturbing FireStorm
The MMU, PMP, and stack-protection features support running this firmware safely — tasks can be isolated, FreeRTOS's own kernel can be protected, and runaway code paths get caught at silicon level during development.
Why It Matters
Debugging an FPGA design traditionally means either external logic analyser probes (slow, invasive, limited bandwidth) or instantiating an internal debug core in fabric (consumes thousands of LUTs that would otherwise serve audio DSP, rasteriser logic, or voice count). The hard core is a third option: a resident application-class RV32 processor with full silicon-speed visibility into FireStorm's internals, consuming no programmable fabric, communicating through DeMon's existing JTAG and the AntOS debug server.
In production use it remains active — surfacing meaningful diagnostics to AntOS (which voice underflowed, which DMA stalled, what cycle budget the current frame consumed) instead of opaque hardware failures.
Possible Future Direction — Software CPU Personalities
The hard core's current role is debug and monitoring only. But the 800 MHz RV32 core is a genuine application-class processor, and one plausible future use is hosting software-based CPU personalities.
Today a personality cartridge recreates a guest CPU (Z80, 68000, 6502, …) as a fabric softcore synthesised into the FPGA. An alternative, for guests where a software emulator is preferable to a fabric softcore, would be to run the emulator on the hard core rather than in fabric: the 800 MHz clock, 32 KB I/D caches, and tightly-coupled ILM/DLM are well suited to an interpreter or dynarec hot loop, and Shared DDR3 mode gives the emulator direct access to guest memory alongside FireStorm's chipset. That would let a software CPU personality run at silicon speed while leaving the FPGA fabric free for the chipset rather than spending LUTs on a softcore. This on-die-coprocessor idea is now developed further as the near backend of the provisional Xaccel offload extension — FireStorm handing compute kernels (or a guest-CPU emulator) to the A25 over AXI, with results returned through the register scoreboard.
This is a future possibility, not a current capability — the hard core ships running debug firmware, and nothing about software CPU personalities is implemented yet. It's noted here because the hardware headroom exists: the same silicon that watches FireStorm during development could later carry emulated guest CPUs in production.
Distinction from FireStorm
| Aspect | FireStorm EE | Hard RISC-V Coprocessor |
|---|---|---|
| Where | FPGA fabric (soft core) | FPGA silicon (hard core) |
| Architecture | RV64GC + 8 custom extensions | RV32 base + M; MMU + PMP + HPM; hardware stack protection |
| Clock | ~380 MHz | 800 MHz |
| L1 caches | none (Xcrisp prefetch buffers, BSRAM scratchpads) | 32 KB I-cache + 32 KB D-cache (LRU) |
| Local memory | n/a | 64 KB ILM + 64 KB DLM tightly-coupled |
| Address space | 64-bit (DDR3 + SRAM + BSRAM + chipset MMIO) | 256 MB instruction / 2 GB data (32-bit); can reach DDR3 via Shared DDR3 mode |
| Programmable by user | yes — applications, games, demos | no — system / debug firmware only |
| Visible to AntOS | yes, as the application CPU | only as a diagnostic data source |
| Configurable | bitstream-defined; personality cartridges can replace it | fixed (silicon) |
The two are architecturally independent. FireStorm runs the user-facing software stack at its own clock and has its own memory subsystem; the hard core runs its debug firmware at its faster silicon clock and watches the chipset from the inside. There is no shared instruction stream, no shared register file, and no scheduler coupling between them. The one point of physical sharing is DDR3, when Shared DDR3: Logic R/W Mode is enabled — both can read/write DDR3 concurrently through the arbiter, which is what makes the hard core's diagnostic role on the Ant64 substantially more capable. Even there, the coupling is just bus arbitration; there's no software-visible interaction unless the firmware on each side cooperates by convention (e.g. a shared debug-buffer region).
Connections to the Rest of the System
The FPGA has several external interfaces to the supporting chips:
| Interface | Connected to | Purpose |
|---|---|---|
| JTAG | DeMon (CM5) | FPGA bitstream programming, flash access, FireStorm debug |
| PCIe ×1 | DeMon (CM5) | Bidirectional register / data link (commands + FireStorm→DeMon return) |
| HDMI (×2) | DeMon (CM5) | HDMI0 720p over-plane + HDMI1 under-plane video |
| OPI / SSPI | Pulse (ESP32-P4) | Register window (runtime, x8 OPI); Pulse can also reflash the FPGA over this link (QPI, x4, at boot) |
| MIPI RX #1 (4-lane-capable, 2-lane used) | Pulse (ESP32-P4) MIPI TX | Sequencer UI feed + bulk data |
| MIPI RX #2 (4-lane, spare) | Cartridge port MIPI TX | Active-cartridge display input (cartridges) |
| OPI (8-bit SPI) → Pulse | Pulse (ESP32-P4) | FireStorm → Pulse return: mixer readback, telemetry, bulk data (+ interrupt) |
| GPIO / status | DeMon (CM5) | Reconfig, READY, DONE, reset, interrupt |
| Audio I²S | WM8960 (+ PCM3168A on the audio expansion) | Audio output |
| Video out | HDMI / VGA / DP transmitters | Display |
| User I/O header | 3.3 V (Pi-layout) | 28 fabric GPIO (GPIO0–27) / full 18-bit SMI / Z80-bus lines — pinout |
JTAG
Signal Lines
| Signal | Direction | Description |
|---|---|---|
TCK |
In (from DeMon) | Clock |
TMS |
In | Mode select |
TDI |
In | Data in |
TDO |
Out | Data out |
Status Pins
READYCONFIGDONE
DeMon (the CM5) drives JTAG, monitors status pins, and can re-configure the FPGA on demand. The same JTAG chain also gives DeMon access to FPGA flash for asset updates.
A second config path. Beyond DeMon's JTAG, Pulse can reconfigure the FPGA over its SSPI/OPI link (QPI while programming, x8 OPI at runtime) — a fast, JTAG-independent route. The boot-mode straps MODE0/1 are driven from DeMon's I/O expander — MODE2 is resistor-strapped low (and reused as VSYNC_OUT after configuration), since both MSPI boot and SSPI programming need MODE2=0. Board resistors default to MSPI-boot-from-flash at cold power-on; to hand the part to Pulse, DeMon flips MODE0/1 to SSPI and pulses RECONFIG_N. Two independent reconfig routes: DeMon-JTAG and Pulse-SSPI.
On the Tang Primer 25K prototype board, the debug test points are the JTAG lines.
Register Windows
External chips reach FireStorm's chipset register file through memory-mapped windows — classic memory-mapped-peripheral style, where a chip writes to a FireStorm address and the register at that address updates (the POKE-on-a-C64 model):
- DeMon (the CM5) uses its PCIe ×1 link for register + data access.
- Pulse (the ESP32-P4) uses its OPI (octal SPI) link on the FPGA's SSPI slave bus. At boot Pulse can act as an SSPI master and reflash the FPGA over QPI (quad, x4) — a fast, JTAG-independent config path; once the fabric is running, the same pins widen to Pulse's x8 OPI register/data traffic. (This replaces the earlier QSPI "FRAM"-style window.)
Independent windows — each chip can have its own mapping and access permissions. Each supervisor also drives a display feed alongside its register link (Pulse over MIPI, DeMon over HDMI), composited as display layers so each gets a real-time UI surface alongside the main application output.
Audio Codec
The WM8960 codec is wired to an I2S output. A second I²S — for the PCM3168A on the optional Studio I/O audio expansion — is reserved on the FPGA (the expansion codec's I²S runs from the FPGA, not Pulse). (The WM8960/WM8962 routing below is an earlier alternative.) The DAC drives:
- Headphone / microphone connection
- 2× internal speakers
- Audio sampler connections
- Phono line out
WM8960/WM8962 — I/O Routing
| Input | Source | Output | Destination |
|---|---|---|---|
| L1 (in1) | Headphone microphone (mono) | LHP (2nd DAC) | Headphone L — 5.3mW |
| R1 (in1) | — | RHP (2nd DAC) | Headphone R |
| L2 (in1) | LSAM — Sampler left | LSPK (1st DAC) | L internal speaker — 2W |
| R2 (in1) | RSAM — Sampler right | RSPK (1st DAC) | R internal speaker |
| L3 (in2) | (unused — reclaimed) | L line out 1 | — |
| R3 (in2) | (unused — reclaimed) | R line out 1 | — |
| L4 (in2) | — | L line out 2 | — |
| R4 (in2) | — | R line out 2 | — |
AIF1 is connected directly to FireStorm.
WM8960 — I/O Routing
| Input | Source | Output | Destination |
|---|---|---|---|
| L1 | Headphone microphone (mono) | LHP | Headphone socket L |
| R1 | — | RHP | Headphone socket R |
| L2 | LSAM — sampler socket left | LSPK | Left internal speaker |
| R2 | RSAM — sampler socket right | RSPK | Right internal speaker |
These L3/R3 inputs are free for other uses.
Prototype 1 — Tang Primer 25K
Prototype 1 features: HDMI out · 64MB 5ns SDRAM · 8MB QSPI NOR Flash · ESP32-P4 MIPI interface · I2S raw audio from Pulse · VSync out · HSync out · Pixel clock out · Pulse Sequencer SPI master · I2C system master (all chips).
(Pinouts unchanged from previous prototype board; see hardware schematics for details.)
Full Pinout
The complete ball-by-ball assignment for the production GW5AST-LV138PG676AC1/I0 — every bank and its VCCIO, the DDR3 / SRAM / dual-HyperRAM / HDMI / OPI pins, the boot MSPI and SSPI config pins, the MODE straps, and the translated user I/O header (Raspberry-Pi-layout / SMI / Z80 bus) — lives in the FPGA pinout.
(The hand-listed config-pin table that was here was for a different package and is superseded by that document.)