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

A lot of data and transactions flow through different verification components in an environment or in plain terms, components talk with each other. There are basically three ways to do so:

Events Different threads synchronize with each other via events in the testbench
Semaphores Different threads might need to access the same resource; they take turns by using a semaphore
Mailbox Threads/Components need to exchange data with each other; data is put in a mailbox and sent

What are Events ?

An event is a way to synchronize two or more different processes by making them active only when the event has triggered. Some of the key points are

  • Events are created by using event keyword
  • event eventA, eventB; 
    
  • Trigger an event using the -> operator
  • ->eventA;
    
  • To block execution of code until an event has occured, use either one of the following
  • @eventA;
    wait (eventA.triggered);
    
  • Events can be passed as arguments to functions, just like any other datatype
  •  
    module tb_top;
      event eventA;
      bit   resetn;
     
      initial begin
        resetn = 0;
        #20 resetn = 1;
        fork 
          waitForTrigger (eventA);
          #5 ->eventA;
        join_none
        #10 resetn = 0;
      end
     
      task waitForTrigger (event eventA);
        $display ("[%0t] Waiting for EventA to be triggered", $time);
        wait (eventA.triggered);
        $display ("[%0t] EventA has triggered", $time);
      endtask
    endmodule
     
    Output
    [20] Waiting for EventA to be triggered
    [25] EventA has triggered
    ncsim: *W,RNQUIE: Simulation is complete.
    

What's a semaphore ?

Let's say you wanted to rent a room in the library for a few hours. The admin desk will give you a key to use the room for the time you have requested access. After you are done with your work, you will return the key to the admin, which will then be given to someone else who wants to use the same room. This way you don't have to fight with someone else for the room. The key is a semaphore in this context.

A semaphore is used to control access to a resource and is known as a mutex (mutually exclusive) because only one entity can have the semaphore at a time.

 
module tb_top;
   semaphore key;
 
   initial begin 
      key = new (1);
      fork
         personA ();
         personB ();
         #25 personA ();
      join_none
   end
 
   task getRoom (bit [1:0] id);
      $display ("[%0t] Trying to get a room for id[%0d] ...", $time, id);
      key.get (1);
      $display ("[%0t] Room Key retrieved for id[%0d]", $time, id);
   endtask
 
   task putRoom (bit [1:0] id);
      $display ("[%0t] Leaving room id[%0d] ...", $time, id);
      key.put (1);
      $display ("[%0t] Room Key put back id[%0d]", $time, id);
   endtask
 
   task personA ();
      getRoom (1);
      #20 putRoom (1);
   endtask
 
   task personB ();
      #5  getRoom (2);
      #10 putRoom (2);
   endtask
endmodule
 
Output
[0] Trying to get a room for id[1] ...
[0] Room Key retrieved for id[1]
[5] Trying to get a room for id[2] ...
[20] Leaving room id[1] ...
[20] Room Key put back id[1]
[20] Room Key retrieved for id[2]
[25] Trying to get a room for id[1] ...
[30] Leaving room id[2] ...
[30] Room Key put back id[2]
[30] Room Key retrieved for id[1]
[50] Leaving room id[1] ...
[50] Room Key put back id[1]

Note the following about semaphores :

  • A semaphore object key is declared and created using new () function. Argument to new () defines the number of keys.
  • You get the key by using the get () keyword which will wait until a key is available (blocking)
  • You put the key back using the put () keyword


What's a mailbox ?

A mailbox is like a dedicated channel established to send data between two entities. For example, if a generator wanted to send a data packet to the driver, a mailbox should be established between the generator and the driver, and the data should be put into the mailbox.

 
// Data packet in this environment
class transaction;
   rand bit [7:0] data;
 
   function display ();
      $display ("[%0t] Data = 0x%0h", $time, data);
   endfunction
endclass
 
// Generator class - Generate a transaction object and put into mailbox
class generator;
   mailbox mbx;
 
   function new (mailbox mbx);
      this.mbx = mbx;
   endfunction
 
   task genData ();
      transaction trns = new ();
      trns.randomize ();
      trns.display ();
      $display ("[%0t] [Generator] Going to put data packet into mailbox", $time);
      mbx.put (trns);
      $display ("[%0t] [Generator] Data put into mailbox", $time);
   endtask
endclass
 
// Driver class - Get the transaction object from Generator
class driver;
   mailbox mbx;
 
   function new (mailbox mbx);
      this.mbx = mbx;
   endfunction
 
   task drvData ();
      transaction drvTrns = new ();
      $display ("[%0t] [Driver] Waiting for available data", $time);
      mbx.get (drvTrns);
      $display ("[%0t] [Driver] Data received from Mailbox", $time);
      drvTrns.display ();
   endtask
endclass
 
// Top Level environment that will connect Gen and Drv with a mailbox
module tb_top;
   mailbox   mbx;
   generator Gen;
   driver    Drv;
 
   initial begin
      mbx = new ();
      Gen = new (mbx);
      Drv = new (mbx);
 
      fork 
         #10 Gen.genData ();
         Drv.drvData ();
      join_none
   end
endmodule
 
Output
[0] [Driver] Waiting for available data
[10] Data = 0x9d
[10] [Generator] Put data packet into mailbox
[10] [Generator] Data put into mailbox
[10] [Driver] Data received from Mailbox
[10] Data = 0x9d
ncsim: *W,RNQUIE: Simulation is complete.

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