2016-09-16 90 views
1

我正在创建一个需要对测试台的配置对象进行引用的类。由于配置在整个模拟过程中必须保持完整,我将它作为const ref对象传递。这里是我想要运行的sudo代码:Systemverilog构造对象时的const ref arg位置

class tb_config; 
    int unsigned rate; 
    int unsigned chnls[]; 
    const int unsigned nb_chnls; 

    function new (int unsigned rate, int unsigned nb_chnls); 
    this.rate  = rate; 
    this.nb_chnls = nb_chnls; 
    chnls   = new[nb_chnls]; 
    endfunction 
endclass 

class tx_phy; 
    static int phy_id; 
    tb_config cfg; 

    function new (int unsigned phy_id, const ref tb_config cfg); 
     this.phy_id = phy_id; 
     this.cfg = cfg; 
    endfunction 

endclass 


module test; 
    tb_config cfg = new(100, 4); 
    tx_phy phy = new(1234, cfg); 

endmodule 

上面的代码工作得很好,符合我的期望。但是,如果我将tx_phy :: new中的参数更改为函数new(const ref tb_config cfg,int unsigned phy_id);并将值传递给构造相应我得到Cadence公司的Incisive以下错误:

invalid ref argument usage because actual argument is not a variable. 

而且当我在edaplayground与Aldec公司的测试同样的事情发生:https://www.edaplayground.com/x/5PWV

我认为这是一个语言的限制,但是有没有其他原因?

回答

2

原因是因为如果未指定参数种类是隐含的。您为第一个参数指定了const ref,但第二个参数没有指定,因此它也隐含地为const ref。在第二个参数声明中添加input可修复此问题。

function new (const ref tb_config cfg, input int unsigned phy_id); 

我也想补充const ref tb_config cfg相当于写

function new (tb_config cfg, int unsigned phy_id); 

这些论点都隐含input参数,这意味着它们在进入复制。

一个类变量已经是一个引用。通过ref传递类变量意味着您可以更新函数内类变量所具有的句柄。使参数const ref意味着您将无法更新类变量,但仍可以更新该类的成员变量引用。没有机制来阻止更新类对象的成员,除非声明它们为protectedlocal

在SystemVerilog中通过ref传递函数参数唯一有意义的地方就是当参数是像数组那样的大数据结构时的优化,而且您只需访问数组的一些元素。当参数需要在任务生命周期内更新时(即将时钟作为参数传递)时,您可以使用任务ref参数。

+0

非常感谢!现在它是有道理的。我只添加了ref,因为编译器在我没有指定它的时候给了我错误:期望的记号:'ref'。“”testbench.sv“ – maskarih