UVM factory的实际应用
factory其实是对多态的一个扩展。
例子一:
class bird extends uvm_object;
virtual function void hungry();
$display("I am a bird, I am hungry");
endfunction
function void hungry2();
$display("I am a bird, I am hungry2");
endfunction
`uvm_object_utils(bird)
function new(string name = "bird");
super.new(name);
endfunction
endclass
class parrot extends bird;
virtual function void hungry();
$display("I am a parrot, I am hungry");
endfunction
function void hungry2();
$display("I am a parrot, I am hungry2");
endfunction
`uvm_object_utils(parrot)
function new(string name = "parrot");
super.new(name);
endfunction
endclass
class big_parrot extends parrot;
virtual function void hungry();
$display("I am a big_parrot, I am hungry");
endfunction
function void hungry2();
$display("I am a big_parrot, I am hungry2");
endfunction
`uvm_object_utils(big_parrot)
function new(string name = "big_parrot");
super.new(name);
endfunction
endclass
set_type_override_by_type的基本用法(一)
class my_case0 extends base_test;
function new(string name = "my_case0", uvm_component parent = null);
super.new(name,parent);
endfunction
extern virtual function void build_phase(uvm_phase phase);
extern virtual function void print_hungry(bird b_ptr);
`uvm_component_utils(my_case0)
endclass
function void my_case0::print_hungry(bird b_ptr);
b_ptr.hungry();
b_ptr.hungry2();
endfunction
function void my_case0::build_phase(uvm_phase phase);
bird bird_inst;
parrot parrot_inst;
super.build_phase(phase);
set_type_override_by_type(bird::get_type(), parrot::get_type());
bird_inst = bird::type_id::create("bird_inst");
parrot_inst = parrot::type_id::create("parrot_inst");
print_hungry(bird_inst);
print_hungry(parrot_inst);
endfunction
- 有关类作为函数参数的相关知识(print_hungry)可以参考:https://www.cnblogs.com/xuqing125/p/15934714.html
- my_case0其实是从uvm_component中扩展来的,所以可以直接在my_case0里面调用set_type_override_by_type。
- set_type_override_by_type (uvm_object_wrapper original_type, uvm_object_wrapper override_type, bit replace=1)三个参数的类型:第一个和第二个是uvm_object_registry #(bird,"bird")和uvm_object_registry #(parrot,"parrot"),第三个参数replace只会应用在bird多次override的场景下。
- override语句将会把所有的bird类型替换成parrot类型。内部语法相当于是
bird = parrot
set_type_override_by_type的基本用法(二)
修改上述case.
set_type_override_by_type(bird::get_type(), parrot::get_type());
set_type_override_by_type(parrot::get_type(), big_parrot::get_type());
bird_inst = bird::type_id::create("bird_inst");
parrot_inst = parrot::type_id::create("parrot_inst");
print_hungry(bird_inst);
print_hungry(parrot_inst);
- 联想source code,m_type_overrides[]中有两条override的记录,分别是override.original_type = uvm_object_registry #(bird,"bird") override.override_type = uvm_object_registry #(parrot,"parrot") 和override.original_type = uvm_object_registry #(parrot,"parrot") override.override_type = uvm_object_registry #(big_parrot,"big_parrot")
- bird::type_id::create("bird_inst"),传入的是bird的wrapper,所以find_override_by_type会foreach(m_type_overrides[]),bird->parrot->big_parrot的递归调用find_override_by_type()
- 所以所有的bird和parrot都会被big_parrot替代。其内部语法的实现
bird = big_parrot;parrot = big_parrot
set_type_override_by_type的基本用法(三)
修改上述case
class big_parrot extends bird;
virtual function void hungry();
$display("I am a big_parrot, I am hungry");
endfunction
function void hungry2();
$display("I am a big_parrot, I am hungry2");
endfunction
`uvm_object_utils(big_parrot)
function new(string name = "big_parrot");
super.new(name);
endfunction
endclass
set_type_override_by_type(bird::get_type(), parrot::get_type());
set_type_override_by_type(bird::get_type(), big_parrot::get_type());
bird_inst = bird::type_id::create("bird_inst");
parrot_inst = parrot::type_id::create("parrot_inst");
print_hungry(bird_inst);
print_hungry(parrot_inst);
- set_type_override_by_type的第三个参数replace默认为1.
- 当bird被多次override的时候,replace=1的时候,会把前一次的m_override_types的内容用后一次的刷新。当replace=0的时候,会直接忽略掉这次的override。
set_type_override_by_type(bird::get_type(), parrot::get_type());
set_type_override_by_type(bird::get_type(), big_parrot::get_type(),0);
需要注意的一点是replace的参数仅仅只会在bird第二次以上override的时候才会有作用,如果是第一次override,replace=1/0都没有作用。
//set_type_override_by_type(bird::get_type(), parrot::get_type());
set_type_override_by_type(bird::get_type(), big_parrot::get_type(),0/1);
I am a big_parrot, I am hungry
I am a bird, I am hungry2
I am a parrot, I am hungry
I am a bird, I am hungry2