32-bit Computer. The oddest machine built in a dorm.
Before Tomato, there was the transistor board. Same story, same narrative—but this time, it had to be smarter.
By Tyrone Marhguy · Computer Engineering ’28
Before Tomato, there was an 8-bit ALU built from roughly 3,488 discrete CMOS transistors across a massive 270×270 mm board. It was a beast in its own right: capable of 19 operations, sporting 5 flags, and power hungry.
But for a solo dorm-room project, the manufacturing costs ballooned exponentially, so I needed a pivot. Same story, same narrative—but this time, it had to be smarter. Welcome to Tomato!
The paper: tomato.tmarhguy.com · the site: web/README · the vault: docs/log/.
Lot 07 in the round & on the iron · Dual-LUT slice · playground
Tomato grew as a revolution: a 65k operational space (~3,500× operation increase than the earlier 8bit board for less area) from a dual-LUT3 fused into an adder, built for linear scale. The ALU is two independent 3-input LUTs plus a ripple adder per 4-bit nibble: out = f(a,b,c) + g(a,b,c) + cin. A 512-row opcode ROM fans out into modular control boards that sit next to the hardware they actually drive. The design journal is where the arguments live; this README is the map.
The dual-LUT slice is on the iron — muxes and adders down on one 07_alu board.
See log: First Phase of Assembly
| Metric | Transistor Board (Previous) | Tomato ALU (Current) | Optimization Achieved |
|---|---|---|---|
| Architecture | 8-bit | 32-bit | 4× datapath width |
| Logic Base | ~3,488 discrete CMOS transistors | Dual-LUT3 + Ripple Adder | Massive density increase |
| Ops Space | 19 operations | ~65k combinations | ~3,500× expansion |
| Footprint | Single massive 270×270 mm PCB | Modular 4-bit slice boards | Better routing, linear cost |
| Control | Fixed decode logic | 512-row microcode ROM | Programmable ISA overlay |
Tomato is intentionally a build log machine. Every odd choice is documented somewhere in docs/log/ — what was tried, what broke routing, what was too slow on the bench, what got deleted to recover PCB area. If you love computers because you like how they are built, not just what they run, that journal is the real entry point. Start with Welcome to Tomato 32.
The ALU is the center. Most CPUs hide a small ALU behind a conventional encoding. Tomato flipped it: the bit-slice is a programmable logic plane — half a million theoretical (lutA, lutB, csel) programs per slice — with an adder wired through it. The opcode ROM names a practical subset. Matching every LUT pair to its own instruction was never the goal; dark silicon stays in the catalogs until a program actually needs it.
Building beats spreadsheets. Instruction width, bank counts, and profile matrices are fun to expand. Copper, EEPROMs, and weeks at the wire wrap are not. When a wider word width doubled the explanation burden without doubling silicon on the bench, the answer was to fall back to 32b and ship what already routes.
Decode travels with the datapath. One central microcode blob is elegant in simulation and miserable on a breadboard — shift controls leaving the ALU board, flag writes leaving memory control, PC fields split across ROM bytes. Tomato split decode into small boards with local EEPROMs so ribbons stay short and each slice can be brought up alone.
Clever, but only at the right scale. Naïve shift → add multiply is easy and takes forever — “slower than I am when half-asleep.” A Wallace tree is fast and eats the board. The answer was a priority-encoder loop that jumps over zero bits. Same story for the display: K-map gates were correct and physically absurd; one shared ROM plus latches made sharing invisible (segment display log).
ISA as a wire. Tomato is a parametric datapath: the overlay word, immediate box, and dual-LUT absorb a foreign encoding as a map onto muxes — not an emulator. A casual family count sits around ~37 (profiles.csv has more rows because variants are listed separately). The integer is not a ceiling; it moves as the datapath does.
- Why Tomato
- Architecture at a glance
- Source of truth
- Repository map
- Key hardware modules
- ISA and opcodes
- Run in Digital
- Project status
- Documentation index
- Conventions
- License
- Author
The paper is tomato.tmarhguy.com. Site notes: web/README.
Fetch, IR, ALU datapath, and register operands are 32-bit. The instruction layout is tight: 9-bit opcode, four 5-bit register indices, and a 3-bit bank select fill the word — with low bits often double-booked as immediate or branch/jump mode overlay depending on the mnemonic.
Typical field packing (ALU register ops):
| Field | Bits | Slice | Role |
|---|---|---|---|
| Opcode | 9 | [31:23] |
Indexes microcode ROM (512 rows) |
rd |
5 | [22:18] |
Destination (5-bit index within bank) |
rA |
5 | [17:13] |
ALU operand A |
rB |
5 | [12:8] |
ALU operand B |
rC |
5 | [7:3] |
ALU operand C |
BANK |
3 | [2:0] |
Bank select (8 banks → 32 GPR × 8 = 256 regs) |
Each operand is 5 + 3b bank in address terms: a 5-bit GPR index within the bank selected by BANK[2:0].
[31:23] opcode
[22:18] rd
[17:13] rA
[12: 8] rB
[ 7: 3] rC
[ 2: 0] BANK (+ mode bits for branches/jumps)
Overlay encodings (same slices reinterpreted by microcode):
| Mnemonic class | Overlay | Notes |
|---|---|---|
| Branches | [2:0] = COND |
Taken when selected flag is set |
| Jumps / calls | [0] abs vs PC-rel |
0 = absolute target in low bits; 1 = PC + offset |
ADDI / imm12 |
[12:8] imm-high |
Immediate high nibble; low pieces in other fields |
| Load / store offset | [12:8] imm-high |
Address =rA + sign-extended immediate |
Native ALU syntax (conceptual):
opcode rd, rA, rB, rC ; rd = f(a,b,c) + g(a,b,c) + cinSee opcode-map.csv for mnemonic layout and Load Store Pipeline Analysis for the 48-bit microcode control fields.
32 GPR × 8 banks = 256 addressable registers. Not the full theoretical address space the LUT catalog could name — enough for real programs and modular board bring-up without widening the datapath.
Program Counter ──► Memory ──► Instruction Register (32b)
│
┌───────────────────────────┼───────────────────────────┐
│ │ │
▼ ▼ ▼
Register File 3R1W alu-control mem-io / mem-bus
│ │ │
▼ ▼ ▼
Dual-LUT ALU 32b ◄──────── (drives) Memory ◄── pc-control ──► PC
│
▼
Writeback Mux ─────────────────► Register File
IR ──► shift-mul-control ──► ALU
Control is split into small boards (each with a local EEPROM) that decode the same opcode from the IR. See Microcode Control Modularization. For Mermaid diagrams in Cursor, install extension bierner.markdown-mermaid (listed in .vscode/extensions.json).
alu_out = adder( f(a, b, c), g(a, b, c), carry_in )
Per bit-slice there are 524,288 theoretical (lutA, lutB, csel) combinations; the 512-row opcode ROM exposes what programs need today. The LUT3 feeds the adder directly — no mode mux at the end of the slice — logic rides the arithmetic path instead of racing it. Carry select uses 74251 muxes where 74151 cost routing and drive strength (74251 note). Authority: docs/isa/tomato.v1.csv.
| Layer | Authority | Consumers |
|---|---|---|
| Logic / timing | hardware/digital/modules/*.dig | KiCad bring-up, Verilog export |
| Opcode mnemonics | docs/opcode-map.csv | Assembly reference, ROM programming |
| Microcode fields | docs/isa/tomato.v1.csv | Single ISA / ROM authority |
| LUT programs | docs/isa/lut.csv | ALU primitive catalog |
| Control ROM images | microcode/*.hex | Digital control boards |
| Physical PCB | hardware/kicad/boards/ | Fab / assembly |
| ALU sign-off | verification/ | Digital export →rtl/*.v → formal + directed + UVM |
Policy: Digital .dig schematics are editable source. Exported Verilog in verification/rtl/ is read-only — copy from Digital, then run sign-off.
tomato/
├── docs/
│ ├── isa/ # opcodes, alu8 catalog, profiles
│ ├── log/ # Design journal (Obsidian vault)
│ └── alu/ # LaTeX ALU reference docs
├── hardware/
│ ├── digital/modules/ # Digital schematics (.dig) — logic source of truth
│ ├── kicad/boards/ # Numbered PCB designs (01_alu … 08_display)
│ ├── fpga/ # Vivado projects (FSM, hex display)
│ └── verilog/ # Export policy (read-only netlists)
├── microcode/ # Per-board control ROM hex images
├── verification/ # ALU harness: formal, directed, UVM
├── firmware/ # Stub — not started
├── software/ # Stub — not started
├── web/ # Broadsheet — tomato.tmarhguy.com
└── media/ # Screenshots, PCB photos, schematic exports
| Module | Role |
|---|---|
| main.dig | Top-level CPU integration |
| alu-32b-final.dig | 32-bit ALU |
| alu-control.dig, ir-reg-control.dig, mem-bus-control.dig, mem-io-control.dig, pc-control.dig, shift-mul-control.dig | Modular decode ROM boards |
| register.dig, program-counter.dig, mul-div.dig | Datapath slices |
| alu-display-control.dig | 32-digit hex display for bring-up |
ALU verification ladder: alu-1b-final → 2x alu-4b → 4x alu-8b → alu-32b-final.
| Board | Path | Role | Status |
|---|---|---|---|
| 01 | 01_alu/ | Early ALU experiments | Historical |
| 02 | 02_shift_encoder/ | Shift encoder + mul-div control | In design |
| 03 | 03_memory/ | Memory, byte-lane decoder, VGA | In design |
| 04 | 04_register/ | Register file, IR | In design |
| 05 | 05_program_counter/ | PC, stack pointer | In design |
| 06 | 06_data_bus/ | Data bus, wb_mux, bus arbitration | In design |
| 07 | 07_alu/ | Dual-LUT ALU PCB —board doc + figures | Populating |
| 08 | 08_alu_fsm/, 08_display/ | FSM bring-up, display | In design |
Lot 07 · left: board render · right: routed top copper · two 4-bit cells, flag logic, opcode/operand LED bring-up (full ALU board doc)
512-row opcode ROM — enough for native ALU ops, load/store, branches, shifts, and mul/div without empty decode fanout. See ISA as a Wire.
| Resource | Path | Role |
|---|---|---|
| Mnemonic cheat sheet | docs/opcode-map.csv | 32-bit encoding, syntax, groups |
| Microcode catalog | docs/isa/tomato.v1.csv | Source of truth — burn opcodes + ROM map |
| ALU programs | docs/isa/lut.csv | LUT primitive catalog |
| ISA maps | docs/isa/profiles.csv | Parametric maps onto native opcodes.~37 families; CSV rows are the sweep database |
An ISA is a mapping from an external encoding onto the overlay word, immediate box, and dual-LUT — not a separate hardware ISA, and not an interpreter.
- Install Digital by Heinrich Hneemann — download
Digital.zipfrom Releases, unpack, runDigital.jar(Java required). - In Digital: File → Open →
hardware/digital/modules/main.dig. - Press Run (or single-step with the clock controls).
Other entry points: alu-32b-final.dig (ALU only), alu-display-control.dig (display bring-up). ALU sign-off: verification/README.md.
As of July 2026
| Area | Status | Notes |
|---|---|---|
| Architecture | 32-bit | SeeFalling back to 32b |
ALU PCB (07_alu) |
Populating | First phase of assembly |
| Opcode ROM | 512 rows (planned) | Down from 1024-row budget |
| Register file | 32 GPR × 8 banks | 256 addressable registers |
main.dig + control boards |
In progress | Modular decode on bench |
| ALU verification | Passing on 32b export | verification/ |
| ALU ASIC characterization | Sky130 HD mapped | 6531 µm², 512 cells, ~210 MHz est. |
| Peripheral PCBs | In design | Register, memory, PC, data bus |
| Firmware / software | Not started | README stubs only |
Bring-up direction: Build peripherals and modular control boards — not a throwaway FSM that becomes Tomato anyway. The ALU PCB can be exercised through alu-display-control and simulation vectors while fab runs (lingering catch).
| Log | Topic |
|---|---|
| Web Optimization | What actually ships in the paper’s 3D |
| ISA as a Wire | Parametric datapath — ISA is a first-class input |
| Falling back to 32b | Revert to 32-bit — current direction |
| The lingering catch | FSM vs full control unit bring-up |
| Microcode Control Modularization | Split decode boards |
| Elimination of Mode Multiplexers | LUT3 pass-through into adder |
| Log | Topic |
|---|---|
| Multiplication and Division | Priority-encoder mul/div |
| Load Store Pipeline Analysis | Microcode bit fields, cycle timing |
| ALU segment display design | 32-digit multiplexed display |
| ALU — Redesign with 74251 | Carry mux routing tradeoff |
| README | Content |
|---|---|
| verification/README.md | ALU sign-off harness |
| hardware/kicad/README.md | KiCad overview |
| 07_alu board doc | Dual-LUT ALU PCB — schematics, layout, pinout |
| hardware/digital/README.md | Digital simulation |
| microcode/README.md | Control ROM packing |
docs/log/ — build log from discrete gates through the parametric datapath. Origin: Welcome to Tomato 32. The paper: web/README.
| Change type | Workflow |
|---|---|
| Architecture / tradeoff | New entry indocs/log/ — the default way decisions get made |
| Opcode / mnemonic | Updateopcode-map.csv and microcode hex |
| Microcode fields | Editdocs/isa/tomato.v1.csv, then python3 tools/gen_microcode_v1.py --pack-rom |
| Logic / timing | Edit Digital.dig → export Verilog → make signoff |
| Physical board | KiCad inhardware/kicad/boards/ |
Tomato is licensed under Solderpad Hardware License 2.1 (SHL-2.1,
Apache-2.0 WITH SHL-2.1) — open hardware + RTL + scripts + docs. You may
study, build, fork, and commercialize with attribution; do not strip
copyright or present the dual-LUT architecture as unrelated work.
Architecture credit: Tomato dual-LUT bit-slice datapath — Tyrone Marhguy / Tomato project.
Tyrone Marhguy — Computer Engineering '28, University of Pennsylvania
Tomato is a solo hardware architecture project: discrete-logic CPU design, KiCad PCBs, Digital simulation, and a public build log. Questions, collabs, or “why did you route it that way?” — reach out.



