Verilog Code for Ripple Carry Adder: Syntax and Example
A
ripple carry adder in Verilog is built by connecting multiple 1-bit full adders in series, where the carry output of one adder is the carry input of the next. You define a module for a 1-bit full adder and then chain them to create an N-bit adder using assign statements or a generate block.Syntax
The ripple carry adder is made by connecting several 1-bit full adders. Each full adder has inputs a, b, and cin (carry in), and outputs sum and cout (carry out). The carry out of one adder becomes the carry in of the next.
The main parts are:
- Module declaration: Defines the adder size and ports.
- Full adder logic: Calculates sum and carry for one bit.
- Carry chaining: Connects carry signals between bits.
verilog
module full_adder(
input a,
input b,
input cin,
output sum,
output cout
);
assign sum = a ^ b ^ cin; // XOR for sum
assign cout = (a & b) | (b & cin) | (a & cin); // Carry out logic
endmodule
module ripple_carry_adder #(parameter N = 4)(
input [N-1:0] a,
input [N-1:0] b,
input cin,
output [N-1:0] sum,
output cout
);
wire [N:0] carry;
assign carry[0] = cin;
// Generate N full adders connected by carry
genvar i;
generate
for (i = 0; i < N; i = i + 1) begin : adder_loop
full_adder fa(
.a(a[i]),
.b(b[i]),
.cin(carry[i]),
.sum(sum[i]),
.cout(carry[i+1])
);
end
endgenerate
assign cout = carry[N];
endmoduleExample
This example shows a 4-bit ripple carry adder module and a testbench that adds two 4-bit numbers with an initial carry in. It prints the inputs and the sum with carry out.
verilog
module full_adder(
input a,
input b,
input cin,
output sum,
output cout
);
assign sum = a ^ b ^ cin;
assign cout = (a & b) | (b & cin) | (a & cin);
endmodule
module ripple_carry_adder #(parameter N = 4)(
input [N-1:0] a,
input [N-1:0] b,
input cin,
output [N-1:0] sum,
output cout
);
wire [N:0] carry;
assign carry[0] = cin;
genvar i;
generate
for (i = 0; i < N; i = i + 1) begin : adder_loop
full_adder fa(
.a(a[i]),
.b(b[i]),
.cin(carry[i]),
.sum(sum[i]),
.cout(carry[i+1])
);
end
endgenerate
assign cout = carry[N];
endmodule
module testbench;
reg [3:0] a, b;
reg cin;
wire [3:0] sum;
wire cout;
ripple_carry_adder #(4) rca(
.a(a),
.b(b),
.cin(cin),
.sum(sum),
.cout(cout)
);
initial begin
a = 4'b1010; // 10 decimal
b = 4'b0101; // 5 decimal
cin = 0;
#10;
$display("a = %b, b = %b, cin = %b", a, b, cin);
$display("sum = %b, cout = %b", sum, cout);
$finish;
end
endmoduleOutput
a = 1010, b = 0101, cin = 0
sum = 1111, cout = 0
Common Pitfalls
Common mistakes when writing a ripple carry adder include:
- Not connecting the carry out of one full adder to the carry in of the next, which breaks the carry chain.
- Forgetting to initialize the first carry input (usually set to 0).
- Mixing bit order, causing incorrect sum bits.
- Using blocking assignments (
=) inside combinational logic instead of continuous assignments (assign).
Always use wire for carry signals and assign for combinational logic.
verilog
/* Wrong: carry not chained properly */ module ripple_carry_adder_wrong( input [3:0] a, input [3:0] b, input cin, output [3:0] sum, output cout ); wire c1, c2, c3; full_adder fa0(.a(a[0]), .b(b[0]), .cin(cin), .sum(sum[0]), .cout(c1)); full_adder fa1(.a(a[1]), .b(b[1]), .cin(cin), .sum(sum[1]), .cout(c2)); // Wrong: cin reused full_adder fa2(.a(a[2]), .b(b[2]), .cin(c2), .sum(sum[2]), .cout(c3)); full_adder fa3(.a(a[3]), .b(b[3]), .cin(c3), .sum(sum[3]), .cout(cout)); endmodule /* Right: carry chained correctly */ module ripple_carry_adder_right( input [3:0] a, input [3:0] b, input cin, output [3:0] sum, output cout ); wire c1, c2, c3; full_adder fa0(.a(a[0]), .b(b[0]), .cin(cin), .sum(sum[0]), .cout(c1)); full_adder fa1(.a(a[1]), .b(b[1]), .cin(c1), .sum(sum[1]), .cout(c2)); full_adder fa2(.a(a[2]), .b(b[2]), .cin(c2), .sum(sum[2]), .cout(c3)); full_adder fa3(.a(a[3]), .b(b[3]), .cin(c3), .sum(sum[3]), .cout(cout)); endmodule
Quick Reference
Ripple Carry Adder Key Points:
- Use a 1-bit full adder module with inputs
a,b,cinand outputssum,cout. - Chain carry outputs to carry inputs for all bits.
- Initialize the first carry input to 0 or desired carry in.
- Use
genvarandgeneratefor scalable N-bit adders. - Use continuous assignments (
assign) for combinational logic.
Key Takeaways
A ripple carry adder connects multiple 1-bit full adders by chaining carry outputs to carry inputs.
Use continuous assignments and wires to implement combinational logic and carry signals.
Initialize the first carry input to zero to start the addition correctly.
Use generate loops for scalable and clean N-bit ripple carry adder designs.
Avoid reusing the same carry input for multiple bits to prevent incorrect sums.