After reading this article, you’d be able to:
- Understand the Full subtractor,
- Explain Dataflow modeling in Verilog HDL,
- Write Verilog HDL code for full subtractor, and
- Simulate the hardware description language code to verify the output.
A full subtractor is a combinational circuit that performs the subtraction of three bits. It consists of three inputs and two outputs.
Consider that we want to subtract three 1-bit numbers. The numbers are X, Y and Z then a difference bit (D) and a borrow bit (B) will get generated.
For example, if the numbers are 1, 1, and 0 then, the difference bit and the borrow bit will be both 0. If we calculate all such combinations of these three bits, then we would end up forming the following kind of a table known as the truth table for full subtractor.
Now that we have got the truth table, we can form the boolean equations using K-map or simple minimization. We will get that:
- D = (X’Y’Z + X’YZ’ + XY’Z’ + XYZ) = X ⊕ Y ⊕ Z
- B = (X’Y’Z + X’YZ’ + X’YZ + XYZ) = X'(Y ⊕ Z) + YZ
Following the equations, we can design the circuit diagram of the full subtractor as follows.
Verilog Code for Full Subtractor using Dataflow Modeling
First of all, we declare the module. Remember that a module is a basic building block in Verilog. To declare the module, we have a keyword
module then we write the identifier or the name of the module in this way:
Always remember to put a semicolon at the end of a statement in Verilog. When you declare a module, don’t forget to end the module by writing:
We will now write our complete code in this block for full subtractor.
Next, we mention the input and output ports in the port declaration. By checking the input and output from the circuit shown above, we can easily write-
module Full_Subtractor_3(output D, B, input X, Y, Z);
As we are using dataflow modeling, we will use assignment statements to design. Hence, we write:
assign D = X^Y^Z; assign B = ~X & (Y^Z) | Y & Z;
^ stands for xor, & for and, | for or operation. To end module, we write
Here is the complete code:
module Full_Subtractor_3(output D, B, input X, Y, Z); assign D = X ^ Y ^ Z; assign B = ~X & (Y^Z) | Y & Z; endmodule
Testbench for Full Subtractor in Verilog
The testbench is a provision to provide inputs to our design and view the corresponding output to test our Verilog source code. The testbench for the full subtractor is written as follows:
First, we include the pre-written file using
'include and the file name in inverted commas.
Now we name the present testbench module as follows:
module is the keyword used for declaration and the identifier is
To instantiate a module in another, we write
wire D, B; reg X, Y, Z; Full_Subtractor_3 Instance0 (D, B, X, Y, Z);
Note that the inputs in the circuit here become the
reg datatypes and the outputs are specified as
reg data object holds its value from one procedural assignment statement to the next. A continuous assignment statement assigns values to the
wire datatype and makes a connection to an actual wire in the circuit.
Then to instantiate
Full_Subtractor_3 we have the identifier
D, B, X, Y, Z as the ports.
Now we will provide the test cases in an
initial block as follows:
initial begin X = 0; Y = 0; Z = 0; #1 X = 0; Y = 0; Z = 1; #1 X = 0; Y = 1; Z = 0; #1 X = 0; Y = 1; Z = 1; #1 X = 1; Y = 0; Z = 0; #1 X = 1; Y = 0; Z = 1; #1 X = 1; Y = 1; Z = 0; #1 X = 1; Y = 1; Z = 1; end
#1 gives a delay of one unit of time in between the test cases.
begin is used to start and
end concludes any block in Verilog. Now we observe and check the obtained output using
initial begin to start a block and
end at last.
initial begin $monitor ("%t, X = %d| Y = %d| Z = %d| B = %d| D = %d", $time, X, Y, Z, B, D); $dumpfile("dump.vcd"); $dumpvars(); end
Inside monitor, we mention the arguments that we want to view on the console.
%t is the format specifier for time,
%b is for binary,
%d for decimal.
The port names after inverted commas are given in the same order as required while assigning values. The
$dumpvars is used to specify which variables are to be dumped in the file mentioned by
Here is the complete testbench for a full subtractor.
`include "Full_Subtractor_3.v" module Full_Subtractor_3_tb; wire D, B; reg X, Y, Z; Full_Subtractor_3 Instance0 (D, B, X, Y, Z); initial begin X = 0; Y = 0; Z = 0; #1 X = 0; Y = 0; Z = 1; #1 X = 0; Y = 1; Z = 0; #1 X = 0; Y = 1; Z = 1; #1 X = 1; Y = 0; Z = 0; #1 X = 1; Y = 0; Z = 1; #1 X = 1; Y = 1; Z = 0; #1 X = 1; Y = 1; Z = 1; end initial begin $monitor ("%t, X = %d| Y = %d| Z = %d| B = %d| D = %d", $time, X, Y, Z, B, D); $dumpfile("dump.vcd"); $dumpvars(); end endmodule
Here is the schematic, as viewed in Xilinx Vivado.