systemverilog中的OOP
(2014-07-20 10:55:36)
标签:
systemverilogoop |
分类: Verification |
1,OOP中的几个名词:Class--定义类;Object---类的例化,也是句柄指向的单元;Handle---句柄,指向一个Object的具体地址;Property---类中的变量,也可以称为variable;Method---类中定义的函数(function)或任务(task),也可以叫做routines。
2,一般工程的把一个类的定义放在一个单独的文件中,再把几个有关联的类和文件打包为一个package。
3,在SV中对于每个定义的类,都有一个默认的constructor。这个构建函数主要完成两个工作:分配地址和初始化变量,即2态的变量初始化为0,4态的变量初始化为X。用户也可以自定义自己的new()函数,然后完成自己的初始化赋值。在下例中,new有两个参数,在initial的调用中,只赋值了第一个参数,第二个参数仍为默认值5,除此两个参数外的其他参数都是默认值0或X。
Eg:
4,应该尽量避免将Object的声明和构造放在一条语句中,因为如果new()的声明不是automatic的,那么在仿真的开始SV便会将类构造出来以分配地址,而可能要在进入block中时,类才会被声明。所以应该将类的声明和构造分开。
5,同一类型的句柄之间可以相互赋值,从而改变指向的Object。
6,Object的释放,SV中一条默认的规定是,当一个Object不再指向任何有效的地址时,将会将地址收回。可以通过赋值语句 tr = null来完成地址的释放。如果一个Object中还包含一个运行的thread,那么必须等到进程运行完成,才能释放地址。
7,类中的静态变量相比较于Object中的变量,前者适应在整个类中,所有的已经例化的Object,而Object中的变量只适用于本身。所以static变量的声明只能在class中,而不是在一个new()函数中。调用static变量,通过"::",调用Object自己本身中的变量通过"."。而且static的routines中只能调用static的变量,不能调用去其他的Object中的变量。在下例中,id可以表示每个已经声明的Object的id号,而count可以表示总共的声明的Object的数量。
Eg:
8,在类外定义routines时,可以使用extern声明,在外部定义时,可以使用"::"表示引用。在类的内部定义的必须是一个prototype,在类外部定义时,完全按照这个定义routines的参数。
9,在类中可以使用"this"来指明是类中的变量,从而可以在赋值时方便一些。在下例中,oname在两个scope中都有定义,用"this"来特指类中的定义。在SV中scope可以有:module
program task funtion class foreach begin-end
Eg:
10,在类中定义子类,父类对子类的调用与其他变量相同,不过子类的构造最好直接放在父类的类定义中。在下例中,将stats的构造放在类Transaction中,否则handlestats指向为null。在子类定义比较靠后时,可以通过"typedef"来先进行声明,--typedef
class
Eg:
11,在methods中引用Object时,通过将Object传给method来进行调用,在声明时有两种方式:加ref,不加。在添加ref时,可以改变handle指向的Object的值,不加是,只能使用特指的那一个Object。
Eg:
12,Handle的矩阵表示,在下例中,先声明一个指向类的矩阵handle,然后在foreach中,逐一的来进行构造new()。
Eg:
13,对Object的copy操作,可以方便的完成对象值得赋值,但是因为copy的本质操作也是进行地址的赋值,本身并没有重新构建一个object,所以像id这样的标志两个copy的类会相同。还有一个问题是,在父类中有子类时,两个父类的子类的地址相同,所以任何一个类中的值的改变都会影响另外一个的值。
Eg:
一个比较好的解决方法是:自己写一个copy函数,像下面例子中的那样。
14,在SV中,变量和routines的默认声明会是public,也可以自己加label声明为local和protected的。

加载中…