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.

Half-Adder

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.

Half Adder

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); 
end H_adder;

 

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;

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

architecture dataflow of H_adder is
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;

entity half_adder_tb is
end entity;

architecture tb of half_adder_tb is
component H_adder is
port( a,b : IN std_logic;
sum,carry : OUT std_logic);
end component;

signal a,b,sum,carry: std_logic;

begin

uut: H_adder port map(
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

Half adder-RTL

Simulation Waveforms

Half adder-waveform

Full-Adder

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.

Full Adder

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)); 

end FULLADDER_VIATRUTHTABLE; 

architecture dataflow of FULLADDER_VIATRUTHTABLE is

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;

entity FULLADDER_VIATRUTHTABLE is
    Port ( A : in  STD_LOGIC_VECTOR (2 downto 0);
           O : out  STD_LOGIC_VECTOR (1 downto 0));
end FULLADDER_VIATRUTHTABLE;

architecture dataflow of FULLADDER_VIATRUTHTABLE is

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;

entity FULLADDER_VIATRUTHTABLE_TB is
end entity;

architecture tb of FULLADDER_VIATRUTHTABLE_TB is
component FULLADDER_VIATRUTHTABLE is     
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

uut: FULLADDER_VIATRUTHTABLE port map(
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;

RTL Schematic

Full adder using TT-RTL

Simulation Waveforms

Full adder using TT-waveform

Half-adder and Full-adder (together)

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);
end mix_adder_ff;

architecture dataflow of mix_adder_ff is
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;

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

architecture dataflow of mix_adder_ff is
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;

entity mix_adder_tb is
end entity;

architecture tb of mix_adder_tb is
component mix_adder_ff is
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

uut: mix_adder_ff port map(
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;

RTL Schematic

Half and full adder(together)-RTL

Simulation Waveform

Half and full adder(together)-waveform

As always, if you have any queries, we would love to address them. Just drop in a comment in the comments section below.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.