如何克服 System Verilog 中的函数重载
How to overcome function overloading in System Verilog
program automatic test;
class A;
task get();
$display("A");
endtask
endclass
class B extends A;
task get(int a,int b);
$display("%d %d",a,b);
endtask
endclass
initial
begin
B b = new();
b.get(); // Throws Error Because of Hiding
end
endprogram: test
在 C++ 中,我们可以通过使用 using A::get
来克服这个问题,但在 SV 中如何避免函数隐藏并访问父 class 函数 get()?
由于 Verilog 中的弱类型系统,函数重载很难在 SystemVerilog 中实现。如果您有一个具有 32 位输入的函数并用一个具有 16 位输入的函数重载它,但调用该函数时具有 8 位值,会发生什么情况。你选了哪一个?
但这里确实存在两个截然不同的问题。 C++ 中的函数重载不一定涉及继承——您可以在同一个 class 中声明两个 get
函数。如果您的函数具有不同的原型并且调用者需要知道哪些是可用的,您不妨为它们指定唯一的名称。
module automatic test;
class A;
task get();
$display("A");
endtask
endclass
class B extends A;
task get2(int a,int b);
$display("%d %d",a,b);
endtask
endclass
initial
begin
B b=new();
b.get();
b.get2(1,2);
end
endmodule: test
您还可以利用 SystemVerilog 的默认参数功能为您的参数分配 不可用 值
module automatic test;
class A;
task get();
$display("A");
endtask
endclass
class B extends A;
task get(int a=-1,int b=-1);
if (a<0) super.get();
else $display("%d %d",a,b);
endtask
endclass
initial
begin
B b=new();
b.get(); // indirectly calls A::get()
end
endmodule: test
解决有关访问基 class 的非虚拟成员的其他问题,您需要将句柄向上转换为 A
class 变量。
initial
begin
B b=new();
A a;
a = b;
a.get();
end
您不能使用扩展的 class 对象直接访问基础 class get 方法。但是您可以在扩展 class get 方法中访问它,如下所示。还解决了几个问题。
program automatic test;
class A;
virtual task get();
$display("A");
endtask
endclass
class B extends A;
task get(); // Removed the arguments as during this method call in initial block, you were not passing anything. If you need arguments then pass some value during task call
super.get(); // Using super you can access the base class get method
A::get(); // Or you can also access it using class name and scope operator. This way is helpful when there is a deep down hierarchy
$display("B");
endtask
endclass
initial
begin
B b=new(); // You didn't create the object
b.get();
end
endprogram: test
program automatic test;
class A;
task get();
$display("A");
endtask
endclass
class B extends A;
task get(int a,int b);
$display("%d %d",a,b);
endtask
endclass
initial
begin
B b = new();
b.get(); // Throws Error Because of Hiding
end
endprogram: test
在 C++ 中,我们可以通过使用 using A::get
来克服这个问题,但在 SV 中如何避免函数隐藏并访问父 class 函数 get()?
由于 Verilog 中的弱类型系统,函数重载很难在 SystemVerilog 中实现。如果您有一个具有 32 位输入的函数并用一个具有 16 位输入的函数重载它,但调用该函数时具有 8 位值,会发生什么情况。你选了哪一个?
但这里确实存在两个截然不同的问题。 C++ 中的函数重载不一定涉及继承——您可以在同一个 class 中声明两个 get
函数。如果您的函数具有不同的原型并且调用者需要知道哪些是可用的,您不妨为它们指定唯一的名称。
module automatic test;
class A;
task get();
$display("A");
endtask
endclass
class B extends A;
task get2(int a,int b);
$display("%d %d",a,b);
endtask
endclass
initial
begin
B b=new();
b.get();
b.get2(1,2);
end
endmodule: test
您还可以利用 SystemVerilog 的默认参数功能为您的参数分配 不可用 值
module automatic test;
class A;
task get();
$display("A");
endtask
endclass
class B extends A;
task get(int a=-1,int b=-1);
if (a<0) super.get();
else $display("%d %d",a,b);
endtask
endclass
initial
begin
B b=new();
b.get(); // indirectly calls A::get()
end
endmodule: test
解决有关访问基 class 的非虚拟成员的其他问题,您需要将句柄向上转换为 A
class 变量。
initial
begin
B b=new();
A a;
a = b;
a.get();
end
您不能使用扩展的 class 对象直接访问基础 class get 方法。但是您可以在扩展 class get 方法中访问它,如下所示。还解决了几个问题。
program automatic test;
class A;
virtual task get();
$display("A");
endtask
endclass
class B extends A;
task get(); // Removed the arguments as during this method call in initial block, you were not passing anything. If you need arguments then pass some value during task call
super.get(); // Using super you can access the base class get method
A::get(); // Or you can also access it using class name and scope operator. This way is helpful when there is a deep down hierarchy
$display("B");
endtask
endclass
initial
begin
B b=new(); // You didn't create the object
b.get();
end
endprogram: test