Store Unit

Read time: 18 minutes (4523 words)

We have reached the end of the road! The last stage we need to consider needs to find a home for any data item that arrived at this point. Unfortunately, getting through this stage is a bit complicated, and again, we need to consult the instructions to see what additional parts and wires we need.

The Machine

Here is the full machine, as designed so far. (With a few things added based on my study of a few (not all) of the instructions we have not considered in our studies.


This is a lot of components(13) and a lot of wires (24). Each component is something you have already constructed and tested, or is a modification of one of your other parts, all sitting in the lib folder. All we need to do is work through this last stage, and wire the beast up!

Let’s isolate the last stage and see what we have:


Reviewing the Instructions

Looking back at the instructions we are working with, we see this:

Mnemonic Operands RTL
brne k7 Z == 0 ? PC <- PC + k + 1 : PC <- PC + 1
dec Rd Rd <= Rd - 1, PC <- PC + 1
eor Rd, Rs Rd <- Rd ^ Rs, PC <- PC + 1
in Rd, A8 Rd <- A, PC <- PC + 1
ldi Rd, k8 Rd <- k, PC <- PC + 1
out A8, R4 A <= Rs, PC <= PC + 1
rcall k12 [SP] <= PC + 1, SP <- SP - 2, PC <- PC + K + 1
ret   PC <- [SP], SP <- SP + 2
rjmp k12 PC <- PC + K + 1
sts k16, R4 [k16] <- Rs, PC <- PC + 2

From this table, we see that we need to be able to update the following locations:

  • PCnext: where we will fetch our next instruction
  • Rd - we are to save a calculated result back in this register
  • A - we may write data out to the outside world using an I/O register
  • [k] - we may write data into the data memory at a specified address.

All of the calculated results are available on wires leading into this last unit. Our job is to make sure the control unit can route them properly.

Let’s work our way through this diagram


The next address we need for fetching the following instruction is one of three possible values:

  • PC + 1 - the normal output from the decoder
  • PC + k + 1, this one comes out of the ALU as a 16-bit address
  • A value we popped off of the stack (for a function return statement)

We set up a multiplexor, this one with three inputs, and let the control unit decide which result we want to send back to the fetch unit!

Stack Memory

We need a chunk of memory to serve as our stack. In our AVR example program we saw how we set up for a stack. The actual stack lives in the data memory, but for our simulator, let’s just create a stack that is independent of that memory. The only difference in how this unit works, is we only support push and pop operations, and the stack memory is 16-bits wide. How big we decide to make it is a design decision.

Subroutine Call

If we are calling a subroutine, we want to record the address of the following instruction, which is at PC + 1. We will send that address to the input side of the stack memory unit. Another job for the control unit.

Data Memory Updates

In some instructions, we will calculate a new number, and save it in the data memory. These instructions specify the address where the item will end up. So, we need to route the address, which will be a constant coming out of the decoder, to the address input on the data memory module. The data to store will be sent into the data memory unit through a multiplexor, so we can select an ALU output, or the contents of another source register.

Data Memory Reads

Some instructions will access data memory, and we need to place that item in a specified register. For the instructions we are studying, the destination will be specified by the Rd value we got out of the decoder. That address is already sitting at the address port of the register file, so when the data is ready to write, all we need ot do is trigger a write and save the data we provide back into that register.

I/O Instructions

For IN and OUT instructions (and a few others, we will be dealing with one register and an I/P port address (A). For reads, that port data value will be routed back to the register file through a multiplexor that can select which data item to send back. For OUT`` instructions, the data from the source register needs to be “written” into the I.O memory unit, using the address specified in the instruction.

Since we want to set up virtual I/O devices for our simulator to interact with, foe input and output actions, we will need to pass the data value to an output device, or fetch a data item from an input device. Remember that these locations are not real “memory”, but just an easy way to access I/O devices. “Memory-Mapped-I/O” is a common way to deal with a lot of potential gadgets you might want to hook up to your machine. (The Pentium supports hundreds of devices, the AVR only a few dozen!)