Welcome ! This website will help YOU (recent graduates/professionals) learn verification languages like SystemVerilog and UVM. Register for free and access more content !

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.

Click to try this example in a simulator!   

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.

Click to try this example in a simulator!   

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 

Click to try this example in a simulator!   

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.

Click to try this example in a simulator!   

Was this article helpful ?

We use cookies to personalize content and ads, to provide social media features and to analyze our traffic. You consent to our cookies if you continue to use our website. To find out more about the cookies we use and how to delete them, see our privacy policy.

  I accept cookies from this site.
Agree
EU Cookie Directive plugin by www.channeldigital.co.uk