SystemVerilog -- 3.9 SystemVerilog Events
SystemVerilog Event
An
是一个静态对象句柄,用于在两个或多个并发活动进程之间进行同步。一个进程将触发event,另一个thread的等待event。event
- 可以分配或其它event变量进行比较
- 可以分配给
null
- 当分配给另一个event时,两个变量都指向同一个同步对象
- 可以分配给
- 可以传递给队列、函数、任务
event over; // a new event is created called over
event over_again = over; // over_again becomes an alias to over
event empty = null; // event variable with no synchronization object
How to trigger and wait for an event ?
- 可以使用
->
或->>
运算符触发命名event。 - thread可以使用
@
运算符或。triggered
Example
module tb;
// Created an event variable that processes can use to trigger and wait
event event_a;
// Thread1: Triggers the event using "->" operator
initial begin
#20 -> event_a;
$display ("[%0t] Thread1:triggered event_a", $time);
end
// Thread2: Waits for the event using "@" operator
initial begin
$display ("[%0t] Thread2:waiting for trigger", $time);
@(event_a);
$display ("[%0t] Thread2:received event_a trigger", $time);
end
// Thread3: Waits for the event using ".triggered"
initial begin
$display ("[%0t] Thread3:waiting for trigger", $time);
wait(event_a.triggered);
$display ("[%0t] Thread2:received event_a trigger", $time);
end
endmodule
模拟日志
ncsim> run
[0] Thread2: Waiting for trigger
[0] Thread3: Waiting for trigger
[20] Thread1: triggered event_a
[20] Thread2: received event_a trigger
[20] Thread3: received event_a trigger
ncsim: *W,RNQUIE: Simulation is complete.
What is the difference between @ and .triggered ?
event的状态在整个事件步长中持续存在,直到模拟进行。因此,如果event和event的触发器同时发生,则将存在竞争条件,该属性有助于避免这种情况。triggered
wait triggered
A process that waits on the `triggered` state always unblocks, regardless of the order of wait and trigger. |
module tb;
// Created an event variable that processes can use to trigger and wait
event event_a;
// Thread1: Triggers the event using "->" operator at 20ns
initial begin
#20 -> event_a;
$display ("[%0t] Thread1:triggered event_a", $time);
end
// Thread2: Starts waiting for the event using "@" operator at 20ns
initial begin
$display ("[%0t] Thread2:waiting for trigger", $time);
#20 @(event_a);
$display ("[%0t] Thread2:received event_a trigger", $time);
end
// Thread3: Starts waiting for the event using ".triggered" at 20ns
initial begin
$display ("[%0t] Thread3:waiting for trigger", $time);
#20 wait(event_a.triggered);
$display ("[%0t] Thread2:received event_a trigger", $time);
end
endmodule
请注意,由于@
和->
操作之间的争用条件,Thread2从未收到触发器。
模拟日志
ncsim> run
[0] Thread2: Waiting for trigger
[0] Thread3: Waiting for trigger
[20] Thread1: triggered event_a
[20] Thread3: received event_a trigger
ncsim: *W,RNQUIE: Simulation is complete.
wait_order
等待按给定顺序触发事件,如果任何事件无序执行,则发出错误。
module tb;
// Declare three events that can be triggered aeparately
event a, b, c;
// This block triggers each event one by one
initial begin
#10 -> a;
#10 -> b;
#10 -> c;
end
// This block waits until each event is triggered in the given order
initial begin
wait_order (a,b,c)
$display ("Events were executed in the correct order");
else
$display ("Events were NOT executed in the correct order !");
end
endmodule
模拟日志
Compiler version J-2014.12-SP1-1: Runtime version J-2014.12-SP1-1
Events were executed in the correct order
Merging Events
当一个event变量分配给另一个event变量时,等待第一个event触发的所有threads都将等待第二个变量触发。
module tb;
// Create event variablles
event event_a, event_b;
initial begin
fork
// Thread1: waits for event_a to be triggered
begin
wait(event_a.triggered);
$display ("[%0t] Thread1: Wait for event_a is over", $time);
end
// Thread2: waits for event_b to be triggered
begin
wait(event_b.triggered);
$display ("[%0t] Thread2: Wait for event_b is over", $time);
end
// Thread3: triggers event_a at 20ns
#20 ->event_a;
// Thread4: triggers event_b at 20ns
#20 ->event_b;
// Thread5: Assigns event_b to event_a at 10ns
begin
// Comment code below and try again to see Thread2 finish later
#10 event_b = event_a;
end
join
end
endmodule
模拟日志
ncsim> run
[20] Thread1: Wait for event_a is over
[20] Thread2: Wait for event_b is over
ncsim: *W,RNQUIE: Simulation is complete.