Skip to content
tomato
Play TomatoMessage TomatoEngineeringJournalGalleryStatus
HomeArchitecturePlaygroundSoftwareTomato OSISAGalleryBuild journalBoardsVerificationWhat exists todayFAQAboutTour the boardSourceBoard workspace
Home

From circuit boards to a running OS.

See Tomato OS on screen, the ALU board being assembled, and the designs behind the hardware. These are recordings and photographs from my build.

Swipe to browse · tap frame to expand

1 / 98

Current OS
v3.0 · 14 entries
Capture
1440 × 1000 · browser emulator
Peripherals
Simulated · bridge offline

The current generated OS image runs the Envelop client inside the browser CPU emulator. This is virtual execution with simulated peripherals; it does not prove a programmed FPGA, radio session, or online bridge. Follow the complete message journey.

Capture
1280 × 720 · frameport
Screen
Envelop conversation
State
Bridge online in captured frame

Envelop rendered through the FPGA display path. The frame records the interface and reported bridge state at capture time; it is not evidence that a bridge is currently online.

Capture
FramePort · USB video
Request
Bounded 32-bit job
Result
0x00008115

The FPGA display path shows Envelop returning a bounded compute result. The frame records the interface and reported bridge state at capture time; it does not establish that a bridge is currently online.

Format
MP4 · HDMI
Path
Nexys A7 · DVI PMOD
Page
Tomato OS

Desktop, menu, and games on the FPGA computer—clean HDMI capture, not a phone pointed at a monitor. Same clip featured on the Tomato OS page.

Status
Soldered

Iron on the desk. Boards and DigiKey parts were already ordered — just waiting on delivery.

OS
Tomato OS
Capture
HDMI

TomatoOS desktop home—wallpaper on the FPGA path. The rest of the computer catching up to the ALU.

OS
Desktop v1.2
Capture
HDMI

A historical twelve-entry menu capture; Tomato OS v3.0 now has fourteen entries, including Envelop and Compiler, off one jump table. Same screen as the menu sheet.

Screen
System info
Capture
HDMI

What Tomato is, in its own words — Dual-LUT ALU, register file, immediate box, and all, straight off the HDMI stream.

Input
D-pad + cycle
Cells
30 filled

Thirty cells in, gold clues fixed. Same screen as the OS sheet.

App
ALU Studio
Check
MASKADD vs AND + ADD

MASKADD in one ALU pass against the two-instruction RV32I reference — match checked on the CPU itself. Counts exclude loads and UI.

Input
D-pad + cycle
Board
9×9

Sudoku without waiting on the full keyboard matrix. Move with arrows; cycle 1–9 with another button.

Why
Always nearby

Of course Tomato needs Sudoku—the paper book is always within arm’s reach.

Habit
Ink on paper

Same desk, same habit—then the machine gets its own board.

Path
HDMI · not a phone

Clean capture of Tomato OS from the HDMI stream—no filming the monitor.

Gear
HDMI capture

The order that turns “can it produce video?” into “how do I capture it nicely?”

OS
Tomato OS

The main menu running live on the TV via the 12-bit PMOD. Six entries, all navigable with the D-pad.

Tools
FOSS stack
Clip
~21 s · terminal
Log
Beyond Vivado

Beyond Vivado. Yosys, nextpnr, and Project X-Ray compile the Tomato core to a bitstream on the Mac — terminal capture from synthesis through DONE. Same clip as the dispatch.

Board
07_alu
Status
On the bench

The slice under test. Copper on the mat, tools around it — the board is no longer a render.

View
Bench · landscape
Clip
~45 s · 3s / 2s still

Soldering lights on the loop, cut with the on-board test still every three seconds — desk, iron, then the slice on the mat.

On the bench
74ACT151 · 74ACT283
Lamps
7 LEDs down
Status
One board soldered

The silicon on the copper at last. I got every mux down on one board, both adders, and the first few lamps of the debug wall. Holding it right next to the sim, the slice finally started looking like the machine I designed.

Format
MP4 · bench
On the board
Every 151 · each 283

Tweezers, an iron, one SOIC at a time. Real parts on real pads instead of schematic symbols.

