【SystemVerilog】UVMで検証環境を作成する~Virtual SequencerとVirtual Sequence~【#7】

Systemverilog

前回のおさらい

uvm_monitorを継承してMonitor階層を作成しました。

Virtual SequencerとVirtual Sequenceを作成する

複数の検証コンポーネントをテストベンチに組み込むと、Sequenceも増えていきます。

それらのSequenceをまとめる、Virtual Sequencer/Virtual Sequenceを作成します。

sample_vsequencer.svh
class sample_vsequencer extends uvm_sequencer;
    `uvm_component_utils(sample_vsequencer)

    sample_sequencer seqr;  // Sequencerを宣言。

    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
endclass
sample_vseq.svh
class sample_vseq extends uvm_sequence;
    `uvm_object_utils(sample_vseq)
    `uvm_declare_p_sequencer(sample_vsequencer)

    sample_seq seq;  // Sequenceを宣言。

    function new(string name="sample_vseq");
        super.new(name);
        set_automatic_phase_objection(1);
    endfunction

    virtual task body();
        seq = sample_seq::type_id::create("seq");
        `uvm_do_on(seq, p_sequencer.seqr)  // Sequenceが使用できる。
    endtask
endclass
sample_test.svh
class sample_test extends uvm_test;
    `uvm_component_utils(sample_test)

    sample_env env;
    sample_vsequencer vsequencer;

    function new(string name="sample_test", uvm_component parent=null);
        super.new(name, parent);
    endfunction

    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        uvm_config_db #(uvm_object_wrapper)::set(
            this, "vsequencer.run_phase",
            "default_sequence", sample_vseq::type_id::get());  // sample_vseqに変更。
        env = sample_env::type_id::create("env", this);
        vsequencer = sample_vsequencer::type_id::create("vsequencer", this);  // sample_vsequencerに変更。
    endfunction

    function void connect_phase(uvm_phase phase);
        $cast(vsequencer.seqr, env.agent.sequencer);  // SequencerをVirtual Sequencerに渡す。
    endfunction

    task run_phase(uvm_phase phase);
        `uvm_info(this.get_name(), "Hello World", UVM_NONE)
    endtask
endclass
top.sv
module top;
    `include "uvm_macros.svh"
    import uvm_pkg::*;

    `include "sample_sequence_item.svh"
    `include "sample_monitor.svh"
    `include "sample_sequencer.svh"
    `include "sample_driver.svh"
    `include "sample_agent.svh"
    `include "sample_env.svh"
    `include "sample_seq.svh"
    `include "sample_vsequencer.svh"  // 追加。
    `include "sample_vseq.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)
    );
endmodule

解説

Virtual Sequenceで、インスタンスしているSequenceを生成します。

Sequenceはuvm_objectなので、下記で生成します。

<変数> = <型>::type_if::create(“<変数名>”)

seq = sample_seq::type_id::create("seq");

`uvm_do_on(<Sequence>, <Sequencer>)で、Sequenceが実行されます。

`uvm_do_on(seq, p_sequencer.seqr)  // Sequenceが使用できる。

下の階層まで理解したくないので、Virtual Sequencerに他のSequencerを接続します。

function void connect_phase(uvm_phase phase);
    $cast(vsequencer.seqr, env.agent.sequencer);  // SequencerをVirtual Sequencerに渡す。
endfunction

まとめ

Virtual SequenceとVirtual Sequencerを作成しました。

コメント

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