(2011-10-20 09:52:54)
分类: uvm |
preface
uvm_objection是在uvm_object上扩展出来的一个专门针对数据单元的类。该类也用来协调多个component的行动
ie:the ~uvm_test_done~ built-in objection provides a means for
// coordinating when to end a test, i.e. when to call <global_stop_request> to
// end the <uvm_component::run> phase. When all participating components have
// dropped their raised objections with ~uvm_test_done~, an implicit call to
// ~global_stop_request~ is issued
1.uvm_objection_events是一个内部类,作用:里边记录的是某个component在等待本objection raised dropped all_dropped 发生,同一component每等待一次 waiters++
int waiters;
event raised;
event dropped;
event all_dropped;
2.uvm_objection_context_object这是一个内部的类,定义了一些属性,在uvm_objection中声明了一个这个类的pool,该类主要记录了一个component到objection的映射关系,为这个映射关系提供了描述,定义了一个count来为每次objection调用component的raised等方法提供一个数字
uvm_object obj;
uvm_object source_obj;
string description;
int count;
3. uvm_objection extends uvm_report_object
protected bit m_trace_mode=0;//记录目标活动使能
protected int m_source_count[uvm_object];//某个component raised count
protected int m_total_count [uvm_object]; //某个component及其子孙共raised的count
protected time m_drain_time [uvm_object];//某个component的drain time
protected bit m_draining [uvm_object];//某个component 正在draining
protected uvm_objection_events m_events [uvm_object];//记录某个component的raised dropped等情况
bit m_top_all_dropped;//top是否all_dropped
protected process m_background_proc;
protected uvm_root m_top = uvm_root::get();
static uvm_objection m_objections[$];//全局的对象,记录了所有的objection
local uvm_objection_context_object m_context_pool[$];
local uvm_objection_context_object m_scheduled_list[$];
bit m_hier_mode = 1;
uvm_root top = uvm_root::get();
protected bit m_cleared = 0;
3.1 function new(string name="");//根据命令行的情况设置m_trace_mode,并把本objection注册入m_objections
3.2 function bit trace_mode (int mode=-1);//设置m_trace_mode
3.3 function void m_report(uvm_object obj, uvm_object source_obj, string description, int count, string action);//该函数比较实际,他就是打印本component obj raised的objections的数目,以及本obj的子孙们共raised的objection的个数
3.4 function uvm_object m_get_parent(uvm_object obj);//如果obj是component返回component的父,如果是sequence那么返回sequence对应的sequencer,如果都不是那么返回top
3.5 function void m_set_hier_mode (uvm_object obj);//对每一个以obj为子孙的component,把本obj对objection的raised count记到每个以obj为子孙的component m_total_count中
3.6 virtual function void raised (uvm_object obj,
uvm_object source_obj,
string description,
int count);//对每个obj为component的部件,调用component的raised函数,并触发m_events[obj].raised
3.7 virtual function void dropped (uvm_object obj,
uvm_object source_obj,
string description,
int count);//参考3.6
3.8 virtual task all_dropped (uvm_object obj,
uvm_object source_obj,
string description,
int count);//参考3.6
3.9 function void get_objectors(ref uvm_object list[$]);//返回m_source_count
3.10 function int get_objection_count (uvm_object obj=null);//返回m_source_count[obj]
3.11function void do_copy (uvm_object rhs);//copy 3.1开头的几个量
3.12 virtual function string get_type_name ();//return "uvm_objection"
3.13 function uvm_object create (string name="");//顾名思义
3.14 static function type_id get_type();把objection做一个针对工厂的包装 typedef uvm_object_registry#(uvm_objection,"uvm_objection") type_id; return type_id::get();
3.15 protected function string m_display_objections(uvm_object obj=null, bit show_header=1);//对由本obj及子孙认领的所有objections做一个统计信息的打印
3.16 function void display_objections(uvm_object obj=null, bit show_header=1);调用3.15实现
3.17 function time get_drain_time (uvm_object obj=null);返回obj的drain_time
3.18 function int get_objection_total (uvm_object obj=null);返回一个由obj及其子孙所raised的objection的统计信息,如果set_hier_mode=0应该统计一遍返回,否在直接返回m_total_count[obj]
3.19 task wait_for_total_count(uvm_object obj=null, int count=0);//等待obj及其子孙raised的objection数目等于count
3.20 task wait_for(uvm_objection_event objt_event, uvm_object obj=null);//component obj等待 obj_event发生,这个等待通过uvm_objection_events来记录,uvm_objection_events的waiters记录了obj还有多少个等待事件在等待触发
3.21 function void set_drain_time (uvm_object obj=null, time drain);设置obj的drain_time,同事调用m_set_hier_mode(obj);
3.22 virtual function void clear(uvm_object obj=null);//把3.1中的属性清除,设置m_cleared表明本objection被清理过了,关闭处理本objection的进程,从新开启一个进程处理本objection并把进程句柄赋值给m_background_proc
3.23 virtual function void raise_objection (uvm_object obj=null,
string description="",
int count=1);
把m_cleared清零,调用m_raised
3.24 virtual function void drop_objection (uvm_object obj=null,
string description="",
int count=1);//调用m_drop
3.25 function void m_propagate (uvm_object obj,
uvm_object source_obj,
string description,
int count,
bit raise,
int in_top_thread);//根据raise调用m_raise和m_drop在以obj为根的地方向上,在整个树形结构总递归处理给个component的raise和drop操作
3.26 function void m_raise (uvm_object obj,
uvm_object source_obj,
string description="",
int count=1);//将m_source_count, m_total_count进行加操作,如果m_hier_mode=1那么就递归地进行处理,直到顶层,如果m_hier_mode=0那么就直接对top对应的m_source_count, m_total_count项进行处理,如果通过m_draining表明某个component对本objection的处理已经结束,那本m_raise将返回,剩余的工作将交给drain进程进行处理。否者将调用m_raise或者m_propagate对各个obj的父component在本objection中的情况进行升级
3.27 function void m_drop (uvm_object obj,
uvm_object source_obj,
string description="",
int count=1,
int in_top_thread=0);//与3.26刚好相反,会设置m_draining,调用 m_forked_drop,或者规划一个事件,并把该事件做记录并放入m_scheduled_list
3.28 function void m_forked_drop (uvm_object obj,
uvm_object source_obj,
string description="",
int count=1,
int in_top_thread=0);//在对m_draining后有事件正在处理的时候,如果又有objection raised那么处理终止,并对本次raised事件做处理,去掉m_draining[obj]标志,并递归的对obj的各祖先在本objection中做rasied操作或者drop操作
3.29 task m_execute_scheduled_forks;把m_scheduled_list.pop_front()抓出来做m_forked_drop处理,处理完了后放回m_context_pool,m_context_pool中的东西几乎没什么用,更每次新造一个一样
3.30 static function void m_init_objections();静态方法,对每个objection开启一个线程,调用3.29
对3做一些总结,3的实现机制可谓极其复杂,但是还是有章可循,在3.1的属性中记录了本objection相关的各个component对本objection的count raised dropped等操作;但是component本身也是通过parent层次化的,一个objection被component source_obj raised了,那么obj的父component 也应该知道并在本objection中做一个raised操作,本操作被记录在m_total_count[obj]中;一个objection 一般是sour_obj raised的,obj和souce_obj也可被设置为相同,当不同时,obj及其以上的层次被认为是应该在m_total_count中记录的。drop的时候也是这样的道理;但是中情况当某个obj的m_total_count==0时,那说明本obj及其子孙对本objection来说没有操作了,这是可以m_forked_drop处理了,但是在处理的过程中又有obj对objection的raised操作,那么记录本次raised操作,中断m_forked_drop本对raised操作做处理,从新回到m_draining==0的时代。
每个objection都通过m_init_objections m_execute_scheduled_forks m_forked_drop 启动一个线程执行,该线程在 task m_execute_scheduled_forks;中执行死循环,来监控本objection的改变,并根据改变来执行相应的操作;监控的是m_scheduled_list,如果m_scheduled_list中有事件就把时间抓出来执行;m_scheduled_list又是用drop操作来产生的,当drop操作把某些m_total_count降为0的时候就可以规划一个M_draining==1的m_scheduled_list事件;而raised操作可以说随机的和异步的。这些处理中,如果整个component不是hierarchy的那么就处理流程就有些许差异,这些差异主要体现在把每个component都认为是top的子孙来体现
4.uvm_test_done_objection extends m_uvm_test_done_objection_base
m_uvm_test_done_objection_base和uvm_callbacks_objection或者 uvm_objection是同一种类型。这是一个singleton模式
如下函数简洁明了,在介绍其他singleton的时候都有介绍就直接列了出来
4.1 static function uvm_test_done_objection get();
4.2 virtual function string get_type_name ();
4.3 function uvm_object create (string name="");
4.4 typedef uvm_object_registry#(uvm_test_done_objection,"uvm_test_done") type_id;static function type_id get_type();
4.5 virtual task force_stop(uvm_object obj=null);//component obj调用本函数,强制的通过本类让仿真的本阶段结束
4.6 virtual function void qualify(uvm_object obj=null,
bit is_raise,
string description);//查看obj是 <uvm_component> or <uvm_sequence_base>
4.7 virtual function void drop_objection (uvm_object obj=null,
string description="",
int count=1);//调用super.drop_objection(obj,description,count)实现drop
4.8 virtual function void raise_objection (uvm_object obj=null,
string description="",
int count=1);//调用super.raise_objection,如果在执行停止请求的过程调用了本function,那么对应的raised将被ignore并给出警告信息
4.9 virtual task all_dropped (uvm_object obj,
uvm_object source_obj,
string description,
int count);//如果不是top直接调用super.all_dropped(obj,source_obj,description,count);并返回;如果是top,调用m_top.all_dropped(this, source_obj, description, count),最后设置m_executing_stop_processes进行stop处理,处理完后m_executing_stop_processes = 0;同时对stop处理进行时间监视,如果时间太长就报错返回。最后显示运行阶段结束,extract阶段开始,并把所有的m_event事件all_dropped;最后设置m_top_all_dropped = 1
4.10 task m_stop_request();//调用raise_objection答应一行信息,#0后调用drop_objection打印一行信息表示stop_request被调用了
4.11 function void stop_request();//join_none方式调用4.10
4.12 time stop_timeout = 0;给stop处理一个时间限制
4.13 task m_do_stop_all(uvm_component comp);//递归调用comp及其所有子component,如果某个component允许stop某个阶段,那么在stop对应阶段前m_n_stop_threads++;。然后调用comp.stop_phase(run_ph),如果调用成功m_n_stop_threads--,每个component启动一个这样的线程,进行统计
5.uvm_callbacks_objection extends uvm_objection;
该类里边在uvm_objection里头挂了uvm_objection_callback ;通过uvm_callbacks_objection 的三个接口函数间接调用uvm_objection_callback 中对应的接口
5.1 virtual function void raised (uvm_object obj, uvm_object source_obj,
string description, int count);调用
`uvm_do_callbacks(uvm_callbacks_objection,uvm_objection_callback,raised(this,obj,source_obj,description,count))
5.2 virtual function void dropped (uvm_object obj, uvm_object source_obj,
string description, int count);调用
`uvm_do_callbacks(uvm_callbacks_objection,uvm_objection_callback,dropped(this,obj,source_obj,description,count))
5.3 virtual task all_dropped (uvm_object obj, uvm_object source_obj,
string description, int count);调用
`uvm_do_callbacks(uvm_callbacks_objection,uvm_objection_callback,all_dropped(this,obj,source_obj,description,count))
在uvm中有许多这种代理了又代理,封装了又封装的东西,感觉很绕,没有vmm的直接了当,每个类都清晰直接,明了。
6.uvm_objection_callback extends uvm_callback;
该callback定义了3个空的接口
virtual function void raised (uvm_objection objection, uvm_object obj,
uvm_object source_obj, string description, int count);
virtual function void dropped (uvm_objection objection, uvm_object obj,
uvm_object source_obj, string description, int count);
virtual task all_dropped (uvm_objection objection, uvm_object obj,
uvm_object source_obj, string description, int count);