在systemverilog中通过ref传递和通过val传递有什么区别?

What is difference between pass by ref and pass by val in systemverilog?

在systemverilog中通过ref传递和通过val传递有什么区别?

我只想知道在systemverilog中pass by refpass by val有什么区别?

我找不到任何 example.also 特别是,这是什么?有谁知道这是什么并解释一下吗?

 interface xxx
  ...
 event yyy;
 event ggg;

 modport io_bus ( ref yyy,
                  ref ggg,
                  ....
                 );
 endinterface

modport 的目的是什么 "ref yyy"?

下面的两个代码块总结了不同之处。

value = 1;
IncreaseByOne(ref value); //pass by reference
//value will be set to 2

value = 1;
IncreaseByOne(value); //pass by value
//value will still be 1

引用传递是指获取参数的方法可以更改变量,从而使原始变量也发生更改。按值传递意味着传递值的副本,对该副本的任何更改都不会反映到原始变量上。

按值传递

在 SystemVerilog 中,按值传递是将参数传递给子例程的默认机制。此参数传递机制通过将每个参数复制到子例程区域来工作。如果子例程是自动的,则子例程在其堆栈中保留参数的本地副本。

按引用传递

通过引用传递的参数不会复制到子例程区域,而是将对原始参数的引用传递给子例程。

子例程然后可以通过引用访问参数数据。不允许铸造。

另请注意,对于具有静态生命周期的子例程,使用引用传递参数是非法的。

只有以下通过引用传递才合法:

— A variable,
— A class property,
— A member of an unpacked structure, or
— An element of an unpacked array.

Nets 和 select into nets 不得通过引用传递

针对您的问题

What is the purpose "ref yyy" in the modport ?

当多次触发不同的事件时使用对事件的引用会提高一些性能,但最好只在性能优化相当大的情况下使用 required/necessary。可以在 link

中找到一个使用引用传递的推荐示例

这里我展示了一种使用带有 ref 事件的 modport 的方法。

interface intf(input clk);
event out_event;
  logic clk;
  modport dut(input clk,ref out_event);  
  always @(out_event)
    $display ($time,"ns"," out_event triggered");
endinterface

module dut( intf.dut d);
  reg [2:0] count;
  initial
    count = 0;
  always @ (posedge d.clk)begin
    count = count + 1'b1;
    if ( count == 'd2)
      -> d.out_event;
      end
endmodule

module top (input clk);
  intf int_f(.clk(clk));
  dut u0(.d(int_f.dut));
endmodule

上面的工作示例可以在 link EDA-Playground

有关按值传递的更多详细信息,请参阅 SystemVerilog LRM IEEE 1800-2012 的第 13.5.1 节和按引用传递参考第 13.5.2 节