Saturday 13 September 2014

Semaphore in System Verilog

For verification purpose we need high level and easy to use synchronization and communication mechanism for our test bench.

Sytem verilog supports mailbox for communication between dynamic processes and semaphore for synchronization between dynamic processes.

Semaphore

Semaphore is like bucket of keys for processes. When a semaphore is created a bucket is created that has capability to contain fixed number of keys. The processes that uses semaphore must first get its keys and than only it is able to start its process. It is like token passing mechanism and as resources are always limited here number of token are also limited.

We will consider following example to understand Semaphore. 

Suppose we have two running processes and both of them access same interface. Both porcesses are independent of each other.  So it is possible that both the process starts driving the interface at the same time. If both processes are driving interface at the same time we will get wrong data on interface until and unless both processes are driving same data on same time !! But that is not going to happen anyway. This type of situations can be managed by keeping some flag that indicates that interface is free or not and our process starts if and only if interface is free. But what will happen if you have say m number of processes that is driving n (n < m) number of interfaces. For this kind of senariaos it will be dificult to syncronize between processes.
For such application semaphore is the best options. 

Lest assume that in some BFM two process write_data () & read_data() this both tasks are getting called randomly and they are using same interface to complete read or write operation. For such type of situation we can implement our read and write progreamn following way.
class semaphore_example;

  semaphore smphr = new(1);

    task read();
       smphr.get(1);       

       // Code to read data from interface

       smphr.put(1);
    endtask : read


task write();
       smphr.get(1);
    
       // Code to write data from interface

       smphr.put(1);
 endtask : write

      
endclass : semaphore_example

In the above example whenever the read or write task is getting called it first gets key form semaphore using smphr.get(1) task and than starts driving the interface and once done with the interface puts the key to the semaphore. This way whenever any task/process gets key from semaphore it is certain that interface is not driven by other process.

There are four methods are defined for semaphores which is listed down here. For more details you can use LRM for System Verilog.

New() ;

Prototype 
                    function new (int KeyCount = 0);
Then KeyCount indicates number of key that is initially allocated to the semaphore.

put ()

The semaphore method used put keys back into semaphore.
Prototype :   function void put(int KeyCount = 0);

get()

The method get() is used to procure specific number of key from semaphore.
Prototype : task get(int KeyCount = 0);
This task blocks the execution of the process until it gets the semaphore key.

Try_get();

The method is used to procure specific number of keys form semaphore but without blocking the process.
Prototype : function void try_get(int KeyCount = 0);











No comments:

Post a Comment