Format
MP4 · bench
Count
7 down · 126 to go

These indicators are insanely tiny. Align, don’t bridge it, repeat. I only managed to get seven on the wall at this point.

Outline
99.95 × 99.80 mm
Qty
5 boards · JLCPCB
Status
Power continuity clean

Five boards showed up. Continuity on power was clean on all of them. I still remember placing every trace on this outline.

And then the soldering began.

Format
MP4 · bench
Boards
5 × 07_alu

A slow pass over the stack. You can really see the mask colour, the edge plating, and that massive LED wall footprint right before I started populating them.

Text
0x1800 Memory

The most important screen on the system. Overcoming the low memory wall allowed this massive text block to be rendered by pulling from higher memory via pointers.

Test
Multimeter · power rails
Result
No islands

The very first bring-up step: checking continuity on VCC and GND across every board. They were perfectly clean on all five. No open pours, and definitely no shorted islands from the fab.

Format
MP4 · bench
Peripheral
12-bit PMOD

Soldered the PMOD pins, plugged in HDMI, got color bars — red, green, blue, gray. First sign the video path works.

Board
Nexys A7-100T
PMOD
JC + JD

The bring-up rig: Nexys A7 with the iCEBreaker 12-bit DVI PMOD seated on JC and JD, HDMI out, DONE lit after an open-source bitstream flash.

Tool
LibreLane
Role
Upstream PRs

The same open toolchain ethic as the FPGA pivot on the Mac. LibreLane is where tapeout habits get tested before they touch Tomato copper.

Stack
Yosys · nextpnr · X-Ray

Researching the FOSS FPGA and ASIC stacks that could replace slow closed tools. OpenROAD sits in the same toolbox as the Nexys bring-up Makefile.

Vendor
Mouser

After the VGA adapter refused to play along, I had to pivot. The PMOD order receipt from Mouser marks that shift in strategy.

Part
VGA PMOD

The rest of the Mouser order. A CPU without a display is a heater, so this PMOD was critical to getting pixels on the screen.

Vendor
DigiKey

DigiKey receipt for the 74xx parts. Drawing them is free. Buying them is not.

Vendor
JLCPCB

Checkout on JLC. Then you wait for the boards to show up.

Screen
About

The screen that used to flash for one frame before the debounce arithmetic fix. Now it reliably waits for the next key press.

Layer
2-layer

Order placed. ENIG boards inbound.

Status
Confirmed

Order summary. These line items become physical boards a week later.

Stack
2-layer · ENIG
Qty
5 boards

Five boards for under six dollars. That was cheap enough to spin again without thinking twice if the fab made a mistake.

Source
DigiKey
Ship
17 Aug 2026

The delayed order. I got it replaced on the phone, and it finally showed up. After weeks of staring at schematics, the chips were finally a box I could actually hold.

Hit
AND3 · 0x80
Plane
Artix-7

That same sweep, but running on hardware. This FPGA clip confirmed the sim hit way before any copper was populated.

Hit
AND3 · 0x80
Plane
Digital

A brute-force sweep running in Digital. The AND3 family surfaces right at opcode 0x80, just before I replayed that exact same vector on real silicon.

Source
KiCad GLB
Light
Studio · mask & copper

The front-page orbit. I set up paper-stock lighting on the real mask colour. It's the exact same model you see on the interactive bench.

Game
Tetris

One of the first games on TomatoOS. Tetris on hardware you soldered hits different from an emulator.

Nets
185 routed
Unrouted
0

The status bar at lock-in: every net closed, DRC passed, ready for Gerber export and JLCPCB.

Mask
Green
Cells
Two nibble slices

July render with the green solder mask. The dual-LUT plane reads clearly in 3D long before any SOIC landed on the desk.

Layer
B.Cu
Pours
Ground flood

The back side: ground pours, stitching vias, and the underside of the LED wall. Two-layer boards still have a face you rarely show off.

Cells
CELL 0 / CELL 1
Blocks
flags · LED wall

The KiCad 3D render right before fab. Two alu_4b nibble cells chained on CIN-MAIN, complete with the flag block and an opcode lamp wall for bench debug.

