多态(Polymorphism),从字面意思上看指的是多种形式,在OOP(面向对象编程)中指的是同一个父类的函数可以体现为不同的行为。
在SystemVerilog中,指的是我们可以使用父类句柄来保存子类对象,并直接使用父类句柄来调用子类的方法。
因此,SystemVerilog中的多态性是一种根据父类对象句柄实际指向不同的对象类型使相同的代码具备不同行为的能力。
为了实现这个目的,父类中的function或者task必须是virtual的。这样,当扩展类覆盖这个function或者task时,实际指向扩展类的父类句柄就可以调用扩展类的function或者task
因此,用一句话可以概括:
polymorphism = inheritance + virtual methods + upcasting.
SystemVerilog多态的示例:
class vehicle; // Parent class
virtual function vehicle_type( ); // Virtual function
$display("vehicle");
endfunction
virtual task color( ); // Virtual task
$display("It has color");
endtask
endclass
class four_wheeler extends vehicle; //child class
function vehicle_type( ); //override parent class virtual
//function
$display("It is a four wheeler");
endfunction
task color( ); //override parent class virtual task
$display("It has diferent colors");
endtask
endclass
class BENZ extends four_wheeler; // "grand" child class
function vehicle_type();
$display("It is a Benz");
endfunction
task color();
$display("It is Black");
endtask
endclass
module polymorphism;
initial begin
vehicle vehcl;
four_wheeler four_whlr;
BENZ benz;
four_whlr = new ( );
benz = new ( );
vehcl=four_whlr;//parent class variable holding child
//class handle. No need to create an
//object (of vehcl) by calling a new method
vehcl.vehicle_type( );
// accessing child (four_whlr) class method from
// parent class (vehcl) variable
vehcl=benz;
vehcl.vehicle_type( );
//accessing "grand" child method from parent class
//variable (vehcl)
four_whlr=benz;
four_whlr.color( );
// accessing child class method from parent class
// "four_whlr"
end
endmodule
仿真log:
It is a four wheeler
It is a Benz
It is Black
$fnish at simulation time 0
V C S S i m u l a t i o n R e p o r t
在上面这个例子中,我们首先声明一个名为“vehicle”的父类。在这个父类中,我们声明了两个virtual 方法“vehicle\_type”和“color.” 。
然后我们创建一个名为“four\_wheeler”的扩展类,并覆盖父类的virtual方法。
我们再扩展自“four\_wheeler”创建一个扩展类“BENZ”。
所以,类的继承关系如下:
“vehicle” -> “four_wheeler” ->“BENZ”
在program “polymorphism”中,我们声明每种class类型的句柄,但是仅实例化两个子类,即“four\_whlr”和“benz”,而没有实例化父类。
这里需要回顾下一个upcast的概念,即将扩展类对象直接赋值给父类句柄。当我们实例化扩展类对象“four\_wheeler”时,实际上为该类“four\_wheeler”和相应的父类“vehicle”分配了物理内存空间。
当我们执行
vehcl = four_whlr
父类句柄中就包含了子类实例,据此我们可以访问被覆盖的virtual方法,这就是多态性。
下面是另外一个展示多态性的示例:
// base class
class animals;
virtual function void display( );
$display("Inside base class animals");
endfunction
endclass
// extended class 1
class parrot extends animals;
function void display( );
$display("Inside extended class parrot");
endfunction
endclass
// extended class 2
class tiger extends animals;
function void display( );
$display("Inside extended class tiger");
endfunction
endclass
// extended class 3
class lion extends animals;
function void display( );
$display("Inside extended class lion");
endfunction
endclass
// module
module polymorphism;
initial begin
//instantiate subclasses
parrot p1 = new( );
lion A1 = new( );
tiger t1 = new( );
//base class array variable
animals a1[3];
//assigning extended class object handles to
//base class array variable
a1[0] = p1;
a1[1] = A1;
a1[2] = t1;
//accessing extended class methods using base class
variable
a1[0].display( );
a1[1].display( );
a1[2].display( );
end
endmodule
仿真log:
Inside extended class parrot
Inside extended class lion
Inside extended class tiger
V C S S i m u l a t i o n R e p o r t
分别将不同的子类对象赋值被3个父类句柄,可以看出最后相同的父类函数打印出不同的内容。
作者: 验证哥布林
来源:芯片验证工程师
推荐阅读
更多数字IC设计技术干货等请关注数字芯片实验室专栏。添加极术小姐姐(微信:aijishu20)微信可申请加入IC设计交流群。