# 數位系統實驗報告Lab10 :::info 學號: B093040044 系級: 資工113 姓名: 蔡明軒 ::: ``` 實驗日期: 2021/11/22 ``` ## 實驗一 ### 內容 - 用Stuctural level modeling設計並驗證一個由兩個4-bit carry-look ahead adders組成的8-bit carry-look ahead adder ### 過程 1. 利用$C_{i+1}=G_i+P_iC_i$,推出各項carry $C_1=G_0+P_0C_0$ $C_2=G_1+P_1C_1=G_1+P_1G_0+P_1P_0C_0$ $C_3=G_2+P_2C_2=G_2+P_2G_1+P_2P_1G_0+P_2P_1P_0C_0$ $C_4=G_3+P_3C_3=G_3+P_3G_2+P_3P_2G_1+P_3P_2P_1G_0+P_3P_2P_1P_0C_0$ 2. 將以上式子寫成Verilog的module,名稱為carry_lookahead_generator ```verilog= module carry_lookahead_generator(P,G,C0,C); input[3:0] P,G; input C0; output[3:0] C; wire[9:0] w; and(w[0],P[0],C0); or(C[0],w[0],G[0]); and(w[1],P[1],P[0],C0); and(w[2],P[1],G[0]); or(C[1],G[1],w[1],w[2]); and(w[3],P[2],P[1],P[0],C0); and(w[4],P[2],P[1],G[0]); and(w[5],P[2],G[1]); or(C[2],G[2],w[3],w[4],w[5]); and(w[6],P[3],P[2],P[1],P[0],C0); and(w[7],P[3],P[2],P[1],G[0]); and(w[8],P[3],P[2],G[1]); and(w[9],P[3],G[2]); or(C[3],G[3],w[6],w[7],w[8],w[9]); endmodule ``` 3. 根據$P_i=A_i\oplus B_i,G_i=A_iB_i$, 對陣列A,B的每個bit算出carry propagate ( P ) 及carry generator ( G ) ,之後再將P,G放入剛剛寫的carry_lookahead_generator,完成4-bit carry-look ahead adder ```verilog= module four_bit_adder(A,B,C0,S,C4); input[3:0] A,B; input C0; output[3:0] S; output C4; wire[3:0] P,G,C; xor(P[0],A[0],B[0]); and(G[0],A[0],B[0]); xor(P[1],A[1],B[1]); and(G[1],A[1],B[1]); xor(P[2],A[2],B[2]); and(G[2],A[2],B[2]); xor(P[3],A[3],B[3]); and(G[3],A[3],B[3]); carry_lookahead_generator clg(P,G,C0,C); buf(C4,C[3]); xor(S[3],C[2],P[3]); xor(S[2],C[1],P[2]); xor(S[1],C[0],P[1]); xor(S[0],C0,P[0]); endmodule ``` 4. 將8-bit的A,B分別切成一半,使用兩個4-bit carry-lookahead adder處理,其中,後半段陣列的adder(ADD_1)所輸出的$C_4$,會變成前半段陣列adder(ADD_2)的$C_0$ ```verilog= module eight_bit_adder(A,B,C0,S,C8); input[7:0] A,B; input C0; output[7:0] S; output C8; wire C4; four_bit_adder ADD1(A[3:0],B[3:0],C0,S[3:0],C4) ,ADD2(A[7:4],B[7:4],C4,S[7:4],C8); endmodule ``` 5. 撰寫testbench檔案,變數名稱和實驗提供的ppt相同 - 依助教需求,我產生了四組測試資料 | 測資 | A | B | | --- | --- | ---- | | 1 | 200 | 58 | | 2 | 0 | 87 | | 3 | 88 | 12 | | 4 | 142 | 103 | ```verilog= `timescale 1ns / 1ps module tb; reg[7:0] A; reg[7:0] B; reg C0; wire[7:0]S; wire C8; eight_bit_adder UUT(.A(A),.B(B),.C0(C0),.S(S),.C8(C8)); initial begin A=8'd200;B=8'd58; C0=1'b0; #10 A=8'd0;B=8'd87; C0=1'b0; #10 A=8'd88;B=8'd12; C0=1'b0; #10 A=8'd142;B=8'd103; C0=1'b0; #10 $finish; end endmodule ``` 6. Run Synthesis and Simulation 7. 確認結果是否符合預期 ### 結果 - 預期結果如下 | 測資 | A | B |S|C8| | --- | --- | ---- |-|-| | 1 | 200 | 58 |2|1| | 2 | 0 | 87 |87|0| | 3 | 88 | 12 |100|0| | 4 | 142 | 103 |245|0| - 輸出結果和上面的預期結果相同 ![](https://i.imgur.com/sMzy2uh.png) ## 實驗二 ### 內容 - 設計並驗證一個 2-digit decimal adder ### 過程 1. 首先要實作1-bit的decimal_adder先對A,B兩組bit array做相加,並將答案存在K及temp,再利用$C=K+Z_8Z_4+Z_8Z_2$,確認temp是否需要再 +6 ,這裡是利用C生成一個長度為四命名為six的bit array,若C是1,six為0110,反之則為0000,最後將temp和six相加就會得到答案。 ```verilog= module decimal_adder(A,B,C0,Z,C); input[3:0] A,B; input C0; output[3:0] Z; output C; wire K,w1,w2,w3; wire[3:0] six,temp; assign{K,temp} = A+B+C0; and(w1,temp[3],temp[2]); and(w2,temp[3],temp[1]); or(C,K,w1,w2); and(six[3],C,0); and(six[2],C,1); and(six[1],C,1); and(six[0],C,0); assign{w3,Z}=temp+six; endmodule ``` 2. 接著要將兩個1-bit的decimal_adder組合成2-bit的形式,這裡把A,B兩個長度為8的bit array切成一半,後半給ADD1處理,再將得到的carry傳輸到ADD2,和前半段的bit array一起處理。 ```verilog= module two_digit_decimal_adder(A,B,C0,Z,C); input[7:0] A,B; input C0; output[7:0] Z; output C; wire temp; decimal_adder ADD1(A[3:0],B[3:0],C0,Z[3:0],temp); decimal_adder ADD2(A[7:4],B[7:4],temp,Z[7:4],C); endmodule ``` 3. 撰寫testbench,這裡我們將ppt所給的數字先轉成BCD,再輸進去testbench裡面 - 測資表 | 測資 | A | B | | -------- | -------- | -------- | | 1 | 32 | 41 | | 2 | 25 | 57 | | 3 | 86 | 79 | ```verilog= `timescale 1ns / 1ps module tb; reg[7:0] A; reg[7:0] B; reg C0; wire[7:0]Z; wire C; two_digit_decimal_adder UUT(.A(A),.B(B),.C0(C0),.Z(Z),.C(C)); initial begin A=8'b00110010;B=8'b01000001; C0=1'b0; #10 A=8'b00100101;B=8'b01010111; C0=1'b0; #10 A=8'b10000110;B=8'b01111001; C0=1'b0; #10 $finish; end endmodule ``` 4. Run Synthesis and Simulation 5. 確認結果是否符合預期 ### 結果 - 預期結果如下 | 測資 | A | B |S |C| | --- | --- | ---- |- |-| | 1 | 32 | 41 |73|0| | 2 | 25 | 57 |82|0| | 3 | 86 | 79 |65|1| - 輸出結果與上面的預期結果相同(輸出為十六進位制) ![](https://i.imgur.com/u4DX330.png) ## 實驗心得 >這次的實驗主要是實作上上週的正課課程,carry lookahead adder以及decimal adder。首先,實驗一為實作出8-bit的carry lookahead adder,在實作的過程中,我原本想要直接拿$C_1$的結果直接算出$C_2$,但在仔細思考過後,發現這樣會變成很多level的電路,導致速度較差,達不到carry lookahead adder的效果,於是我最後決定還是乖乖把$C_1$展開,實作速度較快的carry lookahead adder。 >我在實驗二花了不少的時間,最大的原因可能是因為我不太熟悉Behavioral Level Modeling,我把 {K,temp}=A+B+C0寫成了{K,temp}={A+B+C0},我找這個錯誤找了快一個小時,直到我向助教求助後才發現我多加了大括號,並解決掉輸出不對的問題。 >課堂結束後,我有試著把{A+B+C0}輸出出來(A,B都是長度為四的bit array),發現A+B就算是有進位的狀況,輸出結果最大的那一位仍然還是0,這很有可能就是我發生錯誤的原因。 - 測試畫面 ![](https://i.imgur.com/qX4QJSu.png)