uvm_primer ch13 uvm_env
不要把一段代码在工程中copy多处
random_test() 和add_test()三种实现方式的对比
最差的结构
好一点的结构
将两个tester的共用的run_phase()写到base_tester;这样run_phase()在base_tester中复用;
然后定义get_op get_data两个纯虚函数,纯虚函数会强制在子类重写
virtual base_tester 是一个虚类 ,只能继承,不能实例化;
最优结构
add_tester重写random_tester的get_op函数;并复用random_tester的的get_data函数,因为两者是一样的;
将激励从component中独立出来;
separate structure from stimulus;
使用factory来构造component
<variable>=<class_name>::type_id::create("",this);
这个工厂方法有两个好处,相对于链接: uvm_primer ch9.
- 如果要给工厂增加新的类型的话,直接使用
`uvm_component_utils()
和`uvm_object_utils()
- 这个工厂返回对象的类型就是该类型,不需要$cast, ch9 返回的类型是其父类;
tester_h = base_tester::type_id::create("tester_h",this);
base_tester
是一个虚类,但是这里构造了一个对象;
这里base_tester是一个占位符,factory会返回一个base_tester子类的对象;
存在疑问???
class env extends uvm_env;
`uvm_component_utils(env);
base_tester tester_h;
coverage coverage_h;
scoreboard scoreboard_h;
function void build_phase(uvm_phase phase);
tester_h = base_tester::type_id::create("tester_h",this);
coverage_h = coverage::type_id::create ("coverage_h",this);
scoreboard_h = scoreboard::type_id::create("scoreboard_h",this);
endfunction : build_phase
function new (string name, uvm_component parent);
super.new(name,parent);
endfunction : new
endclass
这样 env中代码就一样了,利用多态的特性,如果创建不同的case,在case中指定tester_h 里边具体的类型,这样就不用不同的case有不同的env; 实现了env的复用;
override factory
<base_class_name>::type_id::set_type_override(<child_class_name>::get_type())
static方法set_type_override告诉工厂,当有一个构造base_class_name的申请时,返回一个child_class_name的对象;
random_test就相当于my_case0; 是uvm_test_top;
class random_test extends uvm_test;
`uvm_component_utils(random_test);
env env_h;
function void build_phase(uvm_phase phase);
base_tester::type_id::set_type_override(random_tester::get_type());
env_h = env::type_id::create("env_h",this);
endfunction : build_phase
function new (string name, uvm_component parent);
super.new(name,parent);
endfunction : new
endclass
在接下来的4个章节中,当在一个复杂的testbench中,各个object之间要进行通信将怎么处理,会对此进行详细的描述.
来源:oschina
链接:https://my.oschina.net/u/4418764/blog/4925089