Errors
0
Warnings
0

The green check before checkout. No clearance violations, no unrouted nets — the board was allowed to leave the editor.

Stage
Placement only
Airwires
Still routing

Nine footprints placed and a cloud of cyan airwires. This is the moment the schematic stops being abstract and starts demanding vias.

Sheets
alu_4b × 2
Support
flags · iopins · LEDs

The schematic tree directly mirrors the Digital simulation. The hierarchy on the sheet matches the verification ladder exactly, right from 1b up through 8b.

Board
07_alu
View
Top copper

The routed board before export. Two 4-bit cells, flag block, and the LED wall footprint all locked on one 100 mm square.

Game
Racer

Racer on TomatoOS. Simple graphics; still fun because it is on the real machine.

Mask
Olive
Silk
Penn mark

The olive finish with Penn on the silk. Same geometry as the fab order — just the branding pass I wanted on the first spin.

Sheet
Root

The root sheet: power, connectors, and the two alu_4b instances that become the 8-bit slice.

Cell
alu_4b

One nibble cell: dual-LUT muxes, carry chain, and the opcode select that repeats across the word.

Block
Flags

Zero, carry, negative, overflow — the flag block that turns arithmetic into branch conditions.

Block
I/O pins

Bench headers and probe points. The slice has to be debuggable without a logic analyzer on every net.

Block
LED wall

The opcode lamp wall on its own sheet — one LED per function so the bench can read what the ALU is doing.

Block
Glue logic

Decoders and support logic that tie the hierarchy together — the sheets you only notice when something does not enable.

Nets
185 · 0 unrouted
DRC
Clean

The fab-ready top layer. 308 vias, 2404 segments, and I made sure every single net was closed before the order went out.

Cell
LUT2 from muxes

Feeding hex control into stacked 4-to-1s. This was the dual-LUT idea, still just a schematic and not yet 74ACT151 copper.

Game
Snake

The Snake port game over screen. Built entirely with the parametric ISA and the new pseudo-instructions.

Part
NE555

The heartbeat of the very early machine. I modeled the analog in Spice first, aiming for a square wave that the rest of the sim could actually trust.

Width
1 bit
Select
Opcode

The primitive here is just a mux. You land the opcode on the select pins, and the ALU bit becomes whatever the mux is wired to emit. Slice that cell and you get a word. Digital is where I tested that claim before locking in any footprint.

Plane
Software twin

The same ISA, but absolutely no gates. I built this page to step the machine, mostly so the Digital netlist would have a referee to argue with.

Plane
Digital

The big sheet, running live. Just a program counter walking through a ROM I wrote.

Width
32b on the sheet

Boxes before any footprints. Source A, Source B, destination, memory, and flags. Later sheets would test this exact unit in Digital. If the arrows lied, the sim was always going to say so louder than any DRC.

Sheet
main.dig
Nodes
629

The living top sheet: control decode, alu-32b-final, register file, RAM and VGA, IR, PC, and the data-bus switch — labeled tomato-v1-burn. Same machine the FPGA and the OS boot from.

Sheet
main.dig

Mid-June: MMIO and arbiter experiments showing up on the same canvas as the ALU slices.

Sheet
main.dig
Status
Programs running

Late June — the sheet that became the front-page Digital plate. Custom programs and Fibonacci already behaving like a CPU.

Sheet
main.dig

Early June on the big sheet — still wiring the control spine before the custom programs ran clean.

Program
Fibonacci

Fibonacci on the slow clock — the usual sanity check once fetch and execute behave.

Sheet
main.dig

Another day on main.dig. The bus and register file start to look like a machine instead of a pile of parts.

Sheet
main.dig

Fetch and execute paths tightening. Each snapshot is a commit in the sim before any Gerber existed.

Word
40b control

One memory, driving a lot of enables. Fanout is simply the tax you pay for having a centralized control unit.

Machine
States on a sheet

A tiny state diagram that eventually grew into the full microcode.

Width
8-bit sim

Take the cell, lay it out eight times. This is the direct ancestor to the two 4-bit cells that eventually became 07_alu.

