Verification Engineerの戯言
ovm_transactionクラスの例題としては、examples/hello_world/ovmディレクトリがあるようです。
packet.svファイルにovm_transactionクラスを継承するpacketクラスがあります。
このpacketクラスをproducerクラス(producer.sv)とconsumerクラス(consumer.sv)クラス間で転送します。
2つのクラスは、topクラス(top.sv)クラスでtlm_fifoクラスで接続します。
packet.svファイルにovm_transactionクラスを継承するpacketクラスがあります。
このpacketクラスをproducerクラス(producer.sv)とconsumerクラス(consumer.sv)クラス間で転送します。
2つのクラスは、topクラス(top.sv)クラスでtlm_fifoクラスで接続します。
class top extends ovm_component; producer #(packet) p1; producer #(packet) p2; tlm_fifo #(packet) f; consumer #(packet) c; `ovm_component_utils(top) function new (string name, ovm_component parent=null); super.new(name,parent); p1 = new("producer1",this); p2 = new("producer2",this); f = new("fifo",this); c = new("consumer",this); p1.out.connect( c.in ); p2.out.connect( f.blocking_put_export ); c.out.connect( f.get_export ); endfunction endclassproducerクラスのインスタンスp2のoutポートとconsumerクラスのインスタンスcのoutポートがtlm_fifoクラスのインスタンスfで接続されています。また、インスタンスp1のoutポートは、インスタンスcのinポートと直接接続されています。
packetクラスは、producerクラスのrun関数内でclone関数で生成されます。
その後、set_name関数で名前を設定し、set_initiator関数でイニシエータとして自分自身(this)を設定します。
recording_detail変数がOVM_NONE以外のときは、enable_recording関数でトランザクションを記録します。
次のrandomize関数でメンバー変数の値を生成し、`ovm_msg_detail(OVM_HIGH)マクロの戻り値がtrueの時は、print関数で内部状態を表示します。最後に、outポートへパケットをput関数で送信します。
task run(); T p; string image, num; for (count =0; count < num_packets; count++) begin $cast(p, proto.clone()); num.itoa(count); p.set_name({get_name(),"-",num}); p.set_initiator(this); if (recording_detail!=OVM_NONE) p.enable_recording("packet_stream"); void'(p.randomize()); if (`ovm_msg_detail(OVM_HIGH)) p.print(); out.put(p); #10; end endtaskproto.clone()でパケットを生成し、pに$castを使って代入します。
その後、set_name関数で名前を設定し、set_initiator関数でイニシエータとして自分自身(this)を設定します。
recording_detail変数がOVM_NONE以外のときは、enable_recording関数でトランザクションを記録します。
次のrandomize関数でメンバー変数の値を生成し、`ovm_msg_detail(OVM_HIGH)マクロの戻り値がtrueの時は、print関数で内部状態を表示します。最後に、outポートへパケットをput関数で送信します。
packetクラスに対するset_name、set_inhitiator、enable_recording、randomize、print関数は、すべてpacketクラスではなく、祖先のクラス内で定義されています。
このうち、set_initiatorとenable_recordingのみがpacketクラスの親クラスであるovm_transactionクラスで定義されています。
このうち、set_initiatorとenable_recordingのみがpacketクラスの親クラスであるovm_transactionクラスで定義されています。
パケットを受け取るconsumerクラスでは、受信したパケットをputタスクに渡してトランザクションを記録しています。
パケットを受信するrunタスク
パケットを受信するrunタスク
task run (); T p; while(out.size()) begin out.get(p); put(p); end endtaskoutポートにデータがある(out.size)まで、データを受信(out.get(p))し、トランザクションを記録する(put(p))
task put (T p); lock.get(); count++; accept_tr(p); #10; void'(begin_tr(p)); #30; end_tr(p); lock.put(); endtaskputタスクの最初と最後は、セマファ(lock)で囲んでいます。
accept_tr、begin_tr、end_trの3つがトランザクション関連の関数です。
検証、Verification、SystemVerilog、OVM、Open Verification Methodology