UVM通过objection机制来控制验证平台的关闭。在每个phase中,UVM会检查是否有objection被提起(raise_objection),如果有,那么等待这个objection被撤销(drop_objection)后停止仿真,如果没有则马上结束当前phase。raise_objection和drop_objection要成双成对出现。raise_objection必须放在main_phase第一个消耗仿真时间的语句之前。
在UVM中,objection一般伴随着sequence,通常只在sequence出现的地方raise_objection和drop_objection,sequence产生transaction,产生tr发送完毕后就可以结束仿真了。
使用default_sequence如何raise_objection和drop_objection?
default_sequence可以用来帮助启动seq。seq有哪些启动方式?
1)手动启动
task mo_env::main_phase(uvm_phase phase)
seq mo_seq;
phase.raise_objection(this);
mo_seq = seq::type_id::creat("seq");
mo_seq.start(mo_agent.seqr);
phase.drop_objection(this);
endtask
在env中通过start手动启动,start参数为在哪个seqr使用,否则不知道将产生的tr传递给哪个seqr。
2)default_sequence
在某个component的build_phase设置如下代码
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(uvm_object_wrapper)::set(this,"mo_agent.mo_seqr.main_phase","default_sequence", seq::type_id::get());
endfunction
第一个参数this是env本身的指针,第二个参数指定在哪个seqr的哪个phase启动seq,第三、四个参数固定。
那么使用default_sequence如何raise_objection和drop_objection?其实,在uvm_sequence这个基类里有starting_phase这个成员变量,它的类型是uvm_phase。seqr在启动seq时,会自动执行如下操作。
task mo_seqr::main_phase(uvm_phase phase);
seq.starting_phase = phase;
seq.start(this);
endtask
因此可以在seq中使用starting_phase raise_objection和drop_objection。
class my_sequence extends uvm_sequence #(my_transaction);
my_transaction mo_trans;
virtual task body();
if(starting_phase != null)
starting_phase.raise_objection(this);
repeat (10) begin
`uvm_do(m_trans)
end
#1000;
if(starting_phase != null)
starting_phase.drop_objection(this);
endtask
`uvm_object_utils(my_sequence)
endclass
从而,objection完全与sequence关联在了一起,在其他任何地方都不必再设置objection。
本文章参考《UVM实战》、《芯片验证漫游指南》等资料整理而成,仅作学习心得交流,如果涉及侵权烦请请告知,我将第一时间处理。