1.在sv中虚函数的重载
//定义一个父类Basic
class Basic extends uvm_component;
//factory机制中使用`uvm_component_utils(Basic)
function new(string name = "Basic",uvm_component parent = null);
super.new(name,parent);
endfunction
//在父类中创建一个虚函数 display
virtual function void display();
$display("Basic::A");
endfunction
endclass
//定义一个子类Child
class Child extends Basic;
//factory机制中使用`uvm_component_utils(Child)
function new(string name = "Child",uvm_component parent = null);
super.new(name,parent);
endfunction
//子类中的虚函数display和父类同名 => 多态
virtual function void display();
$display("Child::B");
endfunction
endclass
//在test中实例化父类和子类
class test extends uvm_test;
`uvm_component_utils (test)
Basic basic;
Child child;
function new (string name = "test",uvm_component parent = null);
super.new (name,parent);
endfunction
virtual function void build_phase (uvm_phase phase);
super.build_phase (phase);
//实例化
basic = new();
child = new();
//factory机制中使用以下方法实例化
//Basic :: type_id :: create ("basic",this);
//Child :: type_id :: create ("child",this);
basic.display();//调用父类函数,打印出A
child.display();//调用子类函数,打印出B
//将父类Basic的basic指针指向子类对象,因为父类使用了虚函数,所以会被子类函数所重载打印出B
//若父类中没有虚函数,则会打印出A
basic = child;
basic.display();
endfunction
endclass
module top_tb;
initial begin
run_test("test");
end
endmodule

2.factory机制的重载
//在以上代码块第44行添加以下代码
//set_type_override("Basic","Child");可以与下列代码相互替换
set_type_override_by_type(Basic :: get_type(),Child :: get_type());

第一次调用的父类的虚函数为什么也会被重载呢?
set_type_override_by_type();
上面这条语句相当于在factory机制的表格中加入了一条重载的记录,所以看似是创建了一个父类Basic的实例,实际却是创建了一个子类Child的实例。因此第一次调用才会打印出Child::B。
使用factory机制的重载的前提条件:
父类和子类都要使用 uvm_component_utils 或者uvm_object_utils 注册到factory表中。
被重载的类,这里是Basic要使用factory机制来实例化,不能使用new函数实例化。
两个类之间Basic与Child之间要有派生关系,这一条不管是在SV还是Factory机制中都应该满足。
被重载的类只能是父类Basic,不能是Child,即set_type_override_by_type()中参数不能颠倒。
3.factory机制中连续的重载
现在从Child类中又派生了一个子类Child_1
class Child_1 extends Child;
`uvm_component_utils(Child_1)
function new(string name = "Child_1",uvm_component parent = null);
super.new(name,parent);
endfunction
virtual function void display();
$display("Child_1::C");
endfunction
endclass
然后在test中build phase中添加如下代码
//set_type_override_by_type(XXX::get_type(),XXX::get_type());
//set_type_override("XXX","XXX");
//以上二者可以替换
set_type_override ("Basic","Child");
set_type_override ("Child" ,"Child_1");
仿真结果

实现了连续的重载
4.替换式重载
如果子类Child_1是从父类Basic派生而来的。
class Child_1 extends Basic;
`uvm_component_utils(Child_1)
function new(string name = "Child_1",uvm_component parent = null);
super.new(name,parent);
endfunction
virtual function void display();
$display("Child_1::C");
endfunction
endclass
然后在test中build phase中添加如下代码
当Basic类被Child重载之后,又被Child_1重载。
set_type_override ("Basic" ,"Child");
set_type_override ("Basic" ,"Child_1");
得到如下仿真结果,替换重载成功

如果想要不能被替换重载
set_type_override ("Basic" ,"Child");
//第三个参数设置为0,表明不能够替换性重载,默认值为1。
set_type_override ("Basic" ,"Child_1",0);
仿真结果
