View Course Path

VHDL code for full adder using behavioral method – full code & explanation

The full adder is one of the most important combinational logic circuits in digital electronics. It adds three 1-bit numbers; the third bit is the carry bit. If a carry generates on the addition of the first two bits, the full adder considers it too.

In this post, we will take a look at implementing the VHDL code for full adder using the behavioral method. First, we will explain the logic and then the syntax before writing the testbench and generating the RTL schematic and simulation waveforms. For the complete code, scroll down.

Explanation of the VHDL code for full adder using behavioral method. How does the code work?

Since we are going to code this circuit using the behavioral modeling method, we are going to need to understand the truth table. In the behavioral model of VHDL coding, we define the behavior or outputs of the circuit in terms of their inputs. The behavior is described on a case by case basis. Let’s first understand the logic circuit of the full adder.

Logic diagram of the full adder

Full Adder

 

We don’t care about the logic gates here. In the behavioral model, we will concern ourselves only with the relation between the inputs and the outputs. As you can see, the full adder has three inputs and two outputs. The two outputs are the SUM and CARRY outputs.

We begin the coding process by naming the entity we will be coding. Let’s call this entity as FULLADDER_BEHAVIORAL_SOURCE.

Next, we will define the ports of the entity. There are three input ports. Let’s define all of them using a single vector A of size three. Since these are vectors, they are STD_LOGIC_VECTOR input ports. If we would have taken distinct ports for all of them, then the syntax would have been STD_LOGIC.

We also need two output ports for the SUM and CARRY outputs. We will define them as vectors too.

Hence the syntax and the VHDL code for declaring the entity and the ports will look like this:

entity FULLADDER_BEHAVIORAL_SOURCE is

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

end FULLADDER_BEHAVIORAL_SOURCE;

A question that might arise in your mind is, why did we declare these ports as vectors. Why not declare them distinctly?

The reason is that since we are using the behavioral model for programming, we will be dealing with the truth table of the full adder. And generally speaking, when we are dealing with multiple inputs of the same kind, using vectors saves us a lot of complexity. We will show you the exact locations where complexities could have arisen if we had used distinct input ports.

Let’s take a look at the full adder circuit’s truth table next. Our entire code will depend on it.

Truth table of 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

After declaring the entity and the I/O ports, the next step is to declare the architecture of the VHDL program that we will be using to code the entity. Therefore, since we are using the behavioral model to write the VHDL code for the full adder, this will be the next statement:

architecture Behavioral of FULLADDER_BEHAVIORAL_SOURCE is

Next, since we have now declared that we are using the behavioral model, we need to keep two key syntax points in mind.

  • the behavioral model needs two begin statements after the architecture declaration.
  • the behavioral model has a process statement between the two begin statements.
begin
process (A)
begin

We will first write the code for the SUM column of the truth table. Using if-else statements, we assign the cases where the output is 1 (One/High) to the if statement and assign the output to else for all other remaining cases. Notice that we use OR logic in the condition of the if statement. And not AND because the output can be one in any singular of these cases at a given instant.

---for SUM

if (A = "001" or A = "010" or A = "100" or A = "111") then
O(1) <= '1';
else
O(1) < = '0';
end if;

---single inverted commas used for assigning to one bit and double inverted commas are used for vector numbers/more than one bit

Similarly, for the CARRY output:

if (A = "011" or A = "101" or A = "110" or A = "111") then
O(0) <= '1';
else
O(0) <= '0';

In the end, we close the if statement, the process statement, and the architecture.

end if;
end process;
end Behavioral;

VHDL code for full adder using behavioral method

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

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

architecture Behavioral of FULLADDER_BEHAVIORAL_SOURCE is

begin
process (A)
begin

---for SUM
if (A = "001" or A = "010" or A = "100" or A = "111") then
O(1) <= '1';
---single inverted commas used for assigning to one bit
else
O(1) < = '0';
end if;

---for CARRY
if (A = "011" or A = "101" or A = "110" or A = "111") then
O(0) <= '1';
else
O(0) <= '0';
end if;

end process;
end Behavioral;

Why didn’t we use discreet input ports?

As you can see in the VHDL code for the full adder above, we decided to use vector inputs. If we had used discrete input ports, we couldn’t have assigned the three input bits to A in the if statement’s condition as we did above. We would have had to assign single bits along with logical AND symbol for bit operation (&). A ="111" would have been written as if ((A='1' & B='1' & C='1') or ....). Quite obviously, that would have been a very lengthy conditional statement.

In the post where we write the VHDL code for the full subtractor, we will use vector outputs along with vector inputs and see how that changes the programming approach.

Testbench

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

entity FullAdder_tb is
end entity;

architecture tb of FullAdder_tb is
component FULLADDER_BEHAVIORAL_SOURCE 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_BEHAVIORAL_SOURCE 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;

You can learn how to write a VHDL testbench in detail here.

RTL Schematic

Full_Adder_Behavioral-RTL

Simulation Waveforms

Full_Adder_Behavioral-Waveform

Edit: Post updated with the testbench, RTL Schematic, and Simulation Waveform by Deepak Joshi.

2 thoughts on “VHDL code for full adder using behavioral method – full code & explanation

  1. Dear Sir

    Can you please email behavioural full adder code. I am stuck with my assignment. It would be greatly appreciated if you could help.

Leave a Reply

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