Wednesday 3 August 2016

The stack pointer, the address register, and the X and Y registers

Program counter - update

Nothing significant - but one of the rather fine features of logisim is that it can handle datapaths of various widths. That means you can arrange the inputs and outputs to a circuit to be, say, 8 bits wide but showing a single connection and wire, which keeps things simple.

So here is a version of the 8-bit up counter modified to have an eight bit input and output, instead of eight individual bits. Right click and save as always...

Stack pointer

At first glance, the stack pointer is pretty similar to the program counter, but there are two significant differences: it doesn't need have a reset, but it needs to count in both directions.

We will build a stack which follows convention and (a) builds downwards as new items are added, and (b) always points at an empty location. To use it, early in the initialise sequence of the processor the stack pointer is set to a convenient point in ram - often the top of memory on a small system such as ours.

When we want to write to the stack, we just write at the stack pointer's current  position, and then let it auto-decrement so it points now at the next free location. To read from the stack, we auto-increment to point at the last used memory, and then read from it.

So we never need to clear the stack pointer (as we do the program counter) but we do need to count in both directions. Once again, we reach for the 74hc catalogue and out pops the 74hc191. (There's an excellent discussion of various counters here and I have cheerfully stolen their logisim implementation of the 191 rather than taking the time to do it myself - thanks guys).

The 191 has exactly the features we need - you'd almost think the designers had computers in mind - with the sole exception of being only four bits wide. Not a problem; we'll bolt a couple together in a similar manner to the 161 we used in the program counter.

One other minor difference - the 161, and so the counter we have built from it, counts on the falling edge of the clock pulse, while the 191 counts on the rising edge. Since we will eventually want to clock everything from a single clock, we might need to invert the clock feed to one or the other of these counters. We can decide which once we decide what else needs to happen on these edges - of which more later.

Logisim model: 74191
Logisim model: 8-bit up down counter with load

The address register

Here's one I haven't mentioned, but which has an essential function: when an address is provided as the second and third bytes of an instruction - say a load, store, or jump - then the address must somehow find its way onto the external address bus. (Note that we haven't considered yet just *how* the external address bus is driven by the program counter or the stack pointer - just take my word for it for now.)

We can't use the program counter; it has to remain pointing at the next byte of the instruction, or at the succeeding instruction. We can't use the stack pointer since it needs to remember the position of the stack. But what we can do is transfer the values as we read them to the address register, and then send the address register to the address bus.

It doesn't need to do anything other than this; it's just a latching register. Well, two latching registers, since it has to be sixteen bits wide and we can only access eight at a time, but you get the idea. We might use any number of 74hc series chips, but the 74hc574 is one possibility; on the rising edge of the clock it will latch the data presented at its inputs and if the output enable is active (low) then it will present the latched data at its outputs.

The X and Y registers

In a similar fashion, we can implement the X and Y registers using single 574s for each.

In total, we have eight actual or virtual 'registers' that talk to the address bus.

With this in place, we have most of the parts we need to put the addressing section together. What we haven't discussed, though, is getting the address out from the appropriate registers to the address bus. I'll cover this in the next section, along with the problem of getting the data in the registers to where we might need it.

1 comment:

  1. You're a savior, I've been looking all over for a 191 in logisim, the one I made just wouldn't work for some reason. Also, I like your post, I'm actually using the 191 as a stack pointer too.

    ReplyDelete