【问题标题】:What does " ref " mean in systemverilog?systemverilog 中的“ref”是什么意思?
【发布时间】:2015-06-24 04:28:57
【问题描述】:

我在systemverilog找到这个:

task automatic xxx(ref xxxpackage bus,input interface ift);

我想知道ref的用法。有什么优势?

【问题讨论】:

    标签: system-verilog


    【解决方案1】:

    通常,声明为input 的任务和函数参数在进入例程时按值复制,而声明为output 的参数在从例程返回时按值复制。 inout 参数在进入和从例程返回时都被复制。使用ref 声明的参数不会被复制,而是对调用例程时使用的实际参数的引用。使用 ref 参数时有更严格的数据类型兼容性规则。

    在消耗时间的任务中,可以使用 ref 代替 inout 来捕获任务处于活动状态时发生的值变化。请记住,inout 参数在调用时复制到任务中,并在任务返回时复制出来。这是您应该尝试的示例。

    module top;
    logic A,B;
    task automatic mytask(inout logic arg1, ref logic arg2);
      #0 $display("%m %t arg1 %b arg2 %b",$time,arg1,arg2);
      // actual arguments have been set to 0
      #5 $display("%m %t arg1 %b arg2 %b",$time,arg1,arg2);
      #0 arg1 = 1; arg2 = 1;
      #5 $display("%m %t arg1 %b arg2 %b",$time,arg1,arg2);
    endtask
    initial #1 mytask(A,B);
    initial begin
           A = 'z; B ='z;
           #2 A = 0; B = 0; // after call 
           // arguments have been set to 1
           #5 $display("%m %t A %b B %b",$time,A ,B);
           #5 $display("%m %t A %b B %b",$time,A ,B);
    end
    endmodule
    

    查看inout 和传递ref 参数之间的区别。

    请注意,类变量已经是对类句柄的引用,因此通过引用传递类变量很少有任何好处。此外,在函数中,ref 参数的唯一好处可能是传递大型数据结构(如数组)而不是使用 input、output 或 inout。

    【讨论】:

    • 谢谢,请告诉我何时应该使用引用传递和验证?
    • 保持价值传递。你最终会明白哪里需要通过引用。
    • 你能告诉我为什么 z 0 变成 0 1。
    • 如果可以的话,你会一步一步告诉我吗?我有点不明白这个例子的意义。
    【解决方案2】:

    ref 参数是通过引用传递的变量。这种类型的参数不是副本,而是对原始变量的引用。

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

    来自IEEE Std 1800-2012 中的第 13.5.2 节。

    【讨论】:

    • 我无法通过他们了解您的解释。那么有什么特殊情况吗?
    • 您可以在我上面写的标准部分获得更多信息。有一些有用的例子可以帮助你理解这个概念。
    【解决方案3】:

    大家好,这里是 DAVE 给出的示例的解释。非常感谢 Dave 的示例。

    module top;
    logic A,B;
    task automatic mytask(inout logic arg1, ref logic arg2);
      #0 $display("%m %t arg1 %b arg2 %b",$time,arg1,arg2);
      // actual arguments have been set to 0
      #5 $display("%m %t arg1 %b arg2 %b",$time,arg1,arg2);
      #0 arg1 = 1; arg2 = 1;
      #5 $display("%m %t arg1 %b arg2 %b",$time,arg1,arg2);
    endtask
    initial #1 mytask(A,B);
    initial begin
           A = 'z; B ='z;
           #2 A = 0; B = 0; // after call 
           // arguments have been set to 1
           #5 $display("%m %t A %b B %b",$time,A ,B);
           #5 $display("%m %t A %b B %b",$time,A ,B);
    end
    endmodule
    
    /*Both the two 'initial' statements are running simultaneously*/
    /* 1) At time t=0 A and B are set to z by second initial statement
       2) At time t=1 mytask(A,B) is called by first initial 
          statement, 
          the first display statements displays arg1 and arg2 =z as 
          set by A and B.
       3) t=3 the second initial statement sets A=0 and B=0, but only  
          A=0 is passed to arg 1 in the ongoing task since it is
          passed by reference, whereas B=0 can only be passed at the
          starting or the end of the task since it is passed by value 
          hence arg2 remains z.
       4) inside the task--At t=6 values of arg1 and arg2 are 
          displayed
       5) at t=6 the values of arg1 and arg2 are made 1.
       6) in the second initial statement at t=7 values of A and B
          is displayed, since arg2 is passed through reference
          therefore it becomes 1, whereas A remains zero until the end of
       the task.
       7) at t=11 the values of arg1 and arg2 are displayed. -- task 
          ends.
       8) Since the task is ended arg2 value is passed to B and is 
          displayed by the second initial statement at t=12. 
       */
    

    我已经根据内核中显示的输出和时间进行了解释,希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2020-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多