Skip to the content
PCBKitNew board
4 layers259.1 × 198.1 mmCpld cpu, the printed circuit board in 3D

A simple CPU implemented by discrete CPLD components.

Size
259.1 × 198.1 mm
Copper layers
4
Thickness
1.6 mm
Parts
441
Nets
505
Pads
1,576
Tracks, vias
4,868, 933
Pours
6
Routed
Yes
KiCad
KiCad 5 (file 20171130)
Created
12 Mar 2017
Updated
12 Jul 2023

Overview

Cpld cpu is an open-source printed circuit board by jimmo, from the jimmo/cpld-cpu repository on GitHub, published under the MIT licence. It is a 4-layer board of 259.1 × 198.1 mm with 441 parts on 505 nets, routed with 4,868 tracks and 933 vias.

Its parts include 209 resistors, 131 diodes, 53 capacitors, 16 connectors and 14 ICs. It belongs with the fPGA and programmable logic boards and the FPGA and CPLD boards of this library.

README

README.md

CPLD CPU

This is a project to create a demonstration CPU that is simple enough to be able to watch its execution but also able to do something almost useful.

It was inspired by the following five projects:

In particular the CPU design (ISA and architecture) is inspired by Fourbit, Tiny CPU, and especially MPU, while the exploded design and "LEDs everywhere" is inspired by the Megaprocessor and monster6502. While nowhere near as capable as monster6502 or the Megaprocessor, it is definitely much more budget-friendly! And it can still compute prime numbers (video) and drive APA102 LED strips.

Also, while not a direct inspiration to this project, it's absolutely worth linking to Breadboard 8-bit computer, by Ben Eater which is a wonderful series about a similar project.

History

This idea started when I was teaching an introduction to "how CPUs work", and wanted something tangible to show my students. The goal is to show how simple logic circuits (i.e. starting with AND and OR gates, flip flops, and a clock) can work together to do computation. No magic required.

Initially I planned to exactly replicate the Fourbit (possibly upgraded to 8-bit), but had trouble sourcing the 74181 ALU. I found a XC9572XL CPLD development board in my board collection and considered replicating the 74181 on that. CPLDs are really useful for a project like this because they do not require external flash for configuration. You can use them almost as a complete drop-in replacement. However, at this point if you're not constraining yourself to using exactly 74xx series parts, then there are several simplifications you can make in the Fourbit design.

So I set about designing a CPU where each functional component is its own CPLD. In some ways this is similar to designing a soft-CPU for an FPGA, but with the additional constraint that signals between components actually need to go via physical pins. For an 8-bit CPU, this uses up a lot of pins very quickly.

For a fun side-quest, I wrote a logic simulator that allows a logic circuit to be defined in Python, and simulated, much the same way that Verilator can simulate an HDL file. This allowed me to test and iterate on some different designs, including an exact clone of the MCPU design. Additionally the simulator allows me to stay closer to my original goal of being able to describe every logic gate, although some shortcuts were taken.

The final design expands on the MCPU design, including 13-bit addressing, an index register, two-byte instruction encoding, a primitive MMU allowing addressing up to 1MiB of physical RAM, and memory-mapped IO. The memory is von Neumann, allowing for RAM and ROM to share the same bus. The simulator allowed some programs to be written and tested, including an assembler supporting some macro commands.

Once that was working, I translated each Python component into VHDL, and tested it on the CPLD breakout board. For example, here's the decoder (Python and VHDL). The most difficult part of this process, and possibly the whole project, was uploading the gateware to the CPLD. In order to keep the design simple, the clock is generated by a ring oscillator in the clock CPLD, which is a terrible idea in general but works well here.

Finally, I designed a schematic and PCB layout, which mostly involved laying out 131 LEDs (and their current limiting resistors). Rather than putting both RAM and ROM into the design, it just has a single RAM chip. This means that it has no persistent program storage, and the program needs to be loaded by an external programmer (implemented using some spare pins on the memory controller).

It's a four-layer PCB and can be assembled by hand with an iron or hot air. The CPLDs are TQFP and the LEDs and resistors are all 0805.

Other than occasionally being used for teaching, I mostly keep it mounted on the wall with the clock speed set to ~5Hz, forever computing prime numbers. It's quite mesmerizing to watch!

