sv环境转换到uvm环境中时,有一些重要的改变发生。
1、clone()函数的调用需要类型转换
比如在chal_pkg中的do_drvie()方法里调用clone()函数
SV环境下,不需要类型转换,因为自定义的clone()函数已经指定了返回类型为chnl_trans;
UVM环境下,需要类型转换,因为clone()是核心基类的方法,返回类型是UVM_object,子类对象调用clone()函数返回的是父类句柄(指向子类对象的父类句柄),想要使用子类成员就需要类型转换(父 -> 子);
// SV中直接进行过clone
rsp = req.clone();
// UVM中需要进行转化
chnl_trans extends uvm_sequence_item;
chnl_trans req, rsp;
void'($cast(rsp, req.clone()));
2、端口类
不是object类,也不是component类,而是uvm_void
,创建的时候要用new()
,而不是type_id::create();
3、创建对象放在new()中还是build_phase()
用new()创建对象可以放在function new()中,也可以放在build_phase中;
用type_id::create()创建对象只能放在build_phase中;
在创建组件的时候,一定要用type_id::create(),提供override的可能,还可以实现字符串的层次化建议把配置放在创建之前;
4、 mcdf_pkg里对象的创建和连接
SV环境下,将创建和连接都放在new()里;
UVM环境下,普通创建放在new()
里,type_id::create()
创建放在build_phase
里,组件之间的连接放在connect_phase
里;
5、test中添加virtual interface
先在test层build_phase
中用config_db::get()
到interface的指针,再在connect_phase
中调用set_interface
将接口set给各个组件
6、 tb中不能用set_interface()
如果想要用set_interface(),就要下面1这样,前提是base_test已经创建了,但实际上base_test()还没有被创建,等到run_test()才会被创建。
base_test.set_interface(vif);
run_test();
如果想下面2这样,先创建环境,然后再set_interface(),也是不行的,run_test()的时候确实在创建环境,创建的同时也会调用各自环境的build_phase,connect_phase,结果不能找的interface的指针。
run_test();
base_test.set_interface(vif);
所以在创建环境之前得先用config_db::set()
把interface的指针set到test层
uvm_config_db#(virtual intf)::set();
run_test();
7、 组件的phase自动执行
SV环境下的run()
是上层调用下层,显式“点火”
UVM环境下的run_phase()
是平行“点火”,因为uvm_root在一层层构建组件的时候也构建了层次,就可以得到所有的组件层次和句柄