# 數位系統 第四次實驗報告 ###### tags: `digital system` 姓名:高聖傑 系級:資工113 學號:B093040016 實驗日期:2021/11/1 ## 實驗一 ### 內容 - 目標 & 要求 - $F(w,x,y,z)=w'yz + w'xy + wxy + xyz + wx'y'$ - 畫出 F 的 K map,並找到所有最簡 sum of products as F1, F2 ... Fn - 使用 dataflow level modeling 模擬並驗證所有最簡 sum of products 等效 ### 過程 先依照 $w'yz + w'xy + wxy + xyz + wx'y'$ 畫出 F 的 K map ![](https://i.imgur.com/3yOtWGE.jpg =360x) 樣子是個樓梯,可以用 4 個 2x1 或 1x2 的區域拼起來,共有 3 種組合方式 - $F_1=w′yz′+xyz+wy′z+wx′y′$ ![](https://i.imgur.com/oBnWomS.jpg =360x) - $F_2=w′yz′+w′xy+wxz+wx′y′$ ![](https://i.imgur.com/xOJOGgj.jpg =360x) - $F_3=w′yz′+xyz+wxz+wx′y′$ ![](https://i.imgur.com/VG6bblD.jpg =360x) 以下的 module exe1_1, exe1_2, exe1_3 分別為 F1, F2, F3 三個 module 皆使用 dataflow level modeling ```verilog= `timescale 1ns / 1ps module exe1_1(w,x,y,z,res); input w,x,y,z; output res; assign res = (~w&y&~z) | (x&y&z) | (w&~y&z) | (w&~x&~y); endmodule module exe1_2(w,x,y,z,res); input w,x,y,z; output res; assign res = (~w&y&~z) | (~w&x&y) | (w&x&z) | (w&~x&~y); endmodule module exe1_3(w,x,y,z,res); input w,x,y,z; output res; assign res = (~w&y&~z) | (x&y&z) | (w&x&z) | (w&~x&~y); endmodule ``` ### 模擬結果 res1 → F1 , res2 → F2 , res3 → F3 ![e1](https://i.imgur.com/YhQ1bhF.png =700x) 三個 function 所產生的波形圖一樣,因此可證明 $F_1, F_2, F_3$ 等效 ## 實驗二 ### 內容 - 目標 & 要求 - $F1(v,w,x,y,z) = \Sigma(1,2,3,6,7,9,10,11,14,15,17,18,19,22,25,26,27,30)$ - 畫出 F1 的 K map - 並利用此 K map ,找出最簡 sum of products as F2 - 使用 Structural level modeling 模擬並驗證 F1, F2 等效 ### 過程 由以下圖之 K map ,可化簡:$F2 = x'z + v'y + yz'$ ![](https://i.imgur.com/kbc7EV2.png =700x) 以下的 module exe2_1, exe2_2 分別為 F1, F2 兩者皆使用 Structural level modeling ```verilog= `timescale 1ns / 1ps module exe2_1(v, w, x, y, z, res); input v, w, x, y, z; output res; wire nv, nw, nx, ny, nz; wire m1, m2, m3, m6, m7, m9, m10, m11, m14, m15, m17, m18, m19, m22, m25, m26, m27, m30; not(nv, v); not(nw, w); not(nx, x); not(ny, y); not(nz, z); and(m1,nv,nw,nx,ny, z); and(m2,nv,nw,nx, y,nz); and(m3,nv,nw,nx, y, z); and(m6,nv,nw, x, y,nz); and(m7,nv,nw, x, y, z); and(m9,nv, w,nx,ny, z); and(m10,nv, w,nx, y,nz); and(m11,nv, w,nx, y, z); and(m14,nv, w, x, y,nz); and(m15,nv, w, x, y, z); and(m17, v,nw,nx,ny, z); and(m18, v,nw,nx, y,nz); and(m19, v,nw,nx, y, z); and(m22, v,nw, x, y,nz); and(m25, v, w,nx,ny, z); and(m26, v, w,nx, y,nz); and(m27, v, w,nx, y, z); and(m30, v, w, x, y,nz); or(res, m1, m2, m3, m6, m7, m9, m10, m11, m14, m15, m17, m18, m19, m22, m25, m26, m27, m30); endmodule module exe2_2(v, w, x, y, z, res); input v, w, x, y, z; output res; wire nv, nx, nz, a1, a2, a3; not(nv, v); not(nx, x); not(nz, z); and(a1, nv, y); and(a2, nx, z); and(a3, y, nz); or(res, a1, a2, a3); endmodule ``` ### 模擬結果 res1 → F1 , res2 → F2 ![e2](https://i.imgur.com/pnSplh1.png =700x) 兩個 function 所產生的波形圖一樣,因此可證明 $F_1, F_2$ 等效 ## 實驗三 ### 內容 - 目標 & 要求 - 使用 K map & don’t-care conditions,設計 4 位元輸入的 9 補數轉換器 - 畫出 9 補數轉換器的 logic diagram - 使用 Structural level modeling 模擬並驗證此轉換器 ### 過程 使用 K map & don’t-care conditions 化簡 - $y_3=x_3'x_2'x_1'$ ![](https://i.imgur.com/aWmmTxj.jpg =360x) - $y_2=x_1\oplus x_2$ ![](https://i.imgur.com/RN1GIRo.jpg =360x) - $y_1=x_1$ ![](https://i.imgur.com/8Ji1M4l.jpg =360x) - $y_0=x_0'$ ![](https://i.imgur.com/x1bC1co.jpg =360x) 由以上 K map 可得 9 補數轉換器的 logic diagram ![](https://i.imgur.com/yrSRrnf.png =650x) ```verilog= `timescale 1ns / 1ps module exe3( x0, x1, x2, x3, y0, y1, y2, y3); input x0, x1, x2, x3; output y0, y1, y2, y3; wire nx1, nx2, nx3; not(y0, x0); not(nx1, x1); not(nx2, x2); not(nx3, x3); buf(y1, x1); xor(y2, x1, x2); and(y3, nx1, nx2, nx3); endmodule ``` ### 模擬結果 $D → x_0, C → x_1, B → x_2, A → x_3$ ![e3](https://i.imgur.com/Ew1l652.png =700x) 由 waveform 可確認 9 補數轉換器的輸出正確 ## testbench code 3 個實驗皆使用我額外寫的 python 腳本, 所自動生成的 testbench code,最後加上部分修改。 僅展示實驗 1 之 tb.v,其餘實驗大致相同 ```verilog= `timescale 1ns / 1ps module tbGen(); reg A, B, C, D; wire res1, res2, res3; exe1_1 _tb1(.w(A), .x(B), .y(C), .z(D), .res(res1)); exe1_2 _tb2(.w(A), .x(B), .y(C), .z(D), .res(res2)); exe1_3 _tb3(.w(A), .x(B), .y(C), .z(D), .res(res3)); initial begin A = 1'b0; B = 1'b0; C = 1'b0; D = 1'b0; #10 A = 1'b0; B = 1'b0; C = 1'b0; D = 1'b1; #10 A = 1'b0; B = 1'b0; C = 1'b1; D = 1'b0; #10 A = 1'b0; B = 1'b0; C = 1'b1; D = 1'b1; #10 A = 1'b0; B = 1'b1; C = 1'b0; D = 1'b0; #10 A = 1'b0; B = 1'b1; C = 1'b0; D = 1'b1; #10 A = 1'b0; B = 1'b1; C = 1'b1; D = 1'b0; #10 A = 1'b0; B = 1'b1; C = 1'b1; D = 1'b1; #10 A = 1'b1; B = 1'b0; C = 1'b0; D = 1'b0; #10 A = 1'b1; B = 1'b0; C = 1'b0; D = 1'b1; #10 A = 1'b1; B = 1'b0; C = 1'b1; D = 1'b0; #10 A = 1'b1; B = 1'b0; C = 1'b1; D = 1'b1; #10 A = 1'b1; B = 1'b1; C = 1'b0; D = 1'b0; #10 A = 1'b1; B = 1'b1; C = 1'b0; D = 1'b1; #10 A = 1'b1; B = 1'b1; C = 1'b1; D = 1'b0; #10 A = 1'b1; B = 1'b1; C = 1'b1; D = 1'b1; #10 $finish; end endmodule ``` ## 實驗心得 > 這次的實驗主要是練習 verilog 程式碼以及 K map 化簡的實驗。 > > 實驗一做到模擬的時候 vivado 當掉了,我把他強制關掉,結果就沒辦法再次模擬了,搞的我要重開一個專案才能完成實驗 > > 在做實驗二的時候,覺得重複性過高,所以我當場寫了一個 python 腳本,讓我能在 2 分鐘內完成程式中有一大串 AND 的部分,省下大量時間,也省得我複製貼上、一個字一個字改的精力,甚至是以後做類似實驗也可以用上。 > > 第三個實驗有遇到需要直接把 input x1 接到 output y2 上的部分,但這不像其他兩種設計方式可以直接 assign 上去。於是我想到課堂中提到的 buffer 元件,我先試了 buffer(),發現沒有變色,換成 buf() 就正確了,後來有聽到助教提醒 buffer 的寫法是 buf(),覺得能自己試出來也是挺酷的。 ## Extra Coding 在做實驗二的時候,覺得重複性過高,所以我當場寫了一個臨時用的 python 腳本,這裡是我課後改良的版本,替換掉當時為了貪快而寫死的東西,也改良到不用額外補字了。 他可以根據第 4 行 ts 給予的 canonical form ,生成 module 裡 sum of products 的部分。 > product of sums 也可以,把第 20, 22 行的 and, or 交換, > 然後第 4 行的 ts 改成找題目 result 裡的 maxterm 即可。 ```python= # num of ports n = 5 # canonical form ts = [1,2,3,6,7,9,10,11,14,15,17,18,19,22,25,26,27,30] # lookups c = ord('z')+1-n ports = list(map(chr, range(c, ord("z")+1))) r = range(n) # wires print(f'wire n{", n".join(map(str, ports))};') print(f'wire m{", m".join(map(str, ts))};\n') # nots for i in r: print(f"not(n{chr(c+i)}, {chr(c+i)});") # products for i in range(2**n): # print(f"{f'{i:0{n}b}'}") if i in ts: tgt = ["n "[int(j)]+k for j,k in zip(f"{f'{i:0{n}b}'}", ports)] print(f"and(m{i}, {','.join(tgt)});") # sum print(f"or(res, m{', m'.join(map(str, ts))});") ``` ### 測試生成結果 測試生成參數: 3 個接口 (n = 3),欲求 sum of products = $\Sigma(m_1, m_2, m_3, m_6, m_7)$ (ts = [1,2,3,6,7]) ```verilog= wire nx, ny, nz; wire m1, m2, m3, m6, m7; not(nx, x); not(ny, y); not(nz, z); and(m1, nx,ny, z); and(m2, nx, y,nz); and(m3, nx, y, z); and(m6, x, y,nz); and(m7, x, y, z); or(res, m1, m2, m3, m6, m7); ```