Implemented RTL code in Verilog for 64-bit ripple carry adder, carry lookahead adder, and carry select adder with equal group size and different group size; Compared all adders in their timing, area, and power performances. Ran logic simulation, wrote Perl script to run synthesis, ran gate-level simulation, and performed STA using Primetime.
- Ripple Carry Adder
The simplest way to build an N-bit carry propagate adder is to chain together N full adders. The Cout of one stage acts as the Cin of the next stage.
We can build a full adder first, and then chain four full adders together to build a 4-bit adder, and chain 4-bit adders together to build a 16-bit adder, and then to build a 64-bit adder.
- Full adder
The Verilog code for full adder is in the following:
module Add_full (sum, c_out, a, b, c_in); output sum, c_out; input a, b, c_in; wire w1, w2, w3; assign sum = a ^ b ^ c_in; assign w1 = a & b; assign w2 = a & c_in; assign w3 = b & c_in; assign c_out = w1 | w2 | w3; endmodule
- 4-bit ripple carry adder
The 4-bit is consisted of four 1-bit adders. Cout from previous adder is propagated to next adder as Cin.
Four full-adder modules are instantiated, as M1, M2, M3, and M4 respectively. The Verilog for 4-bit adder is in the following:
module Add_rca_4 (sum, c_out, a, b, c_in); output [3: 0] sum; output c_out; input [3: 0] a, b; input c_in; wire c_in2, c_in3, c_in4; Add_full M1 (sum[0], c_in2, a[0], b[0], c_in); Add_full M2 (sum[1], c_in3, a[1], b[1], c_in2); Add_full M3 (sum[2], c_in4, a[2], b[2], c_in3); Add_full M4 (sum[3], c_out, a[3], b[3], c_in4); endmodule
- 16-bit ripple carry adder
Four 4-bit adder modules are instantiated, as M1, M2, M3, and M4 respectively. The Verilog for 16-bit adder is in the following:
module Add_rca (sum, c_out, a, b, c_in);     output [15:0] sum;     output c_out;     input [15:0] a, b;     input c_in;     wire c_in4, c_in8, c_in12, c_out;     Add_rca_4 M1 (sum[3:0], c_in4, a[3:0], b[3:0], c_in);     Add_rca_4 M2 (sum[7:4], c_in8, a[7:4], b[7:4], c_in4);     Add_rca_4 M3 (sum[11:8], c_in12, a[11:8], b[11:8], c_in8);     Add_rca_4 M4 (sum[15:12], c_out, a[15:12], b[15:12], c_in12); endmodule
- 64-bit ripple carry adder
All of previous modules don’t include clock, so they have nothing to do with timing. The design has clock and reset signal as inputs. So, we need to include this feature in the top level 64-bit ripple carry adder. The inputs and outputs are listed in the following:
input clock, reset; input [63:0] op1, op2; output reg [63:0] sum; output reg crout;
Clock and reset are for sequential block; op1 and op2 are two 64-bit inputs. Sum is a 64-bit output and crout stands for carry out, which is 1 bit.
The following part instantiates four 16-bit ripple carry adders, stores the sum result into sumbuffer, and stores carry out result into croutbuffer.
Add_rca L1 (sumbuffer[15:0], c_in16, a[15:0], b[15:0], 1'b0); Add_rca L2 (sumbuffer[31:16], c_in32, a[31:16], b[31:16], c_in16); Add_rca L3 (sumbuffer[47:32], c_in48, a[47:32], b[47:32], c_in32); Add_rca L4 (sumbuffer[63:48], croutbuffer, a[63:48], b[63:48], c_in48);
This is the sequential part. This is asynchronous reset. When reset goes to 1, output sum and crout are reset to 0, and input buffers a and b are reset to 0. Otherwise, at every positive edge of clock signal, a and b take values from op1 and op2, sum and crout take values from sumbuffer and croutbuffer.
always @ (posedge clock or posedge reset) if (reset) begin sum <= #1 64'b0; crout <= #1 1'b0; a <= #1 64'b0; b <= #1 64'b0; end else begin a <= #1 op1; b <= #1 op2; sum[15:0] <= #1 sumbuffer[15:0]; sum[31:16] <= #1 sumbuffer[31:16]; sum[47:32] <= #1 sumbuffer[47:32]; sum[63:48] <= #1 sumbuffer[63:48]; crout <= #1 croutbuffer; end
The complete Verilog code for 64-bit ripple carry adder is in the following:
module RippleCarry (sum, crout, op1, op2, clock, reset); input [63:0] op1, op2; output reg [63:0] sum; input clock, reset; output reg crout; wire c_in16, c_in32, c_in48; reg [63:0] a, b; wire [63:0] sumbuffer; wire croutbuffer; always @ (posedge clock or posedge reset) if (reset) begin sum <= #1 64'b0; crout <= #1 1'b0; a <= #1 64'b0; b <= #1 64'b0; end else begin a <= #1 op1; b <= #1 op2; sum[15:0] <= #1 sumbuffer[15:0]; sum[31:16] <= #1 sumbuffer[31:16]; sum[47:32] <= #1 sumbuffer[47:32]; sum[63:48] <= #1 sumbuffer[63:48]; crout <= #1 croutbuffer; end Add_rca L1 (sumbuffer[15:0], c_in16, a[15:0], b[15:0], 1'b0); Add_rca L2 (sumbuffer[31:16], c_in32, a[31:16], b[31:16], c_in16); Add_rca L3 (sumbuffer[47:32], c_in48, a[47:32], b[47:32], c_in32); Add_rca L4 (sumbuffer[63:48], croutbuffer, a[63:48], b[63:48], c_in48); endmodule
2. Carry Lookahead Adder
Large ripple-carry adders are slow is that the carry signals must propagate through every bit in the adder. A carry- lookahead adder (CLA) is another type of carry propagate adder that solves this problem by dividing the adder into blocks and providing circuitry to quickly determine the carry out of a block as soon as the carry in is known.
CLAs use generate (G) and propagate (P) signals that describe how a column or block determines the carry out. The ith column of an adder is guaranteed to generate a carry Ci if Ai and Bi are both 1. Hence Gi, the generate signal for column i, is calculated as Gi = AiBi. The column is said to propagate a carry if it produces a carry out whenever there is a carry in. The ith column will propagate a carry in, Ci−1, if either Ai or Bi is 1. Thus, Pi = Ai + Bi. In equation form, Ci can be computed this way:
For a 4-bit carry lookahead adder, the generate logic is
A block propages a carry if all the columns in the block propagage the carry. For a 4-bit carry lookahead adder, the propagate logic is
In this way, we can quickly compute the carry out of the block, Ci, using the carry in to the block Cj.
This design is using 2-level structure. Four groups of 4-bit CLA adder connected by CLA.