Systemverilog const ref arg构造对象时的位置

时间:2016-09-16 15:33:42

标签: system-verilog

我正在创建一个需要引用测试平台配置对象的类。由于配置必须在整个模拟过程中保持完整,因此我将其作为const ref对象传递。这是我想要运行的sudo代码:

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中收到以下错误:< / p>

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

当我在edaplayground中使用Aldec进行测试时,同样的事情发生了:https://www.edaplayground.com/x/5PWV

我认为这是一种语言限制,但还有其他原因吗?

1 个答案:

答案 0 :(得分:2)

原因是因为如果没有指定,参数类是隐式的。您为第一个参数指定了let storyboard = UIStoryboard(name: "Main", bundle: nil) let vc = storyboard.instantiateViewControllerWithIdentifier("VC") vc.modalInPopover = true vc.modalPresentationStyle = .Popover vc.popoverPresentationController!.sourceRect = CGRectMake(100, 100, 0, 0) vc.popoverPresentationController?.sourceView = self.view self.presentVC(vc) ,但是第二个参数没有指定任何内容,因此它也隐含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 refprotected之外,没有任何机制可以阻止更新类对象的成员。

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