Muxes
74157 × 40

Shift implemented as a complete forest of 2-to-1s. This barrel shifter is exactly why the ALU does a lot more than just add.

Out
p ← 4151657813

The register is not empty. I ran a custom program that left a Fibonacci value sitting on Q and drove pin p. Seeing that number was the first time the paper machine actually behaved like a computer.

Was
Arbiter red
Now
Bus green

Memory-mapped I/O really only counts when the arbiter stops lying to you. It failed, then it passed, and then I captured this still.

Input
Keyboard

Starting to convert an Amazon keyboard into a proper matrix. The 5 buttons on the A7 were too limiting for complex apps.

Plane
Digital

Microcode broken into modules instead of one unreadable sheet. Each block maps to a strobe the datapath can actually route.

Proof
Digital · working mux

The insight on the black card finally turned into a schematic that ran. The nibbles time-share a single ROM, and latches hold a digit each. Without doing this, every single hex lamp would have demanded its own decoder.

Target
7-segment

From hand-drawn hex patterns to a control sheet that drives segments from a nibble. The display problem stays a memory problem.

Part
74182 CLA

Ripple was honest, but lookahead was just faster. This wall of 74182s was the adder finally leaving the yellow pad.

Width
8 × 8-bit slices
Clock
555

Clock, counter, a couple EEPROMs, SRAM, a register file, eight 8-bit ALU blocks, and three hex walls. Microcode fans out the strobes, branch, halt, and the ALU function. 07_alu is really just one slice of this drawing, made small enough so I could actually fab it.

Cell
4-bit slice
Plane
Digital

The nibble cell frozen in Digital before it became KiCad footprints. Two of these chained on CIN-MAIN became 07_alu.

Place
Atlantic City

Atlantic City. Another day, same project, just a different desk and different sand. The build logs caught all the odd offices.

Sum
A ⊕ B ⊕ Cin
Cout
AB + Cin(A ⊕ B)

October 2025. A full adder written out by hand. I found that efficiency is a sentence—the carry-out just reuses the XOR we already paid for in the sum. That ethic stuck.

Target
Segment decode

Digits long before there was a ROM. I drew each nibble out as lamps by hand, just so a lookup table would actually have something to remember later.

Display
Numeric Segment

The seven-segment display churning numbers live as Tomato runs.

Path
Paper → EEPROM

Those same patterns, packed up for a chip. Once you have the glyphs, the display just turns into a memory problem.

Desk
Sand
Sky
Grey

Not every schematic was drawn under a lab light. Sometimes the keyboard sat on the beach, aimed at a grey horizon. The machine was portable way before it was ever a board.

FPGA
Artix-7 100T

The Nexys A7. Silicon that can pretend to be whatever netlist I throw at it. It sat there next to a PCB still routing—two different futures on the exact same desk.

Rev
v1.0
Flags
Z · C · N · V

The whole arithmetic unit laid out on one A2 sheet. Transceivers, SRAM, flag lamps, and all the connectors of the 32-bit machine I ended up walking away from.

Outline
240 mm square

Way too much machine for a first fab run. The traces do exist, but the board would have been the size of a poster.

Outline
270 × 270 mm
Density
436 T/bit

The massive predecessor over on alu.tmarhguy.com. I used discrete MOSFETs there, whereas 07_alu packs dual-LUT logic cleanly into 74xx copper.

Footprints
876
Layer
B.Cu

A 32-bit slice in KiCad with a ratsnest that was never going to become copper. 876 footprints and an ocean of cyan airwires. Walking away was a design decision. 07_alu is the board that actually fit a panel and a budget.

View
KiCad 3D

It was pretty enough to keep the render. Just not small enough to order five of.

All frames

tomato

A computer whose logic changes with each instruction.
Designed by Tyrone Marhguy.

Get in touch
Play TomatoEnvelopComputeTomato OSSoftwareArchitectureStatusGalleryJournalInstruction setPlaygroundBoardsVerificationSourceFAQAboutContact
© 2026 Tyrone MarhguyOpen hardware · Explore on GitHubBack to top