I’m a pretty lazy person. I like to put things off, drag my feet, and make plans that I know will never come true. Perfect example, Fall 2008 I took a digital systems course where we designed a very basic (2-bit) CPU and I decided I wanted to continue working out of class to make a better one. Initially, I was actually making some progress, but quickly outgrew the basic chips (GAL chips) we were using at the time, so I screeched to a stop. After a few months of poking around, I figured out an FPGA might be a better way to go. However, these are expensive and would take a lot of effort to learn, so I put the idea on the back-burner.

Magic 1

Bill Buzbee's homemade CPU, which provided some inspiration for me.

Luckily for me though, my research group started to do some work with FPGA’s, so I was able to get some hands on experience with them. Despite having the needed tools though, I was still dragging my feet on doing any work. Well, a few days ago, I got re-inspired when I found a website about a guy called Bill Buzbee who built his own (and in my opinion) pretty complex CPU. It has all sorts of neat features such as paging and interrupts. Well, that was the inspiration I needed and now, a few days later, I’ve actually got some progress worth mentioning.

I’ve tried designing a CPU several times before, either on paper or just trying to hack out some Verilog code to no avail. I think the main problem is that I haven’t had any clear direction or plan. Because of this, I decided to make a high-level block diagram of the architecture on the computer before I wrote any code. So far, this seems to pretty helpful, as I’ve had several *doh* moments already where I found an error in my design. Doing it on computer (hurray for Visio!) makes it a lot easier than working with pencil and paper too.

As I started my design, I tried to copy what I already knew a little about. In a computer architecture class I took, we had studied the MIPS architecture, so I tried to copy their style of pipelining, though I in no way claim my sketches were anything close to a MIPS design. I quickly figured out pipelining would be pretty difficult for me at this point, so I dropped that idea for now.

After I had revised my drawing a little, I noticed that the memory was being referenced in two separate places in the CPU (see diagram). So this meant that I could do one of two things:

  • Revise the whole design to only reference memory in one place, retaining the Von Neumann structure.
  • Use two separate memory modules, giving me a Harvard architecture.

I thought it might be fun to try something new (and also not redo the drawing again), so I decided to go with the Harvard style and split the data and instruction memory into separate chips. I might regret this later, but we’ll see how it goes for now.

My CPU design

Here is the initial plan for the CPU. The red parts will be external memory chips. The whole second ALU business may or may not be implemented in the first go-around.

Lots of designs are using parallelism today, so of course I didn’t want to be left out. As such, I’m going to try to add a second ALU into my design. This would allow me to do two computations at once. This will probably also make the design a lot more difficult to complete as well. I’m going to add a few restrictions to this second ALU so that it will be easier to work with though, such as it will only operate on certain source and destination registers, unlike the first ALU, which should be able to use most any register available. If this part gets too difficult to deal with, I might drop it, but I am going to try to get it to work.

I haven’t yet decided whether I want to use 8/16/32 bits for addresses and data sizes, how many I/O ports to have, nor exactly how many registers the chip is going to have, but I don’t think that is really important yet. Right now, my layout is such that these choices don’t really matter yet. These issues shouldn’t really become an issue until after the instruction set is designed. One major problem I do see coming up is the implementation of the bi-directional buses on the FPGA. What I mean is that I will need tri-state outputs for the bus, but the FPGA can’t synthesize these internally. It can however, do tri-state outputs on the physical I/O pins. What this means is that I will have to physically wire the bus to various I/O pins on the FPGA, which will be a headache. If you know of an FPGA that can do tri-state logic internally, please leave me a comment!

At this point I have started to write some basic code for the chip. Specifically, I’m working on designing the registers and I/O port modules in Verilog. These seem pretty simple, but I’m making a big effort to actually write tests and make sure that they work properly. Hopefully this attempt will pan out better than my previous efforts!

« »