More topics in VLSI and VHDL course

# VHDL code for ALU (1-bit) using structural method – full code and explanation

An ALU or an Arithmetic Logic Unit is the part of any microprocessor that does the arithmetic and logical operations. Some examples of arithmetic operations are addition, subtraction, multiplication and so on. And some examples of logical operations are AND, NOT, NOR, and XOR operations. We’ll start off coding an ALU using VHDL in a series of progressions. This post is important because here we breakdown every single detail of the coding process. You can expand in on this to code virtually any type of ALU. In this post, we will be coding a simple 1-bit ALU that handles three basic functions. Addition, subtraction, and multiplication. We are going to achieve this by using a half -adder, a half-subtractor and a multiplier. For the full code, scroll down.

Contents

## Explanation of the Arithmetic Logic Circuit (ALU) and its structure

Let’s start with writing the VHDL code for ALU using the structural architecture. To re-iterate for the sake of clarity, we will be coding a 1-bit ALU. However, for the sake of progression, we will code only the arithmetic functionality in this post. In the upcoming posts, we will code the logical functionality. And by the end of this course, we will code a full-fledged ALU.

First, we will understand the functionality of an Arithmetic Logic Unit and then design a structure for it. We will then take a look at the syntax for the ALU’s VHDL programming. Check out the structure for our ALU below. Take a look at the structure above. We have:

1. Two 4:1 multiplexers. Giving a total of two final outputs. These two share two select lines SEL1 and SEL2. The first multiplexer has one free input that we attach to a GND component. The second multiplexer has two free inputs that too are attached to the GND component. We will use these two slots to expand the functionality of the ALU later on.
2. a half adder with two inputs and two outputs. Sum and Carry. The sum output is given to the first multiplexer. The carry output is given to the second multiplexer.
3. A half subtractor with two inputs and two outputs. Difference and Borrow. The difference output is given to the first multiplexer. The borrow, to the second multiplexer.
4. A multiplier with its output given to the first multiplexer.

#### Truth table for the ALU

Here are the possible values for SEL1 and SEL2 and the operations that will be performed based on them. This is for your understanding. Since we aren’t using the behavioural modelling style, we won’t be needing the truth table/the behavior of the multiplexers to define the working of the circuit.

 SEL 2 SEL 1 Output of MUX 1 Output of MUX 2 0 0 SUM CARRY 0 1 DIFFERENCE BORROW 1 0 PRODUCT GND 1 1 GND GND

Now that we have understood the working of the structure of the circuit, let’s finally get down to coding it.

## Explanation of the VHDL code for a 1-bit ALU using the structural method. How does the code work?

As we have seen in the post on structural VHDL for full-adder, we have to code in the individual components of the main circuit before we can code the main circuit using structural modeling. Here, the individual components include the half adder, the half subtractor, the multiplier, and the multiplexer. Additionally, recall that we can use any modeling style to code the individual components. So let’s code them first. You can see that each component’s code is the entire code for that component. By that, we mean that even the header files are included for each individual component.

#### VHDL code for the Half-adder (Component U1)

We code in the component U1 using basic dataflow style of architecture modeling. The logic equations of the half adder and its circuit can be found here.

```library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity HA is

Port ( HAA, HAB : in STD_LOGIC;

SUM, CARRY : out STD_LOGIC);

end HA;

architecture dataflow of HA is

begin

SUM <= HAA XOR HAB;

CARRY <= HAA AND HAB;

end dataflow;
```

#### VHDL code for the half subtractor (Component U2)

The VHDL code for the component U2 is also written using the dataflow modeling style. The half subtractors logic equation and working are explained here.

```library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity HS is

Port ( HSA, HSB : in STD_LOGIC;

DIFFERENCE, BORROW : out STD_LOGIC);

end HS;

architecture dataflow of HS is

begin

DIFFERENCE <= HSA XOR HSB;

BORROW <= (not HSA) AND HSB;

end dataflow;
```

#### VHDL code for the multiplier (component U3)

The VHDL code for component U3 is written using the dataflow style too. The multiplier’s concept and logic are explained here.

```library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity multiplier is

Port ( MA, MB : in STD_LOGIC;

PRODUCT : out STD_LOGIC);

end multiplier;

architecture dataflow of multiplier is

begin

PRODUCT <= MA AND MB;

end dataflow;
```

#### VHDL code for the multiplexer (Components U4 and U5)

The fourth and fifth components are multiplexers. We have previously seen the mux vhdl for dataflow and mux vhdl for behavioral. Here, we will use the dataflow style of modeling to write their VHDL code. The logic circuit and logic equations for multiplexers can be found here.

```library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity MUX is

Port ( A1,A2,A3,A4 : in STD_LOGIC;

S : in STD_LOGIC_VECTOR (1 downto 0);

X : out STD_LOGIC);

end mux;

architecture dataflow of MUX is

begin

with S select

X <=       A1 when "00",

A2 when "01",

A3 when "10",

A4 when others;

end dataflow;
```

#### VHDL code for the GND component (U0)

The GND component (U0) is assigned to the STD_LOGIC ‘U’ which stands for Uninitialized. Here, it means, that we are yet to initialize the signal.

```library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ground is

Port ( N : inout STD_LOGIC);

end ground;

architecture dataflow of ground is

begin

N <= 'U';

end dataflow;

```

Now that all the components are initialized and defined, we can start with the structural modeling of the 1-bit ALU. We start off by declaring the entity. Here we mention all the inputs and outputs of the overall ALU circuit. This means the two inputs, the two select lines, and the two outputs.

```entity ALU is

Port ( A,B,SEL1,SEL2 : in  STD_LOGIC;

ALU1,ALU2 : out  STD_LOGIC);

end ALU;
```