Features

  • All internal state visible via 131 LEDs. This includes:
    • A, X, PC, Instr, and Addr registers (including carry & zero flags).
    • Data bus (and output/input state of each connected component)
    • Memory address
    • Clock
    • Decoder state
    • GPIO
  • 8-bit accumulator
  • 8-bit index register
  • 16-bit program counter
  • 8 instructions (nor a, add a, sta, jcc, nor x, add x, stx, jnz)
  • Variable-speed clock (Hz to >100kHz), including single-instruction and single-cycle step.
  • Expansion header (allowing for memory-mapped peripherals)
  • 8-bit memory-mapped GPIO port (input and output, with jumpered LEDs on each)
  • Serial programming header

Instruction set

The instruction set is heavily inspired by MCPU. See their project description and blog post for more information. The main extension is the addition of the index register (X) as well as a jump-non-zero.

Hardware instructions

nor [mem]

A = A nor [mem + X]

add

A = A + [mem + X]

sta

[mem + X] = A

jcc

Jump if carry not set.

norx

X = X nor [X]

addx

X = X + [mem]

stx

[mem] = X

jnz

Jump if zero flag not set.

Pseudo instructions

These are supported by the assembler and generate a sequence of real instructions.

clr

A = 0

lda

A = [mem]

not

A = ~A

sub

A = A - [mem + X]

clrx

X = 0

ldx

X = [mem]

notx

X = ~X

subx

X = X - [mem]

jmp

Unconditional jump

jcs

Jump if carry flag set

jz

Jump if zero flag set

shl

A = A << 1

inc

A = A + 1

dec

A = A - 1

and

A = A & [mem + X]

or

A = A | [mem + X]

nand

A = ~(A & [mem + X])

xnor

A = ~(A ^ [mem + X])

xor

A = A ^ [mem + X]

ldpg

Sets the current memory page

hlt

Infinite loop

out

(Simulator only) prints A to stdout

Programming

There's a MicroPython script that can load a assembled binary via the serial programming interface (header is next to the memory controller).

