【问题标题】:How to overcome function overloading in System Verilog如何克服 System Verilog 中的函数重载
【发布时间】:2021-06-30 14:24:15
【问题描述】:
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 中如何避免函数隐藏和访问父类函数 get()?

【问题讨论】:

  • 系统verilog中没有重载。因此,只需为函数使用不同的名称即可。

标签: oop verilog system-verilog


【解决方案1】:

由于 Verilog 中的弱类型系统,函数重载在 SystemVerilog 中难以实现。如果你有一个带有 32 位输入的函数并用一个带有 16 位输入的函数重载了它,但是用一个 8 位的值调用了这个函数,会发生什么情况。你选了哪一个?

但这里确实有两个不同的问题。 C++ 中的函数重载不一定必须涉及继承——您可以在同一个类中声明两个 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

解决访问基类的非虚拟成员的另一个问题,您需要将句柄向上转换为A 类变量。

initial  
begin  
    B b=new();
    A a;
    a = b; 
    a.get();
end  

【讨论】:

    【解决方案2】:

    您不能使用扩展类对象直接访问基类 get 方法。但是您可以在扩展类 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 
    

    【讨论】:

    • 你建议如何在 B 中用 2 个 args 实现“get”?
    • 2 种方式:1) 具有默认值的参数 2) 如果参数没有默认值,则在 API 调用期间传递该值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    相关资源
    最近更新 更多