0. 介绍
SV中引入OPP,也会有类似于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 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 |