Worlds first 32 bit Homebrew CPU

Creating the worlds first 32 bit homebrew CPU using 74' series logic.

Similar projects worth following
There is a major CPU that is missing from the world. A 32 bit homebrew CPU that implements a full and modern instruction set. The solution is to use 74' series logic chips and the RISC-V open source instruction set architecture. With a GNU toolchain already created for RISC-V it means we already have an assembler and compiler ready and waiting for our machine. So lets get rocking and create the ultimate in homebrew projects.

Browsing the web, I found a fascinating niche activity. People have built homebrew CPUs/computers using just basic logic chips. And they actually worked, they did real computation. These ranged from trivial 4-bit machines, that barely did anything, up to impressive 8 bit machines that run a customized version of Mimix. One crazy guy in England has used several thousand transistors to create a machine that takes up half a room. They look cool, sound great fun to build and I want in on the action.

But what to do? Well there seems no point in just copying what others have done. The fun is in designing your own unique project and the journey taking it from idea to working machine. Well it seems worthwhile to tread new ground, do something not done before. As far as I can tell, there is no homebrew 32 bit machine (I don't count an FPGA implementation). And certainly, none seem to implement a fully specified existing instruction set architecture (ISA). This is something that must change.

A bit of research later and I have found the perfect ISA. There is relatively new open source 32-bit RISC architecture called RISC-V that has been designed by researchers at UC Berkeley. Being a RISC design, it is relatively small in the number and complexity of the instructions that need implementing. This is important as any 32 bit design is already going to be a big project, so lets not make it impossible by going for something like the CISC of the 80386!

  • ALU - Add and Subtract

    Phil Wright08/08/2017 at 00:01 0 comments

    The ALU for our CPU needs to perform several types of operation. The first of these is the ability to add or subtract two 32-bit numbers. To implement this I have built a stack of four boards that combine together to give the output.

    Adding two numbers is simple, we just use 4 x 74283 and chain the carry output of one to the carry input of the next in sequence. This has been implemented as the 'AddSub Middle' board below.

    Implementing the subtraction operation requires a bit of extra work as we need to apply 2's compliment to the second of the two inputs. 2's compliment is the method used to invert the sign of a value. Converting a positive number like 5 into the negative version -5.

    This approach avoids the need to implement a separate subtraction circuit and instead allows reuse of the existing addition circuit. For example, 10 - 5 can be implemented as 10 + (-5).

    2's compliment is very simple, you just invert all the bits and then add 1. The purpose of the top two boards is to invert all 32-bits of the second input when the control line indicates a subtraction is needed. Adding the extra 1 can be done in the middle layer by providing a initial carry in value to the first adder.

    Finally, the bottom board is used to buffer the output, as only sometimes will the ALU want to perform an add/sub operation. All outputs from the different parts of the ALU are connected to the same output bus and so only the appropriate ALU section should put its output on the bus.

  • Comparator Complete

    Phil Wright07/19/2017 at 00:43 0 comments

    I have been delayed recently by a bad batch of 16 pin long female headers. They arrived from China but were sub-standard, inserting a connector at the top caused some of the bottom pins to be pushed out. They simply didn't work. But a new batch has arrived that works and we are back in business again.

    The 32bit comparator is split into a top and bottom board because there is not enough space to fit it all on a single 100mm x 80mm board. The top board begins by using 4 x 74682 chips to compare each of the 4 bytes from the first and second values.

    Only if all four compares are equal is the 32bit compare also an equal. Discovering if the first value is less than the second is more complicated because there are several combinations that result in the less than result: -

    • First byte is less than and the top three higher bytes are equal
    • Second byte is less than and the top two bytes are equal
    • Third byte is less than and the top byte is equal\
    • Fourth byte is less than

    Adding the logic for calculating the equal and less than outputs of the top board results in the following logic diagram: -

    The bottom board takes the basic output of the top board and applies some extra logic. One of the control inputs is called NEG and is used to negate the output. For example, the branch if equal (BEQ) and branch if not equal (BNE) instructions only differ by setting this NEG control line. Another control line is called UNS and determines if the comparison should be signed or unsigned (BLTU, BGEU instructions). Finally a RES line is used to decide if a result should ever be output. This allows the output to be forced to zero. This is needed because the output of the board will be used as the control line input for a MUX elsewhere. We want to force the value to zero unless we are processing a branch instruction.

    Here is the logic for the bottom board: -Testing shows that the logic is correct and the boards work as required. Although each board only worked on the third attempt at debugging the logic.

    The comparator is going to be one of the slowest paths in the whole design. If you look at the worst path through both boards then it has 18 gates to get through. Yikes, good job I am not designing for speed!

  • 32bit Comparison

    Phil Wright07/02/2017 at 07:53 0 comments

    My processor needs the ability to compare 2 x 32bit values and output a simple true or false. In addition to the values it has a few control lines that indicate the operation (=, <, >=), if the comparison should be inverted and if the comparison is between signed or unsigned values.

    The design is split between a top board that does the basic comparison assuming the values are unsigned. Then the bottom boards take into account the negation and unsigned requirements. Doing a test on this bottom board shows it giving incorrect outputs for when the negation is applied. So I check the circuit design so I could start debugging. Well it didn't take long to find the issue. Here is the last stage of the circuit where it takes negation into account...

    Well that is garbage. Instead of negating the output if the NEG input is true, it simply always outputs zero. So a quick fix solves the problem thus...

    Amazingly the cost of boards from PCB Way has gotten even cheaper. Now just $5 for ten boards, so the fix is a pretty cheap one to resolve.

  • Instruction decoder

    Phil Wright04/05/2017 at 03:51 6 comments

    Instruction decoding is one of the simpler parts of the system. For example, all the branch instructions can be identified using the same 7 bits of the incoming instruction value:-

    All branches have the same '1100011' pattern at positions [0-6]. So I only need a single decoder board that compares and matches this 7 bit sequence in order to generate the correct control lines for the rest of the CPU. The actual comparison of registers rs1 and rs2 is performed by a separate comparison board. This comparison board takes as input the 3 bits at positions [21-14] that uniquely identity the actual branch operation. So '000' will mean BEQ and '001' BNE and so forth.

    This same approach works for other major groups as well. All the ALU operations that take an immediate value have the same '0010011' pattern. The ALU operations that take two registers have the '0110011' pattern. In both cases the ALU implementation will perform the correct function by using the function code that is part of the instruction format and passed directly to the ALU.

    By grouping this way we only need a decoder board for each instruction group that we need to support. As I am only implementing 37 instructions it works out I will need 9 decoder boards.

    A single board looks like this:-

    At the bottom right is an 8-DIP switch that is used to match against the incoming first 7 bits. This means the left most switch on this DIP package is not connected and ignored, but it is easier to order and use 8-DIP packages than try to find ones that support exactly 7.

    Above that are two more DIP packages that are used to define the 16 control output signals. I am assuming that my final design will not have more than 16 different MUX or other boards that need control lines!

    By making the board completely configurable I have the flexibility to implement the rest of the CPU in multiple ways and to change the design if needed. Like my other boards these can be stacked vertically because I am using long female headers for the instruction input, control line outputs and the power connection. So I anticipate a final setup with 9 of these high.

    I use a 74HC688 for the bit pattern comparison, 2 x 74HC241 output drivers for the 16 control lines and an 74HC04 to invert the output of the '688 for use with the output drivers.

  • Let it fly!

    Phil Wright03/20/2017 at 22:40 3 comments

    It took a whole weekend but finally the register file is complete. I took a delivery of new boards last week and the first to be built is the register control board. This is used to drive the 16 individual registers. Once finished it looks quite impressive...

    The control board takes three 4-bit values. The register to output on port A, the register to output on port B and the register to be written to. Our control board has three output headers that are 16 lines wide. So register zero takes bit 0 from each of the three headers as its input. Register one takes bit 1 from all three headers and so forth. This results in the monster wiring loom shown above. I had to make it all by hand using DuPont connectors, a crimper and some heat shrink tubing.

    It would have gone much faster except for some errors that took a long time to notice. Each of the two register stacks had misconnected pins in the middle of the stacks. When connecting them together it can be tricky getting all the 100 long headers to match up. Well I hadn't noticed a couple that had missed on insertion and were not connected. Compounding this I found that one of the ribbon cables I was using to make a test connection had two of the wires transposed. Luckily it was a rainbow coloured cable so I eventually noticed that red and blue lines were in the opposite order at the other end of the cable. Otherwise I would still be scratching my head!

  • Program Counter

    Phil Wright03/14/2017 at 22:18 3 comments

    The program counter module is split between two different boards because there are too many IC's to fit on a single 100mm x 80mm sized board. The top board provides storage by using 4 x 74HC574 IC's that each store 8 bits. Every clock cycle the storage is updated with the incoming 32-bit address. Because our CPU design is single cycle the PC needs updating every cycle. Hence there is no need for a control line that determines if the PC needs updating during the next tick.

    The current value is constantly output to a long header that is connected to the bottom board. This uses 8 x 74HC283 IC's to perform an add of the constant value 4. Because we are implementing the RV32E specification we know it does not need to support the condensed instructions, therefore all instructions are aligned on a 4-byte boundary. Moving to the next instruction always involves adding 4 to the current value. The CPU design will include multiplexors that determine how the input is provided to the PC. It could be the result of adding 4 but it could be the result of a conditional branch or the destination of a jump.

  • Register Control Board

    Phil Wright03/01/2017 at 00:08 0 comments

    Just because the register control board is green doesn't prevent us from testing it. The purpose of this board is to take information from the current instruction and use that to generate individual select lines for the 16 registers in our register file.

    Many of the RISC-V instructions specify two registers as the source of values for the operation. These are called rs1 and rs2 in the ISA description. Here is the specification for the ADD and SUB instructions as an example.

    Our board will take bits 15-18 (4 bits) and 20-23 (4 bits) as inputs. Notice that the instruction above specifies five bits allowing 32 registers to be selected from. But we are implementing the RV32E specification and not the full RV32I version. The RV32E spec only supports 16 registers, so we can simply ignore the most significant bit as the top 16 registers will never be referenced.

    We assume that the code running on our CPU is valid, a commercial system would have checking for invalid instructions and accessing registers out of range. We are not going to bother with that, if your code is wrong then good luck with strange actions occurring!

    So, bits 15-18 arrive at the board representing the rs1 field and are decoded into 16 output lines with only the matching register line selected. In practice, we have implemented the register storage boards to output on a low value. So 15 lines will be high and the matched register number will be set to low.

    We can see this being tested and working below...

    The top left shows our fixed value input board. It has a value of 01 as shown by the output on the top right hex display board. The green board outputs 16 lines and the hex value of that can just about be seen as BFFF or 1011111111111111 as binary. Starting counting at zero it has indeed selected the first line if you start count from the left-hand side. I have tested it with all 16 input values and it does indeed select the correct bit appropriately.

    You might be surprised that it counts from the left and not the right side. Well me too and it turns out I make a snafu on the design. When I reorder it in blue I will rotate the output headers 180 degrees so it matches my expectations. It is not a big deal but as I want to reorder in blue anyway I might as well make the change. It will make wiring slightly neater.

    Bits 20-23 from the instruction provide the rs2 field and are decoded in exactly the same way and simply output on a different header. The final functionality is similar but a little more complicated. Many instructions use the rd field to specify a destination register that should be written to with the result of the operation.

    So we need to decode from a binary number to 16 values. But this time we also need to invert the outputs because writing to a register really does need to be high for a write and low for ignore. Simple enough we just add a bunch of NOT gates. But we also need to ensure we only write when the CLK occurs and the WRITE line is defined. Only some instructions need to update a register and this decoding will set the WRITE line. We only want the update to occur synchronously on the next CLK signal. So, we AND the CLK and WRITE and only when both are set do we enable the outputs for write lines.

    This sounds fine in theory. Time will tell!

  • Am I going colour blind?

    Phil Wright02/28/2017 at 22:45 2 comments

    The next batch of PCB's are in...

    Hang on. I always order blue boards for my cool looking blue CPU. What the hell is this? I double checked my online orders and sure enough, I selected blue for them all. After 8 orders with PCBWAY.COM this is the first mistake they have made. I wonder if they ran out of blue board and just substituted? Wouldn't surprise me.

  • Never trust your Eagle

    Phil Wright02/20/2017 at 08:51 6 comments

    I recently took delivery of some more PCB's from PCBWAY. Given I have never managed to get a design to work the first time around I was not optimistic. Sure enough, I had made a mistake that messed up the board.

    Using Eagle the 74688 IC has an P = Q output pin at the top right.

    The 74688 is used to compare two 8 bit values. So naturally I assumed the P = Q output was HIGH when the two values are equal. When debugging the board I noticed it was the opposite value of what I was expecting. So time to check the actual datasheet.

    What the! The schematic is inverted to the datasheet and so no wonder it doesn't work. So, it seems in future I need to double check the schematic against the actual datasheet for all IC's.

  • Calling clock experts...

    Phil Wright01/27/2017 at 11:59 6 comments

    I am designing a video driver for my upcoming computer. So I have a MX045HS which outputs a 25.175 MHZ signal which is needed to generate a 600x480 resolution VGA output signal. Connecting the crystal output to my trusty oscilloscope gives a pretty poor click signal...

    Using the reference source on the oscilloscope I can see that the poor signal is not a measurement/probe problem...

    I assume it is normal for a crystal to have such a poor signal. What is the standard way to improve this to a nice square wave? A standard circuit you can point me to?

View all 19 project logs

Enjoy this project?



agp.cooper wrote 11/30/2016 at 13:46 point

Hi Phil,

In "Register File Deux" you said "Based on the feedback I have come up with another design that brings the number down to 138 IC's and 18 PCB's. Quite the saving!"

Would you like to share your design/schematic? I would be very interested in having a look. I am particularly interested in your approach to the timing and instruction decoder.


I have used Eagle CAD but unless you pay more than $1k you are limited to 160mm x 100mm (=$169), which is in my mind is too small for a 32 bit CPU sub-board.

I use EasyEDA which is free web based PCB design tool. You can import and export your work (but it is not that faithful). The quote/manufacture is dead simple and pretty cheap (similar to the prices you mention). The main advantage is that there is practically no size limitations. Having said that it can be slow and auto-routing usually need to be manually edited (for large boards).


Something you should consider early is the connection/bus standard between the boards. Having a common bus standard will speed up PCB design significantly. It will also dictate the minimum PCB board width.


For 100+ TTL chips you will need a proper power supply. I spent a lot of time debugging my first CPU only to realise (after much frustration) that the power supply was not up to task.


You will need to think about your method for testing each board and the stack of boards as they are connected. I used an Arduino but you will probably need to use a Mega for the extra IO pins. I can safely say that if you expect the assemble the boards into a full CPU and expect it to work first time you will be disappointed. The game is really about minimising the number of concurrent errors (i.e. debugging a board with one error is much easier than debugging a board with multiple errors) and reworks (i.e. a new PCB).


Unfortunately, building a CPU also requires designing the user interface and operating system. How else are you going to test/demonstrate your CPU when finished? A front panel is okay for my simple CPUs but the more powerful CPU that you are planning will need something better. A serial terminal perhaps? You can cheat here and use a USB to serial converter and use your PC as a terminal (keyboard and display).


Anyway, the above are just suggestions and/or ideas, regards AlanX

  Are you sure? yes | no

Phil Wright wrote 11/30/2016 at 21:57 point


Your make some very good points, if you read the previous 'Register File' entry I outline a few more details. I will be building from 100mm x 80mm boards and so can use the free Eagle software. That means I end up with quite a few boards that need interconnects but that is fine by me. I am not looking to make the fastest CPU or the prettiest.

I am not designing it all in one go and then building, instead I am designing and building a section at a time in a modular way. I have an overall block diagram that you can see in the project images but the rest I design as I go. Not the most efficient way to go but as a hobby it is fun which is the main objective.

Testing will be done using a simple Arduino and using shift/latch IC's to go from serial to parallel to generate 32 bit values.

I am a professional programmer so the software side is easier for me than the hardware. I can use the existing open source GNU RISC-V tool chain to generate machine code from either assembly or C. I suspect I will write my own little OS for the fun of it. Maybe even my own assembler and C compiler and so make it self hosting. Time will tell!

  Are you sure? yes | no

agp.cooper wrote 12/01/2016 at 04:41 point

Hi Phil,

No problems.

If you are staying with the free version of Eagle and the 100mm x 80mm PCB limit, and don't mind lots of boards; You may want to consider strip-board construction. I used it for my Weird CPU ( I used DIYLC (free) for the design work.

The main advantages are:

1) its cheap.

2) it can be rewired if a mistake is made.

The main disadvantages are:

1) manual routing.

2) lots of wire links (I hate the wire links!).

3) limited bus width (~41 strips).

But if you are not using a bus standard then the limit bus width is not much of an issue.

Even though I now use EasyEDA, I still use strip-board for smaller one off support projects.

Regards AlanX

  Are you sure? yes | no

vasili111 wrote 03/21/2017 at 04:09 point

I think it is better to adap NetBSD for your CPU rather than making your OS from scratch. NetBSD was designed to be easy to port to other platforms.

  Are you sure? yes | no

Ingo M. wrote 11/28/2016 at 17:34 point

This is an awesome and very ambitious project! We really need such projects (and Open-V and the like) to ignite the Open Hardware movement. I intend to build the same CPU for myself when the first runs have been successful. I am amazed there have been no comments so far.

Good luck! 

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates