プロデューサクラス(producer.sv)は、次のようになっています。
// テンプレートとして、#(type T=packet)を指定している。packetは前回説明したクラス class producer #(type T=packet) extends uvm_component; // uvm_componentを継承する uvm_blocking_put_port #(T) out; // ブロッキングタイプの出力側のTLMポート function new(string name, uvm_component parent=null); super.new(name,parent); out = new("out",this); // ポート(out)を生成する void'(get_config_int("num_packets", this.num_packets)); endfunction protected T proto = new; protected int num_packets = 1; protected int count = 0; // set_config_xxx/get_config_xxxのためのおまじない `uvm_component_utils_begin(producer #(T)) `uvm_field_object(proto, UVM_ALL_ON + UVM_REFERENCE) `uvm_field_int( num_packets, UVM_ALL_ON + UVM_DEC) `uvm_field_int( count, UVM_ALL_ON + UVM_DEC + UVM_READONLY) `uvm_component_utils_end // run_test()が呼ばれたときに実行されるタスク task run_phase(uvm_phase phase); T p; // Tは、デフォルトでは、packetクラス string image, num; // メッセージ、マクロなので最後に ; をつけない `uvm_info("producer", "Starting.", UVM_MEDIUM) // num_packets回、パケットをoutポートにput(出力)する for (count =0; count < num_packets; count++) begin $cast(p, proto.clone()); // パケットのクローンを作る // パケットの名前を作るために、countを文字列にする(itoa(count)) num.itoa(count); // このクラス(producer)の名前とnumからパケットの名前を作る p.set_name({get_name(),"-",num}); p.set_initiator(this); // パケットのイニシエータを自分にする if (uvm_verbosity'(recording_detail)!=UVM_NONE) p.enable_recording("packet_stream"); // レコーディングをイネーブルにする。 void'(p.randomize()); // パケットの制約付きランダム生成 `uvm_info("producer", $sformatf("Sending %s",p.get_name()), UVM_MEDIUM) if(uvm_report_enabled(UVM_HIGH,UVM_INFO,"")) p.print(); out.put(p); // パケットを出力する #10; // 10単位待ち(ここに時間を設定しないと、 // 時間0でパケットが連続出力されてしまう end `uvm_info("producer", "Exiting.", UVM_MEDIUM) endtask endclass
ポイントは、次の4点、でーす。
1)、パケットのクローンを作る $cast(p, proto.clone()); 2)、パラメータを設定する p.set_name({get_name(),"-",num}); p.set_initiator(this); 3)、パケットの制約付きランダム生成する void'(p.randomize()); 4)、パケットを出力する out.put(p);
検証、Verification、SystemVerilog、UVM、Unified Verification Methodology