Skip to content
tomato
Fig. — Artix-7Opcode sweep · AND3 hit at 0x80

Verification

130 billion cases. Then a proof.

I checked 130 billion simulated cases against a reference model in a 2 hour 45 minute run. Formal verification separately checks the ALU’s mathematical behavior at 1, 8, and 32 bits. Here are the methods, commands, and limits of those checks.

SIMULATION

Try specific inputs

Compare the simulated ALU with an independent reference model, stopping on a mismatch.

FORMAL

Check the mathematical relation

Prove equivalence for the configured ALU model rather than sampling more random inputs.

SCOPE

An ALU result, with boundaries

These checks do not certify the full computer, board timing, or physical signal integrity.

At a glance

Formal

5/5 SymbiYosys jobs · 1b → 8b → 32b spot + flags + full comb equiv (~74 s)

Directed

476/476 Icarus vectors vs unified golden · all csel modes

Gauntlet

10B Verilator on 8b slice · 130B on 32-bit FPGA alu.v

UVM

91-row ALU control table · 1b exhaustive + 8b full + 32b regression (Questa)

Fast CI

make signoff · ~35 s from repo root make test

Golden model

One ripple-LUT reference · out = f + g + cin · shared across all layers

Verification mirrors the hierarchy on the schematic and on lot 07 copper: prove the programmable 1-bit LUT cell, compose it into 8-bit slices, then close the full 32-bit export. Digital .dig is the logic source; read-only netlists land in verification/rtl/. Re-export, re-run sign-off.

The property under test is always the same family: out = f(a,b,c) + g(a,b,c) + h(cin). Two independent 8:1 mux planes per bit feed a ripple carry-select adder. Formal proofs the LUT relations and combinatorial output; directed replay checks the exported netlist against Digital’s vectors; UVM scoreboards the sequential flag path; the gauntlet hammers the FPGA copy of the running machine.

Digital-export sign-off

The main harness in verification/ signs off the Digital-export ALU — not the full CPU, ISA ROM, or memory system. From the repo root, make test runs the fast path.

~35 s

make signoff

~3 min

make signoff_full

476

directed vectors

5/5

formal jobs

  1. 01 · Formal

    SymbiYosys · 1b → 8b → 32b

    1b: k-induction proves MUX_OUT = OPCODE[{C,B,A}], plus generate/propagate for every input. 8b: same relations per bit-slice. 32b spot: 12 fast regression properties. 32b equiv: Out === golden(...) for all inputs (~74 s). Flags: cover mode for FLAG_WE reachability.

    Inventory: 19 source asserts + 20 cover points (40 + 48 elaborated on 8b). See verification/formal/PROPERTY_INVENTORY.md.

  2. 02 · Directed

    476 vectors · Icarus · Digital replay

    Every vector extracted from Digital testbenches passes against the unified golden — no skips. Six flag-only vectors with exp=x are skipped at codegen. Exercises all csel modes and opcode pairs the schematic actually runs.

  3. 03 · UVM

    Questa scoreboard · 1b / 8b / 32b

    1b exhaustive: 128-row 0x96 table + 256× LUT sweep + G/P corners. 8b full: CLA boundaries, logic sweep, 5000 random. 32b regression: 476 directed + 91-op coverage + edge cases + flag test + 10k random. Requires Questa (vlog/vsim) — not wired in GitHub Actions yet.

  4. 04 · Lint

    Verilator · all three slices

    make lint on 1b, 8b, and 32b exports — zero errors before directed replay runs.

FPGA gauntlet · 10B + 130B

Separate tree: verification/gauntlet/ holds a copy of hardware/fpga/core/rtl/alu.v — the ALU that runs Tomato OS on the Nexys A7. Refresh with make sync; do not edit core from here.

SymbiYosys proves 1b, 8b, and 32b Out ≡ golden. Verilator drives 10,000,000,000 vectors on the 8-bit slice and 130,000,000,000 on the full 32-bit ALU. Directed warmup (LUT×minterm×cin on 8b; low-byte grid on 32b), then random fill. Measured on Apple Silicon: ~25 Mvec/s (8b), ~13–16 Mvec/s (32b) — about 7 minutes for 10B and 2 hours 45 minutes for the recorded 130B run.

Fig. — SimulationOpcode space sweep

Fig. — Artix-7AND3 · 0x80

Run it yourself

Dependencies for sign-off: python3, yosys, symbiyosys (sby), z3, iverilog, verilator. Gauntlet needs the FPGA OSS CAD Suite on PATH.

CommandWhat it doesTime
make testRepo root → verification/signoff~35 s
make signoff_full+ 32b combinatorial equivalence proof~3 min
make directed476 Icarus vectorsseconds
make formal_32b_equivFull 32b comb proof alone~74 s
make uvm_regression1b + 8b + 32b UVM (Questa)local
make gauntlet_smoke1M vectors each widthquick
make gauntlet_claimFormal + 10B + 130B → CLAIM.txthours
make fpga-testFull CPU Icarus sim (separate harness)varies
cd verification
make signoff              # fast CI (~35 s)
make signoff_full         # + 32b equiv (~3 min)

cd verification/gauntlet
make sync && make claim   # formal + 10B + 130B

Scope & honest limits

TopicStatus
ALU export onlyFull CPU, ISA ROM, memory, FPGA top — not this harness
op91_cp91 ALU control-table rows — not 512 CPU opcodes, not toggle/branch %
Sequential CSR_FLAGCover + UVM flag test — not SMT latch prove
UVM in CIQuesta not in GitHub Actions yet
Synthesis (make synth)Sky130 characterization — not functional tape-out sign-off