Interrupt sequenceです。CPUのバスインターフェースモデルを使っていると、割り込み発生時の検証には必須ですね。
grab, ungrab(sequencerを掴む、離す)を使うということだけわかっていたのですが、UVMのユーザーマニュアルの例はvirtual sequenceのもので、しかもそれほど書いてなくて。
ググるとVerification Academyのサイトが出てきました。そこに書かれてある例を元に、シンプルな割り込みシーケンスの動作確認ができたので、公開したいと思います。
ポイントは、
モチーフは、10日間で身に付けるUVMのコードです。
2つのシーケンスを追加しました。
既存のシーケンスは、アドレスをインクリメントしながらランダムデータを256回書いてから、256回読むというものです。この連続ライトを途中でとめて、0番地に10回ランダムデータを書くシーケンスを割 りこませます。
まずログから。10 番地まで書いたあと、0番地へ連続ライトしたあと、10番地から再開されていることがわかります。波形は確認していませんが、grabメッセージが表示されてから 10 番地へ書き込みが発生し ていますが、モニタはValid-Readyハンドシェイク完了時に表示しているため、ライトトランザクション中にgrab要求を発行したことになっていると考えています。
# UVM_INFO @ 9100: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=0eh wdata=bfh# UVM_INFO @ 9100: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 9700: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=0fh wdata=cdh# UVM_INFO @ 9700: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 10000: uvm_test_top.tb.sample_model.master.sequencer@@intr_test_seq.intr [SEQ] grab sequencer# UVM_INFO @ 10400: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=10h wdata=77h# UVM_INFO @ 10400: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 11100: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=00h wdata=d7h# UVM_INFO @ 11100: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 12000: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=00h wdata=a5h# UVM_INFO @ 12000: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 13000: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=00h wdata=5fh# UVM_INFO @ 13000: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 13300: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=00h wdata=63h# UVM_INFO @ 13300: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 13800: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=00h wdata=6ch# UVM_INFO @ 13800: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 14100: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=00h wdata=31h# UVM_INFO @ 14100: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 14400: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=00h wdata=24h# UVM_INFO @ 14400: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 15000: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=00h wdata=08h# UVM_INFO @ 15000: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 15300: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=00h wdata=d2h# UVM_INFO @ 15300: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 15800: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=00h wdata=cfh# UVM_INFO @ 15800: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 15900: uvm_test_top.tb.sample_model.master.sequencer@@intr_test_seq.intr [SEQ] ungrab sequencer# UVM_INFO @ 16300: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=11h wdata=9bh# UVM_INFO @ 16300: uvm_test_top.tb.sample_scrbd [SCRBD] write expected data# UVM_INFO @ 17200: uvm_test_top.tb.sample_model.master.monitor [MON] write addr=12h wdata=e7h//------------------------------------------------------------------------class write_read_all_seq extends sample_master_base_seq; write_seq _write; read_seq _read; `uvm_object_utils(write_read_all_seq) function new (string name="write_read_all_seq"); super.new(name); endfunction virtual task body(); int i; for(i=0; i<256; i=i+1)begin `uvm_create(_write) _write.addr = i; _write.data = $urandom_range(255,0); `uvm_send(_write) end for(i=0; i<256; i=i+1)begin `uvm_create(_read) _read.addr = i; `uvm_send(_read) end endtaskendclass//------------------------------------------------------------------------class intr_seq extends sample_master_base_seq; write_seq _write; read_seq _read; `uvm_object_utils(intr_seq) function new (string name="intr_seq"); super.new(name); endfunction virtual task body(); m_sequencer.grab(this); uvm_report_info("SEQ", "grab sequencer"); repeat(10)begin `uvm_create(_write) _write.addr = 0; _write.data = $urandom_range(255,0); `uvm_send(_write) end m_sequencer.ungrab(this); uvm_report_info("SEQ", "ungrab sequencer"); endtaskendclass//------------------------------------------------------------------------class intr_test_seq extends sample_master_base_seq; write_read_all_seq all; intr_seq intr; `uvm_object_utils(intr_test_seq) function new (string name="intr_test_seq"); super.new(name); endfunction virtual task body(); event wait_e; fork begin `uvm_create(all) `uvm_send(all) -> wait_e; end join_none #10000; `uvm_create(intr) `uvm_send(intr) @wait_e; endtaskendclass