You are on page 1of 6

Introduction

An arithmetic and logic unit (ALU) is a combinational circuit that performs various
Boolean and arithmetic operations on a pair of n-bit operands. In this homework, you
will create a 32-bit ALU that can perform the operations of most MIPS arithmetic and
logical instructions.
Design
We will start by constructing a 1-bit ALU and then create the desired 32-bit ALU by
connecting 32 1-bit ALUs. As Figure 1 shows, a 1-bit ALU can be constructed using a
full-adder, two multiplexors and a few gates. The two 1-bit data inputs are named a and b,
and the 1-bit output is named Result. This ALU can perform addition, subtraction, AND,
OR on the two data inputs according to an operation code supplied to the ALU. The twobit control input named Operation partially specifies the operation code. Figure 2
specifies the functionality of this ALU.

Figure 1: A 1-bit ALU.


Operation

Binvert

CarryIn

Result

Function

00
01
10
10
11

0
0
0
1
1

X
X
0
1
1

a AND b
a OR b
a+b
a-b
Less

Logical AND
Logical OR
Addition
Subtraction
Sets on less than

Figure 2: The functionality of the ALU.


In Figure 2, X means don't care, + means arithmetic addition, and - means arithmetic
subtraction. Note that the four-input multiplexor on the right in Figure 1 has its 2-bit
select input connected to the Operation line. The output of this multiplexer is the 1-bit
output of the ALU named Result. Recall that subtracting b from a is the same as adding
the 2's complement of b to a. The two-input multiplexor on the left selects b or its
inverted value, depending on the 1-bit select input named Binvert. This input is set to 0
for addition, AND, and OR, and set to 1 for subtraction. The CarryIn input is set to 0 for
addition and set to 1 for subtraction.
The design of the ALU is incomplete. You will extend the design in a later lab so that
more instructions can be performed by the ALU. For example, the input Less will be
used to support the MIPS set on less than instruction (slt).

VHDL code
We start by specifying the entity declaration for the 1-bit ALU:
library ieee;
use ieee.std_logic_1164.all;
entity ALU1 is
port (a, b, Less, CarryIn, Binvert: in std_logic;
Operation: in std_logic_vector (1 downto 0);
Result, CarryOut: out std_logic);
end ALU1;
Figure 3: Entity declaration for 1-bit ALU.
The input port Operation is declared to be of the predefined type std_logic_vector.
This type provides an easy way to declare a signal to be a group or string of conceptually
related bits, more commonly called a bit vector. The declaration defines Operation as a
2-bit std_logic_vector signal with a descending index range 1 downto 0. Individual
bits of Operation can then be accessed by the indexed named notations, Operation(1)
and Operation(0), with the highest index used for the most-significant bit.
We can define the architecture for the 1-bit ALU as the interconnection of the building

blocks shown in Figure 1. In the previous homework, you already wrote the code for a
full-adder entity named full_adder. (You may need to modify the full_adder code to use
the gate library given in this homework, but lets worry about this after we finish the
whole thing.) We will use this full_adder entity as a component within the architecture
of ALU1. The other components needed are a two-input multiplexer and a four-input
multiplexer. One way to model a multiplexer at the behavioral level is with a VHDL
statement known as selected signal assignment. A selected signal assignment allows a
signal to be assigned one of several values, based on a selection criteria. (This statement
operates very much like a case statement in conventional programming languages.)
Figure 4 shows how it can be used to describe a 4-to-1 multiplexer. The entity is called
mux4to1. The data inputs to the mux4to1 entity are the 1-bit signals named I0, I1, I2
and I3, and the select inputs are the two-bit signal named S. The output is named f. The
selected signal assignment begins with the keyword with and specifies that S is to be
used for the selection criterion. The four when clauses set f to the value of one of the
inputs I0, ..., I3, depending on the value of S. Note that VHDL requires that multibit
values such as "01" be enclosed in double quotes and bit values such as '0' and '1' be
enclosed in single quotes.
library ieee;
use ieee.std_logic_1164.all;
entity mux4to1 is
port (I0, I1, I2, I3: in std_logic;
S: in std_logic_vector (1 downto 0);
f: out std_logic);
end mux4to1;
architecture behavioral of mux4to1 is
begin
with S select
f <= I0 when "00",
I1 when "01",
I2 when "10",
I3 when others;
end behavioral;
Figure 4: VHDL code for a 4-to-1 multiplexer.
Once we have completed the 1-bit ALU, the full 32-bit ALU can be constructed from
32 1-bit ALUs as shown in Figure 5.

