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---------------------------------------




 
沒有留言:
張貼留言
文章有誤或有問題麻煩您留言告知! 謝謝您~~