SystemVerilog 合并事件

SystemVerilog Merging Events

我正在从这个 website 中阅读有关 SV 合并事件的信息。代码如下:

module events_ex;

  event ev_1; //declaring event ev_1
 
  initial begin
    fork
      //process-1, triggers the event
      begin
        #40;
        $display($time,"\tTriggering The Event");
        ->ev_1;
      end
     
      //process-2, wait for the event to trigger
      begin
        $display($time,"\tWaiting for the Event to trigger");
        #60;
        @(ev_1.triggered);
        $display($time,"\tEvent triggered");
      end
    join
  end
  initial begin
    #100;
    $display($time,"\tEnding the Simulation");
    $finish;
  end
endmodule

相同的结果是:

0  Waiting for the Event to trigger
40  Triggering The Event
100 Ending the Simulation

在此特定代码中,触发器首先在 40 time units 执行,然后在 60 time units 应用等待。众所周知,如果触发器先执行,则等待进程保持阻塞状态。如果我在 line 17 中使用 #60 wait(ev_1.triggered); 这可以解决。但是,它仍然显示相同的结果?我想知道这背后的概念。

机制非常简单:event.triggered 的值仅在与触发时相同的模拟刻度中设置。它不粘,在下一个 tick 时变为 0。

It is known that, if the trigger executes first, then the waiting process remains blocked.

是的,因为解封事件已经过去了,#60来不及检测到。因此,@wait.

都无法再检测到它

现在,您可以做的是在事件中设置一个粘性变量,例如下面的triggered

module events_ex;

  event ev_1; //declaring event ev_1
  logic triggered = 1'b0;
  
  initial begin
    fork
      //process-1, triggers the event
      begin
        #40;
        $display($time,"\tTriggering The Event");
        ->ev_1;
      end
     
      begin 
        @(ev_1)
        triggered = 1'b1; // << set the sticky var
      end
      
      //process-2, wait for the event to trigger
      begin
        $display($time,"\tWaiting for the Event to trigger");
        #60;
        wait(triggered); // << wait for sticky var value of 1
        $display($time, "\tEvent triggered");
      end
    join
  end
  

  initial begin
    #100;
    $display($time,"\tEnding the Simulation");
    $finish;
  end
endmodule

然而,您可以看到 @wait 运算符之间的语义差异。 @ 等待值的更改,发生在#40 并且它也无法在#60 捕获它。另一方面,wait等待级别触发成为1'b1。因此,它将在这里工作,因为已经设置了粘性变量。

那个网站上的例子不是很好。您永远不会想将 @triggered 方法一起使用。

当您触发一个带有-> ev_1->> ev_1的事件时,该事件的triggered方法仅在触发器(或 ->> 的 NBA 触发器区域)直到时间步结束。

@ev_1必须在触发时刻之前执行。否则必须等待下一次触发。

wait(ev_1.triggered()) 构造只有在 触发器之前执行时才有用,或者在同一时间步内执行并且在触发器点和之间存在潜在的竞争条件等待触发。

我不建议大多数用户使用原始事件。通常会有更多类似机制的软件来实现同样的事情。