Figure 5: A 32-bit ALU.


To write the VHDL code for the 32-bit ALU, we first declare the 32-bit ALU as an
entity. Since the data inputs and the result output are 32 bits wide, we declare them as
std_logic_vectors, which are dimensioned 31 downto 0.
library ieee;
use ieee.std_logic_1164.all;

entity ALU32 is
port (a, b: in std_logic_vector (31 downto 0);
CarryIn, Binvert: in std_logic;
Operation: in std_logic_vector (1 downto 0);
Result: out std_logic_vector (31 downto 0);
CarryOut: out std_logic);
end ALU32;
Figure 6: Entity declaration for 32-bit ALU.
One approach to specifying the architecture for the 32-bit ALU is to include a component
declaration for the ALU1 entity and instantiate 32 copies of the ALU1 subcircuit. One
would expect that it could be written in a more compact form using a loop. VHDL
provides a feature called the for generate statement for describing regularly structured
hierarchical code. Fig. 7 shows the architecture for the ALU32 entity written using a for
generate statement.
architecture structural of ALU32 is
component ALU1 is
port (a, b, Less, CarryIn, Binvert: in std_logic;
Operation: in std_logic_vector (1 downto 0);
Result, CarryOut: out std_logic);
end component;
signal c: std_logic_vector (30 downto 0);
signal Less: std_logic;
begin
Less <= '0';
A1: ALU1 port map (a(0), b(0), Less, CarryIn, Binvert, Operation, Result(0),
c(0));
G1: for i in 1 to 30 generate
ALUs: ALU1 port map (
a(i), b(i), Less, c(i - 1), Binvert, Operation, Result(i), c(i));
end generate;
A32: ALU1 port map (a(31), b(31), Less, c(30), Binvert, Operation,
Result(31), CarryOut);
end structural;
Figure 7: Architecture for the 32-bit ALU .

What you need to do


1. create a file using the name ALU32.vhd. All the entities and architectures you
write will be in this one single file.
2. For component 4-to-1 multiplexer, you can type (or paste) the code in Figure 4.
3. Write VHDL code for a 2-to-1 multiplexer, which will be very similar to 4-to-1
multiplexer.
4. For component 1-bit ALU, type (or paste) the entity declaration for the 1-bit ALU
entity given in Figure 3. Write the architecture code for this entity. Remember that
you need to include three components (1-bit full_adder, 4-to-1 multiplexer, 2-to-1
multiplexer) and some gates in this architecture.
5. The entity and architecture for ALU32 are given above. You can just type (or
paste) the code in Figures 6 and 7.

Useful Tips

As soon as you finish coding the entity/architecture for one small component,
compile the file. Do not finish coding all at once, and try to compile the big file.
Similarly, you need to simulate/debug your vhdl file one step a time. Say, you can
debug after you finish coding one-bit full-adder, one-bit ALU, and 32-bit ALU
respectively.
How to debug your VHDL program?
1. Write the VHDL code first
2. Calculate when the outputs will settle based on your design.
3. Change your inputs (note that your inputs cannot change faster than the
time you calculated from step 2), and observe the waveform of the
outputs. Then verify your outputs from the simulation by comparing them
with the results calculated by hand.

You might also like