# Testbench 介紹
###### tags: `verilog` `digital design` `邏輯設計` `邏設`
[TOC]
## 前言
在寫完程式碼之後,勢必要測試它是否正確,而 testbench (簡稱 tb)就是用來幫助我們測試我們的程式是否有誤的方法。
:::warning
testbench 基本上也是一個 verilog 檔案( .v ),所以裡面也是由一個 module 組成,不同的地方在於,一般 verilog 檔案會燒進電路板裡,而 testbench <font color=#bf2222>只是讓我們在電腦模擬的檔案罷了</font>。因此,可以用一些方便的工具執行,例如,<font color=#bf2222> for 迴圈、integer...</font>等。
:::
## 寫法
這裡介紹一種最簡單的模板供大家使用,有興趣的,可以再自己深入研究。
## <font color = #1644aa>step 1</font>
> 首先,我們必須觀察我們寫好的 verilog 檔,判斷哪些是 input ,哪些是 output。
>
> 舉例來說:
> ```clike=
> module Binary_to_Grey (din, dout);
> input [4-1:0] din;
> output [4-1:0] dout;
>
> assign dout = {1'b0, din[4-1:1]} ^ din;
>
> endmodule
>
> ```
>
> 由此範例可得, input 為 din,而 output 為 dout。
## <font color = #1644aa>step 2</font>
> 剛剛說過,tb 也是一個 verilog 檔案,所以起手式都一樣。
> ```clike=
> `timescale 1ns / 1ps //時間參數,請打在 tb 的第一行
>
> module Testbench(); // 由於 tb 是沒有 input , output 的,所以括號裡面不用放東西。
>
> // 直接進入 參數設定
> reg [3:0] din;
> wire[3:0] dout;
> reg CLK;
>
> .
> .
> .
> endmodule
>
> ```
>
## <font color = #1644aa>step 3</font>
> 接著要呼叫我們剛剛寫好的程式碼(呼叫裡面的 module)
> ```clike=
> `timescale 1ns / 1ps
>
> module Testbench(); // 由於 tb 是沒有 input , output 的,所以括號裡面不用放東西。
>
> // 直接進入 參數設定
> reg [3:0] din;
> wire[3:0] dout;
> reg CLK;
>
> Binary_to_Grey name(.din(din), .dout(dout) );
> .
> .
> .
> endmodule
> ```
> * <font color = #bf222>name </font> 是幫這個呼叫取一個名字,因為在之後寫 code 時,每個 module 通常不會只呼叫一次,所以每一個呼叫都需要一個名字,且不能一樣。
>
## <font color = #1644aa>step 4</font>
> 設置常數。
> ```clike=
> `timescale 1ns / 1ps
>
> module Testbench();
>
> reg [3:0] din;
> wire[3:0] dout;
> reg CLK;
>
> Binary_to_Grey name(.din(din), .dout(dout) );
>
> always #5 CLK = ~CLK;
> initial CLK = 1'b1;
> .
> .
> .
> endmodule
>```
><font color = #bf222>always #5</font> 指的是<font color=#bf222>每經過 5 個 cycles </font>,就跑一次後面的式子。
> <font color = #bf222>initial </font> 指的是程式一開始執行時,就先運行這一行式子。
>
## <font color = #1644aa>step 5</font>
> 開始運算
> ```clike=
> `timescale 1ns / 1ps
>
> module Testbench();
>
> reg [3:0] din;
> wire[3:0] dout;
> reg CLK;
>
> Binary_to_Grey name(.din(din), .dout(dout) );
>
> always #5 CLK = ~CLK;
> initial CLK = 1'b1;
>
> initial begin
> din = 4'b0000; //給 din 一個初值
> repeat (2 ** 4) begin //重複 2 ^ 4 次以下這個動作
> @(posedge CLK)
> test; //先照抄
> @(nededge CLK)
> din = din + 1'b1; // din 變成下一個數字
> end
> end
> $finish
>
> .
> .
> .
>
>endmodule
>```
## <font color = #1644aa>step 6</font>
> 寫 test 部分
> ```clike=
> `timescale 1ns / 1ps
>
> module Testbench();
>
> reg [3:0] din;
> wire[3:0] dout;
> reg CLK;
>
> Binary_to_Grey name(.din(din), .dout(dout) );
>
> always #5 CLK = ~CLK;
> initial CLK = 1'b1;
>
> initial begin
> din = 4'b0000; //給 din 一個初值
> repeat (2 ** 4) begin //重複 2 ^ 4 以下這個動作
> @(posedge CLK)
> test; //先照抄
> @(nededge CLK)
> din = din + 1'b1; // din 變成下一個數字
> end
> end
> $finish
>
> task test;
> begin
> if ( (din ===4'd0 && dout === 4'b0000) ||
> (din === 4'd1 && dout === 4'b0001) ||
> (din === 4'd2 && dout === 4'b0011) ||
> (din === 4'd3 && dout === 4'b0010) ||
> (din === 4'd4 && dout === 4'b0110) ||
> (din === 4'd5 && dout === 4'b0111) ||
> (din === 4'd6 && dout === 4'b0101) ||
> (din === 4'd7 && dout === 4'b0100) ||
> (din === 4'd8 && dout === 4'b1100) ||
> (din === 4'd9 && dout === 4'b1101) ||
> (din === 4'd10&& dout === 4'b1111) ||
> (din === 4'd11&& dout === 4'b1110) ||
> (din === 4'd12&& dout === 4'b1010) ||
> (din === 4'd13&& dout === 4'b1011) ||
> (din === 4'd14&& dout === 4'b1001) ||
> (din === 4'd15&& dout === 4'b1000) )
> $display("din = %d, dout = %d, got it !!\n", din, dout);
> else
> $display("din = %d, dout = %d, OOOOOOoooooops!!!\n", din, dout);
> end
> endtask
>
>endmodule
>```
> <font color = #bf2222>task </font> 是一個用來寫重複指令的方法,在這裡我們將所有正確的結果放在 if 裡面,這樣我們就能判斷我們的程式碼是否正確。
>
><font color=#bf222>ps.</font><font color = #1644aa> $display </font> 類似 c 語言的 <font color = #1644aa> printf </font>。
<!--## <font color = #bf2222>LAB 2 更新部分</font>
* sdf :
這次 LAB 我們會使用到 Design vision 的工具,且合成出程式檔。但我們仍然要確認它的正確性,因此,我們需要在我們的 Tb 中微調,如以下範例:(也可以參考助教提供的 Testbench)
:::success
==加入並連結 sdf,並且注意要使用上面的 module instance name !==
![](https://i.imgur.com/K51bNbs.png)
:::-->
## <font color = #bf2222>As4 Part</font>
- Simulate the clock signal.
```clike
always #(cyc/2) clk = ~clk;
```
- Dump nWave file.
```clike=
initial begin
$fsdbDumpfile("as4_2.fsdb");
$fsdbDumpvars;
end
```
# [:maple_leaf:Homepage:maple_leaf:](https://hackmd.io/s/ByZ-fyuHV)