SystemVerilog Interprocess Synchronization and Communication
Previous: Semaphore | Next: Mailbox
Built-in methods in Semaphore
There are four predefined methods inside
a semaphore type class. These methods provide the basic mechanism
of a semaphore. These methodsummarized below and then described in
details in the next sections.
| Method name
|| Create a semaphore with specified number of keys.
|| Obtain one or more keys from a semaphore and block until keys are available.
|| Obtain one or more keys from a semaphore without blocking.
|| Return one or more keys to a semaphore.
Just as any other class, a semaphore needs a constructor. The constructor
new() has an integer argument keyCount that can be used for
creating desired number of keys. The default value of keyCount is 0.
Upon success, the new() function returns the semaphore handle,
otherwise, it returns null. The prototype declaration for new()
is shown below.
function new(int keyCount = 0);
The following declaration creates a semaphore sema4_proc1 with
previously defined N_KEYS keys.
semaphore sema4_proc1 = new(N_KEYS);
The get() task, as the name suggests, is used for obtaining one
or multiple keys for a semaphore. The number of keys to procure is passed
as the argument to get(). The default value of this argument is 1.
The prototype declaration for get() is shown below.
task get (int keyCount = 1);
If a process asks for certain number of keys and they are available, the
call to get() returns and the execution continues. However, if the
required number of keys are not available, the call to get() blocks
subsequent statements and waits for additional keys to be available. This is
why get() is a task, not a function, and hence, can consume
All calls to get() are queued in a FIFO and keys are delivered in a
The following example shows a process that asks for N_KEYS number of keys
and blocks until the keys are available.
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.
function int try_get(int keyCount = 1);
The following example shows how try_get() can be used in your code.
// figure out something else to do
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 keys are passed as an
argument. The prototype for put() is shown below.
task put (int keyCount = 1);
The following example shows you how to use put() in conjunction
An interesting thing to note is that put() is a task, just like
get() is. This is because, a semaphore may be busy when a process
returns keys and hence, there may be time delay.
Another interesting situation to consider here is what happens if a process
procures but never returns keys? This will be akin to not returning your
swimming pool key afer you are done in our imaginary hotel. In this case,
as you might imagine, the total number of keys will be depleted. And
eventually, the semaphore (and the hotel) will run out of keys. This is one
scenario that you may want to avoid. So be a good citizen and return your
However, apart from bad programming mistakes, there are other situations
when a process may fail to return keys. For instance, if the resource becomes
zombie or invalid, the task call will never return. In this case, SystemVerilog
automatically releases keys at the time when the process becomes invalid. You
can also create a method of timing out a key if this is a possible scenario.
Previous: Semaphore | Next: Mailbox