SystemVerilog学习笔记---02面向对象编程(类的继承和多态)

SystemVerilog中面向对象编程

简介

相关术语:类(class):包含变量和子程序的基本构建块。
​ 对象(object):类的一个实例。
​ 句柄(handle):指向对象的指针。
​ 属性(property):存储数据的变量。
​ 方法(method):任务或者函数中操作变量的程序性代码。
​ 原型(prototype):程序的头,包括函数名、返回值类型和参数列表。
关键字:class,endclass

在搭建验证平台的过程中,具体需要四部分来完成:

​ 激励生成器(stimulus generator):生成激励内容

​ 驱动器(driver):将激励以时序形式发送DUT

​ 监测器(monitor):监测信号并且记录数据

​ 比较器(checker):比较数据

验证环境的不同组件其功能和所需要处理的数据内容是不相同的不同环境的同一类型组件其所具备的功能和数据内容是相似的;

类是将相同的个体抽象出来的描述方式,对象是实体。

具有相同属性和功能的对象属于同一类,不同类之间可能有联系(继承)或者没有联系。

​ 类的定义核心是属性声明和方法定义,故类是数据和方法的自洽体,它既可以保存数据,也可以处理数据。

​ 类与结构体在数据保存方面的重要区别:结构体只是单纯的数据集合,而类可以对数据做出符合要求的处理

verilog中的module可以实例化一个对象,但是该对象在编译时就已经例化,而类中的对象只有在new()对象时才被例化。

  • 和所有的编程语言中的面向对象编程的准则一样,systemverilog中的类的属性和方法默认权限是public子类和外部均可访问成员。

  • 如果指明了该访问类型是protected,则只有该类或者子类可以访问成员,外部无法访问

  • 如果访问类型是local,则只有该类可以访问成员,子类和外部均无法访问。

在类的编写中,对类中属性的权限类型应该是local的,通过在类内编写set和get函数获取属性的权限。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

对方法的编写,最好的处理是类内声明,类外定义(后面写)。

构造函数new()

和别的构造函数不同,systemverilog中构造函数用关键字new()去创建一个对象。

  • new()可以初始化类中属性的默认值,也可以传递想要的值。
  • new()没有返回值,因为构造函数总是返回一个指向类对象的句柄,类型是类本身。
class Transcation;
    logic [31:0] addr,crc,data[8];//crc未被初始化,则默认值是x
	function new;//不带参数的构造函数
		addr=3;
		foreach(data[i])
			data[i]=5;
	endfunction
endclass

class Transaction;
logic [31:0] addr,crc,data[8];
    function new(logic[31:0]a=3,d=5); //带有参数值的构造函数
		addr=a;
		foreach(data[i])
            data[i]=d;//给data[8]初始化
	endfunction
endclass

initial begin
Transaction tr;//创建一个句柄
    tr=new(10);//让句柄指向新创建的对象
end
tr = new(.a(10));//a=10,让句柄指向新的对象。使用端口传值,将a端口赋成10,d默认是5

在这里插入图片描述

句柄的传递

句柄可以用来创建多个对象,也可以指向不同的对象。

Transaction t1,t2;//创建两个句柄t1和t2
t1=new();//创建对象并将其指针赋给t1
t2=new();//创建对象并将其指针赋给t2
t1=t2;//将t2的值赋给t1,此时t1和t2指向同一个对象,t1所指向的对象被释放
t2-null;//将t2赋值为空,不知想任何对象
此时指针悬空

对象的复制

在new了一个对象并将句柄指向该对象时,相当于指向了一块class类型的内存空间。

复制分为浅复制深复制

​ 浅复制仅仅复制对象的所有属性,不会调用new函数,也就是当类中的属性是另一个类时,new对象开辟内存空间会开辟两块内存空间,而浅复制仅仅复制对象的所有属性,不会重新开辟一片空间。相当于C++中的浅拷贝和深拷贝,浅复制的语法:tr2=new tr1

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
如上代码中,定义了两个类,transaction类中具有Packet类的对象。在验证代码中,将tr1赋给tr2后。试图通过tr2改变tr1中pkt的内存地址,结果显示,除了属性改变成功,pkt中的内存值并未改变。

