SV中面向对象编程基础
2021/10/30 17:40:28
本文主要是介绍SV中面向对象编程基础,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
验证为什么需要OOP(面向对象编程)?
验证环境不同组件及其功能和所需要处理的数据内容是不相同的,但是不同环境的同一类型的组件所具备的功能和数据内容是相似的,所以验证世界的各个组件角色明确,功能分立,使用面向对象编程与验证世界的构建原则十分符合。
激励生成器:生成激励内容
驱动器:将激励以时序形式发送到DUT
监测器:监测信号并记录数据
比较器:比较数据
OOP术语
(1)类(class):是软件盒子,包含变量和子程序的基本构建块。Verilog中对应的是模块(module),是硬件盒子。
(2)对象(object):类的一个实例。Verilog中module可以例化,SV中class也可以例化。
(3)句柄(handle):用来指向对象的指针。在Verilog中可以通过层次化的索引来找到结构中的设计实例,而在SV的对象索引时,需要通过句柄索引对象的变量和方法。
(4)属性(property):在类中声明的存储数据的变量
(5)方法(method):处理数据的方法,如task,function
将类视为房子的蓝图,则对象是一个实际的房子,而句柄就像是房子的地址。
定制构造函数
Transaction tr; //声明句柄 tr=new(); //创建对象
构建函数new()是系统预定义的函数,不需要指定返回值,函数会隐式地返回例化后的对象指针。构造函数除了分配内存之外,它还初始化变量。在默认情况之下,它将变量设置成默认数值——二值变量为0,四值变量为X。你也可以自定义new函数将默认值设置成你想要的数值。类似于python中的__init__函数。你不能简单地在类的构造函数中初始化静态变量,因为每一个对象都会调用构造函数,你可以在类的定义中初始化。
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; endfunction endclass
对象的解除分配
垃圾回收是一种自动释放不再被引用的对象的过程。SV分辨对象不再被引用的方法是记住指向它句柄的数量,当最后一个句柄不再引用某个对象时,SV就释放该对象的空间。
类的成员
一个类的功能应该尽可能简单,不应该承担过多的责任,也不应该承担不符合它的职责。类作为载体,不会将成员变量直接暴露给外部,通过public,protected,local关键词来设置成员变量方法的外部权限访问。
默认类型是public,子类和外部均可以访问成员。
protected:只有该类和子类可以访问成员,外部是无法访问的
local:只有该类可以访问,子类外部都不行访问
module和class的异同
(1)数据和方法定义方面:两者都使用相同的模板来创建实例,都可以作为封闭的容器来存储数据和方法。
(2)例化方面:module例化是静态的,在编译链接时就完成;而SV中class的例化是动态的,可以在仿真的任何阶段声明并动态创建新的对象,这也使类的例化方式更加灵活而节省空间。
(3)封装性方面:模块内的变量和方法对外部都是开放的,而类可以根据需要来确定外部访问的权限:pubilc,protected,local
(4)继承性方面:模块没有继承性而言
类与结构体的异同
(1)二者都可以定义数据成员
(2)类变量在声明之后,需要构造函数才构建对象实体,而struct在声明变量时已经开辟内存
(3)类不仅可以声明数据变量成员,而且可以声明方法,这是struct做不到的
(4)从根本上说,struct是一种数据结构,而class包含数据成员以及针对这些成员的操作方法
this
class A; string oname; function new(string oname); this.oname=oname; endfuction endclass
当你使用一个变量名时,SV会在当前作用域寻找,接着在上一级作用域上寻找,直到找到该变量为止。但是你在类的很深层的作用域想引用类一级的对象时,就可以采用this。this表示调用的成员是当前类的成员,而非同名的局部变量。
包的使用
SV提供了一个在多个module,interface,program之中共享parameter,data,task,function,class等方法,通过包(package)来实现。这么做的好处是将一族相关的类组织在了单一命名空间下,可以通过package来解决归属问题。
package regs_pkg; `include "stimulator.sv" `include"monitor.sv" `include"checker.sv" `include"env.sv" endpackage
重名的类归属到不同的package编译,不会发生冲突,只需注明是哪一个package
module A; regs_pkg::monitor mon1=new(); arb_pkg::monitor mon2=new(); endmodule
将类封装到一个包之中,那么它就不在其他地方编译,这么做的好处是之后对类的引用更加方便。包中可以定义类,静态方法和静态变量,使用`include来完成类在包中的封装,即“平铺”在包中,按照顺序完成包和各个类的有序编译。使用类可以通过import完成类的导入,使得新的环境可以识别出该类,否则类会躺在包这个盒子里不被外部识别。
这篇关于SV中面向对象编程基础的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-09-19环境变量处理课程:新手入门教程
- 2024-09-19接口模块封装课程:新手入门指南
- 2024-09-19请求动作封装课程:新手入门教程
- 2024-09-19拖拽表格课程:新手入门指南
- 2024-09-19页面权限课程:新手必学的权限管理入门教程
- 2024-09-19如何正确主动登出课程:新手必读教程
- 2024-09-19Element-Plus课程:新手入门与初级教程
- 2024-09-19Token处理入门教程:新手必看指南
- 2024-09-19如何应对被动登出课程的情况:新手必读指南
- 2024-09-19打包优化课程:初学者的必备指南