まぁいろんな要因があるわけですが。
UVMになってというか、OVM2.xあたりからですかね、オブジェクションメカニズムが導入されたのは。
オブジェクションメカニズムというのは、要はsequenceを起動するときに「動きますよ」というフラグをたてて、sequenceが終わるときにそのフラグを解除するという動きです。
UVMでは特にこの仕組みを使うことが必須で、特定のコードを組んでおかないとSimulatorは瞬時に終わってしまいます。1nsも動かない。
UVMのサンプルに、これを解決するコードが例示されています。
/uvm-1.1d/examples/integrated/ubus/sv/ubus_master_seq_lib.svvirtual class ubus_base_sequence extends uvm_sequence #(ubus_transfer); function new(string name="ubus_base_seq"); super.new(name); endfunction // Raise in pre_body so the objection is only raised for root sequences. // There is no need to raise for sub-sequences since the root sequence // will encapsulate the sub-sequence. virtual task pre_body(); if (starting_phase!=null) begin `uvm_info(get_type_name(), $sformatf("%s pre_body() raising %s objection", get_sequence_path(), starting_phase.get_name()), UVM_MEDIUM); starting_phase.raise_objection(this); end endtask // Drop the objection in the post_body so the objection is removed when // the root sequence is complete. virtual task post_body(); if (starting_phase!=null) begin `uvm_info(get_type_name(), $sformatf("%s post_body() dropping %s objection", get_sequence_path(), starting_phase.get_name()), UVM_MEDIUM); starting_phase.drop_objection(this); end endtaskendclass : ubus_base_sequence二か所のtask、pre_bodyとpost_body。sequenceのbody taskの「前」と「後」に実行されるtaskですが、これらを使って、raise_objection, drop_objectionをしています。
上記の記述、pre_bodyとpost_bodyはコピペでOKです。汎用的な記述になっています。
starting_phaseってなんやねん!という疑問が出るかもしれません。なくても動くでしょうけど、どちらかというと書いてある方が「適切」な動きをしますので、なんとなくこの条件文を外すのはお勧めしませ ん。
なお、この仕組みはオプション設定で不要にできるかもしれませんが、デフォルトでONなので、この仕組みを知っておいた方がお得かと。