View Course Path

# VHDL code for half adder & full adder using dataflow method – full code & explanation

In this post, we will take a look at implementing the VHDL code for half adder & full adder using dataflow modeling architecture. First, we will take a look at the logic equations of the circuits and then the syntax for the VHDL code. We’ll also write the testbench in VHDL for the circuit and generate the RTL schematic. We will use the final simulation waveforms to verify our code.

Contents

### Logic equation and logic circuit of a half adder

A half adder is an arithmetic combinational circuit that takes in two binary digits and adds them. The half adder gives out two outputs, the SUM of the operation and the CARRY generated in the operation. Since this carry is not added to the final answer, the addition process is somewhat incomplete. Hence, it’s known as the half adder.

Below you will find the logic circuit and the corresponding logic equation of the half adder. This circuit is made using simple digital logic gates; the EX-OR and AND gates. We will use this equation to program a half adder circuit using VHDL. SUM = $A\oplus B$

CARRY = A.B

### Explanation of the VHDL code for half adder using its logic equation and the dataflow method

We always start the code by including needed libraries and importing the necessary packages from them using the `use` clause.

```library IEEE;
use IEEE.std_logic_1164.all;```

Then we define the entity, where we define the input and output ports of our design. Here we have two input bits and two output bits.

```entity H_adder is
port( a,b : IN std_logic;
sum,carry : OUT std_logic);

Then we write an architecture for the above entity. Inside the architecture, we define the functionality of our design.

```architecture dataflow of H_adder is
begin
sum <= a xor b;
carry <= a and b;

end dataflow;```

Never forget to end the architecture.

### VHDL Code for half-adder using dataflow via logic equation

```library IEEE;
use IEEE.std_logic_1164.all;

port(
a,b : IN std_logic;
sum,carry : OUT std_logic);

begin

sum <= a xor b;
carry <= a and b;

end dataflow;```

### Testbench

We will be using the testbench with a process type in this post. You can learn all about writing testbenches in VHDL in this guide.

```library IEEE;
use IEEE.std_logic_1164.all;

end entity;

port( a,b : IN std_logic;
sum,carry : OUT std_logic);
end component;

signal a,b,sum,carry: std_logic;

begin

a => a, b => b,
sum => sum,
carry => carry);

stim: process
begin

a <= '0';
b <= '0';
wait for 20 ns;

a <= '0';
b <= '1';
wait for 20 ns;

a <= '1';
b <= '0';
wait for 20 ns;

a <= '1';
b <= '1';
wait for 20 ns;

wait;

end process;

end tb;```

### RTL Schematic ### Logic equation and logic circuit of a full adder

A full adder, unlike the half adder, has a carry input. And thus, since it performs the full addition, it is known as a full adder. Accordingly, the full adder has three inputs and two outputs. The relation between the inputs and the outputs is described by the logic equations given below. We will use these equations for the VHDL program. SUM = $A\oplus B\oplus Y$

CARRY = Y(A+B) + AB

### Explanation of the VHDL code for full adder using its truth table and the dataflow method. How does the code work?

Next, we will use another feature given to us by the dataflow architecture. We will use a circuits truth table to design it using VHDL.

### Truth table for a full adder

 A B Y SUM CARRY 0 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 1 0 1 0 1 1 1 0 0 1 1 1 1 1 1

The entity-architecture declaration for the VHDL code of a full adder will have only one difference. We will declare the entities as vectors.

But why? Why not declare each input/output separately?

The reason is that since we are using the truth table of the full adder, we have three inputs and two outputs. We can easily assign two vectors, one to inputs and one to outputs. The input vector will have three slots. And the output vectors will have two slots. The first one will be the SUM, and the second one will be the CARRY. And generally speaking, when we are dealing with multiple inputs of the same kind, using vectors saves us a lot of complexity. Entity name: `FULLADDER_VIATRUTHTABLE`.

```entity FULLADDER_VIATRUTHTABLE is

Port ( A : in  STD_LOGIC_VECTOR (2 downto 0);

O : out  STD_LOGIC_VECTOR (1 downto 0));

begin```

Dataflow architecture has when-else statements that are very handy when coding with truth tables. We saw the syntax for the when-else statements in our post on the dataflow architecture. So using that syntax, we will assign the inputs to the output vector as follows:

```O <= "00" when A = "000"

else "10" when A = "001"

else "10" when A = "010"

else "10" when A = "100"

else "11" when A = "111"

