Vengineerの妄想(準備期間)

人生は短いけど、長いです。人生を楽しみましょう!

UVM 1.0 : examples/simple/tlm2/temporal_decoupling (その3)


initiator.svファイル内のinitiatorクラスで、次のようになっています。
examples/simple/tlm2/basic_blockinginitiator.svに対して、package/endpackageで囲んでいます。
  package init_pkg;                            // init_pkgパッケージにする

    import uvm_pkg::*;                         // UVMパッケージを読み込む
    import apb_pkg::*;                         // apb_pkgを読み込む

    class initiator extends uvm_component;     // uvm_componentを継承する

      uvm_tlm_b_initiator_socket#(apb_rw) sock;// TLM2のイニシエータソケット

      `uvm_component_utils(initiator) // set_config_xxx/get_config_xxxのためのおまじない

      function new(string name = "initiator", uvm_component parent = null);
        super.new(name, parent);
//      sock = new("sock", this);              // ここでsockを生成してもOK
      endfunction

      function void build_phase(uvm_phase phase);
        sock = new("sock", this);    // UVM的には、インスタンスの生成はbuild_phase関数で
      endfunction

      // Execute a simple read-modify-write
      virtual task run_phase(uvm_phase phase); // run_test()が呼ばれると実行される
        apb_rw rw;
        uvm_tlm_time delay = new;

        phase.raise_objection(this);       // おまじない

        // Factoryにて、apb_rwクラスのインスタンスを生成
        rw = apb_rw::type_id::create("rw",,get_full_name());
        rw.kind = apb_rw::READ;            // kindをapb_rw::READを設定
        // apb_rw::は、apb_rwクラスの中に定義されているREADを使うという意味
        rw.addr = 32'h0000_FF00;           // addrを設定

        delay.reset();                     // delayをリセット
        sock.b_transport(rw, delay);       // sock.b_transportでデータを転送する
                                           // 2番目の引数(delay)には、uvm_tlm_time型になる
        // sock.b_transportタスクを実行後、delayに遅延値が格納される。
        $write("Init: delay = %0.3f ns\n", delay.get_realtime(1ns));
        #(delay.get_realtime(1ns));

        // Ok to reuse the same RW instance
        rw.kind = apb_rw::WRITE;           // kindをapb_rw::WRITEを設定
        // apb_rw::は、apb_rwクラスの中に定義されているWRITEを使うという意味
        rw.data = ~rw.data;                // ライトなのでdataを設定
  
        delay.reset();                     // delayをリセット
        sock.b_transport(rw, delay);       // sock.b_transportでデータを転送する
                                           // 2番目の引数(delay)には、uvm_tlm_time型になる
        // sock.b_transportタスクを実行後、delayに遅延値が格納される。
        $write("Init: delay = %0.3f ns\n", delay.get_realtime(1ns));
        #(delay.get_realtime(1ns));

        phase.drop_objection(this);        // おまじない
      endtask

    endclass

  endpackage

ここでのポイントは、下記のsock.b_transportタスク前後のdelay関連です。
delay.reset()でdelayの値をリセットしますが、sock.b_transport(rw,delay)実行後、
delayに遅延値が設定されるというところです。この部分がtemporal decouplingになります。
        delay.reset();                     // delayをリセット
        sock.b_transport(rw, delay);       // sock.b_transportでデータを転送する
                                           // 2番目の引数(delay)には、uvm_tlm_time型になる
        // sock.b_transportタスクを実行後、delayに遅延値が格納される。
        $write("Init: delay = %0.3f ns\n", delay.get_realtime(1ns));
        #(delay.get_realtime(1ns));

検証、Verification、SystemVerilog、UVM、Unified Verification Methodology