Skip to main content

Mailboxes in SystemVerilog

· loading · loading · ·
Course Verification SystemVerilog SystemVerilog IPC Mailboxes Verification Synchronization
Course Verification SystemVerilog
Axolot Logic
Author
Axolot Logic
Digital Design Engineer
Table of Contents
SystemVerilog Design Series - This article is part of a series.
Part 23: This Article

📦 Mailboxes in SystemVerilog
#

Mailboxes are built-in classes in SystemVerilog that provide a powerful and convenient mechanism for interprocess communication and data exchange between concurrent processes. They’re commonly used to implement producer-consumer architectures in testbenches and simulation environments.


🗂️ What is a Mailbox?
#

A mailbox acts as a FIFO queue that stores messages (data) between processes:

  • A producer process puts data into the mailbox.
  • A consumer process gets data from the mailbox.

Mailboxes support both bounded and unbounded queue sizes:

  • Unbounded mailboxes (default) never block on a put operation.
  • Bounded mailboxes suspend the producer if the queue is full, ensuring safe data flow.

🛠️ Creating a Mailbox
#

Mailboxes are created using the built-in mailbox class and the new() constructor.

mailbox mbx;

// Create an unbounded mailbox
initial begin
  mbx = new();
end

// Create a bounded mailbox with a size of 10
initial begin
  mbx = new(10);
end

🚦 Using a Mailbox
#

📤 Putting Data into a Mailbox
#

Use the put() task to store a message in the mailbox.

mbx.put(data); // blocks if mailbox is full (bounded mailbox)

For non-blocking insertion, use try_put():

if (mbx.try_put(data)) begin
  // Data added successfully
end else begin
  // Mailbox is full
end

📥 Getting Data from a Mailbox
#

Use the get() task to retrieve a message from the mailbox.

mbx.get(data); // blocks if mailbox is empty

For non-blocking retrieval, use try_get():

if (mbx.try_get(data)) begin
  // Data retrieved
end else begin
  // Mailbox is empty
end

👀 Peeking at Data
#

Use the peek() task to copy a message without removing it from the queue.

mbx.peek(data); // blocks if mailbox is empty

For non-blocking peek, use try_peek():

if (mbx.try_peek(data)) begin
  // Data peeked
end else begin
  // Mailbox is empty
end

🔍 Summary of Key Methods
#

MethodDescription
new()Creates the mailbox (bounded or unbounded).
put()Places a message in the mailbox (blocks if full).
try_put()Non-blocking attempt to place a message.
get()Retrieves a message from the mailbox (blocks if empty).
try_get()Non-blocking attempt to retrieve a message.
peek()Copies a message without removing it (blocks).
try_peek()Non-blocking attempt to copy a message.
num()Returns the number of messages currently stored.

🛡️ Common Uses
#

  • Producer-Consumer Communication: Send transactions from drivers to monitors.
  • Scoreboard Communication: Transfer data between different testbench components.
  • Flow Control: Manage data throughput using bounded queues.

💡 Best Practices
#

✅ Use try_put() and try_get() when implementing non-blocking data flow.
✅ Always match put() calls with corresponding get() calls to avoid indefinite growth of unbounded mailboxes.
✅ For type safety, consider using parameterized mailboxes when exchanging specific data types.
✅ Document mailbox usage clearly in the testbench architecture.


📖 Conclusion
#

Mailboxes are a versatile mechanism for data exchange and synchronization in SystemVerilog verification environments. When used effectively, they simplify communication between concurrent processes, ensuring safe and reliable simulation results.

module tb_mailbox_demo;

  mailbox mbx;  // Define mailbox

  // Clock generation
  logic clk = 0;
  always #5 clk = ~clk;

  // Producer process: sends data into mailbox
  initial begin
    mbx = new();  // Create an unbounded mailbox

    repeat (5) begin
      automatic int data = $urandom_range(0, 255);
      mbx.put(data);  // Put data into mailbox (blocking)
      $display("[Producer] Sent: %0d at time %0t", data, $time);
      #10;
    end
  end

  // Consumer process: receives data from mailbox
  initial begin
    int received;
    repeat (5) begin
      mbx.get(received);  // Get data from mailbox (blocking)
      $display("[Consumer] Received: %0d at time %0t", received, $time);
      #15;
    end
  end

  // Simulation end
  initial begin
    #100;
    $finish;
  end

endmodule

SystemVerilog Design Series - This article is part of a series.
Part 23: This Article

Related

Semaphores in SystemVerilog
· loading · loading
Course Verification SystemVerilog SystemVerilog IPC Semaphores Verification Synchronization
Course Verification SystemVerilog
Named Events in SystemVerilog
· loading · loading
Course Verification SystemVerilog SystemVerilog IPC Named Events Verification Synchronization
Course Verification SystemVerilog
Interprocess Synchronization and Communication in SystemVerilog
· loading · loading
Course Verification SystemVerilog SystemVerilog IPC Verification Semaphores Mailboxes Named Events
Course Verification SystemVerilog
Object-Oriented Programming in SystemVerilog
· loading · loading
Course Verification SystemVerilog SystemVerilog OOP Object-Oriented Programming Verification Classes
Course Verification SystemVerilog
Advanced OOP in SystemVerilog: Aggregation, Inheritance, and More
· loading · loading
Course Verification SystemVerilog SystemVerilog OOP Object-Oriented Programming Verification Classes
Course Verification SystemVerilog
Advanced OOP in SystemVerilog: Constructors, Handles, and Static Members
· loading · loading
Course Verification SystemVerilog SystemVerilog OOP Object-Oriented Programming Verification Classes
Course Verification SystemVerilog