OVM2.0でinterrputハンドラーはfork...join_noneで走らせていいのかな。

ベリフィケーション・メソドロジ・マニュアルにinterrputが使用できると有り、OVM2.0ではどうかなと
OVM_UserGuideを見るとp115~から記述が有るじゃん。。でもサンプルコード無いね!!

サンプルが無いのでUserGuideに従い、割り込みハンドラー(dmac_interrput_handler_seq)を記述して
dmac_sequencer(xbusならxbus_master_sequencer.sv相当)に設定する記述をしたが、なぜかコンパイルエラー。。
dmac_sequencer(ovm_sequenserを継承している)の中に
dmac_interrput_handler_seqをインスタンスする所でエラーになる。。。

とりあえずnet検索を掛けたらOVM Forumでinterrputを質問している記述有りラッキー!
で内容を見ると。。ovm_sequenserを継承したclass中のtask run()の中に
ハンドラーをべた書き(clk毎に割り込み信号ポーリングしてやんの!)してるよ
位の書き込みしかない。。汗

結局ガイドが言いたかったのは
 1. ovm_sequnseを継承したclassでハンドラーを作る。
 2. @p_sequenser....でイベント待ちをする。foreverで繰り返す。
 3. grab(...) ungrab(...) 割り込み禁止と解除に相当する記述を行う。
 4. ovm_sequenserを継承したclassでハンドラーを走らせる。
     → interrupt_seq.start(this);こんな感じ
 task startの中身はfork...join_anyでプロセスを生成して平行動作状態にしている。

でも4.でエラーになるんだな。。。

とりあえずsequences arrayに登録するシーケンサ中でハンドラーを走らせることにした。
こんな感じ

dmac_interrput_handler_seq interr ;
  .......
virtual task body() ;
interr = dmac_interrput_handler_seq::type_id::create("interr") ;
interr.start(this) ;
.........

でもやっぱりエラー。。汗

いろいろ設定を変えてfork...join_noneに落ち着いた。。
こんな感じ。
interr = dmac_interrput_handler_seq::type_id::create("interr") ;
fork
interr.start(p_sequencer) ;
join_none
これで想定した割り込みハンドラーの動作をするようになった。
ハンドラー内にフラグを追加して波形を見てみたが。。動作している??と思う。
下記に作成したsoruceの1部を貼り付けておきます。
---------------------------------------------------
class dmac_interrput_handler_seq extends ovm_sequence #(dmac_reg_data) ;
protected virtual h_bus_if h_bus_if0 ; ----> bus interfaceをインスタンスする。

`ovm_sequence_utils(dmac_interrput_handler_seq, dmac_sequencer)

function new(string name="dmac_interrput_handler_seq");
super.new(name);
endfunction

// assign_vi
function void assign_vi(virtual interface h_bus_if h_bus_if0);
this.h_bus_if0 = h_bus_if0 ;
endfunction : assign_vi

virtual task body();
int cont = 0 ;
forever begin
@p_sequencer.h_bus_if0.interr[0] ;
p_sequencer.h_bus_if0.int_flag ^= 1'b1 ;
grab(p_sequencer) ;
$display("<<<<<<<<<<<<<<<<< ACCEPT INTERRPUT !!! %d >>>>>>>>>>>>>>>>>>>", cont) ;
ungrab(p_sequencer) ;
cont++ ;
end
endtask : body

endclass : dmac_interrput_handler_seq

class acc_address_seq extends ovm_sequence #(dmac_reg_data);
function new(string name="acc_address_seq");
super.new(name);
endfunction

`ovm_sequence_utils(acc_address_seq, dmac_sequencer)

int cont ;
rand bit [15:0] start_addr;
rand int unsigned transmit_del = 0;
constraint transmit_del_ct { (transmit_del <= 10); }
..........
dmac_interrput_handler_seq interr ;

virtual task body();
interr = dmac_interrput_handler_seq::type_id::create("interr") ;
fork
interr.start(p_sequencer) ;
join_none
..........
..........
-----------------------------------------------------

systemverilog OVM OVM2.0 interrput 割り込み 回路検証 LSI検証