
Building an 8-Bit CPU in Logisim
Over the past few months, I’ve been designing an 8-bit CPU in Logisim with the help of Ross McGowan’s excellent Design a CPU course.
Over the past few months, I’ve been designing an 8-bit CPU in Logisim with the help of Ross McGowan’s excellent Design a CPU course.
The CPU is an 8-bit width computer architecture, meaning that the data buses, registers and arithmetic logic units can only process 8-bit data. Because each bit represents either a 0 or a 1, an 8-bit register can store 28 unique values. In my design, integers are represented by unsigned binary numbers meaning that the 28 values span from 0 to 255.
With the exception of the control section, the 8-bit data bus connects components of the CPU together to allow the transfer of information and data. Data is sent and received through the bus by enabling specific components and setting others. For instance, to store the output of an ADD operation from the ALU to register 0, the CPU would enable the accumulator onto the bus and set register 0.
The Arithmetic Logic Unit (ALU) is a component of the CPU that processes arithmetic, bit shifting and other bitwise operations such as OR, AND, and NOT. The ALU is a combinational circuit, meaning that its output is a function of its current inputs and has no dependence on previous inputs. In other words, all potential operations are performed in parallel in the ALU and the desired one is selected by the opcode.
Opcodes, meaning operation codes, are used to instruct the ALU to perform a specific arithmetic or bitwise operation. In my implementation of the ALU, the opcode size is 3 bits, and a 3x8 binary decoder is used to map the opcode input into its respective operation.
Opcode | Operation | Description |
---|---|---|
000 | ADD | Performs add operation on A and B with carry-out |
001 | SHR | Performs bit shift right operation on A only with carry-in and carry-out |
010 | SHL | Performs bit shift left operation on A only with carry-in and carry-out |
011 | NOT | Performs NOT bitwise operation on A only |
100 | AND | Performs AND bitwise operation on A and B |
101 | OR | Performs OR bitwise operation on A and B |
110 | XOR | Performs comparison between A and B with equal and A larger |
111 | UNUSED |
The main output of the ALU is the result of the arithmetic or bitwise operation. This value is stored in the accumulator that holds the result , which is a type of register.
The ALU also outputs status signals that represent carry out, zero, equal, and A larger. The status signals are stored in an external flag register where the codes are stored for use by the control section.
Registers are storage components of a CPU that are used to temporarily hold information such as instruction addresses and program output, sort of like variables in a function. There are many types of registers that serve specific purposes. My CPU design includes general purpose registers, an instruction register, an instruction address register, a memory address register, an accumulator, and a status register.
The internal workings of a general purpose register include gated SR (set-reset) latch memory followed by an enable AND gate and a controlled buffer. The general purpose registers have input, output, enable, and set pins. However, not all registers have enable pins or controlled buffers and enable gates. For example, the instruction register does not have an enable pin nor an output controlled buffer and its data is always available in the control section.
The Random Access Memory (RAM) was the most satisfying to build. Scalable to 256 bytes, I only implemented 32 bytes for simplicity and efficiency. Each block of memory is a 1 byte (8-bit) register.
The Memory Address Register (MAR) is connected to the bus and stores the address of either an instruction or data in temporary memory.
0000 0000
The stored address is read into two 4x16 decoders with the first four bits indicating the vertical position and the last four bits indicating the horizontal position of the desired memory location.
The clock generator is responsible for syncing all of the processes that occur in the CPU, such as the set and enable signals for many components. The CPU clock is powered by a J-K (Jack Kilby) flip flop and has three outputs—the original clock, the set clock, and the enable clock. The leading and falling edge of the set clock signal must fall between the leading and falling edges of the enable clock. This is exactly what the J-K flip flop circuit does. It takes 4 clock pulses to complete one instruction cycle.
The control section is where all of the control logic resides. While not directly connected to the data bus, the control section is connected to every component, enabling and setting them according to the current instruction. To interpret 8-bits of instruction into physical processes is the remarkable job of this component. The outputs of the control section include the enable and set signals for all of the CPU’s components The inputs of the control section include the clocks, the load pin, the ALU flag (status) register output, a reset pin, the MAR set pin, and most importantly, the instruction itself.
The control logic within the component was the most challenging part of the project. Here are the instruction codes for this CPU design.
1OOORARB
OOO
are the opcodes used to select the arithmetic or bitwise operation,
RA
represents
the two binary
bits of
register A and
RB
represents the two binary digits of register B. The ALU instruction would load
RB
into
the
temporary register which feeds into ALU input B and then
RA
into ALU input A.
0000RARB
RA
represents the two binary bits of register A and
RB
represents the two binary bits of register
B. The
LOAD instruction loads register B from the RAM address in register A.
For example, to load data into register 3 from the RAM address held in register 2, the LOAD instruction would be 00001011.
0001RARB
RA
represents the two binary bits of register A and
RB
represents the two binary bits of register
B. The
STORE instruction stores the contents of register B into the RAM address in register A.
For example, to load the data in register 2 into RAM at the address in register 1, the STORE instruction would be 00010110.
0010XXRB
XX
are not used in this instruction. Only
RB
, the last two bits, are used to represent register B. The
DATA
instruction loads the data in the next RAM address into register B.
0011XXRB
XX
are not used in this instruction. Only
RB
, the last two bits, are used to represent register
B
. The
JUMP REGISTER instruction jumps in the RAM to the address in register
B
.
0100XXXX
XXXX
are not used in this instruction. The JUMP ADDRESS instruction jumps to the next address
in the
RAM.
It
does not load any data into any registers.
0101CAEZ
CAEZ
represent the flags from the ALU, carry out, A larger, equal, and zero. The following
table
explains
the
instructions for each combination of these flags.
0110XXXX
XXXX
are not used in this instruction. The CLEAR FLAGS instruction will clear the ALU flags
CAEZ
.