systemverilog学习(7)OOP
本节关键字:class,methods,数据及其对数据的操作封装起来,继承(inheritance),多态(polymorphism)等等
一:OOP的概念
将数据及其对数据的操作封装在一个独立的对象中。在面向对象编程中, 对象的使用者无须知道对象内部的实现细节, 使用者只要知道如何通过对象的方法和对象进行交互即可。 这使得对象内部实现细节的变动不会影响使用者。 在编写验证平台中, 这对于共享代码很有帮助。
在验证的过程中, 采用对象可以提高验证平台的抽象层次, 这使得开发者可以专注在证平台和被测设计的交互过程。在计算过程中, 提高抽象层次可以让使用者更加容易的处理信息。 在验证平台中, 抽象可以将复杂的情况映射到一个简单的高层次的概念。 例如, 一个数字逻辑电路, 其抽象层次可以从逻辑门电路到比较器到乘法器到算术运算单元或者 CPU。
1:关键字
class:封装数据及其操作,对构建object提供模板
object:对象,类似于instance
handle:句柄(地址),相当于指针
properties:数据变量
method:对数据的操作
二:类的基本概念
包含数据成员与函数成员,句柄(也就是指向对象的指针),即该对象的地址入口
1:定义类
class BusTran
bit[31:0] addr,crc,data[8];
function calc_crc;
.......
endfunction
endclass
2:声明对象与句柄
BusTran b1,b2; //声明两个对象b1,b2;b1,b2为句柄
对象的声明并不意味着对象的创建,声明没有实际分配空间。它只是简单创建了一个标识符。在声明时,对象句柄为空。
3:初始化对象
b1 = new();//初始化时,若class数据为4-state,则缺省初始化为x,2-state时,则缺省初始化为0。
声明与初始化可以用一句表达:BusTran b = new();
4:释放内存
sv能够自动释放内存;
再次new对象b时,第一个内存会被自动回收,b=null是手动释放。
5:在类的定义中声明对象
一个类也可在其定义中引用自身
6:使用对象
使用“ . ”操作符来访问对象中的成员,如下:
三:静态属性与方法
每个类的静态对象都拥有其自身的变量,自身的成员是不和其他对象共享的。假如有两个ether_packet的对象,它们有各自的目标地址,源地址和负荷等。当需要在两个对象之间建立一种练习,可以让该类的所有对象建立一种联系,可以让所有的对象都可以共享,例如,我们在激励产生器中会不断地产生一系列地以太包,在非面向对象的环境中(比如verilog),我们可能会创建一个全局的变量来统计包的个数,而在sv中,我们可以采用静态的方式来声明属性和方法。
静态属性:每个类的例化(也就是每个对象)都拥有它自身每个变量的复制。当要求所有的对象共享一个变量时,我们可以使用static关键字来声明数据成员。
1:静态变量例子
2:解析代码
上述代码中,静态变量count用来统计所有对象的个数,在声明的时候初始化为0,每当有新的对象产生时,count会自增。
静态变量存放在堆里,在run时不会被其它东西破坏掉。
可以这样理解静态变量:static变量与class有关,与object无关,用来存储变化的数据;无论有多少个object,只有一个static变量占用内存。
3:静态方法及其例子
方法也可以被声明为静态的。静态方法对于类的所有对象都可以访问,它就像一个常规的方法一样,可以在类的外部被调用,即使没有该类的初始化。静态方法不能访问非静态的成员,可以访问静态变量或者调用同一个类的静态方法。不能被声明成虚方法(virtual)
四:this
当使用一个变量时, sv会在当前程序范围内查找, 接着回到上一层范围查找, 直至该变量被找到。 假如在一个类的内部而且要求明确的指定引用的就是该类的成员,那该如何处理呢? sv 提供了this这个操作符 (关键字)。关键字this被用来明确地引用当前类的属性或方法。 关键字this对应着一个预定义的对象句柄, 这个句柄可以在该对象内部使用, 并可访问内部成员。 关键字 this只能在非静态方法中使用, 否则会出现错误。
五:类的函数成员
使用function/task
六:对象的赋值与复制
1:packet p1; p1 = new; packet p2; p2 = p1;
声明一个类的变量仅仅定义了它的名字,并没有为其分配空间,所以上述代码实际上只有一个对象。两个句柄,这两个句柄指向同一个对象
2:shallow copy(浅拷贝):值拷贝
pcaket p1,p2;
p1 = new;
p2 = new p1;
产生一个p1的复制
最后一个语句是构造函数new的第二次执行,因此创建了一个新的对象p2,它内部的属性全部复制p1的内容:这种方式的复制叫做浅复制。浅复制只复制变量,包含的对象不会被复制。
3:深复制(deep copy)
完整复制,其中的每个数据成员(包括嵌套的对象)都要被复制
例子:
七:inheritance(继承)
继承 = 原类 + 增加新的properties + 增加methods + 改变原methods函数功能
继承形成派生类;增加可重用性
1:继承使用关键字 extends
2:覆盖父类
子类与父类相同的函数名,会覆盖父类相应的函数,可使用关键字super去除覆盖。
子类calc_crc函数名与父类calc_crc函数名相同,为了继续能够使用父类此函数,可使用super关键字。
八:虚类与虚函数
抽象类与函数;在虚类/虚函数里简单定义成员(即抽象)
虚函数里,只有名字,没有具体实现方式。
九:polymorphism(多态)
由virtual实现
通过父类句柄操作子类的东西,使用父类变量存储子类变量。