【转载】SystemVerilog中有关class类的基础知识

  • Post author:
  • Post category:其他


1

class中的变量、宏定义等称为类的属性,函数和任务称为类的方法

2

声明对象时可以指定input/output/inout/ref

3

复制对象,复制的是句柄而不是对象的内容。

类的每个对象,对于属性、方法等都有自己的副本

4


?

1

2

3

4

5

6


<code>


class


c;


...


endclass


c c0;


</code>


//“c”就是对象c0的句柄,在此处仅相当于一个name,类似于仅是创建了一个c类型的变量c0,而这个变量保存类c对象

的句柄,但其初始化值为NULL

此时,这个对象时不存在,也不包含任何实际的句柄,知道进行初始化:c0 = new()

此时,对象c0的句柄尚未被初始化,因此,为默认值;Null。因此,检测一个对象是否被初始化,与值Null进行比对即可:

值为Null的句柄不可以访问非静态成员和虚方法



?


1


2


3


4


5


6


7


8



<code>


class


obj_example;



...



endclass




task task1(integer a, obj_example myexample);





if


(myexample ==


null


) myexample =


new


;


//初始化



endtask



</code>



4_1




类对象支持的算术/逻辑运算:

—支持的操作—–操作对象—-含义

== 对象/Null

!= 同上

=== 同上

!== 同上

条件操作

类型兼容的对象间互相赋值

赋值Null



5




初始化函数new(),非阻塞,没有返回值类型(但初始化过程中,但暗含的返回值类型就是赋值等号左侧变量的类型)

new()函数,可不人为定义,在对象初始化时会调用默认的new函数,也可以人为定义new函数,以便规定初始化操作。

6、基类、扩展类new()函数的执行:

先调用基类的new函数——super.new(),



eg:




?




1



2



3



4



5



6



7



8



9



10



11



12



13



14



15



16



17



18



19



20



21



22



23



24




<code>


class


C;







int


c1 =


1


;







int


c2 =


1


;







int


c3 =


1


;










function


new


(


int


a);







c2 =


2


;







c3 = a;







endfunction





endclass











class


D


extends


C;







int


d1 =


4


;







int


d2 = c2;







int


d3 =


6


;







function


new


;







super


.


new


(d3);







endfunction





endclass








D obj_d;





obj_d =


new


(d3);





</code>





解释:

会先执行基类C的初始化new函数(即类C的属性、方法的初始和定义等),c1 = 1,c2 = 2;

c3,基类C中new函数的输入参数a此时为d3,但此时d3尚未定义,所以,c3为未定义值;

基类的各种初始完成后开始进行扩展类的初始操作,即执行扩展类的new函数,d1 = 4,d2 = 2(基类中的变量c2,基类此时已初始化完成,所以c2为确定的值),d3 = 6,





7






类声明中的静态属性,只创建、初始化一次,之后则可以为所有的对象访问,并且,可以以无创建对象的方式被访问






?






1





2





3





4






<code>


class


Packet ;









static


integer fileID = $fopen(


"data"


,


"r"


);







endclass







</code>







8








类声明中的静态方法,类的全范围内可以调用,也可以无创建对象的方式被访问,不可以访问非静态的成员(属性和其他方法);

不能声明为virtual,声明中不能使用this句柄;








?








1







2







3







4







5







6







7







8







9








<code>


static


task t();











...









endtask


//正确格式,说明了类中方法的lifetime(理解为:存活时间)























task


static


t();











...









endtask


//错误格式,说明的是方法的参数及方法声明中的各个变量的lifetime









</code>









9










this指针,涉及类的属性、变量参数、对象本地的变量参数或方法,应用在非静态方法中









10










类对象的复制:

(1)

class c;



endclass










?










1









2









3









4










<code>c c0, c1;











c0 =


new


();











c1 = c0;











</code>











解释:new只执行一次,只涉及到一个句柄,所以说,只有一个对象,只是对于对象的句柄而言有两个名字,分别为:c0和c1











(2)












?












1











2











3











4











5











6











7











8












<code>


class


c;















...













endclass
























c c0, c1;













c0 =


new


();













c1 =


new


c0;













</code>













解释:new函数执行两次,创建了两个对象:c0和c1,c1是复制的c0,但只是复制了c0的句柄,也可以认为是一个对象有两个名字

注:这种方式的复制,对于嵌入式的约束,在新的对象中为Null













(3)














?














1













2













3













4













5













6













7













8













9














<code>


class


c;

















...















endclass




























c c0, c1;















c0 =


new


();















c1 =


new


();















c1.copy(c0);















</code>















解释:c0中的任何内容全部复制给了c1,更常用。















11
















扩展类对象的句柄可赋值给基类变量
















?
















1















2















3















4















