【SystemVerilog】Constrained Randomを使用するテストベンチ【サンプルコード】

Systemverilog

はじめに

Constrained Randomの考え方を使ってテストベンチを作成します。

実装

では、実際にテストベンチを作成します。

まずは制約なしで作成します。

構成は以下の通りです。

DUTの仕様

in_validがHighのとき、din1とdin2を加算した結果doutを出力する。

dut.sv
module top(
    input clk,
    input rst_n,
    input in_valid,
    input [3:0] din1,
    input [3:0] din2,
    output logic [3:0] dout
);
    always_ff @(posedge clk, negedge rst_n) begin
        if (!rst_n) begin
            dout <= '0;
        end
        else begin
            if (in_valid) begin
                dout <= din1 + din2;
            end
        end
    end
endmodule

テストベンチの仕様

test_data.svh

入力データを生成します。

class test_data;
    rand bit [3:0] din1;
    rand bit [3:0] din2;
endclass
tb.sv

テストシーケンスの実装、モニタで期待値比較を行います。

module tb;
    bit clk = 0;
    bit rst_n = 1;
    always #5 clk = ~clk;

    bit in_valid;
    bit [3:0] din1;
    bit [3:0] din2;
    bit [3:0] dout;

    dut i_dut(
        .clk(clk),
        .rst_n(rst_n),
        .in_valid(in_valid),
        .din1(din1),
        .din2(din2),
        .dout(dout)
    );

    `include "test_data.svh"

    class monitor;
        int exp_;

        function set(int din1, din2);
            exp_ = din1 + din2;
        endfunction

        task start;
            @(posedge clk iff in_valid);
            if (dout != exp_) begin
                $display("[ERROR]: [act] %d, [exp] %d", dout, exp_);
            end
            else begin
                $display("[INFO]: [act] %d, [exp] %d", dout, exp_);
            end
        endtask
    endclass

    initial begin
        test_data a = new();
        monitor mon = new();

        // 初期化シーケンス
        @(posedge clk);
        rst_n = 1;
        repeat(5) @(posedge clk);

        for (int i = 0; i < 20; i++) begin
            // 入力データと期待値生成
            a.randomize();
            mon.set(a.din1, a.din2);

            // モニタ開始
            fork
                mon.start();
            join_none

            // テストシーケンス
            din1 = a.din1;
            din2 = a.din2;
            repeat(5) @(posedge clk);
            in_valid = 1'b1;
            @(posedge clk);
            in_valid = 1'b0;
        end
        $finish;
    end
endmodule

動作確認

doutが4ビットなので、加算結果が16以上のときはERRORとなります。

[ERROR]: [act]  5, [exp]          21
[INFO]: [act] 14, [exp]          14
[INFO]: [act]  4, [exp]           4
[ERROR]: [act]  7, [exp]          23
[ERROR]: [act]  6, [exp]          22
[ERROR]: [act]  6, [exp]          22
[ERROR]: [act]  1, [exp]          17
[ERROR]: [act]  4, [exp]          20
[ERROR]: [act]  3, [exp]          19
[ERROR]: [act]  3, [exp]          19
[INFO]: [act]  9, [exp]           9
[INFO]: [act] 14, [exp]          14
[ERROR]: [act]  3, [exp]          19
[ERROR]: [act]  1, [exp]          17
[ERROR]: [act] 11, [exp]          27
[INFO]: [act]  8, [exp]           8
[ERROR]: [act]  3, [exp]          19
[INFO]: [act] 11, [exp]          11
[INFO]: [act] 11, [exp]          11
[ERROR]: [act] 12, [exp]          28

波形

制約を付ける(constraint)

さきほどはモニタがオーバーフローを考慮していなかったので、期待値不一致(ERROR)が発生しました。

DUTの使用制約でオーバーフローするデータを入力しない場合、テストベンチでは不必要な入力データを生成しています。

そこで、test_data.svhに定義しているクラスに制約(constraint)を付けます。

class test_data;
    rand bit [3:0] din1;
    rand bit [3:0] din2;
    // din1 + din2 は16以上にしない制約
    constraint max {
        din1 + din2 < 16;
    }
endclass

動作確認

さきほどはERRORがありましたが、入力データに制約を付けることで解消されました。

[INFO]: [act] 10, [exp]          10
[INFO]: [act] 11, [exp]          11
[INFO]: [act] 15, [exp]          15
[INFO]: [act] 12, [exp]          12
[INFO]: [act]  7, [exp]           7
[INFO]: [act] 15, [exp]          15
[INFO]: [act] 15, [exp]          15
[INFO]: [act]  5, [exp]           5
[INFO]: [act] 10, [exp]          10
[INFO]: [act] 14, [exp]          14
[INFO]: [act]  8, [exp]           8
[INFO]: [act] 13, [exp]          13
[INFO]: [act]  7, [exp]           7
[INFO]: [act] 15, [exp]          15
[INFO]: [act] 15, [exp]          15
[INFO]: [act] 10, [exp]          10
[INFO]: [act]  7, [exp]           7
[INFO]: [act] 12, [exp]          12
[INFO]: [act] 13, [exp]          13
[INFO]: [act] 15, [exp]          15

まとめ

Constrained Randomの考え方を使ってテストベンチを作成しました。

コメント

タイトルとURLをコピーしました