# 數位系統實驗報告Lab15
:::info
學號: B093040044
系級: 資工113
姓名: 蔡明軒
:::
```
實驗日期: 12/27
```
## 實驗一
### 內容
- 使用 Verilog HDL ,設計並驗證一個 four-bit universal shift register
### 過程
1. 寫出 four-bit universal shift register 會使用到的 D-flipflop 及 4x1 multiplexer
```verilog=
module D_flip_flop (Q, Q_b, D, Clk, rst);
output Q, Q_b;
input D, Clk, rst;
reg Q;
assign Q_b = ~Q;
always @ (posedge Clk, negedge rst)
if (rst == 0) Q <= 1'b0;
else Q <= D;
endmodule
module mux_4x1(output reg Y,input[3:0] I,input [1:0] S);
always @(I, S)
case (S)
2'b00: Y = I[0];
2'b01: Y = I[1];
2'b10: Y = I[2];
2'b11: Y = I[3];
endcase
endmodule
```
2. 透過 ppt 所給的電路圖,連接所有的 flip-flop 及 multiplexer,完成four-bit universal shift register
```verilog=
module Shift_Register_4_beh(output[3:0] A,input[3:0] I,input[1:0] S,
input MSB_in,input LSB_in,input Clk,input Clear);
wire Q_b0,Q_b1,Q_b2,Q_b3;
wire[3:0] y;
D_flip_flop D3(A[3],Q_b3,y[3],Clk,Clear)
,D2(A[2],Q_b2,y[2],Clk,Clear)
,D1(A[1],Q_b1,y[1],Clk,Clear)
,D0(A[0],Q_b0,y[0],Clk,Clear);
mux_4x1 M3(y[3],{I[3],A[2],MSB_in,A[3]},S),M2(y[2],{I[2],A[1],A[3],A[2]},S)
,M1(y[1],{I[1],A[0],A[2],A[1]},S),M0(y[0],{I[0],LSB_in,A[1],A[0]},S);
endmodule
```
3. 撰寫 testbench 檔案
```verilog=
`timescale 1ns / 1ps
module tb();
reg[1:0] S;
reg MSB_in, LSB_in;
reg clk, reset_b;
reg [3: 0] I_par;
wire [3: 0] A_par;
Shift_Register_4_beh M0 (A_par, I_par,S, MSB_in, LSB_in, clk, reset_b);
initial #200 $finish;
initial begin clk = 0; forever #5 clk = ~clk; end
initial fork
// test reset action load
#3 reset_b = 1;
#4 reset_b = 0;
#9 reset_b = 1;
// test parallel load
#10 I_par = 4'hA;
#10 S = 2'b11;
// test shift right
#30 MSB_in = 1'b0;
#30 S = 2'b01;
// test shift left
#80 LSB_in = 1'b1;
#80 S = 2'b10;
// test circulation of data
#130 S = 2'b11;
#140 S = 2'b00;
// test reset on the fly
#150 reset_b = 1'b0;
#160 reset_b = 1'b1;
#160 S = 2'b11;
join
endmodule
```
### 結果
- 預期結果
| tick | mode | Output |
|:----:|:----------------:|:------:|
| #15 | load | 1010 |
| #35 | shift right | 0101 |
| #45 | shift right | 0010 |
| #55 | shift right | 0001 |
| #65 | shift right | 0000 |
| #85 | shift left | 0001 |
| #95 | shift left | 0011 |
| #105 | shift left | 0111 |
| #115 | shift left | 1111 |
| #125 | shift left | 1111 |
| #135 | load | 1010 |
| #145 | No change | 1010 |
| #150 | No change(reset) | 0000 |
| #165 | load | 1010 |
- 輸出結果符合上面的預期結果
![](https://i.imgur.com/ycWyTrw.png)
## 實驗二
### 內容
- 使用有 asynchoronous reset 的 T-flip-flops 及 Verilog HDL,設計並驗證一個 BCD synchronous counter
### 過程
1. 撰寫實驗會用到的 T-flpflop
```verilog=
module T_flip_flop (Q, Q_b, T, Clk, rst);
output Q, Q_b;
input T, Clk, rst;
reg Q;
assign Q_b = ~Q;
always @ (posedge Clk, negedge rst)
if (rst == 0) Q <= 1'b0;
else Q <= (Q^T);
endmodule
```
2. 參考 ppt 所提供的 boolean function,用 structural modeling 完成 BCD synchronous counter
$T_{Q1}=1,T_{Q2}=Q_8'Q_1$
$T_{Q_4}=Q_2Q_1,T_{Q8}=Q_8Q_1+Q_4Q_2Q_1$
$y=Q_8Q_1$
```verilog=
module BCD_synchronous_counter (
output[3:0] Q,
output y,
input Clk,
input rst
);
wire Q_b8,Q_b4,Q_b2,Q_b1,TQ2,TQ4,TQ8,w1;
and(y,Q[3],Q[0]);
and(TQ4,Q[1],Q[0]);
and(w1,TQ4,Q[2]);
or(TQ8,w1,y);
and(TQ2,~Q[3],Q[0]);
T_flip_flop T8(Q[3],Q_b8,TQ8,Clk,rst),T4(Q[2],Q_b4,TQ4,Clk,rst)
,T2(Q[1],Q_b2,TQ2,Clk,rst),T1(Q[0],Q_b1,1'b1,Clk,rst);
endmodule
```
3. 撰寫 testbench 檔案
```verilog=
`timescale 1ns / 1ps
module tb;
wire[3:0] Q;
wire y;
reg Clk, rst;
BCD_synchronous_counter M1(Q,y,Clk,rst);
initial #120 $finish;
initial begin Clk = 0; forever #5 Clk = ~Clk; end
initial fork
rst = 0;
#2 rst = 1;
join
endmodule
```
### 結果
- 從 0000 數到 1001 在數到 1001 時,y有輸出 1 ,且下個 state 有回到 0000,符合 BCD Counter的行為
![](https://i.imgur.com/6ETWfiS.png)
## 實驗心得
>這次的實驗內容為 Universal shift register 及 BCD Counter,而實驗一就是要我們去設計一個四位元的Universal shift register,這種的 register 功能十分強大,可以平行讀入、控制新的bit要從左邊或右邊加入,聽起來雖然很複雜,但在實作上,它也只是運用我們之前學過的多工器,就可以達到我們要的控制效果。
>實驗二則是 BCD Synchronous Counter 的實作,相較於Ripple Counter,Synchronous Counter 的設計方式更為直觀,只要像上周的實驗一樣,畫出 state diagram,state table,就可以直接推出input equation,實作出 Synchronous Counter。