Skip to content
tomato
Tomato OS Desktop v1.2 with Ghana wallpaper on the FPGA

Tomato OS

My processor. My operating system.

Tomato OS boots on the FPGA computer, draws the wallpapered desktop, reads the controls, and runs games — including Sudoku. I wrote it in Tomato’s own assembly language. These captures are the HDMI stream, not a phone pointed at a monitor.

Tomato OS demo · Desktop, menu, and games · clean HDMI capture · also in the gallery

ALU verification, whole-machine simulation, and FPGA demonstrations are different evidence. Tomato OS exercises keypad MMIO, tile RAM, HDMI timing, the menu loop, and the current 256 × 32-bit FPGA register file. The CPU writes an 80×60 character field over a bitmap wallpaper; a separate scanout block reads it and drives the monitor. No GPU — games are loops in asm.

The clip above is the full tour: boot into Desktop v1.2, walk the application list, and open the games people ask about first — Tetris, Snake, Racer, Sudoku, Fibonacci — all painted by the CPU and scanned out over the DVI PMOD. Same recording lives in the gallery under Tomato OS.

Sudoku puzzle on Tomato OS
Sudoku · arrows move · Enter cycles 1–9 · dispatch
HDTV video capture adapter packaging and user manual
Physical HDMI capture adapter · used with OBS · dispatch
Tomato OS desktop home with wallpaper
Desktop v1.2 · Ghana wallpaper under the glass UI · dispatch
Tomato OS Desktop v1.2 application menu
Historical Desktop v1.2 capture · current Tomato OS v3.0 has fourteen menu entries
Envelop open inside the current Tomato OS image in the desktop Virtual Tomato browser emulator
Envelop · current OS image · browser CPU emulator · simulated peripherals · bridge offline
Compiler screen running inside the current Tomato OS image in the desktop Virtual Tomato browser emulator
Compiler · current OS image · browser CPU emulator · not an FPGA capture

Controls

Five Nexys buttons wired as a D-pad through rtl/board/keypad.v. Center (N17) is Enter. One physical press emits one key event — after fixing a bench that counted hundreds of repeats from a single push (dispatch). In Sudoku, Enter cycles the digit 1…9 then blank.

ButtonKeycodeIn the shell
Up / Down0x1E / 0x1FMove menu highlight
Center0x0DSelect · Enter screen · cycle digits in Sudoku
Left0x11Back to menu
Left / Right0x11 / 0x10Steer in Snake, Tetris, and Racer

Keyboard MMIO lives at 0x780000: word 0 is the keycode (reading consumes it), word 1 is the ready flag. The Nexys 7-segment display follows the last nonzero writeback or store — so it is not stuck at zero while the shell waits for a key.

Boot splash runs once. Then Desktop v1.2: applications on the left, preview and credits on the right. Tomato OS v3.0 currently has fourteen entries, each dispatched through a jump table. Envelop is linked with its setup data and bounded remote executor.

EntryWhat it does
System infoWhat is Tomato — quirks table
Palette16-color swatch chart for the tile attribute field
Font chartCP437-ish glyph grid — every drawable character
Keypad testLive keycodes on screen — bench tool for the D-pad
FibonacciRunning integers; 7-seg tracks the result
SnakeTile paint, timing, keypad input
TetrisBoard in low RAM · piece rotation · line clears
About TomatoCredits, Penn Engineering
Memory mapBus windows the CPU can name
SudokuArrows move · Enter cycles 1–9 · gold clues fixed
ALU StudioMASKADD / XORAND vs reference sequences
RacerSteer through traffic
EnvelopQueued messaging through a nearby verified bridge; local browser demo uses simulated peripherals
CompilerInspect and exercise supported instruction compilation

Display contract

Framebuffer window at 0x300000 — 80×60 cells, each an 8×8 pixel tile, composited over the Ghana wallpaper ROM. One word per cell (videoout.v):

  • [7:0] glyph — CP437-ish code (keycodes can be drawn directly)
  • [11:8] foreground palette index
  • [15:12] background palette index

Attributes with a black background fit in one ADDI — any tile with bg = 0 is 0x0FFF < 4096. Splash / wallpaper art is converted for the character field with software/os/tools/build_wallpaper.py (OS assets README).

Low memory layout

Everything an LA reaches must sit under 4096 — it assembles to ADDI rd, r0, addr. Prose and pointer tables above that line use .word label instead.

RegionAddressUse
Code0x0000Program and helpers
Strings0x0640Menus, tables, jump targets
Tunables0x0F00Bench pokes game speeds before reset
Scratch0x0F08Mutable OS state
Tetris board0x0F20One 10-bit row mask per word
Snake body0x0F40128 packed cells
Tile art0x1200Ghana flag map (4800 words)
Framebuffer0x30000080×60 tile RAM
Keypad0x780000MMIO data + ready

Build & run

  1. Edit software/os/tomato_os.s.
  2. Assemblepython3 software/assembler.py software/os/tomato_os.s -o hardware/fpga/core/tb/mem/tomato_os.mem (opcodes from tomato.v1.csv).
  3. Burnmake -C hardware/fpga/core burn BOOT=tomato_os packs the image into rtl/burn/*.vh for synthesis.
  4. Flash the Nexys A7 bitstream (open-source flow: Yosys · nextpnr · openFPGALoader — no Vivado).

Without hardware, print the framebuffer in simulation: make -C hardware/fpga/core os. Regression: make -C hardware/fpga/core test boots the OS image and checks menu + games. Or skip all of it: run the shipped firmware in your browser — no install, no FPGA.

Tomato OS and microcode are baked into the bitstream as literal Verilog — not loaded from SD card at runtime. After editing the asm, re-burn before synthesising.

On HDMI

Still frames from the same HDMI path — menu chrome, games, and the quirks table. The live tour is the demo at the top of this page.

System info screen on Tomato OS
System infoQuirks table
Tetris on Tomato OS
TetrisTile RAM
Snake game over on Tomato OS
SnakeGame over
Racer on Tomato OS
RacerSeven lanes
Fibonacci on Tomato OS
Fibonacci7-seg tracks
About Tomato window
AboutFull window

~2.1k

lines of assembly


One source file

Menu, chrome, games, helpers — regression-tested with the core.

80×60

text field


CPU-painted

Tile RAM at 0x300000. Scanout is separate silicon.

14

menu entries · OS v3.0


Jump table

Indexed dispatch — new screen is one table row.