天天看点

SV——override

0. 介绍

SV中引入OOP,也会有类似于C++里的override和overload考虑。

1. override 重写

重写有数据成员重写和方法重写,看下面例子

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// 来源 IEEE1800 8.14节

class

Packet;

integer i = 1;

function integer get();

get = i;

endfunction

endclass

class

LinkedPacket extends Packet;

integer i = 2;

function integer get();

get = -i;

endfunction

endclass

LinkedPacket lp = 

new

;

Packet p = lp;

j = p.i; 

// j = 1, not 2 // 父类成员

j = p.get(); 

// j = 1, not -1 or –2

  

从上面看出,父类句柄指向的数据成员是父类的成员。

如果想通过父类句柄调用子类中重写的成员函数,那么需要将父类中的函数定义成virtual类型。

2. 重载 overload

在SV中好像不支持重载(overload),就是不直接支持方法类型相同,参数不同。

在下面例子中,SV检查到B中的dis函数与A中的dis函数返回类型不同,会报错。

  

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

class

A;

  

virtual

function 

int

dis(string str=

"A"

);

    $display(

"this is %s"

,str);

    dis=1;

  endfunction

endclass

class

B extends A;

  function 

void

dis(); 

// 只有函数名相同

    $display(

"this is B"

);

  endfunction

endclass

A a;

B b;

initial begin

  b=

new

;

  b.dis();

  b.dis(

"B"

); 

//在调用的时候,SV会把B的dis当作A中dis的override来处理,句柄b调用的是B中的dis。

end

// 报错:

Error-[SV-IRT] Incompatible 

return

types

./svt.sv, 108

svt, 

"dis"

Definition of 

class

function 

'A::dis'

does not have the same 

return

type as

mentioned in the declaration at: 

"./svt.sv"

, 97.

Error-[TMAFTC] Too many arguments to function/task call

./svt.sv, 116

"b.dis("

B

")"

The above function/task call is done with more arguments than needed.

  

3. override的条件

子类想要正确地override父类中的虚函数,需要保证以下四点:

  1. 函数才能重载函数。
  2. 函数名相同
  3. 返回类型相同
  4. 参数列表相同

子类中要正确重载父类中的虚任务,需要保证以下三点:

  1. 任务才能重载任务。
  2. 任务名相同。
  3. 参数列表相同。

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

// 任务被函数重载了,会出错

program automatic test;

class

A;

virtual

task dis(string str=

""

);

$display(

"this is A"

);

endtask

endclass

class

B extends A;

function 

void

dis(string str=

""

);

$display(

"this is B"

);

endfunction

endclass

A a;

B b;

initial begin

b=

new

;

b.dis();

a=b;

a.dis();

a.dis(

"A"

);

end

endprogram

// 报错:

Error-[SV-ICMO] Illegal 

class

method override

./svt.sv, 100

Virtual task 

'dis'

cannot be overridden with a function.

Virtual method declared at 

"./svt.sv"

, 100

Overriden at 

"./svt.sv"

, 111

  

4. new可以被override吗

之前面试被问到new函数可以重载吗?

在UVM UG1.1 P62页顶部提到”there are limitations on overriding new() in object-oriented language such as System Verilog."这好像说明了new是可以重载的,但是有一些限制。

   在《UVMPrimer》第五章中讲到,new()函数是可以被重载的。比如:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/// 长方形父类

class

rectangle ;

int

width;

int

height;

function 

new

(

int

width,

int

height);

this

.width=width;

this

.height=height;

endfunction

endclass

/// 正方形

class

square extends rectangle;

int

side;

function 

new

(

int

side); 

// 重载了new函数,只有一个参数

super.

new

(side,side);

endfunction

endclass

继续阅读