深复制是创建一个新的和原始句柄指向内容相同的字段,是两个一样大的数据段,所以两个句柄指向的空间是不同的,但是内容相同。之后新对象中的句柄指向的内容发生改变不会引起原始对象所指向内容的改变。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过copy函数去进行深复制。

对象销毁

​ 软件编程的好处在于可以动态的开辟空间,在资源闲置或者不再需要时可以回收空间。

​ SV采用和java相同的自动回收空间的处理方式,无需担心软件空间的开销,不像C++一样用完必须销毁

类的封装

封装是面向对象编程的核心思想,是指将对象的属性和行为封装起来,封装的载体是类,类通常对用户隐藏实现的细节。

采用封装的思想保证类内部的数据结构的完整性。

类与结构体的异同

二者都是容器。

类在声明变量之后需要构造函数new()才会构建对象,而结构体在变量声明时就已经开辟内存。

类除了可以声明数据变量成员还可以声明方法或者任务,但是结构体不行。

从根本来讲,类是某一类事物的抽象模板,而结构体是用户根据实际需要定义的符合数据类型。

类的继承

类继承包括继承父类的成员变量和方法。关键字:extends

在子类重写new函数时,需要先调用父类的new函数(super.new()),如果父类的new函数没有参数,子类也可以省略该调用,系统在编译时自动添加super.new()。

对象的初始化顺序:

  • ​ 子类的实例化对象在初始化时首先会调用父类的构造函数

  • ​ 父类的构造函数执行完,会将子类实例对象中的各个成员变量按照定义时显式的默认初始化

  • ​ 在成员变量默认初始化后,才会进入用户定义的new函数中执行剩余初始化语句。

typedef enum {WHITE,BLACK}color_t;
class ca

类的多态

多态是为了更好的实现代码的复用性,子类继承父类的属性和成员方法,这是继承的一个特性,在继承了父类的方法后对父类方法进行重写实现多态。其中包括父类指针指向子类对象,子类指针指向父类对象,即类型转换。

子类重写父类的方法时需要将父类方法置为虚方法,即在父类的方法前加上关键字virtual实现对父类方法的重写。

super关键字

​ super关键字,主要用于子类访问父类中的属性和方法。一般情况下如果子类对于父类中的属性或者方法进行重写,此时如果要引用父类中被重写的属性或者方法时,就需要明示super。

super.new()方法是为了调用父类中的new方法
在这里插入图片描述
​ 子类在构造时首先执行的是其new函数中的super.new(),即父类的构造函数,在父类的构造函数被调用时,首先会对父类的属性进行初始化,父类属性初始化完毕后,在执行父类中new函数中的相关语句,父类中的new函数执行完毕后返回子类,此时,首先进行的是子类中的属性初始化,然后再执行子类中new函数中除了super.new()以外的语句,从而完成子类的实例化.

super关键字对非new和方法和属性使用

虚方法

关键字:virtual

虚方法为具体的实现提供了一个原型,即在派生类中,重写该方法时必须用一致的参数和返回值。

虚方法可以重写其所有基类中的方法,然而普通的方法被重写后只能在本身和派生类中有效。

每一个类的继承关系中只有一个虚方法的实现,而且是在最后一个派生类中。
在这里插入图片描述
在这里插入图片描述
在上述代码中,my_packet类继承了packet类,packet中有一个虚方法和正常的方法,p1是父类的句柄,p2是子类的句柄,当p1指向p2所指的空间时。

  • 当父类的句柄调用方法时,发现display_a是个正常的方法,则调用自己的display_a方法;父类的句柄调用到display_b时,发现是个虚方法,则调用子类的方法。

  • 当子类的句柄指向正常方法时,调用自己的方法,遇到虚方法时也是调用自己的方法。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

类型转换

父类到子类的类型转换称为向下类型转换,从子类到父类的类型转换称为向上类型转换,前者是安全的的,后者是不安全的。

向上转换(子–>父,父类的指针指向子类开辟的空间)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PbtKDPG3-1692509287085)(C:\Users\史飞洋\AppData\Roaming\Typora\typora-user-images\1684035692676.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ODvWV3pL-1692509287087)(C:\Users\史飞洋\AppData\Roaming\Typora\typora-user-images\1683986996262.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-obyhA4Iw-1692509287091)(C:\Users\史飞洋\AppData\Roaming\Typora\typora-user-images\1684035662914.png)]