TODO

  • Much more documentation and assembly guide (I'd love to do a video series one day)
  • Better demos
  • A higher-level compiler, making better use of the MMU
  • Design a peripheral to use the expansion connector
  • Use an external clock (and find out how fast this can go).

Ideas for future revisions

  • Separate net for the LED ground (allowing it to be disconnected).
  • Fix the missing PC_LOW LED (bodged in on the current board)
  • More LEDs (e.g. ALU current operation)

Parts

441
QtyValueFootprintReferences
131LED_SmallLEDs:LED_0805_HandSolderingD1, D10, D11, D100, D101, D102, D103, D104, D105, D106, D107, D108, D109, D110, D111, D112 +115
1102kResistors_SMD:R_0805_HandSolderingR10, R11, R12, R100, R101, R102, R103, R104, R105, R106, R115, R116, R117, R118, R119, R120 +94
66470Resistors_SMD:R_0805_HandSolderingR107, R108, R109, R110, R111, R112, R113, R114, R123, R124, R125, R126, R127, R128, R129, R130 +50
53100nCapacitors_SMD:C_0805_HandSolderingC1, C2, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20, C21, C22, C23 +37
211.2kResistors_SMD:R_0805_HandSolderingR1, R2, R3, R160, R161, R162, R163, R164, R165, R166, R167, R168, R169, R170, R171, R172 +5
1210kResistors_SMD:R_0805_HandSolderingR189, R190, R191, R196, R197, R202, R203, R204, R205, R206, R207, R208
4MountingHoleMounting_Holes:MountingHole_4.3mm_M4H1, H2, H3, H4
1ALUPin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ7
1ALUHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU7
1ARHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU6
1ARPin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ6
1AXMPin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ4
1AccHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU1
1AccPin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ1
1BTN0Buttons_Switches_SMD:SW_SPST_B3S-1000SW1
1BTN1Buttons_Switches_SMD:SW_SPST_B3S-1000SW2
1BTN2Buttons_Switches_SMD:SW_SPST_B3S-1000SW3
1CY62138FV30LLHousings_SSOP:TSOP-II-32_21.0x10.2mm_Pitch1.27mmU12
1ClockPin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ16
1ClockHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU14
1Conn_01x07Pin_Headers:Pin_Header_Straight_1x07_Pitch2.54mmJ15
1Conn_02x14_Odd_EvenPin_Headers:Pin_Header_Straight_2x14_Pitch2.54mmJ12
1Conn_02x17_Odd_EvenPin_Headers:Pin_Header_Straight_2x17_Pitch2.54mmJ14
1DecPin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ5
1DecoderHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU5
1GPIOPin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ13
1GPIO_RNGHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU13
1HaltButtons_Switches_SMD:SW_SPST_B3S-1000SW4
1IRPin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ3
1IRHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU3
1IndexPin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ8
1KicadLogoSymbols:Symbol_KiCAD-Logo_CopperAndSilkScreenTopS1
1MultiplexerHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU4
1OSHWLogoCPLD_CPU_Symbols:OSHW-Logo2_14.6x12mm_Copper_TopS2
1PC_HHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU11
1PC_HPin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ11
1PC_LHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU9
1PC_LPin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ9
1PagePin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ10
1RAM_IndexHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU8
1RAM_PageHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU10
1ResetButtons_Switches_SMD:SW_SPST_B3S-1000SW5
1S0Buttons_Switches_SMD:SW_SPST_B3S-1000SW7
1S1Buttons_Switches_SMD:SW_SPST_B3S-1000SW11
1S2Buttons_Switches_SMD:SW_SPST_B3S-1000SW8
1S3Buttons_Switches_SMD:SW_SPST_B3S-1000SW12
1S4Buttons_Switches_SMD:SW_SPST_B3S-1000SW9
1Step 1Buttons_Switches_SMD:SW_SPST_B3S-1000SW6
1Step 8Buttons_Switches_SMD:SW_SPST_B3S-1000SW10
1XHousings_QFP:TQFP-44_10x10mm_Pitch0.8mmU2
1XPin_Headers:Pin_Header_Straight_1x05_Pitch2.54mmJ2

Questions

How big is the Cpld cpu PCB?

It measures 259.1 × 198.1 mm and has 4 copper layers, 1.6 mm thick.

What parts does the Cpld cpu use?

441 parts. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Cpld cpu KiCad files?

From the jimmo/cpld-cpu repository on GitHub, at the commit this page was made from: the board is hardware/cpld-cpu.kicad_pcb. PCBKit opens the board in the browser, with nothing to install.

Can I use the Cpld cpu design in my own project?

Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).

Similar boards

  • 4 layers72.2 × 70 mmPanel 3 3, the printed circuit board in 3D

    Panel 3 3

    floxcap/fly2040

    Basic RP2040 board

    441 parts19MIT
  • 4 layers154.1 × 161.7 mmFrankenso, the printed circuit board in 3D

    Frankenso

    glocklueng/rusefi

    https://svn.code.sf.net/p/rusefi/code/trunk/

    441 parts
  • 4 layers300 × 270 mmTbox, the printed circuit board in 3D

    Tbox

    charlieh0tel/ee_stuff

    440 partsBSD-3-Clause
  • 4 layers275 × 240 mmSupervisor, the printed circuit board in 3D

    Supervisor

    BennetLeff/temper

    a breville control freak ++

    440 parts1
  • 4 layers125 × 150 mmAA2380V1, the printed circuit board in 3D

    AA2380V1

    OneAudio/OSVA

    Open source versatible analyzer (24bits 1.536MSPS 2 Channels)

    440 parts11GPL-3.0
  • 4 layers100 × 123 mmDuet3 5+ Wifi, the printed circuit board in 3D

    Duet3 5+ Wifi

    Duet3D/Duet3-Mini5plus

    This repository also contains information in the Mini 2+ : a two driver expansion board for the Duet 3 mini 5+

    440 parts12
  • 4 layers239.5 × 239.5 mmBroadcast clock, the printed circuit board in 3D

    Broadcast clock

    espena/broadcast-clock

    Digital precision studio/broadcast masterclock with WiFi configuration, acts as local NTP server with accurate GPS time sync.

    440 parts28GPL-3.0
  • 4 layers163 × 174.4 mmGd rev3b, the printed circuit board in 3D

    Gd rev3b

    baldengineer/Mega-IIe

    Using the Mega II from a IIgs to make a Apple IIe compatible computer: The Mega IIe!

    440 parts33MIT