You are on page 1of 11

一、 Carry Look-ahead Adder

1. 4-bit CLA Verilog Code


//***************** 4-bit carry look-ahead adder **********************
module cla4(s,cout,i1,i2,c0);
output [3:0] s; //summation
output cout; //carryout
input [3:0] i1; //input1
input [3:0] i2; //input2
input c0; //前一級進位
wire [3:0] s;
wire cout;
wire [3:0] g;
wire [3:0] p;
wire [3:1] c;
assign g[3:0]=i1[3:0] & i2[3:0]; //carry generation
assign p[3:0]=i1[3:0] ^ i2[3:0]; //carry propagation
assign c[1]=g[0] | (p[0] & c0); //calculate each stage carryout
assign c[2]=g[1] | (g[0] & p[1]) | (p[0] & p[1] & c0);
assign c[3]=g[2] | (g[1] & p[2]) | (g[0] & p[1] & p[2]) | (p[0] & p[1] & p[2] &
c0);
assign cout=g[3] | (g[2] & p[3]) | (g[1] & p[2] & p[3])
| (g[0] & p[1] & p[2] & p[3]) | (p[0] & p[1] & p[2] & p[3] & c0);
assign s[0]=p[0]^c0; //calculate summation
assign s[3:1]=p[3:1]^c[3:1]; endmodule

2. 16-bit CLA Verilog Code


//**************** 16-bit carry look-ahead adder ********************
module cla16(sum,carryout,A_in,B_in,carryin);
output [15:0] sum; // 相加總和
output carryout; // 進位
input [15:0] A_in; // 輸入 A
input [15:0] B_in; // 輸入 B
input carryin; // 第一級進位 C0
wire [15:0] sum;
wire carryout;
wire [2:0] carry; // C4,C8,C12
cla4 c1(sum[3:0],carry[0],A_in[3:0],B_in[3:0],carryin);
cla4 c2(sum[7:4],carry[1],A_in[7:4],B_in[7:4],carry[0]);
cla4 c3(sum[11:8],carry[2],A_in[11:8],B_in[11:8],carry[1]);
cla4 c4(sum[15:12],carryout,A_in[15:12],B_in[15:12],carry[2]);
endmodule
3. 16-bit CLA Testbench
module stimulus;
reg [15:0] a;
reg [15:0] b;
reg cin;
wire [15:0]summation;
wire carry16;
cla16 u1(summation,carry16,a,cin);
initial
begin
#10 a=16'b1000000000001001;b=16'b1000000000001001;cin=1'b0;
#10 a=16'b1010101010101010;b=16'b0101010101010111;cin=1'b0;
#10 a=16'b0101010101010101;b=16'b0101010101010101;cin=1'b1;
#10 a=16'b1111111111111111;b=16'b0000000000000001;cin=1'b0;
#50 $finish;
end
initial
begin
$fsdbDumpfile("cla.fsdb");
$fsdbDumpvars;
end
endmodule
4. Simulation Result of CLA (Behavior)

8009h + 8009h = 0012 carry16 =1

5.The Critical Path of the 16-bit CLA

delay path = A_in ~ sum[15:0]

6.Simulation Result of CLA (Gate Level)

aaaah + 5557h = 1 carry16 = 1


二、 Manchester Carry Chain Adder
1. 1-bit Manchester Carry Adder Verilog Code
//***** 1-bit manchester carry chain adder *******
module manadd1(s,cout,i1,i2,cin);
output s; //summation
output cout; //carryout
input i1; //input1
input i2; //input2
input cin; //前一級進位
wire ki; //Carry killed
wire gi; //carry generation
wire pi; //carry propagation
wire t1i; //temporary node
wire t2i; //temporary node
wire t3i; //temporary node
/* implement the Manchester Carry Chain Adder Algorithm */
/* if i1 & i2 =0 then ki = 1 and cout =0 elsi cout =gi + cin (xor) pi
nor n1(ki,i1,i2);
and n2(gi,i1,i2);
xor n3(pi,i1,i2);
and n4(t1i,pi,cin);
nor n5(t2i,gi,t1i);
nor n6(cout,ki,t2i);
xor n7(s,pi,cin);
endmodule
2. 16-bit Manchester Carry Adder Verilog Code
//***** 16-bit manchester carry chain adder *******
module manadder16(sum,carryout,A_in,B_in,carryin);
output [15:0] sum; // 相加總和
output carryout; // 進位 C16
input [15:0] A_in; // 輸入 A
input [15:0] B_in; // 輸入 B
input carryin; // 第一級進位 C0
wire [15:0] sum;
wire carryout;
wire [14:0] carry; //each stage carryout C1 – C15
/* implement 16-bit Manchester Adder */
manadd1 m1(sum[0],carry[0],A_in[0],B_in[0],carryin);
manadd1 m2(sum[1],carry[1],A_in[1],B_in[1],carry[0]);
manadd1 m3(sum[2],carry[2],A_in[2],B_in[2],carry[1]);
manadd1 m4(sum[3],carry[3],A_in[3],B_in[3],carry[2]);
manadd1 m5(sum[4],carry[4],A_in[4],B_in[4],carry[3]);
manadd1 m6(sum[5],carry[5],A_in[5],B_in[5],carry[4]);
manadd1 m7(sum[6],carry[6],A_in[6],B_in[6],carry[5]);
manadd1 m8(sum[7],carry[7],A_in[7],B_in[7],carry[6]);
manadd1 m9(sum[8],carry[8],A_in[8],B_in[8],carry[7]);
manadd1 m10(sum[9],carry[9],A_in[9],B_in[9],carry[8]);
manadd1 m11(sum[10],carry[10],A_in[10],B_in[10],carry[9]);
manadd1 m12(sum[11],carry[11],A_in[11],B_in[11],carry[10]);
manadd1 m13(sum[12],carry[12],A_in[12],B_in[12],carry[11]);
manadd1 m14(sum[13],carry[13],A_in[13],B_in[13],carry[12]);
manadd1 m15(sum[14],carry[14],A_in[14],B_in[14],carry[13]);
manadd1 m16(sum[15],carryout,A_in[15],B_in[15],carry[14]);
endmodule
3. 16-bit Manchester Carry Adder Testbench
module stimulus;
reg [15:0] a;
reg [15:0] b;
reg c0;
wire [15:0]summation;
wire carry16;
manadder16 u1(summation,carry16,a,b,c0);
initial
begin
#10 a=16'b1000000000001001;b=16'b1000000000001001;c0=1'b0;
#10 a=16'b1010101010101010;b=16'b0101010101010111;c0=1'b0;
#10 a=16'b0101010101010101;b=16'b0101010101010101;c0=1'b1;
#10 a=16'b1111111111111111;b=16'b0000000000000001;c0=1'b0;
#50 $finish;
end
initial
begin
$fsdbDumpfile("manchester.fsdb");
$fsdbDumpvars;
end
endmodule

