# 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)