else "01";
```

### VHDL code for full adder using dataflow method – via truth table

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

Port ( A : in  STD_LOGIC_VECTOR (2 downto 0);
O : out  STD_LOGIC_VECTOR (1 downto 0));

begin

O       <= "00" when A = "000"
else "10" when A = "001"
else "10" when A = "010"
else "10" when A = "100"
else "11" when A = "111"
else "01";

end dataflow;```

### Testbench

We will be using the testbench with a process type in this post. You can learn all about writing testbenches in VHDL in this guide.

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

end entity;

Port ( A : in  STD_LOGIC_VECTOR (2 downto 0);
O : out  STD_LOGIC_VECTOR (1 downto 0));
end component;

signal A : STD_LOGIC_VECTOR (2 downto 0);
signal O : STD_LOGIC_VECTOR (1 downto 0);

begin

A => A, O => O);

stim: process
begin

A <= "000";
wait for 20 ns;

A <= "001";
wait for 20 ns;

A <= "010";
wait for 20 ns;

A <= "011";
wait for 20 ns;

A <= "100";
wait for 20 ns;

A <= "101";
wait for 20 ns;

A <= "110";
wait for 20 ns;

A <= "111";
wait for 20 ns;
wait;

end process;

end tb;```

### Explanation of the VHDL code for half adder & full adder using dataflow method. How does the code work?

In the dataflow architecture approach, we can either use the logic equations of a circuit or its truth table to write the code using VHDL. We will be coding the circuits of the half adder and the full adder using the former option first. We will also write the VHDL code for the full adder with the dataflow architecture using its truth tables later in this post.

We will begin writing the code by first declaring the entity-architecture pair. As we have earlier in this VHDL course, the entity-architecture pair completes two main objectives of a VHDL program.

• The entity declares all the input, output, or bi-directional ports and assigns their datatype as scalar or vector. Basically, the entity describes the external part of a logic circuit.
• The architecture defines the relations between these entity items. And there are three types (Dataflow, Behavioral, and Structural).

The syntax for the entity-architecture pair declaration for our program is as follows. The entity name that we have chosen is `mix_adder_ff`.

```entity mix_adder_ff is
port(
a,b,cin : IN std_logic;
HA_sum, HA_carry, FA_sum, FA_carry : OUT std_logic);

begin

```

Once we have the `begin` statement, we can use the powers given to us by the dataflow architecture and start assigning the ports using logic equations. To do this, we use the assignment operator, as shown below. For the half adder:

```HA_sum <= a xor b;
HA_carry <= a and b;

FA_sum <= (a xor b) xor cin;
FA_carry <= (a and b) or (b and cin) or (cin and a);

end dataflow;```

Always remember to end the architecture.

### VHDL code for half adder & full adder using dataflow method

```library IEEE;
use IEEE.std_logic_1164.all;

port(
a,b,cin : IN std_logic;
HA_sum, HA_carry, FA_sum, FA_carry : OUT std_logic);

begin

HA_sum <= a xor b;
HA_carry <= a and b;

FA_sum <= (a xor b) xor cin;
FA_carry <= (a and b) or (b and cin) or (cin and a);

end dataflow;```

### Testbench

We will be using the testbench with a process type in this post. You can learn all about writing testbenches in VHDL in this guide.

```library IEEE;
use IEEE.std_logic_1164.all;

end entity;

port(a,b,cin : IN std_logic;
HA_sum, HA_carry, FA_sum, FA_carry : OUT std_logic);
end component;

signal a, b, cin, HA_sum, HA_carry, FA_sum, FA_carry : std_logic;

begin

a => a, b => b,
cin => cin,
HA_sum => HA_sum,
HA_carry => HA_carry,
FA_sum => FA_sum,
FA_carry => FA_carry);

stim: process
begin

a <= '0';
b <= '0';
cin <= '0';
wait for 10 ns;

a <= '0';
b <= '0';
cin <= '1';
wait for 10 ns;

a <= '0';
b <= '1';
cin <= '0';
wait for 10 ns;

a <= '0';
b <= '1';
cin <= '1';
wait for 10 ns;

a <= '1';
b <= '0';
cin <= '0';
wait for 10 ns;

a <= '1';
b <= '0';
cin <= '1';
wait for 10 ns;

a <= '1';
b <= '1';
cin <= '0';
wait for 10 ns;

a <= '1';
b <= '1';
cin <= '1';
wait for 10 ns;
wait;

end process;

end tb;```