Designing Half Adder and Full Adder Using Verilog
In digital electronics, adders are crucial components used in arithmetic operations, particularly in CPUs and other processing units. This blog post will guide you through designing two fundamental types of adders: the half adder and the full adder, using Verilog, a popular hardware description language.
Prerequisites to Install Icarus Verilog and GTKWave
Before diving into Verilog simulations with Icarus Verilog and visualizing waveforms using GTKWave, it’s important to ensure your system meets the necessary prerequisites for installation. This section Installation process outlines the requirements and steps to prepare your environment for setting up these tools.
Understanding Adders
Half Adder
A half adder is a simple combinational circuit that adds two single-bit binary numbers (A and B). It produces two outputs: the sum (S) and the carry (Cy). The truth table for a half adder is as follows:
Full Adder
A full adder extends the functionality of a half adder by including a carry-in (Cin) input, allowing for the addition of three bits. It produces a sum (S) and a carry-out (Cout). The truth table for a full adder is:
Designing the Half Adder in Verilog
Let’s start by designing the half adder. Below is the Verilog code for the half adder module and its testbench.
Half Adder Module
// Half Adder Module
module half_adder (
input wire a, // Input bit a
input wire b, // Input bit b
output wire sum, // Sum output
output wire carry // Carry output
);
// Sum is the XOR of a and b
assign sum = a ^ b;
// Carry is the AND of a and b
assign carry = a & b;
endmodule
Testbench for Half Adder
// Testbench for Half Adder
module tb_half_adder;
// Inputs
reg a;
reg b;
// Outputs
wire sum;
wire carry;
// Instantiate the Half Adder
half_adder uut (
.a(a),
.b(b),
.sum(sum),
.carry(carry)
);
// Test Vector
initial begin
// Initialize inputs
a = 0;
b = 0;
// Generate waveform file
$dumpfile("half_adder.vcd");
$dumpvars(0, tb_half_adder);
// Display header
$display("a b | sum carry");
$display("-------------");
// Test cases
a = 0; b = 0; #10;
$display("%b %b | %b %b", a, b, sum, carry);
a = 0; b = 1; #10;
$display("%b %b | %b %b", a, b, sum, carry);
a = 1; b = 0; #10;
$display("%b %b | %b %b", a, b, sum, carry);
a = 1; b = 1; #10;
$display("%b %b | %b %b", a, b, sum, carry);
// Finish simulation
$finish;
end
endmodule
Designing the Full Adder in Verilog
Next, let’s design the full adder. Below is the Verilog code for the full adder module and its testbench.
Full Adder Module
// Full Adder Module
module full_adder (
input wire a, // Input bit a
input wire b, // Input bit b
input wire cin, // Carry-in bit
output wire sum, // Sum output
output wire cout // Carry-out output
);
// Internal signals
wire sum1, c1, c2;
// Half Adder for a and b
assign sum1 = a ^ b;
assign c1 = a & b;
// Half Adder for sum1 and cin
assign sum = sum1 ^ cin;
assign c2 = sum1 & cin;
// Carry-out
assign cout = c1 | c2;
endmodule
Testbench for Full Adder
// Testbench for Full Adder
module tb_full_adder;
// Inputs
reg a;
reg b;
reg cin;
// Outputs
wire sum;
wire cout;
// Instantiate the Full Adder
full_adder uut (
.a(a),
.b(b),
.cin(cin),
.sum(sum),
.cout(cout)
);
// Test Vector
initial begin
// Initialize inputs
a = 0;
b = 0;
cin = 0;
// Generate waveform file
$dumpfile("full_adder.vcd");
$dumpvars(0, tb_full_adder);
// Display header
$display("a b cin | sum cout");
$display("------------------");
// Test cases
a = 0; b = 0; cin = 0; #10;
$display("%b %b %b | %b %b", a, b, cin, sum, cout);
a = 0; b = 0; cin = 1; #10;
$display("%b %b %b | %b %b", a, b, cin, sum, cout);
a = 0; b = 1; cin = 0; #10;
$display("%b %b %b | %b %b", a, b, cin, sum, cout);
a = 0; b = 1; cin = 1; #10;
$display("%b %b %b | %b %b", a, b, cin, sum, cout);
a = 1; b = 0; cin = 0; #10;
$display("%b %b %b | %b %b", a, b, cin, sum, cout);
a = 1; b = 0; cin = 1; #10;
$display("%b %b %b | %b %b", a, b, cin, sum, cout);
a = 1; b = 1; cin = 0; #10;
$display("%b %b %b | %b %b", a, b, cin, sum, cout);
a = 1; b = 1; cin = 1; #10;
$display("%b %b %b | %b %b", a, b, cin, sum, cout);
// Finish simulation
$finish;
end
endmodule
Running the Simulations
To simulate the designs, use the following commands:
- For the Half Adder:
iverilog -o half_adder.vvp half_adder.v tb_half_adder.v
vvp half_adder.vvp
2. For the Full Adder:
iverilog -o full_adder.vvp full_adder.v tb_full_adder.v
vvp full_adder.vvp
After running the simulations, you’ll get VCD (Value Change Dump) files named half_adder.vcd
and full_adder.vcd
, respectively. These files can be viewed using GTKWave to analyze the waveforms.
3. Viewing the Waveforms:
gtkwave half_adder.vcd
gtkwave full_adder.vcd
Conclusion
In this blog post, we covered the basics of designing half adders and full adders using Verilog. These simple yet fundamental components are essential in the design of more complex arithmetic units used in digital systems. By simulating these designs, you can visualize how binary addition works at the hardware level, which is a crucial step in learning digital design and Verilog.