Building a 32-Bit Adder Module in Verilog
In digital design, the 32-bit adder module handles the
addition of two 32-bit numbers, incorporates a carry-in, and outputs a
carry-out.
Module Code
module adder_32bit(
input [32:0] a,
input [32:0] b,
input cin,
output [32:0] sum,
output cout
);
assign {cout, sum} = a + b + cin;
endmodule
Explanation
1.
Module Declaration:
v Defines a module called adder_32bit
.
v Specifies inputs and outputs:
·
a
and b
: Two 32-bit input values
·
cin
: Carry-in input
·
sum
: 32-bit output for the result
·
cout
: Carry-out bit for overflow indication
2.
Addition Operation:
v Performs the actual addition and is the core of the adder’s
functionality.
v assign {cout, sum} = a + b + cin;
v {cout, sum}
uses concatenation to
combine the cout
bit and sum
output into a single result.
v The operation a + b + cin
adds the two 32-bit input values with the carry-in bit.
3.
End of Module:
v Marks the end of the module definition.
How It Works
·
The adder_32bit
module takes two 32-bit
numbers and a single carry-in bit.
·
The addition of a
, b
, and cin
produces a sum and, if there’s
an overflow, a carry-out bit.
·
This carry-out is helpful in
designs involving multi-bit arithmetic where the result may need to be passed
to the next stage or to signal an overflow condition.
Creating a Testbench for the 32-Bit Adder Module in
Verilog
Testing is crucial to ensure that modules behave as expected
under various input conditions. Below is the Verilog code for the testbench
that verifies the ‘adder_32bit‘ module.
Testbench Code
‘timescale 1ns / 1ps
module adder_32bit_tb;
// Declare inputs as registers and outputs as wires
reg [32:0] a;
reg [32:0] b;
reg cin;
wire [32:0] sum;
wire cout;
// Instantiate the adder_32bit module
adder_32bit uut (
.a(a),
.b(b),
.cin(cin),
.sum(sum),
.cout(cout)
);
// Test cases
initial begin
// Test Case 1: Add two small numbers
a = 33’h000000001; // 1 in 33-bit
b = 33’h000000001; // 1 in 33-bit
cin = 0;
#10; // wait for 10 time units
$display(“TC1: a = %h, b = %h, cin = %b -> sum = %h, cout = %b”, a, b, cin, sum, cout);
...
$stop;
end
endmodule
Explanation
Key components of this testbench:
1. Module Declaration and
Timescale:
v The ‘timescale‘ directive specifies the time units for the
simulation.
v The module name is ‘adder_32bit_tb‘, following the convention of
appending ‘_tb‘ for testbench files.
2. Declaring Inputs and
Outputs:
v Inputs (‘a‘, ‘b‘, and ‘cin‘) are declared as ‘reg‘ types.
v Outputs (‘sum‘ and ‘cout‘) are declared as ‘wire‘ types.
3. Instantiating the Module
Under Test (MUT):
v The ‘adder_32bit‘ module is instantiated with the label ‘uut‘ (unit
under test).
v The inputs and outputs of ‘adder_32bit‘ are mapped to the
testbench’s ‘reg‘ and ‘wire‘ variables.
4. Defining Test Cases:
v The ‘initial‘ block contains the test cases, each testing a
different input scenario.
v ‘#10‘ is a delay statement that waits for 10 time units to allow the
adder’s outputs to stabilize.
v ‘$display‘ outputs the values of ‘a‘, ‘b‘, ‘cin‘, ‘sum‘, and ‘cout‘
to the console for each test case.
5. Test Cases Overview:
v Test Case 1: Adds two small numbers (‘1 + 1‘), expecting a
straightforward sum without a carry-out.
v Test Case 2: Adds numbers with a carry-in (‘15 + 1 + 1‘), verifying
carry-in functionality.
v Test Case 3: Tests large values close to the 32-bit limit (‘7FFFFFFF
+ 7FFFFFFF‘), potentially producing a carry-out.
v Test Case 4: Tests overflow by adding maximum values and setting ‘cin‘
to ‘1‘ to observe carry-out handling.
6. Ending Simulation:
v ‘$stop‘ terminates the simulation after the test cases are complete.