systemverilog-OOP:封装、继承和多态

1.面向对象的三个基本特征

对象:万物皆对象
类:类就是具有相同属性和行为的对象的抽象的集合
实例:对象就是类的实例
在这里插入图片描述
封装可以隐藏实现细节,使得代码模块化;继承可以扩展已经存在的代码模块,两者的目的都是为了代码重用,多态为了实现另一个目的——接口重用。

1.1 类与结构体的差异

结构体(struct)可以自定义一个类型,类也是一种类型,那类与结构体的异同在于:

  • 二者本身都可以定义数据成员
  • 类在变量声明后,需要构建才会创建对象实体;而struct在变量声明时就已经开辟内存
  • 类可以声明方法和任务,而结构体不能
  • 从根本上看,struct是一种数据结构,而class则包含了数据成员以及针对成员的操作方法

2.封装

封装进行信息隐藏,利用抽象数据类型将数据和基于数据的操作封装在一起,尽可能隐藏内部一些细节,只保留一些对外接口使之与外部发生联系。数据封装、方法封装。
构造new()时,不需要返回值,函数会隐式地返回例化后的对象指针。

//声明类
class Transaction;
	bit[31:0] addr,crc;
	function new();
		...
	endfunction
endclass:Transaction
//声明一个句柄
Transaction tr,tr1,tr2;//指针悬空,为null值,没有指向任何对象
Transaction tr = new();//声明句柄+创建对象,为对象分配一个地址
//创建对象
tr1 = new(); //将句柄赋予给tr1
tr2 = tr1;//将tr1的值赋给tr2,即tr1、tr2指向同一个对象
tr2 = new();//将句柄赋予给tr2

注意:类中定义的变量不能是wire和reg,也不能出现initial和always,即硬件世界的部分不能在软件世界中定义。
调用new()时,系统的步骤:
1.系统开辟空间;
2.将开辟的空间分配给变量,进入new()函数对变量初始化
3.退出new()时,将当前对象的句柄返回
注意:new()函数创建对象时,会为对象分配地址,将类中变量初始化(二值变量为0,四值变量为x)。
systemverilog采取自动回收空间的处理方式,当一个对象,在整个程序中没有任何一个地方再需要它时,便会被“销毁”,即回收其空间。
在类中声明的变量时动态的(这和module恰恰相反),但可以用static来声明静态变量。
在类中声明接口的指针,必须要加virtual.

class TB;
	static int count = 0;//声明一个静态变量
	local virtual interface_test it;//声明一个指针
endclass

3.继承

子类继承了父类所有的成员方法和属性,并且可以拥有自己特性。通过关键字extends实现继承解决代码的重用性。

  • 子类拥有父类非private的属性和方法。
  • 子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
  • 子类可以用自己的方式实现父类的方法。

3.1 成员访问权限

  • 默认情况是子类和外部都可以访问
  • protected只有该类和子类可以访问,外部不可访问
  • local只有该类可以访问,子类和外部都不可访问

3.2 this 和 super的区别

  • this 会先在当前作用域中查找,如果当前作用域中没有,则会去上一级作用域中查找,知道找到该变量为止
  • super首先会先在该类的父类中查找
class Father
	string name = "father";
	function new(string name);
		this.name = name;
	endfunction
endclass
class Son extends Father;
	int son_age = 5;
	function new(string name);
		super.new(name);
		name = "son";
		son_age = 15;
	endfunction
endclass

3.3 类的方法

类的方法——也就是类的作用域定义的内部task或者function

class Transaction;
	bit [31:0] addr,crc,data[8];
	function void display();
		$diaplay("@%0t:TR addr = %h,crc = %h",$time,addr,crc);
		$write("\tdata[0-7]=");
		foreach(data[i]) $write(data[i]);
		$display();
	endfunction
endclass

class PCI_tran;
	bit [31:0] addr,data;
	function void display();
		$display("@a%0t:PCI:addr = %h",$time,addr,data);
	endfunction
endclass

Transaction t;//声明句柄
PCI_Tran pc;

initial begin
	t=new();//创建一个Transaction对象
	t.display();//调用Transcation的方法
	pc=new();//创建一个PCI事务
	pc.display();//调用PCI事务的方法
end

4.多态

“一个接口,多种方法”,同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。

多态的三个条件:

  • 继承的存在
  • 子类重写父类的方法
  • 父类引用变量指向子类对象
    重载(overload)和重写(override)是实现多态的两种主要方式。
  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值