eZX Spectrum — Prototype

How the eZX comes up from cold metal to a usable machine. The methodology matches Ant64's: DeMon supervises and loads the FPGA, Pulse handles MIDI and control, the FPGA does the work. This doc covers the eZX-specific bits — the constraints on the smaller FPGA, the two-image flash layout, and the boot sequence the user sees. For the wider architecture this all sits on, see hardware spec.


Overview

The eZX is built on the same subsystem federation as Ant64: a host FPGA doing all the real-time work, DeMon running AntOS and handling FPGA programming / JTAG / debug / WiFi / USB, Pulse handling MIDI and control surfaces, Sticky owning the 4 joystick / paddle ports, and a new eZX-only Clicky owning the keyboard matrix, the unified WS2812 NeoPixel chain, and the passive buzzer. The bring-up flow is identical to Ant64's — DeMon comes up first, AntOS boots on DeMon, AntOS loads an FPGA image into the host FPGA over JTAG, and the FPGA starts running.

The eZX differences from Ant64 are subtractive in scope, not in FPGA fabric — same 138K LUT4, same FPGA component as FireStorm — with no Colony, no cartridge port, no FireStorm soft core, and no on-board 36-bit SRAM bank (DDR3 only, plus the optional SRAM expansion daughter-board — see expansion) as deliberate design choices rather than fabric constraints. The controller side is also subtractive: no Crank (Ant64's dedicated jog-dial controller), so no jog dials of any kind on the eZX. The Pulse subsystem accordingly has no jog-dial input stream feeding it; the eZX is a keyboard-and-pad machine rather than a synth workstation. The eZX adds Clicky for the integrated keyboard. The user-facing video outputs (HDMI + VGA via on-board bridge chips) match Ant64's exactly. With those constraints in mind, the Ant64 architecture overview covers the wider DeMon / Pulse / Sticky federation this design adopts.

What's new on the eZX side is the two-FPGA-image model. Both images live in DeMon's flash and DeMon picks one at boot — eZX primary (the clean-slate machine) by default, with the Next-compatible image loadable via an AntOS script. Section 3 covers the mechanics.


1. Hardware stack

Block Part Role
Host FPGA GoWin GW5AST-LV138 (138K LUT4, hard RISC-V core) — same FPGA as Ant64's FireStorm Runs whichever FPGA image is loaded — eZX primary chipset + the FireStorm EE, ZX Spectrum Next core, or Classic Spectrum image
Main memory 72-bit DDR3 at DDR3-800 (the GW5AST-LV138's maximum supported DDR3 data rate) Sole bulk memory — no SRAM in eZX
Supervisor DeMon (CM4 lite, user-upgradeable to CM5 lite, + ESP32-C5) Runs AntOS, connects to the FPGA over HDMI ×2 + PCIe 1x (serdes), owns USB host, WiFi, JTAG, NFC, debug bridge
MIDI / control Pulse (ESP32-P4 + 32 MB PSRAM) MIDI ports, controllers (via Sticky), control I/O
Joysticks Sticky (AVR128DB64) 4 × DE-9 joystick ports — digital pads (Atari, Sega 3/6-button) or analog paddle pairs. Unchanged from Ant64
Keyboard, buzzer, NeoPixels Clicky (AVR128DB64) — eZX-only Scans the 8×7 keyboard matrix, decodes to UTF-8 on chip, drives the unified WS2812 chain (8 status LEDs + per-key NeoPixels) and the passive buzzer. UART2 to DeMon. The Ant64 has no equivalent (no integrated keyboard) — its jog-dial controller (Crank) is not present on the eZX
Main display HDMI via Parade PS176 DP→HDMI 2.0 bridge 4K@60 capable — see hdmi_out
Retro display VGA + audio via AG6201 HDMI→VGA bridge DE-15 + 3.5 mm jack, MiSTer-cable compatible — see rgb_out
Storage / I/O USB host, NFC card reader, optional MIDI/audio expansion connector (Ant64-compatible) See Expansion for the unified expansion overview. MIDI/audio expansion connector is mechanically and electrically identical to Ant64's — daughter-boards interchangeable. No separate accelerator expansion — DeMon's own CM4/CM5 module is a full Linux-class ARM host
Wireless ESP32-C5 (inside DeMon) WiFi 6, BT 5.3, Thread, Zigbee

The DeMon, Pulse, and Sticky subsystems are unmodified from Ant64. The host FPGA is the same part Ant64 uses for FireStorm (GW5AST-LV138); differentiation from Ant64 is in the FPGA images and software focus, not in silicon. Clicky is eZX-specific (the Ant64 has no integrated keyboard). The bridge chips and the keyboard-matrix wiring are eZX-specific.

For each subsystem's internals — pinouts, supplies, interconnects, firmware story — the Ant64 subsystem docs are authoritative; nothing differs at that level. With the constraints above noted, those are at ant64.com/demon, ant64.com/pulse, ant64.com/sticky, and ant64.com/clicky — the Clicky doc covers both Ant64 and eZX keyboard configurations in one place, since the same firmware binary runs on both products with a board-strap pin selecting matrix-scan mode.


2. Boot sequence

What happens between flicking the power switch and the eZX prompt appearing:

T+0 ms      Power-up. PSU rails settle. DeMon and Pulse begin their resets.
            The FPGA independently begins loading the eZX primary image
            from its own flash — this does not wait for DeMon.
T+~?        DeMon comes out of reset. CM4/CM5 Compute Module boots Linux
            from the SD card / eMMC, ESP32-C5 powers up. [Note: this stage
            was near-instant on the earlier ESP32-P4 RTOS boot; a full
            Linux boot on the CM4/CM5 is structurally slower — the timing
            below needs revisiting against real numbers, not treated as
            still accurate]
T+~?        AntOS starts on DeMon. DBFS opens, system services start.
T+~?        AntOS checks the FPGA's currently-loaded image and the user's
            configured default. If they already match (the common case —
            the FPGA self-loaded the eZX primary image and that's also
            the configured default), no further FPGA action is needed.
            If a different image is configured as default, or the user
            requests one later via an AntOS command (see section 3), DeMon
            asserts the host FPGA reset and streams the chosen bitstream
            over JTAG — ~900 ms typical for a ~80 Mbit bitstream at
            JTAG-clock rates DeMon can sustain (this figure is unaffected
            by the DeMon chip change — JTAG bitstream loading is the same
            regardless of what's driving it). DeMon then releases the FPGA
            reset and the DDR3 controller calibrates against the SDRAM
            (~50 ms).
T+~?        The running image begins/continues execution. For the eZX
            primary image, this means the eZX CPU fetching from
            $FFFF0000 (the boot ROM in FPGA flash). For the Next-compatible
            image, the Next core's own boot sequence runs.
T+~?        Welcome screen / prompt visible on the user's display.

The numbers above were written for the ESP32-P4 supervisor and are not yet re-measured for the CM4/CM5 Compute Module — a full Linux boot is a fundamentally different order of magnitude from an RTOS cold-start, and this table should not be read as current until it's redone. The bitstream-load timing (JTAG rate, bitstream size) is unaffected by the supervisor change and should still hold.

This timeline also predates the FPGA self-boot correction elsewhere in this doc set (see spec § FPGA images): the eZX primary image loads automatically at cold boot from the FPGA's own flash, not from DeMon over JTAG — DeMon's JTAG path is only used to load the Classic Spectrum or Next-compatible images on demand, or to re-flash the FPGA's own flash. The sequence above should be read with that correction in mind rather than as showing DeMon streaming every boot's bitstream; the JTAG-streaming stage only applies when switching to a non-default image.

This matters because it means the FPGA is never holding state across a reset. A user power-cycle is a clean rebuild every time. The image in flash is the source of truth.


3. The three FPGA images

The eZX has three FPGA images, all pre-built and stored in DeMon's flash:

Image FPGA utilisation Default? Loaded by
eZX primary Moderate — the chipset and CPU together fit comfortably on the GW5AST-LV138 with substantial headroom Yes — boots automatically DeMon at power-on
ZX Spectrum Next compatible ~20k LUT4 of the available 138k — well under 20% utilisation No — explicit load required AntOS script invoked by user
Classic Spectrum Modest — per-model emulation matrix with system RAM in BSRAM for most models No — explicit load required AntOS script invoked by user

The bitstream file size is determined by the FPGA configuration ROM size, not by how much of the fabric the design fills, so all three images write the same number of bits to flash. What the table really shows is the design size — the Next core fits comfortably on a 20k-class FPGA like the Tang Nano 20K (see the upstream NextNano project, which runs a complete Spectrum Next on a Gowin GW2AR-18). Bringing that across to the GW5AST-LV138 leaves over 100k LUT4 free for the eZX-specific debug hardware additions, BSRAM-replication for contention-free sprites, and the 1080p display pipeline — all without resource pressure.

eZX primary

The clean-slate eZX chipset — custom chipset (see ezx) plus the same FireStorm EE the Ant64 runs, with the Xcrisp and Xez extensions (see cpu, Xcrisp, and Xez). This is what boots by default. It's also distributed as an Ant64 personality cartridge, so Ant64 owners get the same machine without buying separate hardware — and since both hosts use the same GW5AST-LV138 FPGA and the same EE, the same bitstream runs unchanged in either context.

Next-compatible

A port of the open-source ZX Spectrum Next FPGA core, upstream from RetroSilicon NextNano (which itself draws on the MiSTer ZXNext core). The core uses Z80N (not eZX — entirely different ISA) and reproduces Next-era memory map, paging, video, and audio. NextNano runs the entire Next stack — full back catalogue, sprites, layered display, NextZXOS — on a Gowin GW2AR-18 (~20k LUT4), which means the eZX's GW5AST-LV138 has well over 100k LUT4 of unused fabric to spend on the eZX-specific additions: proper hardware debug (breakpoints, watchpoints, single-step), a host-side protocol DeMon understands, BSRAM-replication for contention-free sprites, and 1080p output. A stock Spectrum Next has none of these. Developers writing Z80N code may prefer the eZX-running-Next-image to a real Spectrum Next purely for the debugging story.

This is not compatible with the eZX primary image at any level. Loading the Next-compat image replaces the entire FPGA configuration. The three images share the host FPGA, the host DDR3, and the bridge chips driving HDMI and VGA, and nothing else.

Classic Spectrum

Per-model cycle-accurate emulation of the pre-Next Spectrum range (16K, 48K, +, 128, +2, +2A, +3, Pentagon 128, Pentagon 1024, Timex TS2068/TC2048, Didaktik Gamma, Scorpion ZS-256 with Turbo+). Uses the same Z80NG CPU as the Next-compatible image in Z80 strict mode. System RAM lives in BSRAM for every model up to Scorpion ZS-256 (256 KB), with single-cycle deterministic timing matching the original SRAM-based ULA contention pattern. Pentagon 1024 (1 MB) exceeds the BSRAM tier and runs from DDR3 with prefetch. See Classic Spectrum image for the per-model detail.

Switching images

From AntOS on DeMon:

$ fpga.load("next")        # loads Next-compatible image (~600 ms)
$ fpga.load("ezx")         # loads eZX primary image
$ fpga.current()           # returns "ezx" or "next"

The eZX primary image always loads at power-on. Switching to the Next-compatible image is a deliberate post-boot action — the user is in AntOS, runs fpga.load("next"), the FPGA reconfigures (~600 ms), the Next machine comes up. There is no boot-time chord or button sequence to bypass AntOS; the user is always going through AntOS to make the choice.

The switch is destructive — whatever the previous image was doing is gone the moment DeMon asserts FPGA reset. No state crosses the boundary. This is the right behaviour: the user is asking for a different machine and gets one.


4. DeMon as the FPGA loader

DeMon owns the FPGA bitstream pipeline end to end:

  • Storage — all three image bitstreams live in DeMon's flash. The Ant64-platform DeMon has 16 MB of flash available, ample headroom for three GW5AST-LV138 bitstreams plus AntOS, debug firmware, and configuration data.
  • JTAG transport — DeMon drives the FPGA's JTAG pins directly. The same JTAG path that loads the bitstream also serves as the runtime debug channel once the FPGA is up.
  • Configuration register window — DeMon talks to the loaded FPGA image via the QSPI register window (the same DeMon ↔ FireStorm path used on Ant64, repurposed for the eZX image's chipset register file).
  • Image update — new bitstreams arrive over WiFi / USB / SD card, are validated, and written to DeMon's flash. AntOS exposes this as a normal file-system operation. The currently-running image is never replaced live — only the next-boot image is updated.

For developers: an AntOS command (fpga.upload(path)) takes a fresh bitstream from the file system, validates the GoWin file signature, writes it to the appropriate flash slot, and (optionally) reloads the FPGA from the new image. This is the inner loop of FPGA development on the eZX — write HDL, build, copy bitstream to the machine, type one command, the new image is running.


5. Development workflow

Developing the eZX primary image

The eZX primary FPGA image is also an Ant64 personality cartridge. Because the eZX Spectrum uses the same FPGA part as the Ant64 (GW5AST-LV138), the development workflow is single-target:

  • One synthesis target — the GW5AST-LV138. The same bitstream runs on the Ant64 (loaded as a personality cartridge) and on the eZX Spectrum hardware (loaded directly by DeMon at boot). No re-synthesis when moving between the two
  • Develop on whichever host is convenient — Ant64 dev hardware, an eZX Spectrum prototype board, or any Gowin GW5AST-LV138 dev board. AntOS, DeMon, and Pulse behave identically on all of them because they are the same supervisors talking to the same FPGA part
  • Resource pressure is comfortable, not tight — the GW5AST-LV138 has 138K LUT4 and 340 BSRAM blocks, well above what the eZX primary image needs. Debug overlays, profiling, and trial features fit alongside the production design without forcing scope cuts; production releases retain margin for future enhancements
  • Compile-time configuration knobs still exist in the RTL to drop eZX-specific scope choices (no FireStorm soft core, no Colony peripheral I/O) when building for Ant64-platform use — these are scope toggles, not budget-rescue mechanisms

The previous "two-stage development flow" (develop on Ant64's GW5AT-138, retarget to GW5AT-60 for eZX) no longer applies — both hosts now share silicon.

Developing for the Next-compatible image

The Next-compatible image is a port of an upstream open-source project. eZX-specific changes (hardware debug integration, host-protocol additions, BSRAM-replication for contention-free sprites, 1080p display scaling) are maintained as a fork against the upstream repository. Development happens directly on the GW5AST-LV138 with substantial fabric headroom — the upstream design fits in ~20K LUT4, leaving over 100K LUT4 free for the eZX-specific additions.

Re-syncing with upstream is a periodic merge — the eZX fork doesn't aim to diverge from the upstream Next core's behaviour, only to add the debug hardware and the eZX enhancements.

Software development

For software targeting the eZX primary image (the EE with Xez), the toolchain (ezxasm, ezxld, ezxcc, ezxdbg) runs on any modern host. The debug frontend talks to DeMon over USB or network; DeMon translates host-protocol debug commands into FPGA-side JTAG and chipset register operations. See ezxasm for the assembler workflow and cpu for the CPU model the toolchain targets.

For software targeting the Next-compatible image, the standard ZX Spectrum Next toolchain (zasm, sjasmplus, NextDAW, etc.) works unchanged. Compiled NEX files load onto the eZX via AntOS file copy; the eZX's Next-image debugging is exposed through the same DeMon-mediated channel.


6. Prototype hardware

The eZX prototype boards have been bringing up subsystems in order:

  1. DeMon + AntOS — already operational on the CM4/CM5 DeMon board. AntOS runs end-to-end with DBFS, networking, and the full system services. This stage is shared with Ant64 — same DeMon hardware (Ant64 uses CM5 lite where the eZX uses CM4 lite, user-upgradeable to CM5 lite), same AntOS build, same boot.
  2. FPGA bring-up with HDMI direct out — a GW5AST-LV138 dev board with direct FPGA TMDS to a development HDMI connector (no PS176 in the prototype loop). 720p60 and 1080p60 baseline working; serves the chipset bring-up and the basic register-window test.
  3. AG6201 retro path — an AG6201 breakout dongle (community MiSTer Direct Video parts) wired to a secondary FPGA HDMI output. Validates the 240p superresolution path and the audio DAC behaviour before the final PCB integration.
  4. PS176 main HDMI integration — pending. Once the dev FPGA can reliably drive 4 SerDes lanes at HBR2, a PS176 breakout slots in for the 4K@60 main output path.
  5. Pulse, Sticky, and the rest of the I/O stack — slotting in subsystem by subsystem as the prototype PCBs mature. Pulse and Sticky are shared with Ant64 hardware so most of that work is already done.

Each prototype stage gets a known-good configuration before the next subsystem joins. The DeMon-as-loader model means subsystems can come and go without invalidating the rest — the FPGA image is rebuilt for each prototype layout and DeMon loads whichever image matches the current board.


7. Status and open questions

  • PS176 HBR2 timing closure on GW5AST-LV138. The FPGA's SerDes transceivers are rated for the required link rate, but cleanly driving 4 lanes at 5.4 Gbps with the rest of the chipset on the same fabric is the headline integration risk. Closure on the prototype is pending.
  • Bitstream load time. Targeting <1.5 s from power-on to user-visible prompt. DeMon's JTAG clock and the bitstream compression options will determine whether the eZX primary image hits that target.
  • FPGA image storage in DeMon flash. Both images comfortably fit. A third image (Spectrum 128k purist, Spectrum +2A/+3 paging, Spectrum Next "Lite" without the eZX debug additions, etc.) would need either flash expansion or an SD-card-resident image catalogue. Currently parked.
  • Hot reload. It is technically possible to reload the FPGA without a full system reset — the user keeps their AntOS session, DeMon stays up, but the FPGA is reconfigured. This works for image-to-image switches today. What's not yet decided is whether user state (loaded software, paused execution, etc.) survives a reload of the same image. Probably not — if the user wants persistence, save to DBFS first.

Important: The eZX Spectrum board is at early design/prototype stage, everything you see here is subject to change.