Close
0%
0%

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.

So 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!

  • 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?

  • Fixed value board

    Phil Wright01/08/2017 at 12:10 9 comments

    Well the latest batch of PCB's have arrived. Finally I have a simple 32 bit fixed value board. This allows me to set a 32 bit value using dip switches so I can then feed that value into other boards as test values. This makes debugging so much easier.

    I must have picked the wrong component in Eagle to represent a standard resistor because you can see that the space allocated for each one is much greater then really needed. Fortunately it does not really matter as there is plenty of room on the board anyway. Although, adding 32 pull up resistors seems like I am doing things the hard way. There must be a simpler way of achieving the same effect? Any ideas?

    I used the boards straight away to test each of the 2-1 mux boards I have built. I can set two values going in and then use two display boards (each display board only shows 16 bits) to show the 32 bit output. Then just toggle the output select line and instantly check it works as expected.

    Next up was checking that each of the register store boards works. I need a total of 16 for the 16 general registers in the RISC-V ISA. Unfortunately I ran out of components once I have built 10 of them but it still makes quite the impressive vertical stack. The input and two output ports are all connected vertically Arduino style as is the power supply connector. That just leaves a 3 pin right angle connector for each register that allows for per-register selection for output and writing.

    My next job is to get the components ordered to finish the stack and then the board that will be needed to generate the 16 sets of control outputs for them. Then finally the first major block of the CPU will be completed, the general register file.

  • Register Store

    Phil Wright12/26/2016 at 10:10 1 comment

    I finally got some free time over Xmas to test out the register store board. It needs to store 32 bits so I use 4 x 74HC574 in order to store the value for output on port A and then another 4 to store the same value output on port B. So the value is stored twice but always updated together on the write line going high. Because the '574 has buffer out lines it means we end up not needing any separate buffer drivers. Remember that there will be 16 registers all connected to the port A and B and so we can only output when the specific register is selected.

    The left board is the register store and the right just a simple bus board used to distribute values and power. Now I need to order some for '574 chips so I can build out the other 14 that I need.

  • Fame at last

    Phil Wright12/20/2016 at 04:34 3 comments

    I was browsing the popular Hacker News website yesterday when I noticed something a little unexpected. Someone had submitted a link to this project!


    It stayed at the top spot for several hours and resulted in the project views jumping from about 1K to 6.5K overnight. Guess I had better pick up the pace and make more progress!

    I will be designing some new PCB boards in the evenings this week with a view to ordering them from PCBWay before the weekend. I have the following two weeks off as holiday so they should arrive during that time allowing me to continue with development.

  • Mux

    Phil Wright12/18/2016 at 06:35 0 comments

    My CPU design calls for several multiplexers that allow the output to be selected from 2 different input values. For example, one of the inputs to the ALU is chosen from either the program counter or output port A of the register file. The design for this is pretty trivial.

    I use 8 x 74HC241 to perform the actual switching of 2 x 4 input bits to 4 output bits. With the constrained PCB size of 100m x 80m we have enough room for the first 32 bit input at the top and the second input at the bottom of the board. With the IC's in the middle we have the bottom 16 bits output on the right edge and the top 16 bits on the left. So the PCB is very busy with headers around all the edges and filled with IC's.

    You can see the mux board at the bottom left of the image...


    I am only testing with 4 bits in the image. So the first input is 0xC, the second input 0x0 and because the selection bit is high the output is 0xC. Now I just need to order enough headers and IC's to make another 5 or 6 and I should have the mux requirements covered.

  • Debug boards

    Phil Wright12/16/2016 at 11:23 3 comments

    Debugging designs is going to be much easier with a way to see the values being passed around. Using LED's is all well and good but does not scale well to 32 bit buses, especially if you need to look at three such buses at the same time. I would have preferred the debug board be able to show a 32 bit value but it is not possible to fit the 8 segment drivers as well as 8 segment displays on a single board. Instead we will have to settle for half of that.

    So time to create a debug board that is able to display the value of a 16 bit input using 7 segment displays as the output. As each 7 segment display needs to shows values from 0 to F that means we need a driver that takes in 4 bits and outputs the appropriate 7 segment output lines. Looking around it is easy to find drivers for decimal (BCD) but they do not show the values from 10 to 15 as the needed hex characters. Instead they all show characters such as h, e, l and p so that you can spell out the word 'help'. The only driver I could find that I could also buy online is the MC14495 from Motorola. They have not been made for quite some time but someone in China has a warehouse full of them because I was able to get 20 of them from AliExpress. Their production dates range from 1987 to 1997.

    By applying power but letting the data lines float I get the following example output...


    At the top you can see the other board I have created, a simple bus board that has two lanes of 16 bits and will be used to distribute values to various boards in the finished CPU. In this case I am using the first two bits to distribute power and ground to the debug boards.

    Yes, these two boards and pretty trivial but when you have never designed any electronics before it is good to start simple and work your way upwards. Small steps!

  • DuPont Connectors Galore

    Phil Wright12/16/2016 at 11:04 3 comments

    One disadvantage of a 32 bit CPU is that your internal and external connections are 32 bits wide. That makes for a lot of wires. So time to start making plenty of cables for working with prototype boards and hooking everything up. Rather than buy them ready made, which is surprisingly expensive, I have decided to make them myself. So some ribbon cable, DuPont headers, connectors and a crimper...

  • Register File Deux

    Phil Wright11/28/2016 at 00:09 12 comments

    Thanks to Yann Guidon for pointing out how the design of the register file could be improved in order to save on components. In fact the previous design used a total of 255 IC's over 45 PCB's. 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!

    The Register Store design has been changed to remove the use of separate output buffers and instead uses the built in output buffering capability of the 74HC574 IC. In order to make that work we need to store the value twice, once per output port and then use an incoming enable line in order to control when the value is output. Although crowded, we can fit the 8 x 74HC574 and all the headers onto a single board and so reduce the number of PCB's by half as well as saving on IC's. The block diagram is very simple...



    We used to have a Register Select for each register. But instead of providing the register numbers to each register we can use a de-multiplexer to convert the binary numbers into selection control lines that are then distributed to each storage board. That means we have the selection logic once rather than for every register. Here is the block diagram for dealing with the register write functionality...

    The NUM is just a 4 bit binary number that comes from the instruction and is the target register to be written to. But we only want to write when the CLK occurs and the W (write) control line is high. Instruction decode logic elsewhere will decide if the W should be high based on the specific needs of the instruction. We need 2 x 74HC138 IC's to perform the de-multiplexing resulting in 16 output select lines. Because the 74HC574 memory IC needs an active low signal for writing a new value we need to invert all 16 lines before distribution.

    Two more copies of this board are needed in order to generate the port A and port B output signals based on values from other parts of the current instruction. They are simpler in that they do not care about the CLK and W signals, they always output something on both ports at all times. To keep costs down I will use the same design for all three boards but the port A and B instances will have jumpers that connect the CLK and W to high so that the output is always applied.

    I should be able to get this designed in Eagle during the next couple of days and then ordered.

  • Register File

    Phil Wright11/25/2016 at 00:20 3 comments

    You can see the specification for the user level RISC-V ISA by going to the http://riscv.org website and looking inside the specifications menu section. We are going to be implementing the RV32E specification. This is a 32 bit machine with the embedded microprocessor (E) extension. It only requires 16 general purpose registers instead of the standard 32 and it also makes optional some of the features that would otherwise be mandatory.

    Our first design step is to work on the register file as it is the heart of the processor. It needs to need the following requirements...

    • 32 bits per register
    • One input port
    • Optional write per cycle
    • Two output ports working in parallel

    Here is out black box diagram for it...


    The blue input port (Data In) and output ports (A and B) are both 32 bit buses. The green control lines provide a clock signal (CLK) and a write (W) line. Only if the write line is high does a target register get updated on the clock signal. Most processor instructions do not cause a register to be updated so the W line will only be high for update instructions. The IN control line is 5 bits wide and specifies the target register for the write. The A and B control lines are also 5 bits wide and identify the register to output to the matching port. Five bits gives us 2^5 = 32 possible target registers. Strictly speaking we only need 4 bits to encode the 16 registers but I went with the 5 for a couple of reasons.

    The RISC-V instructions have 5 bits assigned to selecting registers and so it becomes natural to pass those instruction bits straight to the register control lines without throwing one away. Plus, in the future it would be easy to expand the processor to have the full 32 registers if I decide to switch from the RV32E to the RV32I specification. It is easy to make it 5 instead of 4 at this stage and we might as well leave future options open by doing so.

    If we expand into a high level design we get the following...


    To implement the output ports we need to ensure that only 1 of the possible 16 registers outputs to each port at a time. So we use buffer drivers on each port. In order to decide if the buffer should output or be high impedance we use the selection logic on the left side of the diagram. They do a compare against the A and B control lines to decide if this register is selected. To update the memory we need to ensure we are the selected IN register along with the write line being high and the clock high. Only if all three constraints occur should the memory update occur.

    Converting this into an actual logic chip design we get...


    First you will notice we have split the register into two half's, the left side is performing the selection logic and then the right half is implementing the actual memory and output. This is because there are too many logic chips to fit on a single 100mm x 80mm PCB if it was all implemented at once. So we are forced to split it into more than one board. You will also note that the output buffers suddenly have two control lines going into them.

    The 74HC241 buffer driver IC has an odd specification. It has 8 input lines and 8 output lines but they are split into two blocks of 4. The first block output on a high enable value but the second block outputs on a low enable value. So to get all 8 lines to output (or to turn the output off) I need to provide two control lines that are inverted from each other. Hence on the left side of the diagram you will see there are two NOT gates used to provide those inverted values.


    Register Select

    The left side of the diagram will be implemented as the Register Select board and contain the following components...

    • 3 x 74HC688
    • 1 x 74HC08
    • 4 x 100nF bypass capacitors
    • 1 x 5 position DIP switch
    • 5 x 4.7k ohm resistors
    • 3 x LED
    • 3 x 470 ohm resistors
    • 2 x 10P long female headers
    • 1 x 8P right angle female header

    Each board will have a DIP switch that is used to define the register number along with 5 pull down resistors for when the switch is in the off position. There are three LED's...

    Read more »

  • Eagle and PCB

    Phil Wright11/23/2016 at 04:59 0 comments

    The finished design is going to be quite big. It has to implement the 40 odd instructions of the RISC-V user level ISA as well as handle all the 32 bit data/address buses and connections. So creating it as a big breadboard project is out the window. No. We need to create some actual proper PCB designs that can then be connected together in a modular fashion.

    So we need to use software to design the PCB and then have them manufactured. As a hobby project this needs to be a cheap service. So I have decided to use Eagle. If we stick to just 100mm x 80mm boards then the software is free. So that places a constraint on the maximum size on any of the boards we make. Looking at manufacturers I found a Chinese company called PCBWay that seems about the cheapest option. They can provide 100mm x 100mm boards at just $10 for 10 of them. Even when you factor in postage at $25 that is still only $35 for 10 boards of a professional quality. This is the cheapest way I can find and fits in with the hobby cost I can afford.

    So all the components that make up the CPU need to be built from 100x80 PCB boards that can then be connected together using either simple ribbon cables or headers that directly plug together. In fact, this sounds ideal as each board can be designed and iterated quite cheaply until it works perfectly. All whilst keeping the cost down to a manageable level.

View all 10 project logs

Enjoy this project?

Share      

Discussions

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

Hi

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 (https://hackaday.io/project/12879-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

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

Does this project spark your interest?

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