Logic Design - Semaphores and Mailboxes (SystemVerilog)

in STEMGeekslast year

[Edit of Image1]


Hey it's a me again @drifter1!

Today we continue with the Logic Design series on SystemVerilog in order to cover Semaphores and Mailboxes, which are the two other interprocess communication mechanisms of SystemVerilog. Events were covered last time!

So, without further ado, let's get straight into it!


Semaphores are used for the purpose of mutual exclusion, letting only processes with a key to continue execution. This allows us to control the access of shared resources.

Semaphore Creation

Semaphores objects are created from the built-in semaphore class and allocated / initialized using the new(key_count) function, which takes the number of keys as an argument.

For example, a simple mutex is defined using the following code:

semaphore mutex;

initial begin
    mutex = new(1);

Semaphore Methods

The following methods can be called on a semaphore object:

  • get(key_count) : block execution until the specified amount of keys is obtained from the semaphore (lock).
  • put(key_count) : return the specified amount of keys to the semaphore (unlock).
  • try_get(key_count) : try obtaining the specified amount of keys from the semaphore but don't block execution.

If no number of keys is specified in those functions, then a default value of 1 is used.

The critical sections (sections where synchronization is needed) are thus enclosed within a get() and put() like shown below.

/* critical section */

The last method, try_get(), can be used in conditional statements in order to execute different testing code if the semaphore is available or not:

if mutex.try_get()
    // mutex available
    // mutex unavailable


Mailboxes are dedicated channels that connect two processes / components directly, allowing data to be exchanged between them. They behave like queues, but are different from the queue data structure. A mailbox uses semaphores for controlled atomic access, and operates in FIFO order only.

Mailbox Definition

Mailboxes are objects of the mailbox class. A generic mailbox is thus defined by using the class name mailbox as is:

mailbox mbx;

These generic mailboxes are typeless and any data can be send and received. In order to constrain them to a fixed data type, they can be parameterized to that data type, leading to so called parameterized mailboxes. Compiler errors would then be triggered whenever data type mismatches occur!

For example a string-only mailbox is defined as follows:

mailbox #(string) s_mbx;

Mailbox Methods

The following methods can be called on mailbox objects:

  • new(size) : allocate mailbox with the specified queue size.
  • num() : returns the number of messages in the mailbox.
  • put(msg) : blocking method that stores the given message in FIFO order. Blocks if the mailbox is full.
  • try_put(msg) : same as put(msg) but non-blocking. Returns 0 if the mailbox is full.
  • get(msg_ref) : blocking method that retrieves one message from the mailbox (by deleting it) and blocks execution if the mailbox is empty.
  • try_get(msg_ref) : same as get(msg_ref) but non-blocking. Returns 0 if mailbox is empty.
  • peek(msg_ref) : blocking method that copies one message from the mailbox without deleting it, and blocks execution if the mailbox is empty.
  • try_peek(msg_ref) : same as peek(msg_ref) but non-blocking. Returns 0 if the mailbox is empty.

For example:

// create mailbox that can hold
// up to 2 string messages
mailbox #(string) s_mbx = new(2); 

// store messages
s_mbx.put ("Komi");
s_mbx.put ("Tadano");

// retrieve message (deleting it)
string x;
// x now contains "Komi"

// try peeking message (copy don't delete)
string y;
if s_mbx.try_peek(y)
    // the mailbox contained an item
    // so this code would be executed
// y now contains "Tadano"

// store message
s_mbx.put ("Yamai");

// try storing message
if s_mbx.try_put("Najimi")
    // the mailbox is full
    // so this code would not be executed!



  1. https://www.chipverify.com/systemverilog/systemverilog-tutorial
  2. https://www.asic-world.com/systemverilog/tutorial.html


  1. https://www.flickr.com/photos/creative_stock/5227842611

Block diagrams and other visualizations were made using draw.io

Previous articles of the series



  • From Verilog To SystemVerilog → Data Types, Arrays, Structures, Operators and Expressions
  • Control Flow → Additional Procedural Blocks, Loops, Conditional Statements, Functions and Task Features
  • Processes → Fork - Join in Verilog and SystemVerilog, Process Control (wait fork, disable fork)
  • Events → Interprocess Communication, Events (Definition, Triggering, Waiting, Sequencing, Merging, as Arguments)

Final words | Next up

And this is actually it for today's post!

Next time we will cover interfaces and maybe even program blocks...

See Ya!

Keep on drifting!

Posted with STEMGeeks