5















6















7















8















9















10















11
















<code>


class


c;



















class


cc


extends


c;



















......



















endclass

















endclass
































c c0;

















cc cc0;

















cc0 =


new


();

















c0 = cc0;

















</code>

















注:扩展类中的属性或方法被重写覆盖时,通过以上方法,可以获得基类中各成员的原始值/内容

且当基类中为纯虚方法、扩展类中方法的定义也必然是虚方法,这种情况下,基类变量可以直接访问扩展类的方法


















?


















1

















2

















3

















4

















5

















6

















7

















8

















9

















10

















11

















12

















13


















<code>


class


c;





















class


cc


extends


c;





















int


i =


1


;





















int


i =


2


;





















endclass



















endclass




































c c0;



















cc cc0;



















cc0 =


new


();



















c0 = cc0;



















j = c0.i;


//j = 1,而不是等于2,所以说,扩展类中变量i进行何种操作,基类都会保留变量i的原始值



















</code>



















注:扩展类声明变量(cc cc0;)可以赋值给基类声明变量(c c0;)或更高层次类的声明,反过来则是错误的,除非基类中调用了扩展类



















12




















super 访问当前类的上一层次的类的成员




















?




















1



















2



















3



















4




















<code>


super


.


new


//先于当前类的new执行,可以用户手动添加,或者编译器会自动添加执行super.new的阶段





















function


new


();


//扩展类中new函数





















super


.


new


(


5


);


//启动当前类基类的new函数,并且是带有参数的,会传递给基类的初始化函数





















</code>





















13






















类中数据的封装与保护:定义成员关键字含义local和protected






















?






















1





















2





















3






















<code>local


//

只有当前类中方法可以访问,不同对象间可以互相访问,但扩展类中方法不能访问
























protected


//

同local定义基本相同,唯一差别在于可以被继承、扩展类可以访问
























</code>























14
























类中属性/成员:const、local、protected、static

类中方法:virtual

const:定义只读变量,分为global const和instace const,























区别在于:前者声明时进行赋值,同static,所有的对象均可访问,且内容一样;后者只是声明,实例化时才会赋值
























?
























1























2























3
























<code>


const


int


max_size =


9


*


1024


;


// global constant,也可以声明为static

























const


int


size;


// instance constant

























</code>

























15


























抽象类:可以看作是模板或原型


























?


























1

























2

























3

























4


























<code>virtual


class


BasePacket;





























...



























endclass



























</code>



























无法直接创建抽象类的对象.



























纯虚方法:定义在抽象类中的虚方法,具体的实现则是在扩展类(非抽象类)中定义完成的




























?




























1



























2



























3



























4



























5



























6



























7



























8



























9



























10



























11




























<code>virtual


class


BasePacket;































pure virtual function integer send(bit[


31


:


0


] data);


// No implementation





























endclass
























































class


EtherPacket


extends


BasePacket;































virtual function integer send(bit[


31


:


0


] data);































// body of the function































...































endfunction





























endclass





























</code>





























当基类中为纯虚方法、扩展类中方法的定义也必然是虚方法,这种情况下,基类变量可以直接访问扩展类的方法






























?






























1





























2





























3





























4





























5





























6





























7





























8





























9





























10






























<code>BasePacket packets[


100


];































EtherPacket ep =


new


;


// extends BasePacket































TokenPacket tp =


new


;


// extends BasePacket































GPSSPacket gp =


new


;


// extends EtherPacket




























































packets[


0


] = ep;































packets[


1


] = tp;































packets[


2


] = gp;































packets[


1


].send();


//invoke the send method associated with the TokenPacket class































</code>































16
































类的嵌套:嵌套的类可以访问被嵌套类的local、protected、static等成员,有完全访问权
































?
































1































2































3































4































5































6































7































8































9































10































11































12































13































14































15































16































17































18
































<code>


class


Outer;



































int


outerProp;



































local


int


outerLocalProp;



































static


int


outerStaticProp;



































static


local


int


outerLocalStaticProp;


































































class


Inner;


//类Inner为嵌套类



































function


void


innerMethod(Outer h);


//类Outer声明

































outerStaticProp =


0


;


// Legal, same as Outer::outerStaticProp

































outerLocalStaticProp =


0


;


// Legal, nested classes may access local's in outer class

































outerProp =


0


;


// Illegal, unqualified access to non-static outer

































h.outerProp =


0


;


// Legal, qualified access.

































h.outerLocalProp =


0


;


// Legal, qualified access and locals to outer class allowed.



































endfunction



































endclass
































































endclass

































</code>

































17


































外部定义:在类内带extern关键字进行声明,类外定义时,需指明类作用域,用”::”符号

例子1:


































?


































1

































2

































3

































4

































5

































