# Coding for Reuse Course - Module 2 Lesson 2 ALU Preliminary

In this lesson we will partition and develop a preliminary version of our arithmetic/logic unit for our microprocessor.

ALU Partitioning

Before we begin partitioning the ALU, let's examine what it does and where various pieces may fit. This exercise will require you to apply your knowledge of Boolean math, our earlier lessons and evolution, and general FPGA and CPLD knowledge.

1. We require an incrementer to increase the operand bit value of the selected source by one. THE INCREMENTER IS USED DURING THE EXECUTION OF EVERY INSTRUCTION. The reason for this statement is simple. The program counter is used to fetch instruction opcodes and progresses upward. The stack pointer register must also progress downward for every byte "pushed" and upward for every byte "popped".

The incrementer is used to convert one's complement values from the source mux into two's complement values. This conversion is only used during decrement, add, and subtract operations in the 8085 series processors.

The incrementer is also used selectively during the 'add with carry' and 'subtract with borrow' instructions. In an 'add with carry' instruction, the source is incremented by one if carry flag is set, using the distribution theorem. During a 'subtract with borrow' operation, the incrementer is used if the carry flag is reset, because in Boolean math the addition of a one's complement value will effectively subtract the source minus 1, and a two's complement value the source, compatible with distribution theorem.

Needless to say, but the incrementer is used to calculate the results of 'increment' and 'decrement' instructions.

2. The ALU must also must contain the following functional blocks in order to calculate a result:

1. A 16-bit adder. This adder is used to calculate the results of all instructions requiring add, subtract, compare and, as will be seen in later lessons, multiply and divide.

2. A logic unit. This unit is used during 8-bit logic operations to calculate the 'AND', 'OR', and 'XOR' function logical results.

3. A left/right, variable width shift unit. This unit is able to shift or rotate 8, 9, 16, or 17 bit operands left or right by one-bit position. It must also select between 8 and 16-bit source widths and whether or not to include the carry bit in the source, destination, or both.

4. A multi-cycle multiply block.

5. A multi-cycle divide block.

3. All of these various paths must then be re-combined into a unified result from the ALU.

4. Lastly the ALU must also calculate a new set of flags from the operation. These new flags reflect the current state of the flags, the inputs to certain ALU operations, the outputs from many ALU instructions, the instruction itself, or a combination of all of the former.

Preliminary ALU Architecture

We can see immediately from this diagram that the output mux should be moved and combined into the destination mux. Then separate outputs will be taken from the incrementer, adder, multiply unit, divide unit, shifter, and the logic unit and routed into an enhanced destination. The destination mux, itself, must be considerably modified to incorporate these changes. It must be capable of accepting and selecting these multiple outputs. For best practice, it should also feedback the initially selected destination results to the ALU before any crossover:

Modified ALU Architecture

Modified destination mux

Preliminary ALU

We don't have to design all the blocks of the ALU at once. For example; we could have enough infrastructure in place for more than 50% of the instructions if we just code the incrementer and incrementer logic. When we incorporate the adder and most of the flag logic, this figure becomes more like 78%. When we introduce the logic unit code, this infrastructure will support more than 98% of the instructions. Of course a 'black box' module will be needed for the shifter, multiply unit, and divide unit to provide a source for output signals and a sink for input signals.

Let us conduct a detailed analysis of how best to implement these four blocks before we begin coding.

Preliminary ALU Coding

Now let's modify the destination mux and code our preliminary ALU:

In order to prevent errors or extensive warnings when compiling different models, extensive use of conditional directives is used during flag logic instantiation, declaration and coding.

Exercise
1. Why do we split the adder into 4-bit chunks?

2. How did we modify the destination mux and why?

3. What does the increment logic do?

4. Why isn't the incrementer implemented as an adder?

5. Why don't we use UDP's for the incrementer and logic unit?

6. What functions are performed by the logic unit?

7. How do we prepare our un-coded units for compile and simulation?

8. Why do we partition the ALU?

9. When is the incrementer used?

10. How many 4-input logic cells does our logic unit use?