This is an old revision of the document!
By: Lyra Silverwolf
I built a display/diorama of an entire computer Central Processing Unit (CPU) out of nested cardboard boxes.
At the highest level of abstraction are the 5 major information stages a CPU is commonly divided into: instruction fetching, instruction decoding, the register file, the arithmetic logic unit (ALU), and data memory. I chose these particular stages for the CPU, because in a pipeline CPU when multiple instructions can be executed simultaneously, these are the typical partitions.
Inside of each outer level box are more boxes representing what happens inside of that particular unit. For example, inside of the ALU there is a box for the adder/subtractor, which in turn contains a box with a gate level schematic of a 1-bit full adder inside. This allows the person exploring the diorama to extrapolate how the components fit together all the way from the individual gates to the top-level information stages.
There were several reasons I chose to make a physical display of a CPU for my final project. First of all, I think that Computer Architecture is a very exciting field, and I wanted to make it more approachable for all audiences. When I set out to construct this display I had my 12-year-old sister in mind as my potential audience, and while I may have not achieved quite that level of clarity, I believe that I've made something that other Oliners can interact with and get excited about.
This project also wraps up the big picture of the entire course very well, because I've explored all of the levels of abstraction that we discussed in class throughout the semester. We started out initially talking about logic gates and binary math, and then slowly progressed up to the CPU itself, and in this project I present a little bit of everything. Through pulling it all together in this way, I certainly reinforced most of the concepts that I was having trouble with in the class and found gaps in my knowledge that I wasn't even aware I had.
I started out by sketching out the CPU at its highest level of abstraction and deciding how many very large boxes I needed to acquire. I then determined what exactly went into each upper-level box and what subset of those things I wanted to also give boxes to.
In the end I decided on the following boxes:
On the lid of each box I described the function of that particular box in the context of the level within which it was contained. Inside of the box I drew a complete schematic of that item, and I wrote detailed descriptions of what each element in the schematic was responsible for doing, even if it didn't have its own box.
In the end I wound up with the following descriptions of the components: Instruction Fetch Unit - The instruction fetch unit is responsible for keeping track of the CPU’s current location in the program it is running using the program counter (a piece of memory). Within the instruction fetch unit, the program counter can either be incremented to the next line of the code, branch to a line in the code a certain number of lines away from the one it is currently on, or jump to a completely different line specified by the previous instruction executed. It also houses the instruction memory, which consists of a lot of memory cells that store all of the CPU’s instructions. The fetch unit outputs the instruction stored at the location indicated by the program counter for execution by the CPU. Program Counter - The program counter is a register (small bit of memory) that “bookmark’s” the computer’s place in its instruction sequence so that it will know which instruction to execute next. Concatenator - The concatenator combines the 4 highest order digits of the current program counter value with the last 26 digits of the previous instruction to build a new program counter value. Branch Multiplexer - This multiplexer controls what is passed in as the second operand of the adder. If there is no branch and the program counter should continue on to the next operation in the instruction set, this multiplexer will pass through the zero from the top. However, the multiplexer will choose the sign-extended version of the immediate value passed in through the previous instruction if the program counter should branch to a different part in the code a certain number of lines ahead. Adder - The adder either adds only 1, using the carry-in, or the sign-extended immediate value and 1 to the previous program counter value depending on the output of the branch multiplexer. Jump Multiplexer - This multiplexer has the final say over what the next program counter value will be. It either chooses the output of the concatenator if a jump is specified or the output of the adder if the program counter will be continuing or branching. The blue “jump” input at the bottom chooses which data is passed through. Sign Extender - The sign extender takes a 16-digit immediate number and transforms it into a 32-digit binary number by repeating the most significant digit of the number in 16 positions to the left of that number. Sign extension is important because a 1 as the most significant digit of a signed binary number implies that it is a negative number and a 0 as the most significant digit implies a positive number. Therefore, when stretching a 16-digit binary number to be a 32-digit binary number, one must use sign extension rather than just using 0’s like we do with decimal values. Sign Extender Multiplexer - This multiplexer chooses 16 0’s if the first digit of the immediate is 0 or 16 1’s if the first digit of the immediate is 1 so that the concatenator can sign extend the immediate. Sign Extender Concatenator - The concatenator combines the 16 0’s or 1’s from the multiplexer with the 16-digit immediate value passed into the sign extender to produce a valid 32-digit value that could be used as the program counter value. Instruction Memory - The instruction memory stores all of the instructions that the CPU can execute in chunks of 8 digits called bytes. Each instruction is a set of 4 bytes (for a total of 32 digits). The program counter value is fed into the instruction memory, and the instruction memory returns the byte of information at that location and the 3 bytes after it so that a full instruction is emitted. Since it does not make sense to call bytes from the middle of an instruction, the program counter will always end in two zeros (which signifies in binary that it is a multiple of 4).
Include everything necessary to pick up where you left off. This should include: Code Schematics build instructions A list of difficulties and ‘gotchas’ while doing this project Work Plan reflection A possible TODO to extend the depth of the project