1.
若一AND閘(gate) 之輸出延遲為1ns,OR閘之輸出延遲為1ns,INVERTER閘之輸出延遲為0ns,請計算下列加法器之輸出延遲。
(A)以全加器與半加器設計之4位元漣波加法器(ripple carry adder)。
假設a,b為被加數與加數,cout為相加後的進位,sum為相加後的總和,cin為進位輸入。
1位元半加器之運算式為下列:
sum=a ^ b 延遲2ns
因 a ^ b= (a & ~b) | (~a &b)
因a,b同時輸入,故(a &
~b)和(~a & b)同時運算完成同時延遲1ns
延遲1ns後待計算完&後在計算| 故在延遲1ns
則^總延遲為2ns,故sum得出結果後延遲2ns
cout=a & b 由題目假設得知延遲1ns
1位元全加器之運算式為下列:
sum=cin^a^b 延遲2ns
因為cin和a和b為時輸入並同時做XOR運算故延遲僅為2ns
cout=(a&b)|(a|b)&cin
延遲 3ns
因a,b同時輸入,故(a&b)和(a|b)同時運算完成同時延遲1ns
當(a&b)和(a|b)運算完後(a|b)要先跟cin 做&,故在延遲1ns,最後(a|b)&cin運算完後再跟(a&b)做|在延遲1ns,故總延遲為 3ns
由於四位元漣波加法器需用到一個半加器和三個全加器,由圖中可以看到每個半加器與全加器的輸入a、b皆為同時輸入,我先看低位元的半加器,其半加器之sum在延遲2ns時即得到結果,cout在延遲1ns時得到結果,而第二位元全加器之sum需等待第一位元(半加器)的cout運算完在輸入至cin做XOR運算,故在這邊延遲為1+2=3ns,而第二位元全加器的cout在延遲1ns時先做了 a&b、 a|b運算,此時前一個位元(半加器)之cont也一同運算出來並輸入至第二位元的cin,故第二位元在延遲1ns把運算完的(a|b)跟cin做&運算完,在延遲1ns把運算完的(a|b)&cin跟(a&b)做|,故第二位元的cout延遲為3ns,第三位元之sum需等第二位元之cout運算完才能做XOR,故第三位元之sum延遲為3+2=5ns,而第三位元之cout在延遲1ns時先做了 a&b、 a|b運算,此時第二位元的cout還沒運算完,還差3-1=2ns,故延遲2ns 第二位元cout才輸入至第三位元cin,在延遲1ns把運算完的(a|b)跟cin做&運算完,在延遲1ns把運算完的(a|b)&cin跟(a&b)做|,故第三位元的cout延遲為5ns,第四位元之sum要等到第三位元之cout輸出至第四位元cin,故延遲5+2=7ns,而第四位元之cout在延遲1ns時先做了 a&b、 a|b運算,此時第三位元的cout還沒運算完,還差5-1=4ns,故延遲4ns 第三位元cout才輸入至第四位元cin,在延遲1ns把運算完的(a|b)跟cin做&運算完,在延遲1ns把運算完的(a|b)&cin跟(a&b)做|,故第四位元的cout延遲為7ns。
結論由於整個4位元之cout與sum皆為延遲7ns,故漣波加法器延遲7ns。
(B)4位元進位前瞻(carry lookahead)加法器。
進位前瞻加法器會預先運算完每個位元的進位位元,在此我假設cin為進位輸入,c0為第一位元運算後的進位,c1為第二位元運算後的進位,c2為第三位元運算後的進位,而cout=c3為第四位元運算後的進位,sum0為第一位元相加之和,sum1為第二位元相加之和,sum2為第三位元相加之和,sum3為第四位元相加之和。
由公式來看:
pi=ai+bi 延遲1ns
gi=ai.bi 延遲1ns
ci=gi+pi.c(i-1)
則
p0=a0+b0
g0=a0.B0
c0=g0+p0.0=g0
c1=g1+p1.c0=g1+p1.g0
c2=g2+p2.c1=g2+p2.(g1+p1.g0)=g2+p2.g1+p2.p1.g0
c3=g3+p3.c2=g3+p3.(g2+p2.g1+p2.p1.g0)
=g3+p3.g2+p3.p2.g1+p3.p2.p1.g0
因pi gi皆延遲1ns則c1在延遲1ns時p1、g0、g1運算完成,在延遲1ns p1跟g0做and,在延遲1ns跟g1做OR,故c1延遲3ns
因pi gi皆延遲1ns則c2在延遲1ns時p1、p2、g0、g1、g2運算完成,在延遲1ns p1、g0、 p2做and和p2、 g1做and,在延遲1ns g2、 p2.g1 、 p2.p1.g0做OR,故c2延遲3ns
因pi gi皆延遲1ns則c3在延遲1ns時p1、 p2、 p3、 g0、 g1、 g2、 g3運算完成,在延遲1ns p1、 g0、 p2、 p3做and和p2、 g1、 p3和p3、 g2做and,在延遲1ns g3、 p3.g2、 p3.p2.g1、 p3.p2.p1.g0做OR,故c1延遲3ns
sum0=a0^b0由於同時輸入且由上得知XOR延遲2ns
sum1=a1^b1^co0由於同時輸入且由上得知XOR延遲2ns
sum2=a2^b2^co1由於同時輸入且由上得知XOR延遲2ns
sum3=a3^b3^co2由於同時輸入且由上得知XOR延遲2ns
最後由於a,b,cin為同時輸入,故延遲時間以最長為3ns
2.
將一數加1在演算法中會經常用到,若以一般加法器來實作會速度較慢面積也較大,因此可以單獨設計一加一器(incrementer),請以進位前瞻加法器之方法設計一4位元incrementer,模組為inc4(a[3:0], cout, inc[3:0]),其中a為輸入,cout為進位輸出,inc為4位元結果。
--------------------------------incrementer.v-----------------------------------
module
cla4(a,cout,inc);
input [3:0]
a;
output [3:0]
inc;
output cout;
wire [2:0]
co;
assign #1
co[0]=a[0]&1'b1;
assign #1
co[1]=(a[1]&1'b0)|((a[1]|1'b0)&(a[0]&1'b1));
assign #1
co[2]=(a[2]&1'b0)|((a[2]|1'b0)&((a[1]&1'b0)|((a[1]|1'b0)&(a[0]&1'b1))));
assign #1
cout=(a[3]&1'b0)|((a[3]|1'b0)&((a[2]&1'b0)|((a[2]|1'b0)&((a[1]&1'b0)|((a[1]|1'b0)&(a[0]&1'b1))))));
assign #1
inc[0]=a[0]^1'b1;
assign #1
inc[1]=a[1]^1'b0^co[0];
assign #1
inc[2]=a[2]^1'b0^co[1];
assign #1 inc[3]=a[3]^1'b0^co[2];
endmodule
------------------------------incrementer_prove.v-----------------------------
module
cla4(a,cout,inc);
input [3:0]
a;
output [3:0]
inc;
output cout;
wire [2:0]
co;
assign #1
co[0]=a[0]&1'b1;
assign #1
co[1]=(a[1]&(a[0]&1'b1));
assign #1
co[2]=(a[2]&(a[1]&(a[0]&1'b1)));
assign #1
cout=(a[3]&(a[2]&(a[1]&(a[0]&1'b1))));
assign #1
inc[0]=a[0]^1'b1;
assign #1
inc[1]=a[1]^1'b0^co[0];
assign #1
inc[2]=a[2]^1'b0^co[1];
assign #1
inc[3]=a[3]^1'b0^co[2];
endmodule
------------------------------------GTKWAVE---------------------------------------
3.
假設4位元加法器,模組為cla4(a[3:0],
b[3:0], cin, cout, sum[3:0]),請以此模組為底(base)再加其他必須之邏輯,設計
(A)4位元乘法器,模組為mult4(a[3:0], b[3:0], axb[7:0]),其中a,b為輸入,axb為輸出。
-------------------------------------mult4_1.v----------------------------------------
module
cla4(a,b,cin,cout,sum);
input [3:0]
a,b;
input cin;
output [3:0] sum;
output cout;
wire [2:0]
co;
assign #1
co[0]=(a[0]&b[0])|((a[0]|b[0])&cin);
assign #1
co[1]=(a[1]&b[1])|((a[1]|b[1])&((a[0]&b[0])|((a[0]|b[0])&cin)));
assign #1
co[2]=(a[2]&b[2])|((a[2]|b[2])&((a[1]&b[1])|((a[1]|b[1])&((a[0]&b[0])|((a[0]|b[0])&cin)))));
assign #1
cout=(a[3]&b[3])|((a[3]|b[3])&((a[2]&b[2])|((a[2]|b[2])&((a[1]&b[1])|((a[1]|b[1])&((a[0]&b[0])|((a[0]|b[0])&cin)))))));
assign #1
sum[0]=a[0]^b[0]^cin;
assign #1 sum[1]=a[1]^b[1]^co[0];
assign #1
sum[2]=a[2]^b[2]^co[1];
assign #1
sum[3]=a[3]^b[3]^co[2];
endmodule
module mult4(a,b,axb);
input [3:0]
a,b;
output [7:0]
axb;
wire [3:0]
pp0,pp1,pp2,pp3;
assign #1 pp0=b[0]?a:0;
assign #1
pp1=b[1]?a:0;
assign #1
pp2=b[2]?a:0;
assign #1
pp3=b[3]?a:0;
wire [3:0]
s1,s2;
wire c1,c2;
cla4 u1
({1'b0,pp0[3:1]},pp1,1'b0,c1,s1);
cla4 u2
({c1,s1[3:1]},pp2,1'b0,c2,s2);
cla4 u3
({c2,s2[3:1]},pp3,1'b0,axb[7],axb[6:3]);
assign axb[2]=s2[0];
assign axb[1]=s1[0];
assign axb[0]=pp0[0];
endmodule
------------------------------------GTKWAVE---------------------------------------
(B)再以cla4, mult4模組為底,設計8位元乘法器mult8(a[7:0],
b[7:0], axb[15:0]),其中a,b為輸入,axb為輸出。
------------------------------------mult8.v---------------------------------------
module
cla4(a,b,cin,cout,sum);
input [3:0] a,b;
input cin;
output [3:0]
sum;
output cout;
wire [2:0]
co;
assign #1
co[0]=(a[0]&b[0])|((a[0]|b[0])&cin);
assign #1
co[1]=(a[1]&b[1])|((a[1]|b[1])&((a[0]&b[0])|((a[0]|b[0])&cin)));
assign #1
co[2]=(a[2]&b[2])|((a[2]|b[2])&((a[1]&b[1])|((a[1]|b[1])&((a[0]&b[0])|((a[0]|b[0])&cin)))));
assign #1
cout=(a[3]&b[3])|((a[3]|b[3])&((a[2]&b[2])|((a[2]|b[2])&((a[1]&b[1])|((a[1]|b[1])&((a[0]&b[0])|((a[0]|b[0])&cin)))))));
assign #1
sum[0]=a[0]^b[0]^cin;
assign #1
sum[1]=a[1]^b[1]^co[0];
assign #1
sum[2]=a[2]^b[2]^co[1];
assign #1
sum[3]=a[3]^b[3]^co[2];
endmodule
module mult4(a,b,axb);
input [3:0]
a,b;
output [7:0] axb;
wire [3:0]
pp0,pp1,pp2,pp3;
assign #1
pp0=b[0]?a:0;
assign #1
pp1=b[1]?a:0;
assign #1
pp2=b[2]?a:0;
assign #1
pp3=b[3]?a:0;
wire [3:0]
s1,s2;
wire c1,c2;
cla4 u1
({1'b0,pp0[3:1]},pp1,1'b0,c1,s1);
cla4 u2
({c1,s1[3:1]},pp2,1'b0,c2,s2);
cla4 u3
({c2,s2[3:1]},pp3,1'b0,axb[7],axb[6:3]);
assign axb[2]=s2[0];
assign axb[1]=s1[0];
assign axb[0]=pp0[0];
endmodule
module mult8(a,b,axb);
input [7:0]
a,b;
output [15:0]
axb;
wire [7:0]
sum0,sum1,sum2,sum3;
wire cout0,cout1,cout2,cout3;
wire [3:0]
result0,result1,result2,result3,result4;
mult4 V1
(a[3:0],b[3:0],sum0);
mult4 V2
(a[7:4],b[3:0],sum1);
mult4 V3
(a[3:0],b[7:4],sum2);
mult4 V4
(a[7:4],b[7:4],sum3);
cla4 V5
(sum0[7:4],sum1[3:0],1'b0,cout0,result0);
cla4 V6 (result0,sum2[3:0],1'b0,cout1,axb[7:4]);
cla4 V7
(sum1[7:4],sum2[7:4],cout0,cout2,result2);
cla4 V8
(result2,sum3[3:0],cout1,cout3,axb[11:8]);
assign result3=sum3[7:4];
assign #1 result4=cout2?(result3+4'h1):result3;
assign #1
axb[15:12]=cout3?(result4+4'h1):result4;
assign axb[3:0]=sum0[3:0];
endmodule
------------------------------------GTKWAVE---------------------------------------
4.
請設計一8位元回復式除法器,div8(a[7:0],
b[7:0], q[7:0], r[7:0]),其中a為被除數,b為除數,q為商數,r為餘數。
------------------------------------PRcalc8.v---------------------------------------
module PR_calc(a,b,q,PR);
input [15:0] a;
input [7:0] b;
output q;
output [15:0] PR;
assign #1 q=((a<<1)
>= (b<<8))?1:0;
assign #1
PR=q?(a<<1)-(b<<8):(a<<1);
endmodule
module restoring_div4(a,b,q,r);
input [7:0] a,b;
output [7:0] q,r;
wire [15:0] PR1,PR2,PR3,PR4,PR5,PR6,PR7,PR8;
PR_calc U1(a,b,q[7],PR1);
PR_calc U2(PR1,b,q[6],PR2);
PR_calc U3(PR2,b,q[5],PR3);
PR_calc U4(PR3,b,q[4],PR4);
PR_calc U5(PR4,b,q[3],PR5);
PR_calc U6(PR5,b,q[2],PR6);
PR_calc U7(PR6,b,q[1],PR7);
PR_calc U8(PR7,b,q[0],PR8);
assign r=PR8[15:8];
endmodule
------------------------------------GTKWAVE---------------------------------------
沒有留言:
張貼留言
文章有誤或有問題麻煩您留言告知! 謝謝您~~