Context

I am pushing to design the remaining boards.

I had assumed that the most complicated one to design was the main board — the ALU — which is done and routed (07_alu). The next thing is everything else: register file, memory, PC/stack, data bus, shift/mul-div. The ALU was the deep combinational problem; what is left is mostly 32-bit plumbing — mux trees, decode fanout, and connectors that do not fight the floor plan.

That is the plan from last week: while the ALU fab runs, design slices that ship in the final machine instead of a throwaway FSM.


Starting with multiplexers

The first slice I am tackling is the multiplexers on the data path — writeback mux, bus arbitration, and the glue that ties ALU, memory, and register ports onto one 32-bit highway.

A naïve 32-bit mux bank (one huge 74257 tree per source, every bit routed independently) costs hundreds of millimetres of trace and real estate. The approach for Tomato:

  1. Bus drivers (74AC125 / tri-state family) on each contributor — ALU result, memory read, PC+1, shift/mul, etc.
  2. Matched decode enables from the modular control boards — only one driver active per phase, same idea as the ALU display scan chain (one hot index, shared bus).
  3. KiCad target: 06_data_bus — wb_mux.kicad_sch, bus_arbitration.kicad_sch, tied to Digital wb_mux.dig and bus-arbitration.dig.

Digital already has the behavior; the board work is making the 32-bit fanout physically tolerable.


Contention and timing

Contention is a real issue on a shared tri-state bus — two drivers fighting the same line is not theoretical.

But I am not running at GHz. At breadboard / bring-up clock rates, the window where two enables overlap badly is small. From earlier calculations, the chance of meaningful contention during switching is ~1%, or more accurately under 5% of transitions — acceptable for lab bring-up if decode is one-hot and enables are never deliberately stacked.

Heat from brief overlap at these speeds should be ok. Production hygiene still matters: one active driver per bus, decode timed to the sequencer phases documented in Load Store Pipeline Analysis.


Board queue (after ALU)

BoardKiCadDigital anchorNotes
06 data bus06_data_bus/wb_mux, bus-arbitrationCurrent focus — mux + drivers
04 register04_register/register.dig, ir.dig3R1W, 32 GPR × 8 banks
05 PC / SP05_program_counter/program-counter.dig, sp.digFetch address source
03 memory03_memory/memory.dig, byte-lane-decoderLoad/store path
02 shift / mul-div02_shift_encoder/
08 display / FSM08_display/, 08_alu_fsmalu-display-controlBench debug

Control ROM boards (microcode modularization) ride with their datapath slices — not a separate queue item.


Open questions

  • One consolidated 06_data_bus PCB vs split wb_mux and arbitration across connectors?
  • Which 74xx driver family on the 32-bit backplane — AC125 vs HC125 vs registered enables for cleaner turn-off?
  • Order after mux: register file (loopback tests) vs memory (load/store integration)?
  • Re-run contention estimate at target max clock once sequencer timing is nailed down.

Lean recommendation (today)

Finish the mux + driver plan on 06_data_bus in KiCad first — it unblocks every other board that needs to read or write the shared 32-bit word. Keep enables decode-driven and one-hot; do not sprawl a discrete 32-bit mux forest across the whole CPU footprint.

The ALU was the hard part. The rest is wiring Tomato's existing simulation into boards that fit the bench.