An event is a static object handle to synchronize between two or more concurrently active processes. One process will trigger the event, and another process waits for the event.
Can be assigned or compared to other event variables
Can be assigned to null
When assigned to another event, both variables point to same synchronization object
Can be passed to queues, functions and tasks
1 2 3 4
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?
Named events can be triggered using -> or ->> operator
Processes can wait for an event using @ operator or .triggered
// Create an event variable that processes can use to trigger and wait event event_a;
// Thread1: Triggers the event using "->" operator initialbegin #20 ->event_a; $display ("[%0t] Thread1: triggered event_a", $time); end
// Thread2: Waits for the event using "@" operator initialbegin $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" initialbegin $display ("[%0t] Thread3: waiting for trigger ", $time); wait(event_a.triggered); $display ("[%0t] Thread3: received event_a trigger", $time); end endmodule
Simulation Log
1 2 3 4 5 6 7
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.
An event’s triggered state persists throughout the time step(triggered状态在时间片内都敏感), until simulation advances. Hence if both wait for the event and trigger of the event happens at the same time there will be a race condition and the triggered property helps to avoid that.
A process that waits on the triggered state always unblocks, regardless of the order of wait and trigger.
// Create an event variable that processes can use to trigger and wait event event_a;
// Thread1: Triggers the event using "->" operator at 20ns initialbegin #20 ->event_a; $display ("[%0t] Thread1: triggered event_a", $time); end
// Thread2: Starts waiting for the event using "@" operator at 20ns initialbegin $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 initialbegin $display ("[%0t] Thread3: waiting for trigger ", $time); #20wait(event_a.triggered); $display ("[%0t] Thread3: received event_a trigger", $time); end endmodule
Note that Thread2 never received a trigger, because of the race condition between @ and -> operations.(但是triggered状态能够采样到->操作)
Simulation Log
1 2 3 4 5 6
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.
module tb; // Declare three events that can be triggered separately event a, b, c;
// This block triggers each event one by one initialbegin #10 -> a; #10 -> b; #10 -> c; end
// This block waits until each event is triggered in the given order initialbegin
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
Simulation Log
1 2 3
Compiler version J-2014.12-SP1-1; Runtime version J-2014.12-SP1-1; Events were executed in the correct order V C S S i m u l a t i o n R e p o r t
When one event variable is assigned to another, all processes waiting for the first event to trigger will wait until the second variable is triggered.(这句话不知道是什么鸟语,看下面程序的执行结果和自己的理解,就是事件赋值而已)。
initialbegin 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 30ns #30 ->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
Simulation Log
1 2 3 4
ncsim> run [20] Thread1: Wait for event_a is over [20] Thread2: Wait for event_b is over ncsim: *W,RNQUIE: Simulation is complete.