SystemVerilog正在合并事件



我正在这个网站上阅读关于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。

已知,如果触发器先执行,则等待进程保持阻塞状态。

是的,因为解除阻塞事件已经过去,#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。因此,它将在这里工作,因为已经设置了sticky变量。

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

当您触发具有-> ev_1->> ev_1的事件时,该事件的triggered方法仅从触发时刻(或->>触发器的NBA区域)到时间步长结束时有效。

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

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

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

最新更新