Wednesday, June 19, 2013

Semaphore

Semaphore is used for lock/unlock of a common resource. If resource is in unlock state the resource can be used, if it is in lock state, then it can not be used.

Lets assume that in a Verification env, we have single ethernet port/driver and there are 2 packet generators using this one ethernet port, one generating normal frames and other generating flow control (pause) frames.

So each of this two packet generators can use semaphone to if ethenet driver is free (unlock) state, before it can transmit the frame. So if the driver is free, then it locks the drivers and transmits the frame, once tramitted, it unlocks the drivers.



When driver is in lock state, it will wait till driver is in unlock state.
Semaphore in SystemVerilog supports following methods for above operations.


Semaphore allocation : new()
Using semaphore keys : get()
Returing semaphore keys : put()
Try to obtain one or more keys without blocking: try_get()

new()
Semaphores are created with the new() method.
function new(int keyCount = 0 );
Where
keycount : The keyCount specifies the number of keys initially allocated to the semaphore bucket.
The new() function returns the semaphore handle or, if the semaphore cannot be created, null.


put()
The semaphore put() method is used to return keys to a semaphore.
task put(int keyCount = 1);
Where
The keyCount specifies the number of keys being returned to the semaphore. The default is 1.

get()
The semaphore get() method is used to procure a specified number of keys from a semaphore.
task get(int keyCount = 1);
Where
The keyCount specifies the required number of keys to obtain from the semaphore. The default is 1.
If the specified number of keys is not available, the process blocks until the keys become available.
The semaphore waiting queue is first-in first-out (FIFO).

try_get()
The semaphore try_get() method is used to procure a specified number of keys from a semaphore, but without blocking.
function int try_get(int keyCount = 1);
Where
The keyCount specifies the required number of keys to obtain from the semaphore. The default is 1.
If the specified number of keys is available, the method returns a positive integer and execution continues.
If the specified number of keys is not available, the method returns 0.


Example : Semaphore
1 program semaphore_ex; 
3 semaphore semBus = new(1); 
5 initial begin 
6 fork 
7 agent("AGENT 0",5); 
8 agent("AGENT 1",20); 
9 join 
10 end 
11 
12 task automatic agent(string name, integer nwait); 
13 integer i = 0; 
14 for (i = 0 ; i < 4; i ++ ) begin 
15 semBus.get(1); 
16 $display("[%0d] Lock semBus for %s", $time,name); 
17 #(nwait); 
18 $display("[%0d] Release semBus for %s", $time,name); 
19 semBus.put(1); 
20 #(nwait); 
21 end 
22 endtask 
23 
24 endprogram

-----------------------------------------------------------------------------------------------------------------------
Another Explanation of same thing :


Inter Process Communication: Semaphores

A semaphore allows you to control access to a resource. A semaphore is an equivalent of a key (or a set of keys) when a process tries to access a shared resource.

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. Depending on the availability of a key, a key is either allotted to the current process or not. If a key is allotted to a process when this process is done with using the resource, it will give the key back to the semaphore and that key may be allotted to other processes who are waiting for a key.

Syntactically, the semaphore is a built-in class that allows only certain pre-defined operations on the keys.

A semaphore declaration is shown below:


Built-in methods in Semaphore

There are 4 predefined methods inside a semaphore type class.
new( ): Create a semaphore with specified number of keys.
get( ): Obtain one or more keys from a sempahore and block until keys are available.
try_get( ): Obtain one or more kets from a semaphore without blocking.
put( ): Return one or more keys to a semaphore

new( )
Just as any other class, a semaphore needs a constructor.

The prototype declaration for new( ) is shown below:

The constructor new( ) has an integer argument key_count that can be used for creating a desired number of keys.
The default value of key_count is 0.
Upon success, the new( ) function returns the semaphore handle, otherwise, it returns null.

get( )
The get( ) task is used for obtaining one or multiple keys for a semaphore.

The prototype declaration for get( ) is shown below:

The number of keys to procure is passed as the argument to get( ).
The default value of this argument is 1.
If a process asks for certain number of kets and they are available, the call to get( ) returns and the execution continues.
If the required number of keys are not available, the call to get( ) blocks subsequent statements and waits for additional keys to be available. That is why get( ) is a task, not a function, and hence, can consume time.
All calls to get( ) are queued in a FIFO and keys are delivered in a first-come-first-serve basis.


try_get( )
If you do not want to block while trying to get keys for a semaphore, try_get( ) is your solution. Unlike get( ), try_get( ) is a function that checks for key availability and procures them if they are available (and returns 1). But, if they are not, try_get( ) does not block and returns 0.

The prototype for try_get( ) is shown below:


put( )
Now, suppose that a process is done with using a resource. According to the good code of conduct in the semaphore land, that process must return the keys (so that another process can use them). This is done by the put( ) task, where the number of returned kets are passes as an argument.

The prototype for put( ) is shown below:


#copied from internet : another resource

Ethernet and more

Ethernet is a protocol under IEEE 802.33 standard User Datagram Protocol (UDP) UDP is a connectionless transport protocol. I...