ubus_tb_top.sv

興味あるところは1つだけ。initial文のところです。

  initial begin
    uvm_config_db#(virtual ubus_if)::set(uvm_root::get(), "*", "vif", vif);
    run_test();
  end

ここの、uvm_config_dbのset文です。ここでvirtual interfaceのセットをしていることはわかるのですが、この1行で何をしているのかと。

調べたら難しかったので、ubusで使用している使用例から考えていきます。

  • virtual interfaceのセットは、module ubus_tb_topで行っている。このとき
      • uvm_config_db#(virtual ubus_if)::set(uvm_root::get(), "*", "vif", vif);
    • 第一引数は、どのアクセス対象のinstance情報を渡しているようです。実行するuvm_testクラスはわからないので、こう書くのかな?
    • 第二引数はインスタンス名。すべてのインスタンスを対象。
    • 第三引数はフィールド名。クラスの変数(メンバ)名を指定します。
    • 第四引数は、見つけたフィールドにvifを渡しています
  • その他は、UVMのクラスの中でセットしており、
      • uvm_config_db#(int)::set(this,"ubus_example_tb0.ubus0.masters[0].sequencer.loop_read_modify_write_seq", "itr", 6);
    • 第一引数は "this"、つまり自分自身を基準に、第二引数引数で具体的なインスタンス名、第三引数でフィールド、第四引数で値をセットしています。

この使い方から、virtual interfaceだけ使い方が異なることがわかります。

以下に途中まで調べた経緯を書いていますが、頓挫してしまいました。

とりあえず、適当なuvm_test classを用意して、uvm_root::get()を実行してみました。

# uvm_root::get()='{m_leaf_name:"", m_inst_id:13, use_uvm_seeding:1, m_inst_count:451, __m_uvm_status_container:@uvm_status_container@1, m_rh:@uvm_root_report_handler@1, enable_stop_interrupt:0, print_enabled:1, recorder:null, m_domain:@uvm_domain@2, m_phase_imps:'{ }, m_current_phase:@uvm_phase@6, m_phase_process:null, m_build_done:1, m_phasing_active:0, m_parent:null, m_children:'{"uvm_test_top":@test@1 }, m_children_by_handle:'{@test@1:@test@1 }, m_stream_handle:'{ }, m_tr_h:'{ }, m_name:"", event_pool:null, recording_detail:0, m_verbosity_settings:'{}, m_config_set:1, print_config_matches:0, type_name:"uvm_component", m_time_settings:'{}, clp:@uvm_cmdline_processor@1, top_levels:'{@test@1}, enable_print_topology:0, finish_on_completion:1, phase_timeout:9200000000000000, m_phase_all_done:0, m_inst:@uvm_root@1}

う…いろんなところの値を所有しているんですね。

ところで、uvm_root::という表記なので、uvm_rootはclassです。uvm_rootはどんな人かというと

class uvm_root extends uvm_component

でした。んーそうですか。追うのがたいへんそうなので置いておいて、uvm_config_dbのsetメソッドを見てみましょう。

class uvm_config_db#(type T=int) extends uvm_resource_db#(T);

いました。この中を探すと

  static function void set(uvm_component cntxt,
                           string inst_name,
                           string field_name,
                           T value);

んー、arg0がuvm_componentなんですが、上記で述べたように、uvm_root::get()はいっぱい出てきます。ただし、あの表示は "%s" ではなくて "%p" なんです。"%p"ってなに?

あーありました。見つけました。verificationguildに。

オブジェクトの表示に使うそうです。

function uvm_root uvm_root::get();
  if (m_inst == null) begin
    m_inst = new();
    void'(uvm_domain::get_common_domain());
    m_inst.m_domain = uvm_domain::get_uvm_domain();
  end
  return m_inst;
endfunction

m_instは、uvm_root classでした。んーこのファイルだけではわからない…。