【SystemVerilog】UVMで検証環境を作成する~Virtual InterfaceでクラスとDUTを接続する~【#5】

Systemverilog

前回のおさらい

Sequence_item/Sequencer/Driver/Sequenceを作成してテストベンチに組み込みました。

ここまではclass内で完結する話でした。

Virtual InterfaceでclassとDUTを接続する

今回は、classでDUTを動かすためにVirtual Interfaceを組み込みます。

まずはinterfaceを作成します。

sample_if.sv
interface sample_if;
    logic [2:0] din1;
    logic [2:0] din2;
    logic [3:0] dout;
endinterface

interfaceをtop.svにインスタンスして、uvm_config_dbでUVM環境のデータベースにVirtual Interfaceとして登録します。

top.sv(sample_if.svをインスタンスする)
module top;
    `include "uvm_macros.svh"
    import uvm_pkg::*;

    `include "sample_sequence_item.svh"
    `include "sample_sequencer.svh"
    `include "sample_driver.svh"
    `include "sample_agent.svh"
    `include "sample_env.svh"
    `include "sample_seq.svh"
    `include "sample_test.svh"

    initial begin
        run_test("sample_test");
    end

    // 以下の記述を追加。
    sample_if vif();

    initial begin
        uvm_config_db #(virtual sample_if)::set(null, "*", "vif", vif);
    end

    dut i_dut(
        .din1(vif.din1),
        .din2(vif.din2),
        .dout(vif.dout)
    );

    initial begin // デバッグ用
        #5;
        $display("din1 %d", vif.din1);
        $display("din2 %d", vif.din2);
        $display("dout %d", vif.dout);
    end
endmodule

登録したVirtual InterfaceをDriverの中で呼び出します。

ついでにrun_phase()の中身を修正します。

sample_driver.svh(sample_if.svをUVMデータベースから呼び出す)
class sample_driver extends uvm_driver #(sample_sequence_item);
    `uvm_component_utils(sample_driver)

    virtual sample_if vif;
    function new(string name, uvm_component parent);
        super.new(name, parent);
        if (!uvm_config_db #(virtual sample_if)::get(this, "", "vif", vif)) // 追加。
            `uvm_fatal(this.get_name(), "vif is invalid")
    endfunction

    task run_phase(uvm_phase phase);
        `uvm_info(this.get_name(), "Driver", UVM_INFO)

        forever begin
            seq_item_port.get_next_item(req);

            vif.din1 = req.din1; // 修正。
            vif.din2 = req.din2; // 修正。

            seq_item_port.item_done(rsp);
        end
    endtask
endclass

適当なDUTを作成して、動かしてみます。

dut.sv
module dut(
    input [2:0] din1,
    input [2:0] din2,

    output logic [3:0] dout
);
    assign dout = din1 + din2;
endmodule

これで、現在作成したファイルは以下になります。

  • top.sv
  • dut.sv
  • sample_if.sv
  • sample_sequence_item.svh
  • sample_sequencer.svh
  • sample_driver.svh
  • sample_agent.svh
  • sample_env.svh
  • sample_seq.svh
  • sample_test.svh

それでは実行してみましょう。

実行結果
[UVM_INFO][uvm_test_top] Hello World
[UVM_INFO][env] Env
[UVM_INFO][agent] Agent
[UVM_INFO][sequencer] Sequencer
[UVM_INFO][driver] Driver
din1 4
din2 7
dout 11

解説

top.svで以下の記述を追加しました。

uvm_config_db #(virtual sample_if)::set(null, "*", "vif", vif);

uvm_config_db #(<この型で>)::set(null, “<ここの>”, “<ここに>”, <この値を>)

登録します。

そして、sample_driver.svhで以下の記述を追加しました。

uvm_config_db #(virtual sample_if)::get(this, "", "vif", vif)

uvm_config_db #(<この型で>)::get(this, “<ここの>”, “<ここに登録した値を>”, <この変数に>)

呼び出します。

まとめ

Virtual Interfaceを作成しました。

コメント

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