CODE
The Hidden Language of Computer Hardware and Software
2nd Edition

Chapter 23. CPU Control Signals

Chapter 23 constructs a CPU that executes a subset of the instructions of the classic Intel 8080 microprocessor. This CPU requires the Arithmetic Logic Unit and the Register Array from the previous two chapters, along with several smaller components. Tying everything together is the Instruction Decoder that generates all the control signals for the other parts.

Instruction Decoder (pages 365 – 376)

The Instruction Decoder is easily the messiest part of the CPU. It is shown in several parts in the pages of Chapter 23, but here all the components are assembled into an extremely scary circuit.

Unless you have a giant screen, you might need to zoom out your browser window to see the whole monster circuit.

An opcode is selected using the spin control at the upper left. The instruction mnemonic appears above the spin control. As you'll note, many of the Intel 8080 instructions are not implemented in this circuit.

The decoders below the spin control are used in conjunction with a series of AND gates to determine which family of instructions the opcode belongs to.

By default, instructions are assumed to have a one-byte fetch and a one-cycle execution. If that is not the case, then the gates at the lower left determine how many bytes must be fetched from memory and how many cycles are required for the execution. The flip-flops, counter, and decoder generate signals corresponding to the fetch cycles, the Program Counter (PC) increment cycles, and the execute cycles. Some of the circuitry below the 4-to-16 Decoder is a little different from that shown on page 370 of the book.

At the far right on the bottom you'll see signals that are used to control several of the components in the CPU. These control signals are the same for all instructions. Control signals that are specfic to each instruction are handled by the big diode matrix that dominates the top right part of the circuit. Each family of instructions generates certain control signals for the first and second execution cycles, and the corresponding Pulse cycles.

Your browser does not support the canvas element.

You control the fetch and execution of each instruction by pressing the Clock button.

For example, dial up the instruction C6h, which is the ADI instruction, or Add Immediate. Press and release the Reset button to return everything to initial conditions.

You'll see that the circuitry at the bottom left has determined that this instruction requires a 2-Byte Fetch (the instruction byte itself and the data byte that follows the instruction) and a 2-Byte Execute. However, this information is not used quite yet. In an actual CPU, it wouldn't be available until the instruction has been fetched from memory and stored in the instruction latch.

The 4-to-16 Decoder in the Cycle Decoding section has inputs of all 0's which means that the 0 output signal is 1, indicating Fetch Cycle 1. At the far right, you'll see that the Program Counter Enable signal has put the contents of the Program Counter on the address bus to address the Random-Access Memory, and the RAM Data Out Enable signal has allowed the contents of the memory to be put on the data bus. This is the instruction byte.

Now press the Clock button but don't release it. The Pulse signal causes the Instruction Latch 1 Clock to store the instruction and the Increment-Decrement Clock signal to store the contents of the address bus in the Incrementer-Decrementer. Now release the Clock button.

Press and release the Clock button again. Now we're in a PC Increment Cycle and the Increment Enable signal has allowed the incremented value of the Program Counter to be put on the address bus.

Now press the Clock button but don't release it. The Pulse signal triggers the Program Counter Clock to store the incremented address in the Program Counter. Now release the Clock button.

Press and release the Clock button. Now we're in Fetch Cycle 2, and the Program Counter Enable and RAM Data Out Enable signals have put the next byte (the data byte of this instruction) on the data bus.

Pressing the Clock button causes the Pulse signal to trigger Instruction Latch 2 to store that byte, and the Increment-Decrement Clock to store the value of the Program Counter in the Incrementer-Decrementer.

Pressing and releasing the Clock button puts us in another PC Increment Cycle as earlier. Pressing the button again stores the incremented value back in the Program Counter.

Press and release the Clock button again. Now we're in Execute Cycle 1 ready to execute this instruction. You'll notice at the top that the diode matrix and the Execute Cycle 1 signal have caused the Inst Latch 2 Enable signal to put the value of the data byte on the data bus.

Press the Clock button without releasing it. The Pulse signal has triggered the ALU Clock to store that value in the Arithmetic Logic Unit. Release the Clock button.

Press and release the Clock button again. Now we're in Execute Cycle 2 and the ALU Enable signal has allowed the contents of the Arithmetic Logic Unit to be put on the data bus. This value is the Accumulator plus the data byte.

Press the Clock button without releasing it. The Pulse signal triggers the Acc. Clock to store that value in the Accumulator. Release the Clock button. The instruction has been executed.

If you keep pressing and releasing the Clock button, the instruction will be executed again, but in a real CPU, a different instruction will be fetched from memory.

The Central Processing Unit (pages 356 – 376)

All the components of the CPU have been assembled here and connected to a block of Random-Access Memory. Components are connected with the 8-bit data bus (the thinner data path), the 16-bit address bus (the thicker data path), and control signals (lines). The Instruction Decoder shown above is now encapsulated in a large box in the center.

This circuit demonstrates how an entire program is executed by the CPU. The bytes stored in memory constitute the program shown on page 318 of the book. This program adds a pair of two-byte numbers, the hexadecimal equivalents of 5,000 and 2,500.

Your browser does not support the canvas element.

As you click the Clock button, the Instruction Decoder below it indicates the cycle and the fetched opcode. Control signals trigger the Instruction Latches, Program Counter, and Incrementer-Decrementer to the left of the Instruction Decoder, and the Register Array and Arithmetic Logic Unit to the right of the Instruction Decoder.

Keep in mind that the S0, S1, S2, D0, D1, and D2 signals from the Instruction Decoder to the Register Array might be affected by instructions that do not involve the Register Array. The Source signals are only meaningful when the RA Clock signal saves a value in the Register Array; the Destination signals are only meaningful when the RA Enable signal puts a value on the data bus.

Similarly, the R0, R1, and R2 signals from the Instruction Decoder to the Arithmetic Logic Unit are only meaningful when the ALU Clock signal saves a value in the ALU.

As you repeatedly click the Clock button, the Memory component at the far left displays what byte is being addressed. The two busses show what value is on that bus. When the program executes the HLT instruction at memory location 000Eh, the program has completed. The sum of the two values being added is stored in the memory locations 0x0010 and 0x0011. That value is 1D4Ch or 7,500 in decimal.