上述代码中,当父类的句柄指向父类对象时,首先调用父类的方法和属性。当父类句柄指向子类对象时,如果子类中没有相应的方法,则会调用自己的方法,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VIdDfqEW-1692509287094)(C:\Users\史飞洋\AppData\Roaming\Typora\typora-user-images\1684036302566.png)]

向下转换(父–>子,子类的指针指向父类开辟的空间)

借助cast函数实现

​ $cast函数是一个类型检查的函数。用在动态类型转换中。

向下类型转换指的是子类句柄指向了父类的对象。由于子类继承了父类的属性和方法,故子类中包含所有父类中的属性和方法(前提不能设置为loca权限),即就是当子类使用父类的属性和方法时(父类的句柄指向子类的对象时)是不会出现任何意外的。但是当子类的句柄指向父类的对象时,如果调用父类中的属性和方法时会出现父类中没有而子类中有的情况。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jtg9XI9d-1692509287097)(C:\Users\史飞洋\AppData\Roaming\Typora\typora-user-images\1684039095869.png)]

Coach001

static静态变量和静态函数

静态变量

在类中,每一个对象都有自己的局部变量,这些变量不与其他的对象共享。但是如果有多个对象需要一个某种类型的变量,此时使用静态变量最好,静态变量是开始于编译阶段,贯穿整个仿真阶段。

关键字:static

引用方式:

直接引用:类名::静态变量;

对象引用:对象名.静态变量。

初始化:在声明时初始化,即在类中定义时就需要初始化,不能在构造函数中对静态变量进行初始化。
静态变量的另一个用途时在类的每一个实例都需要从同一个对象中获取信息时。
在使用静态变量时需要注意共享资源的保护。
在这里插入图片描述
在这里插入图片描述

静态方法

在使用更多的静态变量时,操作的代码会迅速增长,此时可以定义以静态方法用于读写该静态变量,甚至可以在第一个实力产生之前读写静态变量。

静态方法无法读取非静态变量。

静态方法中可以声明和使用动态变量,但是无法使用类的动态变量。因为在调用静态方法时,可能没有创建具体的对象,因此也没有为动态变量开辟空间,因此在静态方法中使用类的动态变量是禁止的,但是静态方法可以使用静态变量,静态方法和静态变量一样在编译阶段就为其分配好了空间。
在这里插入图片描述

静态方法的引用:

类名::方法名或者对象名.方法名。

通过对象名.方法名也可以对静态属性进行修改。

在类内声明方法,在类外定义方法

在SystemVerilog中所有类的方法都可以定义于类内,也可以定义于类外。一般将比较复杂的方法的实现放在类外,这样可以增加代码的可读性,而比较简单的方法在类内实现。如果什么方法的定义都放于类内部的话,那么查找一个方法将会比较麻烦。所以在实际使用时,经常将方法定义于类外,方法定义于类外一般分为两步实现:
第一步:在类内完成方法原型的声明,此时在方法原型前要使用关键字extern;

第二步:在类外实现方法,此时方法名前需要加上“类名::”,用于限定了该方法属于哪个类;

在完成了上述两步后,就完成了类内方法在类外实现的步骤。在完成了类内声明和类外定义之后,在使用时还需要注意类内和类外方法的匹配问题,也就是方法原型与实现的声明匹配问题,下面将通过示例说明常遇到的声明匹配问题。
但是在类内声明方法和类外定义方法时要注意参数列表的匹配问题,必须要参数列表相同。
在这里插入图片描述

抽象类

抽象类:可以被继承但不能直接实例化的类。

关键字:在class前加virtual

纯虚方法:在抽象类中,可以定义没有实体的方法原型,被称为纯虚方法,使用pure virtual修饰。

纯虚方法只能在抽象类中定义。

virtual class Packet;//抽象类的定义
    pure virtual function int send(bit[31:0] data);//抽象类中的纯虚方法
endclass

抽象类无法直接被创建对象,但是可以声明抽象类的句柄,必须要先扩展该类(就是让别的类对其继承)并且对所有的纯虚方法进行实现。相当于抽象类提供了某一类事务的一个类的最初的模板和模板方法。使用别的类对其继承并且实现里面的纯虚方法,就可以使用。

1、抽象类不能被直接实例化;

