Vengineerの妄想

人生を妄想しています。

UVM 1.0 : examples/simple/sequence/basic_read_write_sequence (その5)


ドライバ、シーケンサ、そしてシーケンスをuvm_envクラスを継承するenvクラスの中で組み立てます。
インスタンスは、new関数で生成しています。なぜ、build_phase関数で生成しないのでしょうか?
同様に、connect_phase関数でドライバ(drv)とシーケンサ(sqr)を接続しないのでしょうか?

一貫性がやっぱりありません

    `define NUM_SEQS 10

      // uvm_envクラスを継承
      class env extends uvm_env;

        int i;
        // シーケンサ、シーケンス、ドライバをインスタンス
        // シーケンスは、10個
        uvm_sequencer #(bus_req, bus_rsp) sqr;
        sequenceA #(bus_req, bus_rsp) sequence_a[`NUM_SEQS];
        my_driver #(bus_req, bus_rsp) drv ;

        function new(string name, uvm_component parent);
          string str; // <= このstrは使っていませんが、
          super.new(name, parent);
          // シーケンサを生成
          sqr = new("sequence_controller", this);
          // `NUM_SEQS(10)個のシーケンスを生成
          for (i = 0; i < `NUM_SEQS; i++) begin
          // for ( int i = 0; i < `NUM_SEQS; i++) begin
          // の方がSystemVerilogらしいが
          // そうすれば、int i; がいらない
            sequence_a[i] = new("sequence");
          end
          // ドライバを生成
          drv = new("slave", this);
          // ドライバ(drv)とシーケンサ(sqr)を接続
          drv.seq_item_port.connect(sqr.seq_item_export);
        endfunction

        // uvm_envクラスを継承したら、このタスクを実装する
        task run_phase(uvm_phase phase);
          int i;
          // おまじないのraise_objection/drop_objectionで囲む
          phase.raise_objection(this);

          for (i = 0; i < `NUM_SEQS; i++) begin
          // for ( int i = 0; i < `NUM_SEQS; i++) begin
          // の方がSystemVerilogらしいが
          // そうすれば、int i; がいらない
          // fork/join_noneで`NUM_SEQS(10)こシーケンスを起動する
            fork
              sequence_a[i].start(sqr, null);
            join_none
            #0;
          end

          // 起動したすべてのシーケンスが終了するまで待つ
          wait fork;

          // おまじないのraise_objection/drop_objectionで囲む
          phase.drop_objection(this);
        endtask

      endclass

    endpackage

build_phase関数connect_phase関数を使うと、こんな感じでしょうか?

        function new(string name, uvm_component parent);
          super.new(name, parent);
        endfunction : new

        task build_phase(uvm_phase phase);
          sqr = new("sequence_controller", this);
          for ( int i = 0; i < `NUM_SEQS; i++)
            sequence_a[i] = new("sequence");
    
          drv = new("slave", this);
        endtask : build_phase
 
        task connect_phase(uvm_phase phase);
          drv.seq_item_port.connect(sqr.seq_item_export);
        endfunction

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