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


	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

Example


module tb;
  
  // Create 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] Thread3: received event_a trigger", $time);
  end
endmodule	
 Simulation Log
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 ?

An event's triggered state persists throughout the time step, 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.


module tb;
  
  // Create 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] Thread3: received event_a trigger", $time);
  end
endmodule

Note that Thread2 never received a trigger, because of the race condition between @ and -> operations.

 Simulation Log
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

Waits for events to be triggered in the given order, and issues an error if any event executes out of order.


module tb;
  // Declare three events that can be triggered separately
  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
 Simulation Log
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 

Merging Events

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.


module tb;
  
  // Create event variables
  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 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
ncsim> run
[20] Thread1: Wait for event_a is over
[20] Thread2: Wait for event_b is over
ncsim: *W,RNQUIE: Simulation is complete.