##N 类内延迟循环

时间:2021-05-02 16:00:54

标签: system-verilog

带有默认时钟块的接口内的##N 应该延迟 N 个周期

如果我在接口中有一个类,这似乎不起作用。 LRM 似乎没有指定任何错误,我也没有收到任何编译错误

请参阅以下代码段,其中接口内有一个访问器类,并且该类有一个用于等待周期的成员。调用这个任务似乎没有引入任何延迟

interface my_if (
  input logic clk,
  inout logic valid,
  inout logic[1:0] req );
  
  default clocking cb @(posedge clk);
    inout valid;
    inout req;
  endclocking

  class accessor_c;
    function new();
    endfunction
    
    task wait_cycles(int value);
      ##value;
    endtask
      
  endclass
  
  initial begin
    accessor_c acc;
    acc = new();
    #100;
    $display("%t: call wait", $time);
    acc.wait_cycles(1);
    $display("%t: after wait", $time);
  end
  
endinterface

以上两个显示同时打印。

edaplayground 上的代码,其中直接在接口中等待而在类内部不起作用时 https://www.edaplayground.com/x/9_u_

1 个答案:

答案 0 :(得分:2)

你有一个竞争条件——它与 ##value 在一个类中无关。

竞争是因为您在 #100 块中有 initial 延迟,并且与测试台中的 always 块竞争,产生 posedge clk 在时间 100。所以对 wait_cycles 的调用是在竞争,无论它是在时钟边缘之前还是之后调用。

要解决此问题,请将 #100 更改为与posedge 时钟不一致的值,或者最好使用像 repeat (5) @cb 这样的延迟。

一般来说,使用 repeat(N) @cb 语法比使用 ##N 语法更好,因为您可以在不允许默认时钟块的情况下使用它(例如在包中),并且您可以分层访问不同的时钟块通过虚拟接口。