1. UVM component 与UVM object的区别:
a. UVM component 派生自UVM object , 所以UVM 具备所有UVM object 的特性。但是UVM component又具有两点是UVM object 不具备的(1.使用new()函数通过指定parent 形成树形结构,2. 具有phase运行机制,可自上向下运行phase)
b. 既然UVM_object已经属于UVM_component的父类,那么为什么还需要借助UVM_obejct 扩展出UVM_component?原因就是因为UVM_Object 属于基类,简单理解就是分子,但是对分子的操作仍然比较复杂或者没有那么简单,因此扩展出UVM_Component这个生命体,对生命体的操作会更直接一些。
总结: 所以简单理解UVM_Obeject 是UVM_Component 的基类,属于“分子级别”,UVM_component属于生命体,具备一些额外的功能或者特性。sequence_item就是贯穿分子和生命体之间的血液。
2. UVM object和component 相关的宏
a.`uvm_object_utils: object 注册类宏
`uvm_object_param_utils:带有参数的object 注册类宏
`uvm_obejct_utils_begin: file automation 机制
-----------
`uvm_object_utils_end : file automation 机制
b.`uvm_object_utils: component 注册类宏
`uvm_object_param_utils:带有参数的component 注册类宏
`uvm_obejct_utils_begin: file automation 机制
-----------
`uvm_object_utils_end : file automation 机制
3. UVM 的根在哪里?
从UVM 的树状结构可以看出UVM的很应该是UVM_top或者UVM_test_top.那么到底是哪个呢?在使用UVM_factory 机制实例UVM 组件的时候,我们有指定这个参数为this,env = my_env::type_id::create("env", this); 指定this以后表明, my_env的父类是UVM_evn,假设我们不指定this,设置为null, 如:env = my_env::type_id::create("env", null); 那么UVM会会自动帮我们指定为uvm_top,因此可以看出uvm_top是UVM的根。
4.UVM 的file automotion 机制:
变量使用`uvm_object_utils_begin:.........`uvm_object_utils_end注册以后,可以根据变量的类型就行注册,并指定UVM内置file automotion 函数(copy , print, clone, compare.....)的开启或者关闭情况(常用的是UVM_ALL_ON),UVM_ALL_ON的值是’b000000101010101,表示打开copy、compare、print、record、pack功能,如果想关闭某种函数,可以自行查阅相应的资料
5.UVM 打印机制的控制:
a.在打印信息之前,UVM会比较要显示信息的冗余度级别与默认的冗 余度阈值,如果小于等于阈值,就会显示,否则不会显示。默认的冗余度阈值是UVM_MEDIUM,所有低于等于UVM_MEDIUM(如UVM_LOW)的信息都会被打印出来。
6. config_db机制
a.一个component(如my_driver)内通过get_full_name()函数可以得到此component的路径
收信函数get: uvm_config_db#(int)::get(this, "", "pre_num", pre_num);
注意: set设置的第一个参数如果设置为null,相当于设置第一个参数为uvm_top
b. 跨层次的多重设置:
文件:src/ch3/section3.5/3.5.4/normal/my_case0.sv
32 function void my_case0::build_phase(uvm_phase phase);
33 super.build_phase(phase);
…
39 uvm_config_db#(int)::set(this, "env.i_agt.drv", "pre_num", 999);
40 `uvm_info("my_case0", "in my_case0, env.i_agt.drv.pre_num is set to 999",UVM_LOW)
文件:src/ch3/section3.5/3.5.4/normal/my_env.sv
19 virtual function void build_phase(uvm_phase phase);
20 super.build_phase(phase);
…
31 uvm_config_db#(int)::set(this, "i_agt.drv", "pre_num", 100);
32 `uvm_info("my_env", "in my_env, env.i_agt.drv.pre_num is set to 100",UVM_LOW)
36 endfunction
最终pre_num的值为:999(my_case>my_env)
当同一个发信人先后发了两封信 时,那么最近收到的一封为准
文件:src/ch3/section3.5/3.5.4/abnormal/my_case0.sv
32 function void my_case0::build_phase(uvm_phase phase);
33 super.build_phase(phase); …
39 uvm_config_db#(int)::set(uvm_root::get(), "uvm_test_top.env.i_agt.drv", "pre_num", 999);
43 `uvm_info("my_case0", "in my_case0, env.i_agt.drv.pre_num is set to 999", UVM_LOW)
文件:src/ch3/section3.5/3.5.4/normal/my_env.sv
19 virtual function void build_phase(uvm_phase phase);
20 super.build_phase(phase); …
31 uvm_config_db#(int)::set(uvm_root::get(), "uvm_test_top.env.i_agt.drv", "pre_num", 100);
32 `uvm_info("my_env", "in my_env, env.i_agt.drv.pre_num is set to 100",UVM_LOW) 36 endfunction
最终pre_num的值为:100(uvm_root::get()=uvm_top,)my_env后执行
c.同一层次的多重设置
同一个组件多次设置set,会被覆盖,如下图,drv 中pre_num =109
uvm_config_db#(int)::set(this, "env.i_agt.drv", "pre_num", 100);
uvm_config_db#(int)::set(this, "env.i_agt.drv", "pre_num", 109);
d.非直线的设置与获取 需要在set和get设置第一个参数为:uvm_root::get()或者this.m_parent