Next up is the architecture statement.

```architecture Structural of ALU is
```

In structural modeling, between the architecture statement and the begin statement, there are a couple of things we need to do. So recall the individual components that we declared above. Those need to be CONNECTED to the main program. How do we connect the individual components to the main program in the structural modeling architecture in VHDL? We do that by using a block known as Component Declaration. This is extremely similar in syntax to an entity declaration. The only difference is that we replace the term ‘entity’ with ‘component’. Watch.

```component HA is

Port ( HAA, HAB : in STD_LOGIC;

SUM, CARRY : out STD_LOGIC);

end component;

component HS is

Port ( HSA, HSB : in STD_LOGIC;

DIFFERENCE, BORROW : out STD_LOGIC);

end component;

component multiplier is

Port ( MA, MB : in STD_LOGIC;

PRODUCT : out STD_LOGIC);

end component;

component MUX is

Port ( A1,A2,A3,A4 : in STD_LOGIC;

S : in STD_LOGIC_VECTOR (1 downto 0);

X : out STD_LOGIC);

end component;

component ground is

Port ( N : inout STD_LOGIC);

end component;
```

Last but not least, we need to declare all the signals that are involved in this operation. The two inputs, the outputs of the arithmetic digital circuits that are fed as inputs to the multiplexers, and the final outputs.

```signal S0,S1,S2,S3,S4,S5: STD_LOGIC;
```

and now we can

```begin
```

The actual part of coding in structural is very straightforward. All you need to do is list each component (U0 to U5) out. And then use PORT MAP to assign the components inputs to the signals that we declared. That’s it. You’re good to go. Remember to end the architecture. You should know by now what that is we hope! (Hint: It’s got the word end in it).

```U0: ground PORT MAP(N=>S5);

U1: HA PORT MAP(HAA=>A,HAB=>B,SUM=>S0,CARRY=>S3);

U2: HS PORT MAP(HSA=>A,HSB=>B,DIFFERENCE=>S1,BORROW=>S4);

U3: multiplier PORT MAP(MA=>A,MB=>B,PRODUCT=>S2);

U4: MUX PORT MAP(A1=>S0,A2=>S1,A3=>S2,A4=>S5,X=>ALU1,S(0)=>SEL1,S(1)=>SEL2);

U5: MUX PORT MAP(A1=>S3,A2=>S4,A3=>S5,A4=>S5,X=>ALU2,S(0)=>SEL1,S(1)=>SEL2);
```

## Full VHDL code for an Arithmetic Logic Unit (ALU) using the structural modeling method

```library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity HA is

Port ( HAA, HAB : in STD_LOGIC;

SUM, CARRY : out STD_LOGIC);

end HA;

architecture dataflow of HA is

begin

SUM <= HAA XOR HAB;

CARRY <= HAA AND HAB;

end dataflow;

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity HS is

Port ( HSA, HSB : in STD_LOGIC;

DIFFERENCE, BORROW : out STD_LOGIC);

end HS;

architecture dataflow of HS is

begin

DIFFERENCE <= HSA XOR HSB;

BORROW <= (not HSA) AND HSB;

end dataflow;

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity multiplier is

Port ( MA, MB : in STD_LOGIC;

PRODUCT : out STD_LOGIC);

end multiplier;

architecture dataflow of multiplier is

begin

PRODUCT <= MA AND MB;

end dataflow;

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity MUX is

Port ( A1,A2,A3,A4 : in STD_LOGIC;

S : in STD_LOGIC_VECTOR (1 downto 0);

X : out STD_LOGIC);

end mux;

architecture dataflow of MUX is

begin

with S select

X <=       A1 when "00",

A2 when "01",

A3 when "10",

A4 when others;

end dataflow;

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ground is

Port ( N : inout STD_LOGIC);

end ground;

architecture dataflow of ground is

begin

N <= 'U';

end dataflow;

```
```library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ALU is

Port ( A,B,SEL1,SEL2 : in  STD_LOGIC;

ALU1,ALU2 : out  STD_LOGIC);

end ALU;

architecture Structural of ALU is

component HA is

Port ( HAA, HAB : in STD_LOGIC;

SUM, CARRY : out STD_LOGIC);

end component;

component HS is

Port ( HSA, HSB : in STD_LOGIC;

DIFFERENCE, BORROW : out STD_LOGIC);

end component;

component multiplier is

Port ( MA, MB : in STD_LOGIC;

PRODUCT : out STD_LOGIC);

end component;

component MUX is

Port ( A1,A2,A3,A4 : in STD_LOGIC;

S : in STD_LOGIC_VECTOR (1 downto 0);

X : out STD_LOGIC);

end component;

component ground is

Port ( N : inout STD_LOGIC);

end component;

signal S0,S1,S2,S3,S4,S5: STD_LOGIC;

begin

U0: ground PORT MAP(N=>S5);

U1: HA PORT MAP(HAA=>A,HAB=>B,SUM=>S0,CARRY=>S3);

U2: HS PORT MAP(HSA=>A,HSB=>B,DIFFERENCE=>S1,BORROW=>S4);

U3: multiplier PORT MAP(MA=>A,MB=>B,PRODUCT=>S2);

U4: MUX PORT MAP(A1=>S0,A2=>S1,A3=>S2,A4=>S5,X=>ALU1,S(0)=>SEL1,S(1)=>SEL2);

U5: MUX PORT MAP(A1=>S3,A2=>S4,A3=>S5,A4=>S5,X=>ALU2,S(0)=>SEL1,S(1)=>SEL2);

end Structural;
```

1. hussin khoramdell says: