View Course Path

# Verilog Code for Full Subtractor using Dataflow Modeling

• 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.

Contents

## Full Subtractor

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.

 X Y Z B(Borrow) D (Difference) 0 0 0 0 0 0 0 1 1 1 0 1 0 1 1 0 1 1 1 0 1 0 0 0 1 1 0 1 0 0 1 1 0 0 0 1 1 1 1 1

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:

`module Full_Subtractor_3();`

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:

`endmodule`

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

`endmodule`

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.

``include "Full_Subtractor_3.v"`

Now we name the present testbench module as follows:

`module Full_Subtractor_3_tb;`

`module` is the keyword used for declaration and the identifier is `Full_Subtractor_3_tb`.

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 `wire`. The `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 `Instance0` with `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 `\$monitor`. Write `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 `\$dumpfile` .

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```

## Hardware Schematic

Here is the schematic, as viewed in Xilinx Vivado. ## Simulation of the Verilog code for the Full-subtractor using dataflow modelling

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

Top