## Monday, November 21, 2011

### Designing a simple ALU with multiplexers

What is an ALU? It is short for Arithmetic Logic Unit and it represents a circuit found in processors that performs different arithmetic and logic functions on 2 or maybe more operands. The basic functionality of an ALU is: it receives 2 operands on a number of bits and a select_operation signal that specifies the operation to perform and then outputs the result to another circuit like a register.
The ALU we will design is very simple and you won't find such a circuit in any processor out there but it's a good circuit to see the application of multiplexers.
Design data:
- two 3 bit operands
- a 3 bit result
- a 2 bit select_operation input (so we will be able to have 2^2 operations)
- 4 operations to perform (and, or, sum, xor)

Note: the sum function is not a complete add operation because the operands and th result are 3 bits in length although the result should be of 4 bits ("111" + "001"= "1000"). Real adders will be covered in more advanced tutorials.

The black box of the circuit:
The entity should look like so:

Another important thing to note is that in order to use the + operation you need the numeric library declared:
use IEEE.numeric_std.ALL;

Now let's talk about how the ALU will work:
op1 and op2 are the 2 input operands. These will go through the 4 operations specified and the results will be put in 4 signals. Those signals represent the data inputs of the multiplexer and operation is the selection signal. The output of the mux is the result. So if we have op1="1010", op2="0010" and operation="10" witch will be addition then the result will be result="1100".

Let's see the internals of the ALU:

This is the basic structure of an ALU. The circuit can be described using data flow or structural description. Because the operations we are using are simple it's better to use data flow but when designing advanced ALUs with complex operations it's better to describe it using structural description.

The code is:

Perhaps an explanation is needed for sum:
unsigned(op1) and unsigned(op2) transforms the std_logic_vector type into unsigned type in order to do the + operation (that's why we imported the numeric library). After the operation is done we need it in std_logic_vector form so we use std_logic_vector(unsigned(op1)+unsigned(op2)). It is like using a signal addition of unsigned type to store the addition result and then converting it like so:
signal addition:unsigned(2 downto 0);