前一节https://www.cnblogs.com/xuqing125/p/15826609.html讲述了UVM phase整体是怎么运行起来的,里面忽略了objection的概念。
抛开UVM这个框架,我们想最基础的systermverilog到底是怎么控制进程线程的呢?
可以参考我之前的文章:https://www.cnblogs.com/xuqing125/p/15662318.html
其实UVM也是用了这些方式来控制线程,通过raise_objection+drop_objection+fork/join三兄弟+process来实现的。
1. objection top
回顾一下run_test()和add()函数
- 顶层调起来uvm_objection::m_init_objection
- wait()
- $finish
- 所有的task_phase都会例化一个uvm_objection
- 这也就是你可以在所以的task_phase里面raise_objection/drop_objection.
2. raise_objection()
- drv---raise_objection + mon---raise_objection
- objection的管理还是基于uvm_component的UVM tree结构而言的。(seq除外)
- m_total_count[]:raise_objection会引起其以上的结点对应的增加
- m_source_count[]: 表示的是谁raise_objection的结点
- m_total_count[]/m_source_count[]的实现是通过m_propagate()的m_raise()的obj = m_get_parent(obj)的条件递归来实现的。
3. drop_objection
- 跟raise_objection类似,drop_objection会将m_total_count[]/m_source_count[]往反方向实现,直到m_total_count[] == 0,m_schedule_list.push_back().这个数组是干嘛的呢?别急,想想run_test里面有一个m_init_objection()
4. uvm_objection::m_init_objection()
- m_schedule_list不为空的时候进入循环
- set_drain_time,这里会在drop_objection之后还再延迟一段时间。
- all_dropped() 触发all_drop event,并将m_top_all_dropped = 1;
小结:
UVM 的objection机制分析到这里就比较明确了。通过数据来对raise_objection和drop_objection进行计数,当全部drop以后延迟set_drain_time的时间以后,trigger事件,赋值变量,主程序$finish.