The half subtractor and the full subtractor are combinational logic circuits that are used to subtract two 1-bit numbers and three 1-bit numbers respectively. They both produce two outputs, Difference and Borrow.
The half subtractor does not account for any borrow that might take place in the subtraction. Hence, since it performs only half the operation, it is known as the half subtractor.
The full subtractor, in contrast, has three inputs, one of which is the borrow input. Since the full subtractor considers the borrow operation, it is known as a full subtractor.
In this post, we will take a look at implementing the VHDL code for full subtractor & half subtractor. First, we will explain the logic and then the syntax. For the full code, scroll down.
Since we will be coding the half subtractor and the full subtractor using the dataflow models, all we need is their logic equations. If you are having trouble recalling the logic circuits in this course, I would highly recommend you to brush up your knowledge of digital electronics and circuits here.
Contents
Half Subtractor
Logic diagram and logic equation of the half subtractor
From the above logic diagram, the logic equations for the half subtractor are as follows
Difference =
Borrow = A’B
Explanation of the VHDL code for half subtractor using the dataflow method
We always start writing a VHDL program by including the required libraries and using the necessary packages from the library using the use
clause.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;
Then we create an entity, where we define the input and output ports of the design. Here, we have two input bits (A, B) and two output bits(DIFF, Borrow). And don’t forget to end the entity as well.
entity half_sub is port( A, B : in std_logic; DIFF, Borrow : out std_logic); end entity;
Then we start writing architecture for the above entity. Inside the architecture, we define the functionality of our design.
architecture dataflow of half_sub is begin DIFF <= A xor B; Borrow <= (not A) and B; end architecture;
Also, remember to close the architecture using end
keyword.
VHDL Code for half subtractor using dataflow
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity half_sub is port( A, B : in std_logic; DIFF, Borrow : out std_logic); end entity; architecture dataflow of half_sub is begin DIFF <= A xor B; Borrow <= (not A) and B; end architecture;
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 half_sub_tb is end entity; architecture tb of half_sub_tb is component half_sub is port( A, B : in std_logic; DIFF, Borrow : out std_logic); end component; signal A, B, DIFF, Borrow : std_logic; begin uut: half_sub port map( A => A, B => B, DIFF => DIFF, Borrow => Borrow); 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
Simulation Waveforms
Full Subtractor
Logic diagram and logic equation of the full subtractor
From the above logic diagram, the logic equations for the full subtractor are as follows
Difference =
Borrow = A'(B+D) + BD
Explanation of the VHDL code for full subtractor using the dataflow method
We always start writing a VHDL program by including the required libraries and using the necessary packages from the library using the use
clause.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;
Then we create an entity, where we define the input and output ports of the design. Here, we have two input bits (A, B, C) and two output bits(DIFF, Borrow). All the input and output ports are of datatype std_logic
. And don’t forget to end the entity as well.
entity full_sub is port( A, B, C : in std_logic; DIFF, Borrow : out std_logic); end entity;
Then we start writing architecture for the above entity. Inside the architecture, we define the functionality of our design.
architecture dataflow of full_sub is begin DIFF <= (A xor B) xor C; Borrow <= ((not A) and (B or C)) or (B and C); end dataflow;
Also, remember to close the architecture using end
keyword.
VHDL Code for full subtractor using dataflow
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity full_sub is port( A, B, C : in std_logic; DIFF, Borrow : out std_logic); end entity; architecture dataflow of full_sub is begin DIFF <= (A xor B) xor C; Borrow <= ((not A) and (B or C)) or (B and C); 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 full_sub_tb is end entity; architecture tb of full_sub_tb is component full_sub is port( A, B, C : in std_logic; DIFF, Borrow : out std_logic); end component; signal A, B, C, DIFF, Borrow: std_logic; begin uut: full_sub port map( A => A, B => B, C => C, DIFF => DIFF, Borrow => Borrow); stim: process begin A <= '0'; B <= '0'; C <= '0'; wait for 20 ns; A <= '0'; B <= '0'; C <= '1'; wait for 20 ns; A <= '0'; B <= '1'; C <= '0'; wait for 20 ns; A <= '0'; B <= '1'; C <= '1'; wait for 20 ns; A <= '1'; B <= '0'; C <= '0'; wait for 20 ns; A <= '1'; B <= '0'; C <= '1'; wait for 20 ns; A <= '1'; B <= '1'; C <= '0'; wait for 20 ns; A <= '1'; B <= '1'; C <= '1'; wait for 20 ns; wait; end process; end tb;
RTL Schematic
Simulation Waveforms
Half Subtractor and Full Subtractor (together)
Explanation of the VHDL code for full subtractor & half subtractor using the dataflow method. How does the code work?
We can either code both the circuits using the same inputs, or we can use separate inputs for them. We will proceed with the option of the same inputs. Hence we will first declare standard (non-vector) inputs using STD_LOGIC
. We will, however, need separate outputs so as not to jumble up our results. This way, we can get outputs for both the circuits. Both the circuits have two outputs, Difference and Borrow. So to differentiate them and avoid confusion we have added a prefix letter to the output label. That means, “H_DIFFERENCE” and “H_BORROW” are the outputs of the half subtractor. And “F_DIFFERENCE” and “F_BORROW” are the outputs of the full subtractor.
Port ( A, B, C : in STD_LOGIC; H_DIFFERENCE, H_BORROW, F_DIFFERENCE, F_BORROW : out STD_LOGIC); end SUBTRACTOR_SOURCE;
Next, we will declare that the architecture we are using for this program is dataflow. And hence the single begin
statement will follow the architecture statement.
architecture dataflow of SUBTRACTOR_SOURCE is begin
In the next lines of code, We will simply use the respective logic equation to generate the outputs.
---half subtractor H_DIFFERENCE <= A xor B; H_BORROW <= (not A) and B; ---full subtractor F_DIFFERENCE <= A xor B xor C; F_BORROW <= ((not A) and (B or C)) or (B and C); end dataflow;
At the end of the program, the end dataflow command indicates that the architecture with the label ‘dataflow’ is complete.
VHDL code for full subtractor & half subtractor using dataflow method
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity SUBTRACTOR_SOURCE is Port ( A, B, C : in STD_LOGIC; H_DIFFERENCE, F_DIFFERENCE, H_BORROW, F_BORROW : out STD_LOGIC); end SUBTRACTOR_SOURCE; architecture dataflow of SUBTRACTOR_SOURCE is begin ---half subtractor H_DIFFERENCE <= A xor B; H_BORROW <= (not A) and B; ---full subtractor F_DIFFERENCE <= A xor B xor C; F_BORROW <= ((not A) and (B or C)) or (B and C); 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 SUBTRACTOR_SOURCE_TB is end entity; architecture tb of SUBTRACTOR_SOURCE_TB is component SUBTRACTOR_SOURCE is Port ( A, B, C : in STD_LOGIC; H_DIFFERENCE, H_BORROW, F_DIFFERENCE, F_BORROW : out STD_LOGIC); end component; signal A, B, C : STD_LOGIC; signal H_DIFFERENCE, H_BORROW, F_DIFFERENCE, F_BORROW : STD_LOGIC; begin uut: SUBTRACTOR_SOURCE port map( A => A, B => B, C => C, H_DIFFERENCE => H_DIFFERENCE, H_BORROW => H_BORROW, F_DIFFERENCE => F_DIFFERENCE, F_BORROW => F_BORROW); stim: process begin A <= '0'; B <= '0'; C <= '0'; wait for 20 ns; A <= '0'; B <= '0'; C <= '1'; wait for 20 ns; A <= '0'; B <= '1'; C <= '0'; wait for 20 ns; A <= '0'; B <= '1'; C <= '1'; wait for 20 ns; A <= '1'; B <= '0'; C <= '0'; wait for 20 ns; A <= '1'; B <= '0'; C <= '1'; wait for 20 ns; A <= '1'; B <= '1'; C <= '0'; wait for 20 ns; A <= '1'; B <= '1'; C <= '1'; wait for 20 ns; wait; end process; end tb;
RTL Schematic
Simulation Waveforms
As always, if you have any queries, we would love to address them. Just drop in a comment in the comments section below.