6

































7

































8

































9

































10

































11

































12

































13

































14

































15

































16


































<code>


class


Packet;





































Packet next;






































































function Packet get_next();


// single line





































get_next = next;





































endfunction





































// out-of-body (extern) declaration





































extern


protected


virtual function


int


send(


int


value);



































endclass




































































function


int


Packet::send(


int


value);





































// dropped protected virtual, added Packet::





































// body of method





































...



































endfunction



































</code>



































例子2:




































?




































1



































2



































3



































4



































5



































6



































7



































8



































9



































10



































11



































12



































13



































14



































15




































<code>typedef real T;





































class


C;







































typedef


int


T;







































extern function T f();







































extern function real f2();





































endclass








































































function C::T C::f();


// the return must use the scope resolution,以区分"typedef real T"和"typedef int T"







































return


1


;





































endfunction








































































function real C::f2();







































return


1.0


;





































endfunction





































</code>





































例子3:






































?






































1





































2





































3





































4





































5





































6





































7





































8





































9






































<code>typedef


int


T;







































class


C;









































extern function


void


f(T x);


//原型中,T采用的是"typedef int T"









































typedef real T;







































endclass












































































function


void


C::f(T x);


//error,在此处采用的是类中声明的"typedef real T"







































endfunction







































</code>







































注:最好是用作用域符号”::”







































18








































参数化类:类似于C++中的模板







































例子1:








































?








































1







































2







































3







































4







































5







































6







































7







































8








































<code>


class


vector #(


int


size =


1


);











































bit [size-


1


:


0


] a;









































endclass
















































































vector #(


10


) vten;


// object with vector of size 10









































vector #(.size(


2


)) vtwo;


// object with vector of size 2









































typedef vector#(


4


) Vfour;


// Class with vector of size 4









































</code>









































例子2:










































?










































1









































2









































3









































4









































5









































6









































7









































8









































9









































10










































<code>


class


stack #(type T =


int


);













































local T items[];













































task push( T a ); ... endtask













































task pop( ref T a ); ... endtask











































endclass




















































































stack is;


// default: a stack of int’s











































stack#(bit[


1


:


10


]) bs;


// a stack of 10-bit vector











































stack#(real) rs;


// a stack of real numbers











































</code>











































例子3












































?












































1











































2











































3











































4











































5











































6












































<code>


class


C #(type T = bit); ... endclass


// base class













































class


D1 #(type P = real)


extends


C;


// T is bit (the default)













































class


D2 #(type P = real)


extends


C #(integer);


// T is integer













































class


D3 #(type P = real)


extends


C #(P);


// T is P













































class


D4 #(type P = C#(real))


extends


P;


// for default T is real













































</code>













































18_2














































还是讲参数化的类:

以两个例子说明参数化的类及声明静态变量时的情况:













































eg:














































?














































1













































2













































3













































4













































5













































6













































7













































8













































9













































10













































11













































12













































13













































14













































15













































16













































17













































18













































19













































20













































21













































22













































23













































24













































25













































26













































27













































28













































29













































30













































31













































32













































33













































34













































35













































36













































37














































<code>program param_stack;

















































class


stack #(type T =


int


);

















































int


m_cnt;

















































static


int


counter =


2


;






























































































function


new


;















































m_cnt = counter++;

















































endfunction:


new






























































































endclass: stack






























































































class


stacked


extends


stack #(real);















































...

















































endclass: stacked











































































































































typedef stack #(


byte


) stack_byte;

















































typedef stack #() stact_int;











































































































































stack_byte S1 =


new


();

















































stack_byte S2 =


new


();

















































stack S3 =


new


();

















































stack #(bit) S4 =


new


();

















































stacked S5 =


new


();











































































































































initial begin

















































$display (


"Counter value of S1 instance = %0d"


, stack #(


byte


)::counter);

















































$display (


"Counter value of S2 instance = %0d"


, stack_byte:: counter);

















































$display (


"Counter value of S3 instance = %0d"


, stack #()::counter);

















































$display (


"Counter value of S4 instance = %0d"


, stack#(bit)::counter);

















































$display (


"Counter value of S5 instance = %0d"


, stacked::counter);

















































end




























































































endprogram: param_stack















































</code>















































打印的值依次为:
















































?
















































1















































2















































3















































4















































5















































6
















































<code>


3

















































4

















































3

















































3

















































3

















































</code>

















































解释:虽然静态变量只会存在一个副本。

















































由于S1和S2均由stack_byte创建,所以S1时counter的值为3,S2为4;

S3则是由默认参数类创建,等同于程序中的stack_int,counter值为3;

S4则是type为bit的类创建,counter同样为3;

S5亦然。

















































即当参数类的参数不同时,他们是不同的类。