跳轉到

Verification: Writing Testbenches

Clock

原題:Clock

這裡第一次練習 testbench,重點是理解 timescale、clock 產生方式,以及模擬結束條件。 第一行的格式是 `timescale 時間單位/時間精度#5 代表延遲 5 個 time unit;若 timescale 設定為 1ps/1ps,就代表延遲 5 ps。 time precision 則代表模擬可分辨的最小時間刻度;這裡的最小刻度是 1 ps。 補充:Verilog timescale

在 testbench 中,驅動 DUT input 的訊號宣告成 reg;接收 DUT output 的訊號宣告成 wire。原因是 DUT 的 input 對 testbench 來說是輸出刺激,而 DUT 的 output 對 testbench 來說是被觀察的輸入。

initial block 負責初始化數值。這題需要持續產生 clock,因此不需要 $finish

Verilog
`timescale 1ps/1ps
module top_module ( );
    reg clk;
    initial begin
        clk = 1'b0;
    end
    always #5 clk = ~clk;

    dut inst( .clk(clk)) ;
endmodule

Testbench1

原題:Testbench1

這裡不需要無限產生 clock,可以用 $finish 限制模擬時間。

Verilog
module top_module ( output reg A, output reg B );//

    // generate input patterns here
    initial begin
        A = 1'b0;
        B = 1'b0;
        #10 A = 1'b1;
        #5 B = 1'b1;
        #5 A = 1'b0;
        #20 B = 1'b0;
        #300 $finish;
    end

endmodule

AND gate

原題:AND gate

這裡不需要無限產生 clock,可以用 $finish 限制模擬時間。

Verilog
module top_module();
    reg [1:0]in;
    wire out;
    initial begin
        in = 2'b00;
        #10 in = 2'b01;
        #10 in = 2'b10;
        #10 in = 2'b11;
        #20 $finish;
    end

    andgate and_gate(.in(in), .out(out));
endmodule

Testbench2

原題:Testbench2

regwire 變多時,可以把不同初始化流程拆成多個 initial block,提高可讀性。

Verilog
module top_module();
    reg clk, in;
    reg [2:0] s;
    wire out;

    initial begin
        clk = 1'b0;
    end    
    always #5 clk = ~clk;

    initial begin
        in = 1'b0;
        #20 in = 1'b1;
        #10 in = 1'b0;
        #10 in = 1'b1;
        #30 in = 1'b0;
    end

    initial begin
        s = 3'd2;
        #10 s = 3'd6;
        #10 s = 3'd2;
        #10 s = 3'd7;
        #10 s = 3'd0;
    end

    initial begin
        #100 $finish;
    end

    q7 inst(.clk(clk), .in(in), .s(s), .out(out));
endmodule

T flip-flop

原題:T flip-flop

依照題目要求產生輸入序列即可;此題不需要特別調整時間間隔。

Verilog
module top_module ();
    reg clk;
    reg reset;
    reg t;
    wire q;

    initial begin
        clk = 1'b0;
    end
    always #5 clk = ~clk;

    initial begin
        reset = 1'b1;
        #10 reset = 1'b0;
    end

    initial begin
        t = 1'b0;
        #10 t = 1'b1;
    end

    initial begin
        #100 $finish;
    end

    tff inst(.clk(clk), .reset(reset), .t(t), .q(q));
endmodule