In this part of the series, I’ll introduce the necessary components needed for storing and executing programs on our micro processor! I’ll try to keep this part quite short, because I already explained what a micro-instruction is and what it consists of on this CPU in part 2!
The CPU will have 256 micro-instructions with a length of 32 Bit. This means, that it’s possible to store programs with a length of 8.192 Bit.
In my design, I want to utilize a ROM for storing the program in the CPU. The line of code, that’s about to be executed, will be loaded in a separate 32-Bit register which is then connected to the relevant parts.
Let’s take a look at one micro-instruction. For now we know, that it will consist of 32-Bits and it will hold the following information. The number in the parentheses is the number of bits needed to store the information:
a) ALU-OP (2)
b) REG-A (4)
c) REG-B (4)
d) REG-R (4)
e) EN-WRITEBACK (1)
f) SHIFT (2)
g) JUMP (2)
h) JMP-ADDR (8)
i) EN-MEM-ADDR (1)
j) EN-MEM-BUFF (1)
k) RW-FLAG (1)
l) MEM-SELECT (1)
m) USE-MEM (1)
And I want to organize one complete instruction like this:
This way, the first 6-Bits are used for control-flow and calculations, the next big portion of 20-Bits is used to address various things (like the register file). The last 6-Bits are memory flags of all sorts.
Let’s say we want to take the registers R12 and R1 and perform an addition on the values stored in them. The result should be stored in R3. There are no external memory-operations in this call.
Our instruction looks like this (in binary):
// ALU-Addition = 10
// R12 = 1100; R1 = 0001; R3 = 0011
As you can see, there’s nothing really complicated about this. All the codes can be found in part 2 of the series!
Now it’s time to add the program storage and part of the instruction-decoder to the theoretical CPU design.
Please note, that I didn’t include the whole 256-lines of the program storage to keep the design small and easier to understand. The ROM with the address-decoder and the current-instruction and instruction-counter registers looks like this:
Click here to enlarge the image or here to open the simulator and try it yourself!
In the first clock-period, the next instruction is loaded from the ROM and it is then stored in the 32-Bit register below. This register is connected to the respective parts of the circuit. For example: The two ALU-OP-Bits go over to the ALU and tell it what to do next (ADD, AND, NOT or nothing).
You might ask yourself, why the 32-Bit register is needed. This way, the instruction can be stored for the entire length of the calculation right until the next instruction is needed. This ensures, that the instruction is present for the entire length of the calculation and therefore we can increment the program counter and index a new entry in the ROM in the meantime without interrupting the current calculation.
Once the instruction got loaded into the register, the instruction counter either gets incremented by one or, if the instruction contains a jump, it is set to the new address. The next instruction is placed in the 32-Bit register from above after the current calculation finishes. The following part of the circuit manages the jumps:
To view the image it in full resolution, click here or display it in the logic-simulator, by clicking here!
The following adder increments the instruction counter by one, if no jump occurred:
View the current progress of my CPU-design in the simulator!
In the next part …
… I’ll finish the design by adding the connections to the ALU and to the instruction-register and by building the 4-phase-clock.
Table of contents
Part 1 – Basics and the ALU
Part 2 – Registers and memory
Part 3 – Applications (You are here)
Part 4 – The completed CPU
3 thoughts on “How to design your own CPU from scratch – Part 3”