(7)UVM objection机制
UVM-1.1之后,结束仿真的机制有且只有一种,那就是利用objection挂起机制来控制仿真结束。
objection机制
参与到objection机制中的参与组件,可以独立的各自挂起objection,来防止run_phase退出,但是只有这些组件都落下objection后,uvm_objection共享的counter才会变为0,这意味run_phase退出的条件满足,因此可以退出run_phase。
task main_phase(uvm_phase phase);
phase.raise_objection(this);
...
phase.drop_objection(this);
endtask
在run的过程中,至少要有一个组件挂起objection若没有任何一个组件举起objection,则会立刻退出uvm;退出到run_phase进行到下一个阶段;
在进入到某一phase时,UVM会收集此phase提出的所有objection,并且实时监测所有objection是否已经被撤销了,当发现所有都已经撤销后,那么就会闭此phase,开始进入下一个phase。当所有的phase都执行完毕后,就会调用Sfinish来将整个的验证平台关掉。
对于component()而言,用户可以在run_phase()
中使用phase.raise_objection()/phase.drop_objection()
来控制run phase退出。对于uvm_top或者uvm_test_top应该尽可能少地使用set_drain_time()。
//挂起objection
raise_objection(uvm_object obj=null,string description="",int count=1)
//落下objection
drop_objection(uvm_object obj=null,string description="",int count=1)
//设置退出时间
set_drain_time(uvm_object obj=null,time drain)
控制objection的最佳选择
在monitor和reference model中,都有类似的情况,它们都是无限循环的。因此一般不会在driver和monitor中控制objection。
一般来说,在一个实际的验证平台中,通常会在以下两种objection的控制策略中选择一种:
- 第一种是在scoreboard中进行控制。,scoreboard的main_phase被做成一个无限循环。如果要在scoreboard中控制objection,则需要去除这个无限循环,通过config_db:;set的方式设置收集到的transaction的数量pkt_num,当收集到足够数量的transaction后跳出循环。
task my_scoreboard::main_phase(uvm_phase phase);
phase.raise_objection(this);
fork
while(1) begin
exp_port.get(get_expect);
expect_queue.push_back(get_expect);
end
for(int i=0;i<pkt_num;i++) begin
act_port.get(get_actual);
...
end
join_any
phase.drop_objection(this);
endtask
上述代码中将原本的fork.join语句改为了fork…join_any。当收集到足够的transaction后,第二个进程终结,从而跳出fork…join_any,执行drop_objection语句。
- 第二种,在sequence中提起sequencer的objection,当sequence完成后,再撤销此objection。
以上两种方式在验证平台中都有应用。其中用得最多的是第二种,这种方式是UVM提倡的方式。UVM的设计哲学就是全部由sequence来控制激励的生成,因此一般情况下只在sequence中控制objection。
这篇笔记参考《UVM实战》、《芯片验证漫游指南》和某验证视频整理而成,仅作学习心得交流,如果涉及侵权烦请请告知,我将第一时间处理。