# 數位系統 第 8 次實驗報告
###### tags: `digital system`
姓名:高聖傑
系級:資工113
學號:B093040016
實驗日期:11/29
## 實驗一
### 內容
- 目標 & 要求
- 模擬並驗證 8-bit magnitude comparator
- 其內部由兩個 4-bit magnitude comparators 所組成
### 過程
從 most significant bit 往 least significant bit
一個一個比,遇到平手就繼續往下比較,若比到最後全都一樣,即是等於。
換句話說就是:若高位提前分出勝負,低位的勝負就沒有那麼重要了。
且最後都沒有分出勝負,才能說雙方平手。
而兩個 4-bit comparators 之間也一樣
以 8-bit 為例,7=MSB,0=LSB,
cmp4_1 負責 [7:4],output L1, G1,cmp4_0 負責 [3:0]
輸出的 L 是小於 (Lesser) 的意思
G 是大於 (Greater) 的意思
E 是等於 (Equal) 的意思
最後連結兩者的核心邏輯就是:
```
L = L1 + E1L0
G = G1 + E1G0
E = E1E0
```
#### module code
```verilog=
module cmp_4bit(output gt, output lt, output eq, input [3:0] A, B);
wire[3:0] x, na, nb, agb, alb;
not(na[0], A[0]);
not(na[1], A[1]);
not(na[2], A[2]);
not(na[3], A[3]);
not(nb[0], B[0]);
not(nb[1], B[1]);
not(nb[2], B[2]);
not(nb[3], B[3]);
xnor(x[0], A[0], B[0]);
xnor(x[1], A[1], B[1]);
xnor(x[2], A[2], B[2]);
xnor(x[3], A[3], B[3]);
and(eq, x[0], x[1], x[2], x[3]);
and(agb[3], A[3], nb[3]);
and(agb[2], x[3], A[2], nb[2]);
and(agb[1], x[3], x[2], A[1], nb[1]);
and(agb[0], x[3], x[2], x[1], A[0], nb[0]);
or(gt, agb[0], agb[1], agb[2], agb[3]);
and(alb[3], na[3], B[3]);
and(alb[2], x[3], na[2], B[2]);
and(alb[1], x[3], x[2], na[1], B[1]);
and(alb[0], x[3], x[2], x[1], na[0], B[0]);
or(lt, alb[0], alb[1], alb[2], alb[3]);
endmodule
module cmp_8bit(output gt, output lt, output eq, input [7:0] A, B);
//L = L1 + E1L0;
//G = G1 + E1G0;
//E = E1E0;
wire l0, l1, g0, g1, e0, e1;
wire[1:0] w;
cmp_4bit cmp4_0(g0, l0, e0, A[3:0], B[3:0]);
cmp_4bit cmp4_1(g1, l1, e1, A[7:4], B[7:4]);
and(w[0], e1, l0);
and(w[1], e1, g0);
and(eq, e1, e0);
or(lt, w[0], l1);
or(gt, w[1], g1);
endmodule
```
#### testbench code
```verilog=
//tb1
`timescale 1ns / 1ps
module tbGen1();
reg[7:0] A, B;
wire eq, gt, lt;
cmp_8bit _tb1(.A(A), .B(B), .eq(eq), .gt(gt), .lt(lt));
initial begin
A = 8'b10101010; B = 8'b10101010;
#10
A = 8'b11010011; B = 8'b10100000;
#10
A = 8'b01010111; B = 8'b01010011;
#10
A = 8'b01111111; B = 8'b10000000;
#10
A = 8'b10010011; B = 8'b10010100;
#10
$finish;
end
endmodule
```
### 模擬結果

兩數字的比較結果正確,有正確判斷大於、小於、等於
## 實驗二
### 內容
- 目標 & 要求
- 模擬並驗證 3-to-8 decoder
- 其內部由兩個 2-to-4 decoders 所組成
### 過程
用 input 的 enable 選擇兩個 decoder 的其中一個來使用
且要把其中一個 enable 反相。
如圖

#### module code
```verilog=
module decoder2to4(output[3:0] y, input[1:0] x, input e);
assign
y[0] = ~x[0] & ~x[1] & e,
y[1] = x[0] & ~x[1] & e,
y[2] = ~x[0] & x[1] & e,
y[3] = x[0] & x[1] & e;
endmodule
module decoder3to8(output[7:0] y, input[2:0] x);
wire ne;
not(ne, x[2]);
decoder2to4 d03(y[3:0], x[1:0], ne);
decoder2to4 d47(y[7:4], x[1:0], x[2]);
endmodule
```
#### testbench code
```verilog=
//tb2
`timescale 1ns / 1ps
module tbGen2();
wire[7:0] y;
reg[2:0] x;
decoder3to8 _tb2(.y(y), .x(x));
initial begin
x = 3'b000;
#10
x = 3'b001;
#10
x = 3'b010;
#10
x = 3'b100;
#10
x = 3'b111;
#10
$finish;
end
endmodule
```
### 模擬結果

