6502 from 74HC logic
I designed and built an 8-bit CPU from scratch with 74HC logic gates using the 6502 instruction set. It is capable of running the 6502 version of Microsoft BASIC (source tarball). I have also written a program to calculate 500 digits of pi — and it works! It uses no microprocessor — apart from EPROMs it uses only 74HC series parts (gates, registers, counters etc.). It uses a total of 96 ICs (that is CPU + front panel logic) and runs at up to about 4 MHz, doing about one million instructions per second (instructions taking 2-7 clock cycles). It was constructed on six 160x100 mm perfboards using pen wiring and took about 3 months to design and build (my studies taking up a lot of my time during term).
Here you can see it just hooked up to RAM:
Running a simple program at slow speed (1.3 MB GIF)
The architecture was intentionally kept simple and the CPU has a fairly long datapath, but the focus was on producing a working design, with performance a secondary consideration. It does use a fairly horizontal microcode (40 bits wide), allowing me to do a few things in parallel and speeding up many instructions. Addressing the microcode ROM took advantage of the enormous EPROMs available today, allowing me to use 16 address bits of which 8 bits are simply the opcode, 4 bits act as a microprogram counter and 4 processor status bits are also available (IRQ, alu carry, P register carry bit and another bit from the P register). The microcode syntax is fairly nice and makes the instruction set almost self-documenting, e.g.:
0x69 A = A + [PC++] + C <NVZC>;
0x65 A = A + zero + C <NVZC>;
This defines the ADC instruction for immediate and zero page operands. zero is a "function" defined by
func zero {
AL = [PC++];
return [0:AL];
}
This is compiled to binary form by a microcode compiler written in C. There are a few caveats which were mostly hacks in order to save precious microcode bits.
- schematics and board layouts as png files
- Repository with code, EAGLE files and board layouts
IC | function | total | AL | AH | ALU | ROM | FP1 | FP2 |
---|---|---|---|---|---|---|---|---|
74HC00 | 4×NAND | 2 | 2 | |||||
74HC02 | 4×NOR | 1 | 1 | |||||
74HC04 | 6×NOT | 2 | 1 | 1 | ||||
74HC08 | 4×AND | 3 | 1 | 1 | 1 | |||
74HC14 | 6×Schmitt trigger | 2 | 1 | 1 | ||||
74HC32 | 4×OR | 5 | 4 | 1 | ||||
74HC86 | 4×XOR | 2 | 2 | |||||
74HC138 | 3-to-8 Decoder | 4 | 1 | 1 | 2 | |||
74HC151 | 8-to-1 Mux | 6 | 6 | |||||
74HC154 | 4-to-16 Decoder | 2 | 2 | |||||
74HC163 | 4-bit Counter | 10 | 4 | 2 | 4 | |||
74HC181 | 4-bit ALU | 2 | 2 | |||||
74HC244 | 8× 3-state Buffer | 32 | 10 | 9 | 3 | 6 | 4 | |
74HC374 | 8-bit register | 3 | 1 | 1 | 1 | |||
74HC377 | 8-bit register | 9 | 2 | 2 | 1 | 2 | 2 | |
27C1001 | 1 Mbit EPROM | 5 | 5 | |||||
ULN2003 | Transistor array | 6 | 3 | 3 | ||||
total | 96 | 17 | 16 | 18 | 14 | 15 | 16 |