Projects · Space Wars FPGA

Space Wars on Tang Primer 20K

A modern twist on the classic Space Wars - on a Sipeed Tang Primer 20K FPGA. Version 1.01.DONE; board-tested final release, chip full.

Full write-up (video, hardware, bring-up)

IMPORTANT: Game over - end of the line. This FPGA is full. GAME OVER. Thanks for flying.

Version 1.01.DONE - board-tested on the Tang Primer 20K Dock + 5" LCD. Final release for this FPGA (chip is full).

This is my very first FPGA design, and I built it in just a few days.

AI helped with Verilog edits and GitHub updates. I owned the architecture, bring-up plan, game rules, trade-offs, and the call to stop at 1.01.DONE when the chip was full.

There were many trade-offs in this design, and these choices led to the path I took.

I drew inspiration from the classic, without copying it, to bring a modern FPGA take into the light.

Original HDL game inspired by the 1977 Space Wars arcade (sun, thrust, shots) - not a ROM dump.

You fly the diamond-shaped ship (green) and AI flies a wedge-shaped ship (yellow).

AI hunts and shoots at you, and is more aggressive as time goes on.

Vector outlines, orange sun / black hole, bounce walls, scores, fuel, and a countdown.

Play now (web)

Launch the playable web version

Open that link to run the game in your browser (no install, no FPGA board).

Attract demo starts on load - press Fire (Space / K) for a 1:30 match.

Ships

Diamond ship (player) -  green outline on LCD

On the LCD, outlines match these roles:

Ship Who Outline on LCD
Diamond Player Bright green
Wedge AI Bright yellow
Wedge ship (AI) -  yellow outline on LCD

Left: Diamond (you). Right: Wedge (AI). Thrust flame is drawn from mid-hull in-game.

Hyperspace flashes the Diamond red/green for about 1.5 s. Shots render white.

Hardware

Item Used here
Board Sipeed Tang Primer 20K Dock
FPGA Gowin GW2A-LV18PG256C8/I7 (GW2A-18C), 46 BSRAM
Display 5" 800x480 RGB LCD (RGB565; 5 px rim - black normally, red in black-hole mode)
Clock 27 MHz on H11 -> rPLL 33 MHz pixel clock
Tools Gowin FPGA Designer (synthesize / program)

DIP1 down enables the core (required for flash / run).

DIP5 up = normal attract; DIP5 down = attract test mode

You fly the Diamond; the AI Wedge is frozen, but you can still fly and shoot.

Keys are active-low. Dock buttons and DIP2-5 use a 1.5 V bank (LVCMOS15); LCD, clock, and reset use 3.3 V (LVCMOS33).

Control Pin Action
S0 T10 Hyperspace
S1 T3 Rotate left
S2 T2 Rotate right
S3 D7 Thrust
S4 C7 Fire / start match
DIP5 T5 Attract test when down (up = normal)

FPGA reset is PLL lock only (no button reset).

Hyperspace: vanish ~1 s -> random warp -> ~1.5 s red/green flash at ~10 Hz with spawn invulnerability.

Board bring-up / debug

I brought this up in steps on the Tang Primer 20K Dock + LCD.

I started from a color-bar test on the LCD and drew a 5-pixel box around the active area.

Once pixel timing was solid, I designed a ship, moved it on screen, and found I needed a framebuffer to hold the playfield.

As the game grew, I added test points and wrote checks in the HDL to catch broken behavior early.

To validate game rules without a full fight, I needed the AI off my back - DIP5 down freezes the AI Wedge so I can fly, shoot, and exercise hyperspace alone; DIP5 up restores normal attract / match AI.

When the LCD looks wrong, I still debug by layer: timing and video first, then motion/buffer, then rules and AI, then HUD/scanout.

Known-good savepoints and Gowin util / timing reports are the budget check.

This release is board-validated even though static timing does not close at 33 MHz.

Cinematronics Space War arcade PCB (1979), rebuilt with military-grade integrated circuits
Cinematronics Space War board (1979), rebuilt with military-grade integrated circuits. The arcade classic this FPGA game draws from (original HDL, not a ROM dump). Click the photo to open it in a new tab; click the image there for full size.