# 數位系統 第四次實驗報告
###### 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

樣子是個樓梯,可以用 4 個 2x1 或 1x2 的區域拼起來,共有 3 種組合方式
- $F_1=w′yz′+xyz+wy′z+wx′y′$

- $F_2=w′yz′+w′xy+wxz+wx′y′$

- $F_3=w′yz′+xyz+wxz+wx′y′$

以下的 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

三個 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'$

以下的 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

兩個 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'$

- $y_2=x_1\oplus x_2$

- $y_1=x_1$

- $y_0=x_0'$

由以上 K map 可得 9 補數轉換器的 logic diagram

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

由 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);
```