Vengineerの妄想(準備期間)

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

UVM 1.0 : フェーズ(その1)


UVM 1.0では、各クラスで実装するフェーズに関する関数・タスク名が変更になりました。
    build      =>    build_phase
    connect    =>    connect_phase
    run        =>    run_phase

    extract    =>    extract_phase
    check      =>    check_phase
    report     =>    report_phase

build_phase では、そのクラスが持っているインスタンスやポートを生成します。
(UVM 1.0では、new関数でインスタンスやポートを生成すべきではありません。)

connect_phaseでは、そのクラス内のインスタンス間を接続します。

この2点は、基本ですので覚えておきましょう!

run_phaseを持っているのは、
    base/uvm_root.svh
    base/uvm_component.svh
    comps/uvm_in_order_comparator.svh
    seq/uvm_sequncer_base.svh
    seq/uvm_push_sequencer.svh
ですが、ユーザはuvm_componentクラスを継承し、
run_phaseを再定義することになります。

OVMでは、runタスクでしたが、UVM 1.0では、run_phaseタスクになり、
つぎのように、run_phaseタスクの中でrunタスク呼んでいます。
    task uvm_component::run_phase(uvm_phase phase);
      run();
      return;
    endtask
ですから、runタスクのみ定義しても正しく動きますが、
runタスクrun_phaseタスクの両方を定義すると、
run_phaseタスクの内容によっては、runタスクが呼ばれなくなります!

おまけに今の実装では、'buildタスクbuild_phaseタスクの両方を
定義すると、たぶん動きません。なぜなら、uvm_componentクラスの下記の部分
    function void uvm_component::build_phase(uvm_phase phase);
      m_build_done = 1;
      apply_config_settings(print_config_matches);
      build();
    endfunction

    // Backward compatibility build function
    function void uvm_component::build();
      m_build_done = 1;
    endfunction
で、共にm_build_doneを1にセットしているので、どこかで使っているのでしょう!
調べてみました。uvm_phases.svhの2635行目です。
          UVM_PHASE_EXECUTING: begin
            if (!(phase.get_name() == "build" && comp.m_build_done)) begin
              uvm_phase ph = this; 
              if (comp.m_phase_imps.exists(this))
                ph = comp.m_phase_imps[this];
              ph.execute(comp, phase);
            end
            end
m_build_doneが1でないと、実行されない部分があるということになります。

その1なので、その2もあります。乞うご期待。

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