After reading this article, you’ll able to:
- Understand the half subtractor.
- Explain Dataflow modeling in Verilog HDL.
- Write Verilog code for half subtractor circuit, and
- Simulate the hardware description language code to verify the output using a testbench.
The Half-Subtractor circuit
Consider that we want to subtract two 1-bit numbers. The numbers are x and y. A difference bit (D) and a borrow bit (B) will be generated.
The binary subtraction consists of four possible elementary operations: 0-0, 0-1, 1-0, and 1-1.
The operations 0-0, 1-0, and 1-1 produces a subtraction of 1-bit output.
Whereas the remaining operation 0-1 produces a 2-bit output.
So, if the numbers are 0 and 0 then, the difference bit and the borrow bit will be both 0. If we calculate all such combinations of these two input bits, then we would end up forming the following kind of a table known as the truth table for half subtractor:
|A||B||DIFFERENCE (D)||BORROW (B)|
If you try to analyze this truth table, you’ll realize that:
- B = X’Y
- D = X’Y + XY’
Now that we have the logic equations, we can form the digital circuit as follows:
Verilog Code using Data-Flow Modelling
Dataflow modeling describes combinational circuits by their function rather than by their gate structure. You have to use the circuit’s logic formula in dataflow modeling. The formula for any logic circuit describes its function quite aptly. Dataflow modeling in Verilog uses continuous assignment statements and the keyword
assign. So let’s proceed with the code.
First, we will declare the module name. A
module is a fundamental building block in Verilog HDL, analogous to the ‘function’ in C. The module declaration is as follows:
module Half_Subtractor_2(output D, B, input X, Y);
module is a keyword. An identifier follows it. The identifier is the name of the module. After naming the module, in a pair of parentheses, we specify:
- the direction of a port as input, output or inout.
- Port size, and
- port name.
Half_Subtractor_2 is the identifier; output ports are the difference (
D), borrow (
B) and; input ports are
Y. As these are not multi-bit buses, their port size is not mentioned explicitly, and it is considered to be 1. Next up, since it is a dataflow modeling style, we use the
assign D = X ^ Y; assign B = ~X & Y;
The equations, as formed by the truth table, are replicated here in dataflow modeling. We assign to the output difference (D) the xor operated on the two inputs X and Y. Borrow bit (B) is also assigned the and operation of x’ with y. Then we write:
to end this module.
You may look at the full code here:
module Half_Subtractor_2(output D, B, input X, Y); assign D = X ^ Y; assign B = ~X & Y; endmodule
Testbench in Verilog of a half-subtractor
The test bench is the file through which we give inputs and observe the outputs. It is a setup to test our Verilog code.
The first line is:
We start by writing
'include which is a keyword to include a file. It includes the Verilog file for the design. Notice that the file name has to be in inverted commas and no semicolon at the end.
This line assigns an identifier for the testbench and ends in a semicolon. We provide no ports for the test bench as there will be ports inside the testbench and not outside. Then we have:
wire D, B; reg X, Y;
Keenly observe that the inputs in the half subtractor become the
reg datatypes and the outputs are specified as
Half_Subtractor_2 Instance0 (D, B, X, Y);
We instantiate a module in Verilog or say we copy the circuit contents in this testbench. The name given to this instance is Instance0, and the ports are provided. The name of the ports may or may not be the same from the Half_Subtractor_2.v file. Next, we write the test cases for the test bench.
initial begin X = 0; Y = 0; #1 X = 0; Y = 1; #1 X = 1; Y = 0; #1 X = 1; Y = 1; end
Here, X and Y are assigned every possible value to get the output.
#1 gives a delay of one unit of time in between the test cases. Then we have,
initial begin $monitor ("%t, X = %d| Y = %d| B = %d| D = %d", $time, X, Y, B, D); $dumpfile(dump.vcd); $dumpvars(); end
We have monitor keyword to view our results in the console. This is housed in an
initial block. Note that
%t is the format specifier for time,
%d for decimal. The port names after inverted commas are given in the same order as required while assigning values. The next lines are
dumpvars(). These are written to get the waveform in the file named dump.vcd. That is all needed to build a testbench.
Here is the full code –
`include "Half_Subtractor_2.v" module Half_Subtractor_2_tb; wire D, B; reg X, Y; Half_Subtractor_2 Instance0 (D, B, X, Y); initial begin X = 0; Y = 0; #1 X = 0; Y = 1; #1 X = 1; Y = 0; #1 X = 1; Y = 1; end initial begin $monitor ("%t, X = %d| Y = %d| B = %d| D = %d", $time, X, Y, B, D); $dumpfile("dump.vcd"); $dumpvars(); end endmodule
Here is the schematic, as viewed in Xilinx Vivado.
Simulation of the Verilog code for a half-subtractor using dataflow modeling
Thanks for reading! If you have any queries, let us know in the comments section below!