# How to create a 64 bit Carry Look ahead adder?

I am trying to implement the verilog code using generate statement.There is issue with taking four bits for calculating P and G values.Added the code below for reference. Cin is taken as Zero.

timescale 1ns/10ps

module cla_64bit(sum,c_out,a,b,c_in);

input [64:0]a,b;
input c_in;
output [64:0]sum;
output c_out;
wire [65:0]sum_out;
wire [64:0]c_in;
wire [64:0]c_out;

assign c_in[0]=1'b0;

genvar i;
generate
for (i = 0;i<64;i=i+16)
begin : FA
.sum    (sum_out[i]),
.c_out  (c_in[i-1]),
.a  (a[i]),
.b  (b[i]),
.c_in   (c_in[i])
);
//assign g[i]=a[i] & b[i];
//assign p[i]=a[i] ^ b[i];
//assign c_in[i+1]= g[i]|(p[i] & c_in[i]);
end

assign c_out=c_in[63];
assign sum=sum_out[63:0];

endgenerate
endmodule

input [15:0]a,b;
input c_in;
output [15:0]sum;
output c_out;
wire [15:0]p,g;
wire [15:0]sum_out;
wire [16:0]c_in;
wire [16:0]c_out;

assign c_in[0]=1'b0;

genvar i;
generate
for (i = 0;i<16;i=i+4)
begin : FA
.sum    (sum_out[i]),
.c_out  (c_in[i+1]),
.a  (a[i]),
.b  (b[i]),
.c_in   (c_in[i])
);
assign g[i]=a[i] & b[i];
assign p[i]=a[i] ^ b[i];
assign c_in[i+1]= g[i]|(p[i] & c_in[i]);
end

assign c_out=c_in[15];
//assign sum=sum[15:0];

endgenerate
endmodule

input [3:0]a,b;
input c_in;
output [3:0]sum;
output c_out;
wire  [3:0]p,g;
wire [3:0]sum_out;
wire [4:0]c_in;
wire [4:0]c_out;
assign c_in[0]=1'b0;

genvar i;
generate
for (i = 0;i<4;i=i+1)
begin : FA
.sum    (sum_out[i:0]),
.c_out  (c_in[i+1]),
.a  (a[i]),
.b  (b[i]),
.c_in   (c_in[i])
);
assign g[i]=a[i] & b[i];
assign p[i]=a[i] ^ b[i];
assign c_in[i]= g[i]|(p[i] & c_in[i]);
end

assign c_out=c_in[3];
assign sum=sum_out[3:0];

endgenerate
endmodule

module add_full (sum, c_out, a, b, c_in);
output sum, c_out;
input  a, b, c_in;
wire   w1, w2, w3;

add_half M1 (w1, w2, a, b);
add_half M2 (sum, w3, w1, c_in);
or M3 (c_out, w2, w3);
endmodule

module add_half (sum, c_out, a, b);
output sum, c_out;
input  a, b;
xor M1 (sum, a, b);
and M2 (c_out, a, b);
endmodule

• You know, you wouldn't have to write -1 quite so many times if you actually started using zero indexing... e.g. for (i=0;i<64;i=i+1). Nov 29, 2015 at 20:46
• .sum (sum_out[i-1:0]), why? Nov 29, 2015 at 20:48
• .c_out (c_in[i]), and assign c_in[i]= g[i-1]|(p[i-1] & c_in[i-1]); both assign a value to the same bit of c_in. Why? Nov 29, 2015 at 20:52
• Trying to save final c_in[i] by calculating g[i-1]|(p[i-1] & c_in[i-1] and then assigning it to .c_out (c_in[i]).Please correct me. Nov 29, 2015 at 21:07
• It would probably help if you had a separate wire vector for c_out. Nov 29, 2015 at 21:15

c_in is a 1-bit input, but is also defined as a 64-bit (too wide) interconnect. Lets rename the interconnect to carry and make it 5 bits wide; one bit for each of the add_16bit's c_in plus the final carry out.

You need to use range section. [i] only indexes one bit. To get 16-bits use [16*i+15 : 16*i] or use bit slicing (+:) [i +: 16]. Bit slicing is explained on StackOverflow: Indexing vectors and arrays with +: and What is +: and -:?. The big difference is bit slicing can be used in procedural blocks and generate loops. The expanded form can only be used when i is a genvar or parameter.

wire [4:0] carry;
genvar i;
for (i = 0;i<64;i=i+16) begin : FA
`