SystemVerilog Interprocess Synchronization and Communication


[Part 1]

Previous: Built-in methods in Semaphore | Next: More methods in Mailbox

Mailbox

Mailboxes are another convenient way for inter-process communication. Semaphores provide a way for processes to communicate indirectly; mailboxes are facilities where processes can communicate directly with one another.

Mailboxes operate in the same manner as a real mailbox. A process may submit a letter (which, in this case, will contain a data message) for another process in a mailbox. The message stays in the mailbox until the receiving process comes and retrieves it. If the receiving process checks the mailbox before the sending process deposits the message in the mailbox, the receiving process goes back empty handed.

A message in this case can be any singular type (i.e. any variable other than an unpacked array, structure or union type). A non-parameterized mailbox (discussed later) can accept and retain messages of any valid singular type. The only other restriction is that a message must be a valid left hand side expression. For example, a net type, such a wire, is not a valid message. So, you can use a single mailbox to handle various type of messages (from a single or multiple source). Also, a mailbox can be bounded, meaning it can hold only a pre-specified maximum number of messages. Or, it can be unbounded, when it will hold all the messages that it receives.

Syntactically, a mailbox is a built-in class (just as semaphore is, with all the rules for a general class being equially applicable for mailbox too) that can be defined as follows.

mailbox uGotMail;

Built-in methods in Mailbox

The class mailbox provides 8 methods that can be used for accessing a mailbox. These methods are summarized below in the table and then described in details in the next sections.

Method name Summary
new() Create a mailbox with specified number of slots.
num() Find the number of messages in a mailbox.
get() Retrieve a message, if available, from the mailbox. Block otherwise.
try_get() Retrieve a message from a mailbox without blocking.
peek() Copy a message, if available, from the mailbox. Block otherwise.
try_peek() Copy a message from a mailbox without blocking.
put() Put a message in a mailbox.

new()

The function new() is the constructor method for the class mailbox. It takes one integer argument bound that describes the number f messages that this mailbox can hold. If bound is 0, the mailbox can hold (theoretically) infinite number of messages. The default value of this argument is 0. The prototype declaration for new() is shown below. Note that, new() being a function, can not block or consume time.

function new (int bound = 0);

The following example shows a mailbox declaration that can hold N_MSG (a non-negative integer) number of messages with a call to its constructor new.

mailbox uGotMail = new(N_MSG);

num()

As mentioned earlier, num() returns the number of messages in a mailbox. However, this number changes whenever a process puts or retrieves a message in a mailbox. So, the validity of the result of a num() call should be examined carefully before use. In practice, for this reason, num() is rarely used.

The prototype for num() is shown below. Note that, num(), similar to new() is a function and hence, non-blocking. It returns the number of messages in the mailbox and takes no argument.

function int num();

The following example shows a code snippet that prints the number of messages in a mailbox.

   int i;
   ...
   if ((i = uGotMail.num()) == 0)
      $display("The mailbox is empty");
   else 
      $display("The mailbox has %d messages", i); 

put()

A process uses the put() method to place a message in a mailbox. This method is a task and if there are not enough places to put the message in a bounded mailbox, the call will block (i.e. wait until a place is available). The prototype for put() method is shown below.

task put (singular message);

The following example illustrates the use of the put method. Note that, the mailbox uGotMail is used for two different types of messages, the first one is an integer and second one is a string.

   int msg1;
   string msg2;
   ...
   if (msg_is_available) begin 
      uGotMail.put(msg1);
      uGotMail.put(msg2);
   end 

try_put()

The method try_put() is very similar to put(), except that it does not block if there is no place available in the mailbox. The prototype for try_put() method is shown below.

function try_put (singular message);

Previous: Built-in methods in Semaphore | Next: More methods in Mailbox

Share/Save/Bookmark



Verification Management
Join Verification Management Group


Book of the Month


From Our Press