story · 2022年11月29日

从本质上理解SystemVerilog的多态(Polymorphism)

多态(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设计交流群。
推荐阅读
关注数
12319
内容数
221
前瞻性的眼光,和持之以恒的学习~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息