3.8 シナリオの作成
3.8.4 Virtual Sequencer と Virtual Sequences
システム・レベルの検証を行なう時には、複数のコンポーネントがシーケンサー、及び、シーケ ンスを使用してトランザクションを生成します。即ち、複数のシーケンサーが同時に実行してい る状況が発生します。多くの場合、システム・レベルの検証ではそれらのシーケンサー、及び、
シーケンスが生成するデータのタイミングをコーディネイトする必要があります。その為には、
特別なシーケンサー、及び、シーケンスを使用します。それらが、バーチャル・シーケンサー
(virtual sequencer)、及び、バーチャル・シーケンス(virtual sequences)です。
3.8.4.1 Virtual Sequencer
通常のシーケンサーにはドライバーが対応していますが、バーチャル・シーケンサーは以下の特 性を持ちます。
① バーチャル・シーケンサーは対応するドライバーを持ちません。
class test_read_modify_write extends ubus_example_base_test;
`uvm_component_utils(test_read_modify_write)
function new(string name="test_read_modify_write", uvm_component parent=null);
super.new(name,parent);
endfunction : new
virtual function void build_phase(uvm_phase phase);
begin
uvm_config_db#(uvm_object_wrapper)::set(this,
"ubus_example_tb0.ubus0.masters[0].sequencer.run_phase", "default_sequence",
read_modify_write_seq::type_id::get());
uvm_config_db#(uvm_object_wrapper)::set(this,
"ubus_example_tb0.ubus0.slaves[0].sequencer.run_phase",
"default_sequence",slave_memory_seq::type_id::get());
// Create the tb
super.build_phase(phase);
end
endfunction : build_phase
endclass : test_read_modify_write
② データを処理しません。
この特性を満たすシーケンサーをバーチャル・シーケンサーと呼びます。バーチャル・シーケン サーはシーケンサーへのポインターを保有するコンポーネントです。
バーチャル・シーケンサーを定義する手順は以下の様になります。
① uvm_sequencerをベース・クラスにします。
② シーケンサーへのreferenceメンバーを定義します。referenceへのポインターの設定は、高位 レベルのコンポーネント(通常はテストベンチ)で行います。
バーチャル・シーケンサーの定義例を以下に示します([2])。
referenceメンバーはサブ・シーケンサー(sub-sequencers)とも呼ばれます。これらは、通常のシ
ーケンサーでも良いし、別のバーチャル・シーケンサーでも構いません。
3.8.4.2 Virtual Sequences
バーチャル・シーケンスは通常のドライバー・シーケンスと同じ様に使用しますが、以下の違い があります。
① バーチャル・シーケンスのバーチャル・シーケンサーに接続しているサブ・シーケンサーの シーケンスを実行する為には、`uvm_do_onマクロ、又は、`uvm_do_on_withマクロを使用し なければなりません。
② バーチャル・シーケンスは、対応するシーケンサーの他のバーチャル・シーケンスを実行す る為には、`uvm_doマクロ、又は、`uvm_do_withマクロを使用しなければなりません。バー チャル・シーケンスはデータ項目を実行する為に`uvm_doマクロ、又は、`uvm_do_withマク ロを使用する事は出来ません。バーチャル・シーケンサーにはシーケンスが対応しますが、
データ項目は対応していません。
バーチャル・シーケンスを定義する手順は以下の様になります。
① uvm_sequenceクラスを使用してバーチャル・シーケンスのクラスを定義します。
② シーケンスの機能をタスクbody()に定義します。
③ `uvm_do_onマクロ、又は、`uvm_do_on_withマクロを使用してサブ・シーケンサーのシーケ
ンスを実行する様にします。
④ 現在のバーチャル・シーケンサーの他のバーチャル・シーケンスを実行する為には、
class simple_virtual_sequencer extends uvm_sequencer;
eth_sequencer eth_seqr;
cpu_sequencer cpu_seqr;
// Constructor
function new(input string name="simple_virtual_sequencer", input uvm_component parent=null);
super.new(name, parent);
endfunction
// UVM automation macros for sequencers
`uvm_component_utils(simple_virtual_sequencer) endclass: simple_virtual_sequencer
バーチャル・シーケンスの定義例を示します([2])。
3.8.4.3 Virtual Sequencerとsub-sequencersの接続 以下の様な手順で接続をします。
① シーケンサーへの reference にシーケンサーのインスタンスを割り当てます。この割り当て は、全てのコンポーネントが作成された後に行います。
② environmentクラスのconnect()フェーズで割り当てをします。
以下に例を示します([2])。
class simple_virt_seq extends uvm_sequence;
...
// Constructor and UVM automation macros ...
// A sequence from the cpu sequencer library cpu_config_seq conf_seq;
// A sequence from the ethernet subsequencer library eth_large_payload_seq frame_seq;
// A virtual sequence from this sequencer's library random_traffic_virt_seq rand_virt_seq;
virtual task body();
// Invoke a sequence in the cpu subsequencer.
`uvm_do_on(conf_seq, p_sequencer.cpu_seqr)
// Invoke a sequence in the ethernet subsequencer.
`uvm_do_on(frame_seq, p_sequencer.eth_seqr)
// Invoke another virtual sequence in this sequencer.
`uvm_do(rand_virt_seq) endtask : body
endclass : simple_virt_seq
class simple_tb extends uvm_env;
cpu_env_c cpu0; // Reuse a cpu verification component.
eth_env_c eth0; // Reuse an ethernet verification component.
simple_virtual_sequencer v_sequencer;
...
// Constructor and UVM automation macros
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
// Set the default sequence for the virtual sequencer.
uvm_config_db#(uvm_object_wrapper)::set(this,
"v_sequencer.run_phase","default_sequence", simple_virt_seq.type_id::get());
// Build envs with subsequencers.
cpu0 = cpu_env_c::type_id::create("cpu0", this);
eth0 = eth_env_c::type_id::create("eth0", this);
// Build the virtual sequencer.
v_sequencer = simple_virtual_sequencer::type_id::create(
"v_sequencer",this);
endfunction : build_phase
上記の例では、バーチャル・シーケンサー(v_sequencer)に default_sequence を割り当てていま す。これにより、バーチャル・シーケンサーが動作する様になります。サブ・シーケンサーにも
default_sequenceが割り当てられていれば、バーチャル・シーケンサー、及び、サブ・シーケンサ
ーが同時に動作する様になります。
バーチャル・シーケンサーだけを動作させたい時には、以下の様にしてサブ・シーケンサーをオ フに設定しなければなりません([2])。
// Connect virtual sequencer to subsequencers.
function void connect_phase();
v_sequencer.cpu_seqr = cpu0.master[0].sequencer;
uvm_config_db#(uvm_sequencer)::set(this,”v_sequencer”,
”eth_seqr”,eth0.tx_rx_agent.sequencer);
endfunction : connect_phase endclass: simple_tb
// Configuration: Disable subsequencer sequences.
uvm_config_db#(uvm_sequence_base)::set(this, "*.cpu_seqr.*_phase",
"default_sequence", null);;
uvm_config_db#(uvm_sequence_base)::set(this, "*.eth_seqr.*_phase",
"default_sequence", null);
4 テストベンチの作成
これまでに準備したUVCsを使用してテストベンチの環境を作成します。