decoder 成功根據少量的輸入,選擇正確輸出的 wire
## 實驗三
### 內容
- 目標 & 要求
- 使用 Behavioral level modeling 模擬並驗證 8-to-1 multiplexer
- 使 8-to-1 multiplexer 根據 F(A, B, C, D) = Σ(1, 2, 5, 8, 9, 10, 12, 13) 做對應輸出
### 過程
觀察輸出與 D 的關係,且將觀察結果寫進 Behavioral level modeling 的case區塊裡面。
計算過程如圖:

#### module code
```verilog=
module mux8(output reg Y, input A, B, C, D, input[2:0] sel);
always @ (A, B, C, D, sel)
case (sel)
3'b000: Y = D;
3'b001: Y = ~D;
3'b010: Y = D;
3'b011: Y = 0;
3'b100: Y = 1;
3'b101: Y = ~D;
3'b110: Y = 1;
3'b111: Y = 0;
endcase
endmodule
```
#### testbench code
```verilog=
`timescale 1ns / 1ps
module tbGen3();
reg A, B, C, D;
reg[2:0] sel;
wire Y;
mux8 _tb3(.Y(Y), .A(A), .B(B), .C(C), .D(D), .sel(sel));
initial begin
A = 1'b0; B = 1'b0; C = 1'b0; D = 1'b0; sel = 3'b000;
#10
A = 1'b0; B = 1'b0; C = 1'b0; D = 1'b1; sel = 3'b000;
#10
A = 1'b0; B = 1'b0; C = 1'b1; D = 1'b0; sel = 3'b001;
#10
A = 1'b0; B = 1'b0; C = 1'b1; D = 1'b1; sel = 3'b001;
#10
A = 1'b0; B = 1'b1; C = 1'b0; D = 1'b0; sel = 3'b010;
#10
A = 1'b0; B = 1'b1; C = 1'b0; D = 1'b1; sel = 3'b010;
#10
A = 1'b0; B = 1'b1; C = 1'b1; D = 1'b0; sel = 3'b011;
#10
A = 1'b0; B = 1'b1; C = 1'b1; D = 1'b1; sel = 3'b011;
#10
A = 1'b1; B = 1'b0; C = 1'b0; D = 1'b0; sel = 3'b100;
#10
A = 1'b1; B = 1'b0; C = 1'b0; D = 1'b1; sel = 3'b100;
#10
A = 1'b1; B = 1'b0; C = 1'b1; D = 1'b0; sel = 3'b101;
#10
A = 1'b1; B = 1'b0; C = 1'b1; D = 1'b1; sel = 3'b101;
#10
A = 1'b1; B = 1'b1; C = 1'b0; D = 1'b0; sel = 3'b110;
#10
A = 1'b1; B = 1'b1; C = 1'b0; D = 1'b1; sel = 3'b110;
#10
A = 1'b1; B = 1'b1; C = 1'b1; D = 1'b0; sel = 3'b111;
#10
A = 1'b1; B = 1'b1; C = 1'b1; D = 1'b1; sel = 3'b111;
#10
$finish;
end
endmodule
```
### 模擬結果

8-to-1 mux 有正確在 1, 2, 5, 8, 9, 10, 12, 13 的位置輸出 1
## 實驗心得
> 這次的實驗主要是讓我們練習用 verilog 程式碼實做 Magnitude Comparator, Decoder, Multiplexer 的 module。
> 在做實驗一時,我們觀察到一個現象,不論是單 bit 或是整個區塊的比較器,都是從 most significant bit 往 least significant bit
往下比較,這是因為低位的權重沒有高位的權重來的重要。
> 換句話說就是:若高位提前分出勝負,低位的勝負就沒有那麼重要了。
且最後都沒有分出勝負,才能說雙方平手。
> 實驗二是用兩個 2-to-4 decoders 組成一個 3-to-8 decoder,
有編碼,就有解碼,不知道以後會不會做到 encoder 呢?
> 實驗三要實做一個 8-to-1 multiplexer,過程上沒遇到什麼大問題,就是看錯幾次。我到對答案的時候才發現,可以做下面已經給好答案的,這次就把他當作是我自己想練習囉 XD