SV Verification Directory

Interprocess communication is a way to communicate between different processes and testbench components. There are three mechanisms:

  1. Events
  2. Mailbox
  3. Semaphore

Events

Events are static objects in SystemVerilog, used to synchronize different testbench components. The events are triggered using -> or ->> and the process can wait for the event to be triggered using @ operator or wait() construct.

EventDescription
- >Blocking events, also know as instanteous event, block the process untill the event is triggered.
- >>Non-blocking events, using this operator does not block the process. Can be used when two events are triggere at the same time.
@Blocks the calling process untill the given event is triggered. This is an edge-sensitive operator, hence, waiting event should be triggered before triggering an event to aviod blocking the waiting process.
wait()Unlike @ operator, the wait() construct does not block the process. Triggering an event and waiting for an event can occur at the same time.

This is a two stage mechanism where:

  1. First Stage: trigger an event.
  2. Second Stage: wait for an event to be triggered.

Three Types of Event Trigger

Events are distinguished based on which stage occurs first.

  1. Type A: Second stage and then first stage.
  2. Type B: First stage followed by second stage.
  3. Type C: First and second stage occurs at the same time.

Combination of event triggers(-> and ->>) and wait responses(@ and wait()) can be used to synchronize processes based on the requirement.

Type A

The wait event is triggered first followed by the event.

// class
class event_typeA;

  event ev;

  task ev_trg();
     #10;
     $display("t= %0t => Trigger event", $time);
     ->ev;
     $display("t= %0t => Event is triggered", $time);
  endtask

  task wait_trg();
     #5;
     $display("t= %0t => Wait for the event", $time);
     @ev;
     //wait(ev.triggered);    // uncomment to comment @ev to see the difference
     $display("t= %0t => Wait event is triggered", $time);
   endtask

endclass


module test;

   event_typeA ev_a;          // class handle

  task run(event_typeA arg);
    arg.ev_trg();
    arg.wait_trg();
  endtask

   initial begin
     ev_a = new( );           // construct the class object

     $display("---------------------- Event: Type A ----------------------");
     run(ev_a);

   end

endmodule

Execute the code in EDA Playground

Type B

The event is triggered first followed by the wait event.

// class
class event_typeB;

  event ev;

  task ev_trg();
    #10;
    $display("t = %0t => Trigger event", $time);
    ->ev;
    $display("t = %0t => Event is triggered", $time);
  endtask

  task wait_trg();
    #15;
    $display("t = %0t => Wait for the event", $time);
    @(ev);
    //wait(ev.triggered);
    $display("t= %0t => Wait event is triggered", $time);
   endtask

endclass


module test;

   event_typeB ev_b;          // class handle

  task run(event_typeB arg);
    fork
        arg.ev_trg();
        arg.wait_trg();
    join
  endtask

   initial begin
     ev_b = new( );           // construct the class object

     $display("---------------------- Event: Type B ----------------------");
     run(ev_b);

   end

endmodule

Execute the code in EDA Playground

Type C

Event trigger and wait event both are triggered at the same time.

// class
class event_typeC;

  event ev;

  task ev_trg();
    $display("t = %0t => Trigger event", $time);
    ->ev;
    $display("t = %0t => Event is triggered", $time);
  endtask

  task wait_trg();
    $display("t = %0t => Wait for the event", $time);
    @(ev);
    //wait(ev.triggered);
    $display("t= %0t => Wait event is triggered", $time);
   endtask

endclass


module test;

   event_typeC ev_c;          // class handle

  task run(event_typeC arg);
    fork
        arg.ev_trg();
        arg.wait_trg();
    join
  endtask

   initial begin
     ev_c = new( );           // construct the class object

     $display("---------------------- Event: Type C ----------------------");
     run(ev_c);

   end

endmodule

Execute the code in EDA Playground

Difference between @ Operator and wait() Construct

The wait event does not block the process. When both the event and wait event is triggered at the same it always best to use a wait() construct. If the event triggering and waiting for event trigger with @ operator happens at the same time, @ operator may miss detecting the event trigger.

// class
class event_typeC;

  event ev;

  task ev_trg();
    $display("t = %0t => Trigger event", $time);
    ->ev;
    $display("t = %0t => Event is triggered", $time);
  endtask

  task wait_trg();
    $display("t = %0t => Wait for the event", $time);
    //@(ev);
    wait(ev.triggered);
    $display("t= %0t => Wait event is triggered", $time);
   endtask

endclass


module test;

   event_typeC ev_c;          // class handle

  task run(event_typeC arg);
    fork
        arg.ev_trg();
        arg.wait_trg();
    join
  endtask

   initial begin
     ev_c = new( );           // construct the class object

     $display("---------------------- Event: Type C ----------------------");
     run(ev_c);

   end

endmodule

Execute the code in EDA Playground

Difference between -> and ->> Event Triggers

Similar to the @ operator and the wait() construct, the -> operator blocks the process until it is triggered, while the ->> operator does not block the process. When using the ->> operator, irrespective of the @ operator or the wait() construct, the process continues to execute. The following code illustrates these differences more clearly.

// class
class event_typeC;

  event ev;

  task ev_trg();
    $display("t = %0t => Trigger event", $time);
    ->>ev;
    $display("t = %0t => Event is triggered", $time);
  endtask

  task wait_trg();
    $display("t = %0t => Wait for the event", $time);
    @(ev);                     // comment and uncomment
    //wait(ev.triggered);      // comment and uncomment
    $display("t= %0t => Wait event is triggered", $time);
   endtask

endclass


module test;

   event_typeC ev_c;          // class handle

  task run(event_typeC arg);
    fork
        arg.ev_trg();
        arg.wait_trg();
    join
  endtask

   initial begin
     ev_c = new( );           // construct the class object

     $display("---------------------- Event: Type C ----------------------");
     run(ev_c);

   end

endmodule

Execute the code in EDA Playground