2、一个由抽象类扩展而来的类,要想被实例化(即成为一个非抽象类),只能在所有的纯虚方法都有实体,变成虚方法后才能实例化;

3、纯虚方法是一个原型,不是一个空的虚方法。空的虚方法如下,可以调用它,但它会立即返回:

  pure virtual function int send(bit[31:0] data);//抽象类中的纯虚方法
endclass

抽象类无法直接被创建对象,但是可以声明抽象类的句柄,必须要先扩展该类(就是让别的类对其继承)并且对所有的纯虚方法进行实现。相当于抽象类提供了某一类事务的一个类的最初的模板和模板方法。使用别的类对其继承并且实现里面的纯虚方法,就可以使用。

1、抽象类不能被直接实例化;
2、一个由抽象类扩展而来的类,要想被实例化(即成为一个非抽象类),只能在所有的纯虚方法都有实体,变成虚方法后才能实例化;
3、纯虚方法是一个原型,不是一个空的虚方法。空的虚方法如下,可以调用它,但它会立即返回:
4、纯虚方法只能在抽象类中定义,但抽象类中也能定义非纯虚方法
-----------------------------------------------------------------------------------------------------------------------------
学习中部分内容来源网上博客!!!

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: SystemVerilog IEEE 1800-2017 是一种面向硬件设计的编程语言,主要用于系统级集成电路和芯片设计。这一标准包含了许多功能,例如测试和验证、并行性、属性和断言、重用和组合、多态性等。 在测试和验证方面,SystemVerilog允许设计者添加创建测试向量、显示输出和断言的代码,从而简化测试的工作,并可以在设计时验证设计。在并行性方面,SystemVerilog支持多线程和同步,充分利用了现代计算机的多核处理能力。在属性和断言方面,SystemVerilog可以对设计进行形式化验证,并检测到设计中的错误。在重用和组合方面,SystemVerilog支持可重用的程序和模块,并允许开发人员在不同的设计中重复使用设计代码。在多态性方面,SystemVerilog支持多态型、参数和函数,这些功能提高了代码的可读性和可维护性。 总体来说,SystemVerilog IEEE 1800-2017 是一个强大而灵活的编程语言,可以大大简化高级计算机和集成电路设计的工作。 ### 回答2: SystemVerilog IEEE 1800-2017.pdf是SystemVerilog的标准文档,它定义了一种硬件描述语言,用于设计和验证现代计算机芯片和电路。 该文档包括了SystemVerilog语言的语法规则、数据型、控制流结构、函数、任务、、接口、模块、宏等相关内容,为硬件设计工程师提供了一套丰富的语言机制和工具,以实现更容易编写和验证复杂的设计和测试。 SystemVerilog的特点包括强大的数据型支持、多态、多时钟域、复杂的继承等。它也允许使用高级特性,如随机性和约束来进行验证,同时也支持集成测试、断言和仿真等关键测试功能。 SystemVerilog的应用涉及到许多领域,包括系统级验证、芯片设计和验证、高级集成电路设计和验证等,它被广泛应用于数字电子产品的开发和制造。对于从事硬件设计和验证领域的工程师和研究人员来说,学习和掌握SystemVerilog语言,是十分必要和有价值的,因为它可以提高工作效率和工作质量,减少开发成本和时间,而SystemVerilog IEEE 1800-2017.pdf则是系统学习和使用SystemVerilog语言的重要参考资料。 ### 回答3: systemverilog ieee 1800-2017.pdf 是一份由国际电气与电子工程师协会(IEEE)发布的规范,它涉及了一种名为SystemVerilog的硬件描述语言。 SystemVerilog在设计和验证芯片上有着广泛的应用。它是Verilog HDL的扩展,加入了、接口、包、结构体、枚举、并发控制、语言连接和其他新特性,可以更好地支持高级验证和抽象化的设计。 这个规范详细规定了SystemVerilog的语法、语义、规则和语言特性。其中,最重要的组成部分是数据型、并发控制和自动化测试框架。 该规范主要针对硬件设计工程师、验证工程师和EDA工具开发人员。实际应用中,SystemVerilog广泛应用于半导体行业、计算机系统和电子设备的设计和测试领域,可以提高设计效率和准确性。 最后,规范的及时更新和完善,可以为SystemVerilog的标准化和可靠性做出贡献,有助于推动行业的进步和发展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值