Home System Verilog Constructs Inter process communication
Main Menu
System Verilog
    - Constructs
        -- Introduction
        -- Data Types
        -- Type Casting
        -- SV Arrays
        -- Assoc Arrays
        -- Dynamic Array
        -- Queues
        -- Operators
        -- Procedural statements
        -- Classes
        -- OOP Concepts
        -- Inter process communication
        -- Randomization
        -- Interface
        -- Clocking block
        -- Conststraits
        -- Coverage
        -- DPI
        -- Regular expression
        -- Files
    - SV Classes
    - Functional Coverage SV
    - Examples
    - Tools
    - Links
    - Books
    - Interview Questions SV
Open Vera
Digital Concepts
Verification Basics
Interview Questions
Computer Architechture
C and C++
AsicGuru Blog
Tags Cloud
Usefull Sites
Know Your IP/Location
Local Information India
Buy Car/Inverter Batteries
Real Estate India
Sports Accessories India
Inter process communication
Share This Articale:

Starting the execution of a block of code while an event triggers is a basic building block in any hardware description language. Verilog provides two such mechanisms: @ and ->. These two operators are adequate for synchronizing hardware related events (and subsequently for writing synthesizable code). But their limitations become apparent while writing complex testbenches, such as a reactive testbench. The main drawback of these two operators is that they can only work on and can create static events (i.e. events that are known at compile or 'elaboration' time).

SystemVerilog offers a set of capabilities that allows you to do just that. This article in two parts describes these capabilities and teaches you how to create inter-process synchronization and communication dynamically (i.e. during run-time), and how to reclaim the resource once their utilities are over. In the first part, we will learn about how to use Semaphores and Mailboxes to synchronize the allocation of a resource (typically a task or function). In the next part, we will explore more on event type that already exists in Verilog but has been enhanced in SystemVerilog.


Imagine a hotel swimming pool that any valid guest can use. However, to comply with the local city law, the hotel management can allow only upto a fixed maximum number of simultaneous users. To restrict the use to this certain maximum number of users at any given time, the hotel management has installed a key system. Every guest who wants to use the pool needs to come to the front desk and take a key to open the gate to the swimming pool. Only a fixed number of keys are issued at a time, as dictated by the city law. When a guest is done, she returns the key to the front desk and that key is then issued to another guest.

A semaphore is equivalent of a key (or a set of keys) in the above example when a process tries to access a shared resource (swimming pool, as in our example). By enforcing a common set of rules to access a resource, a semaphore acts as a common gateway for all the processes that want that resource. This is how it works. A semaphore is first associated with a resource that needs to be protected. Whenever a process wants to access this resource, it seeks a key from the semaphore. (It is possible that to access a resource, a process may need more than one key. In such case, the process will ask for as many keys as it needs). Depending on how many keys have been already alloted to other similar processes, if there is a free key available to the semaphore, it will now be alloted to the current process. When this process is done with using the resource, it will give back the key to the semaphore and that key may be alloted to other processes who are waiting for a key.

Syntactically, semaphore is a built-in class that allows only certain pre-defined operations on the keys by external processes. Just as any other class, a semaphore should be declared before its use.

Events are defined as a basic type in Verilog since its earliest days. You can define an event, for example, code_1 in Verilog as shown below and then associate a block of code with this named event. You can trigger this block of code using the ->code_1; in another part of your code. Furthermore, you can trigger another block of code code_2 when code_1 triggers by using the @(code_1) construct or native task wait(code_1).


event code_1;
   begin: code_1
      a = 1'b0; 
      // insert other code for event code_1 here
      ->code_1; // triggers code_1 above
   @(code_1); // or wait(code_1);


SystemVerilog provides all these and then some more. Most notable of these are listed below.

A. The ->> construct

In order to understand the way the ->> construct works, first look at the example of -> one more time. Notice that when code_1 triggers, it blocks the execution of subsequent code (in this case, some_task()) until code_1 finishes execution.

The previous example is reproduced below where ->> places ->. The ->> construct works similar to the -> construct, but it does not block the code in the same sequential thread. In stead, the triggered event (such as, code_1) is scheduled to occur at the end of the simulation slot (where all other non-blocking assignments are done). A direct consequence of this is later code (such as some_task()) will not see an update of a variable (such as a) to occur in code_1.


event code_1;
   begin: code_1
      a = 1'b0;
      // insert code for event code_1 here
      ->>code_1; // triggers code_1 above


This Articles is written/submitted by puneet (Puneet Aggarwal). You can also contribute to Asicguru.com. Click here to start

Prev << OOP Concepts

Next >> Randomization

Sign In
Login with :-
| | |  
  • Bookmark