4. Simulation Result of MCCA(Behavior)

cin =1, 5555h + 5555h = aaab carry16 = 1


5.The Critical Path of the 16-bit Manchester Carry Chain Adder

delay path = B_in ~ sum[15:0]

6.Simulation Result of MCCA (Gate Level)

ffff + 0001h = 0h ,carry16 = 1


三、Ling Adder
1. 4-bit Ling Adder Verilog Code
//***** 4-bit ling adder *******
module ling4(s,cout,i1,i2,h0);
output [3:0] s; //summation
output cout; //carryout
input [3:0] i1; //input1
input [3:0] i2; //input2
input h0; //前一級進位
wire [3:0] t;
wire [3:0] g;
wire [4:1] h;
assign g[3:0]=i1[3:0] & i2[3:0]; //carry generation
assign t[3:0]=i1[3:0] | i2[3:0]; // ti = i1 + i2
assign h[1]=g[0] | (h0&t[0]); //calculate each stage carryout
assign h[2]=g[1] | g[0] | (t[0]&h0));
assign h[3]=g[2] | g[1] | (g[0]&t[1]) | (t[0]&t[1]&h0);
assign h[4]=g[3] | g[2] | (g[1]&t[2]) | (g[0]&t[1]&t[2]) | (t[0]&t[1]&t[2]&h0);
assign cout=h[4] & t[3]; //real carryout
assign s[0]=(t[0] ^ h[1]) | (h0 & t[0] & g[0]); //calculate summation
assign s[3:1]=(t[3:1] ^ h[4:2]) | (h[3:1] & t[2:0] & g[3:1]);
endmodule

2. 16-bit Ling Adder Verilog Code


//***** 16-bit ling adder *******
module ling16(sum,carryout,toutput,A_in,B_in,carryin,tinput);
output [15:0] sum; // 相加總和
output carryout; // 進位 C16
input [15:0] A_in; // 輸入 A
input [15:0] B_in; // 輸入 B
input carryin; // 第一級進位 C0
wire [2:0] carry; // each stage carryout C4 C8 C12
ling4 l1(sum[3:0],carry[0], A_in[3:0],B_in[3:0],carryin);
ling4 l2(sum[7:4],carry[1], A_in[7:4],B_in[7:4],carry[0]);
ling4 l3(sum[11:8],carry[2], A_in[11:8],B_in[11:8],carry[1],);
ling4 l4(sum[15:12],carryout,A_in[15:12],B_in[15:12],carry[2]);
endmodule
3. 16-bit Ling Adder Testbench
module stimulus;
reg [15:0] a;
reg [15:0] b;
reg cin;
wire [15:0]summation;
wire carry16;
ling16 u1(summation,carry16,,a,b,cin);
initial
#10 a=16'b1000000000001001;b=16'b1000000000001001;cin=1'b0;
#10 a=16'b1010101010101010;b=16'b0101010101010111;cin=1'b0;
#10 a=16'b0101010101010101;b=16'b0101010101010101;cin=1'b1;
#10 a=16'b1111111111111111;b=16'b0000000000000001;cin=1'b0;
#50 $finish;
end
initial
begin
$fsdbDumpfile("ling.fsdb");
$fsdbDumpvars;
end
endmodule

4. Simulation Result of Ling Adder (Behavior)


5.The Critical Path of the 16-bit Ling Adder

delay path = carryin ~ sum[15:0]

6.Simulation Result of Ling Adder (Gate Level)


四、Comparison The Timing and Area of CLA ,Manchester, Ling Adder
CLA Manchester Ling
Timing 3.11 6.28 6.93
Area 2073.6 2211.84 2350.08

上表的結果是經由 Design Optimization 後所得到的,這樣的結果似乎與理論上


有些出入,其中
Speed :CLA > Manchester > Ling
Area :Ling > Manchester > CLA

其實在不考慮輸入值只考慮 worse case 時,Manchester 應該是面積最小但是速


度最慢的加法器因為 C0 要經過十六級的延遲;因此我們決定改用 CLA 以面積
換取時間,C0 變成只需延遲四次,而 Ling Adder 是為了改善 CLA 的面積衍生
出的加法器。所以理論上的狀況如下:

Speed:CLA > Ling > Manchester


Area :CLA > Ling > Manchester

但是同時考慮 sum 與 Carry 時,Ling Adder 的面積將會大於 CLA,因為 Ling


Adder 必須計算真正要傳給下一級的 Ci = hi*ti-1,同時在計算 sum 時也比 CLA
要花費更多的 gate & timing (詳見手算分析)。

You might also like