This is a processor built out of individual transistors — 1,896 of them for one core, fewer than the 2,300 in an Intel 4004.
It knows exactly one instruction. Not a small instruction set: one instruction. It subtracts one number from another and jumps if the result came out zero or negative. That is the entire machine. Addition, multiplication, strings, pointers and loops are all built on top of it in software, which is possible because one instruction is enough to compute anything — a fact that is easier to prove than to believe.
The goal is not one of these but eight, wired in a ring and passing messages to each other. That part appears to be unoccupied ground: every discrete-transistor computer I can find is a single processor, and nearly all of them are NMOS rather than CMOS.
Nothing is soldered yet, and nothing will be for a long time. This is a CMOS homebrew computer being designed in the open, and these logs catch up on how it got here.
Why CMOS, when almost nobody else does
Nearly every discrete-transistor computer ever built is NMOS: one transistor pulling the output down, one resistor pulling it up. Half the parts of the alternative and a far simpler board. MOnSter 6502, discrete6502 and Spikeputor all take that route.
It has one problem, and it is not subtle. A gate holding a low output has its pull-down transistor on and its pull-up resistor still connected to the supply, so there is a complete path from rail to rail. With a 10 kΩ pull-up that is 0.5 mA, burned continuously, per gate.
This machine is on the order of a thousand gates, and at any moment about half of them sit low:
| Current per low gate | 0.5 mA |
| Gates, order of magnitude | ~1,000 |
| Standing current | ~250 mA |
| Standing power at 5 V | ~1.25 W |
Drawn while computing, while waiting, and while doing nothing at all. It does not depend on the clock, so slowing the machine down does not help — the loss is not switching, it is standing. NMOS builds compensate by running slowly anyway; Spikeputor is around 3 kHz, MOnSter 6502 around 50 kHz.
CMOS replaces the resistor with a P-channel transistor that is switched off precisely when the pull-down is switched on. There is never a path from rail to rail, so a gate that is holding a value draws essentially nothing. Current flows only while switching, which makes power proportional to clock rate rather than to gate count. Speed becomes a dial instead of a fixed bill.
The price is exact: two transistors where NMOS needs one. Every gate, across the whole machine.
That factor of two is the largest single cost decision in this project, and it is the reason everything else about the design is strange. One instruction instead of an instruction set, one bit at a time instead of sixteen, and a serial memory instead of a bus — all three exist to win back the transistors that CMOS costs. Take the CMOS decision away and there is no reason to build the machine this way at all.
Three ideas, and each makes the other two cheaper
One instruction. The machine only knows subleq — subtract, and branch if the result is less than or equal to zero. There is no opcode field, so there is nothing to decode, so the instruction decoder does not exist. What would be an instruction set lives in the assembler, as macros.
A few bits at a time. A serial datapath shrinks the ALU from a block to a handful of gates. You pay in clock cycles, which are cheap in CMOS while transistors are not.
One serial wire. Memory, display and input all speak SPI. There is no address bus, no data bus and no bus drivers — roughly six hundred transistors that would compute nothing.
Remove any one and the other two get worse. Serial arithmetic is only attractive because the memory interface is already serial. The result is that the machine is conceptually a single object: a large shift ring with a one-bit ALU in it.
Why a ring, and not just more memory
Measuring where the clock cycles actually go turned up something I did not expect. Over a real program,...
Read more »
Dennis Decoene