Decoder Unit

Read time: 19 minutes (4906 words)

With the fetch unit in hand, we need to explore the decoder unit next.

This part of the system is responsible for taking the single instruction provided by the fetch unit apart. We need ot validate the instruction to prevent the machine from attempting to execute a junk instruction, and basically get everything ready for the next stage in processing.

Some instructions will need support from the Arithmetic-Logic-Unit, which we will set up in our next part of the machine. Here, we need to determine what data will be needed by the ALU, and prepare those items for transfer to the next stage.

We will introduce an important memory element in this stage: the internal registers. Most all processors have a small number of very fast registers in something called a register memory unit. This memory is designed to work slightly differently from normal memory units. We allow two simultaneous reads from the unit in one operation. That speeds up many ALU instructions.

In the ATtiny85, there are 32 8-bit registers available in this register memory unit. Part of the work in decoding an instruction involves figuring out which of those 32 registers we want ot deliver some value from. During later processing, we may need to update some register with a value as well.

Instruction Set Architecture

In the world of processor design, the needs of the final user of the machine drives the design. Processor companies spend a lot of time studying how programmers use their languages, and set up instructions that make things easier for compiler writers to support those needs. We will look at some of the simpler instructions in our chip to get this part of the design going.

The source for information on the instruction set for any processor is the “datasheet” for that chip. Here is the one we need for our chip:

Dig down to page 202 in the PDF file and you will find a table of instructions supported by this chip. The first one listed looks like this:

Mnemonic Operands Description Operation Flags Clocks
ADD Rd, Rr Add two Registers Rd <- Rd + Rr Z,C,N,V,H 1

Instruction Encoding

Deciding on a specific way to encode each instruction is a complex process. Basically, we want to pack as much information as possible into a tight pile of bits. In the end, the chip designers come up with a scheme that the hardware designers need to unscramble. For our simple ADD instruction, here is how they encoded things:

N1 N2 N3 N4
0000 11rd dddd rrrr

The five bits needed to specify which of the 32 registers are involved are split up and put in separate “nibbles” in this 16-bit instruction. Our job in decoding this involves getting things back where we need them.

Basic Decoder Unit

Let’s look at a schematic of a basic decoder unit that will handle this instruction:

The decoder is responsible for generating all signals needed by the rest of the stages in the system. It also updated the program counter based on how many bytes it decides the current instruction needs.

Register File

An important, and unique, chunk of high-speed memory is in this unit as well. All processors provide a set of “registers” where data can be kept while processing. Putting data in these registers speeds up processing, since this memory is very near the other processing components in the machine. Any data that needs to be pulled in from external memory will be very slow to access, sometimes resulting in a stalling of the four-step process while that memory gets the data ready. (Common factors can be as much as 10 times slower. We will see how to speed this up later in the course.)

The AVR provides 32 8-bit registers named R0..R31. The top six of these registers act like 16-bit registers, with this mapping:

  • X -> R26:R27
  • Y -> R28:r29
  • Z -> R30-R31

You will see references to these registers in some instructions.

Dual Port Memory

Register memory is designed in a special way. Since it is so common to need two values to feed the ALU in the next stage, the register memory is designed so you can do two reads simultaneously. Unfortunately, you can only do one write at a time, but that is fine, since we often take the result from the ALU and put it back in some register.

Ever seen a memory cell? Here is an image of one Intel builds:

../../_images/memory-cell.jpg

Hard t tell what is going on here, but a huge bunch of those transistors are sitting in this tiny chunk of electronics.

Decoder Logic

The heart of the decoder simply attacks those instruction bits, looking at the individual bits trying to decide which instruction it is currently examining. As you can see, extracting a set of bits that make up some signal is part of the process, and those bits may not be easy to access.

The real decoder can use electronics trickery to do this job. We can build a device that takes a set of bits in, and reroutes those bits any way we like to the output side of the component. Unfortunately, we will need to use C++ to figure all of this out.

Fortunately, C++ provides the bitset` data type that makes this pretty easy.

Well, easy, but tedious! We will examine this in detail next.