Vengineerの妄想(準備期間)

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

OVM : ovm_doマクロ

Verification Engineerの戯言

ovm_doマクロは、Sequence Actionマクロと呼ばれるもので、クラス・リファレンスのPage.266に説明があります。
Sequence Actionマクロには、ovm_doマクロの他にovm_do_withマクロがあります。
これらマクロは、itemあるいsequenceに対して、次の7つのステップを実行します。
itemはovm_sequence_itemクラスを継承したもの。sequenceは、ovm_sequenceクラスを継承したもの。
    1)、Create
    2)、Synchronize with sequencer
    3)、pre_do
    4)、Randomize
    5)、mid_do
    6)、Post synchronization/body execution
    7)、post_do

それでは、ovm_doマクロのコードを見ていきましょう!
ovm_doマクロのコードは、src/macros/ovm_sequence_defines.svhにあります。
    `define ovm_do(OVM_SEQUENCE_ITEM) \
      begin \
        ovm_virtual_sequencer ovs; \
        ovm_sequence os; \
        OVM_SEQUENCE_ITEM = new(`"OVM_SEQUENCE_ITEM`");\
        if ($cast(ovs, m_sequencer)) \
        if(!$cast(os, OVM_SEQUENCE_ITEM)) \
          ovm_report_fatal("ITMVSQ", "Cannot do items in a virtual sequence."); \
        $cast(OVM_SEQUENCE_ITEM , create_item(OVM_SEQUENCE_ITEM, m_sequencer)); \
        start_item(OVM_SEQUENCE_ITEM); \
        assert(OVM_SEQUENCE_ITEM.randomize()) else begin \
          ovm_report_warning("RNDFLD", "Randomization failed in ovm_do action"); \
        end
        finish_item(OVM_SEQUENCE_ITEM);\
      end
ovm_doマクロでは、
    $cast(OVM_SEQUENCE_ITEM, create_item(OVM_SEQUENCE_ITEM, m_sequencer)でOVM_SEQUENCE_ITEMを生成(1)、
    start_item(OVM_SEQUENCE_ITEM)を実行(2, 3)
    OVM_SEQUENCE_ITEM.randomize()でランダム生成(4)、
    finish_item(OVM_SEQUENCE_ITEM)を実行(5, 6, 7)
を実行しています。
start_itemタスクでは、引数(type_var)がovm_sequence_itemクラスの子クラスあるいはovm_sequenceクラスの子クラスなのかで処理が多少違います。
引数がovm_sequence_itemクラスの子クラスのときは、同期化(this.m_sync(type_var)し、pre_doタスクを引数(1)で実行します。
一方、ovm_sequenceクラスの子クラスのときは、pre_doタスクを引数(0)で実行するだけです。
    task ovm_sequence::start_item(ovm_sequence_item type_var);

      if (type_var.is_item()) begin 
        this.m_sync(type_var);
        this.pre_do(1);
      end 
      else begin 
        this.pre_do(0);
      end

    endtask
finish_itemタスクでもstart_itemタスクと同様に、引数(type_var)がovm_sequence_itemクラスの子クラスあるいはovm_sequenceクラスの子クラスなのかで処理が多少違います。
引数がovm_sequence_itemクラスの子クラスのときは、同期化(this.m_post_sync(type_var)します。
一方、ovm_sequenceクラスの子クラスのときは、Sequncerのbodyタスク(m_seq.body())を実行します。
そして、post_doタスクを実行します。
    task ovm_sequence::finish_item( ovm_sequence_item type_var );

      ovm_sequence m_seq;

      this.mid_do(type_var);
      if(type_var.is_item()) begin
        this.m_post_sync( type_var );
      end
      else begin //is sequence 
        $cast(m_seq, type_var);
        #0 -> m_seq.started;
        m_seq.body();
        -> m_seq.ended;
      end
      this.post_do(type_var);
      m_sequencer.end_tr(type_var);
    endtask
このように、ovm_sequence_itemクラスovm_sequenceクラスでは、多少処理が違います。

ovm_sequenceクラスの最後の方で説明したbodyタスクはここ(m_seq.body())で実行されます。

検証、Verification、SystemVerilog、OVM、Open Verification Methodology