10. 割り込みシーケンス
Interrupt sequenceです。CPUのバスインターフェースモデルを使っていると、割り込み発生時の検証には必須ですね。
grab, ungrab(sequencerを掴む、離す)を使うということだけわかっていたのですが、UVMのユーザーマニュアルの例はvirtual sequenceのもので、しかもそれほど書いてなくて。
ググるとVerification Academyのサイトが出てきました。そこに書かれてある例を元に、シンプルな割り込みシーケンスの動作確認ができたので、公開したいと思います。
ポイントは、
- 割り込み処理シーケンスの「中」でgrab, ungrabすること
モチーフは、10日間で身に付けるUVMのコードです。
2つのシーケンスを追加しました。
- 既存の連続ライト、連続リードシーケンスをfork join_noneで実施し、一定時間後に他のシーケンスを割り込ませ、終わったら元のシーケンスの続きを実施するシーケンス
- 1番で使う割り込みシーケンス。
既存のシーケンスは、アドレスをインクリメントしながらランダムデータを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
endtask
endclass
//------------------------------------------------------------------------
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");
endtask
endclass
//------------------------------------------------------------------------
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;
endtask
endclass