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())
构造只有在 在 触发器之前执行时才有用,或者在同一时间步内执行并且在触发器点和之间存在潜在的竞争条件等待触发。
我不建议大多数用户使用原始事件。通常会有更多类似机制的软件来实现同样的事情。
我正在从这个 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())
构造只有在 在 触发器之前执行时才有用,或者在同一时间步内执行并且在触发器点和之间存在潜在的竞争条件等待触发。
我不建议大多数用户使用原始事件。通常会有更多类似机制的软件来实现同样的事情。