# 數位系統實驗報告Lab12
:::info
學號: B093040044
系級: 資工113
姓名: 蔡明軒
:::
```
實驗日期: 2021/12/6
```
## 實驗一
### 內容
- 利用Structural level modeling,設計並驗證D Latch

### 過程
1. 參考PPT上的電路圖,撰寫 D Latch 檔案
```verilog=
`timescale 1ns/1ps
module D_Latch (
output Q,Qb,
input En,D
);
wire Db,I1,I2;
not(Db,D);
nand(I1,D,En);
nand(I2,Db,En);
nand(Q,Qb,I1);
nand(Qb,Q,I2);
endmodule
```
2. 撰寫testbench檔案
```verilog=
`timescale 1ns / 1ps
module tb ();
reg En,D;
wire Q,Qb;
D_Latch DL(.Q(Q),.Qb(Qb),.En(En),.D(D));
initial begin
En=1'b0;D=1'b0;
#10 En=1'b1;D=1'b0;
#10 En=1'b0;D=1'b0;
#10 En=1'b1;D=1'b1;
#10 En=1'b0;D=1'b0;
#10 $finish;
end
endmodule
```
3. Run Synthesis and Simulation
4. 確認結果是否符合預期
### 結果
| En | D | Next state of Q |
|:---:|:---:|:---------------:|
| 0 | X | No change |
| 1 | 1 | 1 |
| 1 | 0 | 1 |
- 輸出結果符合上面的Function table的行為

## 實驗二
### 內容
- 利用Structural level modeling,設計並驗證正緣觸發的 master-slave D flip-flop
### 過程
1. Master-slave D flip-flop 其實是由兩個 D latch組成,我直接使用我在實驗一裡所寫的D latch
```verilog=
module D_Latch (
output Q,Qb,
input En,D
);
wire Db,I1,I2;
not(Db,D);
nand(I1,D,En);
nand(I2,Db,En);
nand(Q,Qb,I1);
nand(Qb,Q,I2);
endmodule
```
2. 將兩個D latch組合在一起,因為是正緣觸發,所以clk訊號放在slave,nclk(~clk)訊號放在master
```verilog=
module Master_slave_D_FlipFlop (
output Q,Qb,
input D,clk
);
wire nclk,Y,nY;
not(nclk,clk);
D_Latch Master(Y,nY,nclk,D), Slave(Q,Qb,clk,Y);
endmodule
```
3. 撰寫testbench檔案,這裡的testbench是直接參考前面PTT所給的範例而完成的
```verilog=
`timescale 1ns / 1ps
module tb ();
reg D, clk;
wire Q, Qb;
Master_slave_D_FlipFlop M1(.Q(Q), .Qb(Qb), .D(D), .clk(clk));
initial #100 $finish;
initial begin clk = 0; forever #5 clk = ~clk; end
initial fork
D = 1;
#20 D = 0;
#40 D = 1;
#50 D = 0;
#60 D = 1;
#70 D = 0;
#90 D = 1;
join
endmodule
```
4. Run Synthesis and Simulation
5. 確認結果是否符合預期
### 結果
- 每次clk為正緣的時候,Q和D相同,且Q只在正緣的時候變化,符合預期的結果

## 實驗三
### 內容
- 利用Structural level modeling,設計並驗證有 asynchronous reset 的 D flip-flop

### 過程
1. 參考PPT上的電路給的電路圖,撰寫有 asynchronous reset 的 D flip-flop
```verilog=
`timescale 1ns / 1ps
module D_FlipFlop_AR (
output Q,Qb,
input D,Clock,Reset
);
wire S,nS,R,nR;
nand(nS,S,nR);
nand(S,Clock,Reset,nS);
nand(nR,D,Reset,R);
nand(R,Clock,nR,S);
nand(Q,Qb,S);
nand(Qb,Q,R,Reset);
endmodule
```
2. 撰寫testbench檔案,這裡的testbench是直接參考前面PTT所給的範例而完成的
```verilog=
`timescale 1ns / 1ps
module tb ();
reg D, Clock,Reset;
wire Q, Qb;
D_FlipFlop_AR D1(.Q(Q), .Qb(Qb), .D(D), .Clock(Clock),.Reset(Reset));
initial #100 $finish;
initial begin Clock = 0; forever #5 Clock = ~Clock; end
initial fork
D = 1;
Reset = 1;
#20 D = 0;
#40 D = 1;
#50 D = 0;
#60 D = 1;
#70 D = 0;
#90 D = 1;
#42 Reset = 0;
#72 Reset = 1;
join
endmodule
```
3. Run Synthesis and Simulation
4. 確認結果是否符合預期
### 結果
- 每次clk為正緣且reset=1的時候,Q和D相同,且Q只在正緣且reset=1的時候變化,符合預期的結果

## 實驗心得
>這次實驗的內容為各種序向邏輯電路,包括D Latch,Flip-Flop,第一個實驗為實作D Latch,在撰寫Testbench的時候,我有發現一個問題,因為我一開始只是按照之前二進制的順序作為輸入,但是在模擬結果出現的時候,發現這樣的輸入沒辦法測試所有狀況(在En = 0的時候,輸出會跟上一輪的結果有關),因此,我後來改成把En = 0 的測試資料插入在En = 1的狀況之後,這樣就可以確認En = 0是否有No change的特性了。
>實驗二及實驗三因為有clock及reset訊號的加入,設計一個好的testbench難度又提高了,幸好在PPT的前面有提供一個範例的testbench,我只要觀察結果是否有符合Flip-Flop的特性即可。
>另外,在做實驗三的時候,因為電路圖長得很像3個合在一起的D Latch,我一開始想嘗試利用實驗一所寫的D Latch來寫成有 asynchronous reset 的 D flip-flop,但是後來發現電路圖中每個很像D Latch的部分都多了一個input去接收Reset訊號,所以後來就決定用一個一個邏輯閘撰寫了。