前回のおさらい
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を作成しました。
コメント