Contact / Report an issue

SystemVerilog Mailbox

SystemVerilog Mailbox


A mailbox is a communication mechanism that allows messages to be exchanged between processes. The process which wants to talk to another process posts the message to a mailbox, which stores the messages temporarily in a system defined memory object, to pass it to the desired process.
Based on the sizes mailboxes are categorized as,
  • bounded mailbox
  • unbounded mailbox

A bounded mailbox is with the size defined. mailbox becomes full when on storing a bounded number of messages. A process that attempts to place a message into a full mailbox shall be suspended until enough space becomes available in the mailbox queue.

Unbounded mailboxes are with unlimited size.

Mailbox types


There are two types of mailboxes,
  • Generic Mailbox
  • Parameterized mailbox

Generic Mailbox (type-less mailbox)


The default mailbox is type-less. that is, a single mailbox can send and receive data of any type.

mailbox mailbox_name;

Parameterized mailbox (mailbox with particular type)


Parameterized mailbox is used to transfer a data of particular type.

mailbox#(type) mailbox_name;

Mailbox Methods


SystemVerilog Mailbox is a built-in class that provides the following methods. these are applicable for both Generic and Parameterized mailboxes

new();           - Create a mailbox
put();           - Place a message in a mailbox
try_put();       - Try to place a message in a mailbox without blocking
get(); or peek();- Retrieve a message from a mailbox
num();           - Returns the number of messages in the mailbox
try_get(); or try_peek();  - Try to retrieve a message from a mailbox without blocking

new( ); 


Mailboxes are created with the new() method.

mailbox_name = new();        // Creates unbounded mailbox and returns mailbox handle

mailbox_name = new(m_size);  //Creates bounded mailbox with size m_size and returns mailbox handle ,where m_size is integer  variable




SystemVerilog Mailbox example


In the example below,
Mailbox is used for communication between generator and driver.
  • Process-1(Generator class) will generate (created and randomize) the packet and put into the mailbox mb_box
  • Process-2(Driver class) gets the generated packet from the mailbox and display the fields

//-------------------------------------------------------------------------
// Packet 
//-------------------------------------------------------------------------
class packet;
  rand bit [7:0] addr;
  rand bit [7:0] data;

  //Displaying randomized values
  function void post_randomize();
    $display("Packet::Packet Generated");
    $display("Packet::Addr=%0d,Data=%0d",addr,data);
  endfunction
endclass

//-------------------------------------------------------------------------
//Generator - Generates the transaction packet and send to driver
//-------------------------------------------------------------------------
class generator;
  packet pkt;
  mailbox m_box;
  //constructor, getting mailbox handle
  function new(mailbox m_box);
    this.m_box = m_box;
  endfunction
  task run;
    repeat(2) begin
      pkt = new();
      pkt.randomize(); //generating packet
      m_box.put(pkt);  //putting packet into mailbox
      $display("Generator::Packet Put into Mailbox");
      #5;
    end
  endtask
endclass

//-------------------------------------------------------------------------
// Driver - Gets the packet from generator and display's the packet items
//-------------------------------------------------------------------------
class driver;
  packet pkt;
  mailbox m_box;

  //constructor, getting mailbox handle
  function new(mailbox m_box);
    this.m_box = m_box;
  endfunction

  task run;
    repeat(2) begin
      m_box.get(pkt); //getting packet from mailbox
      $display("Driver::Packet Recived");
      $display("Driver::Addr=%0d,Data=%0d\n",pkt.addr,pkt.data);
    end
  endtask
endclass

//-------------------------------------------------------------------------
//     tbench_top  
//-------------------------------------------------------------------------
module mailbox_ex;
  generator gen;
  driver    dri;
  mailbox m_box; //declaring mailbox m_box

  initial begin
    //Creating the mailbox, Passing the same handle to generator and driver, 
    //because same mailbox should be shared in-order to communicate.
    m_box = new(); //creating mailbox

    gen = new(m_box); //creating generator and passing mailbox handle
    dri = new(m_box); //creating driver and passing mailbox handle
    $display("------------------------------------------");
    fork
      gen.run(); //Process-1
      dri.run(); //Process-2
    join
    $display("------------------------------------------");
  end
endmodule

 Simulator Output 

------------------------------------------
Packet::Packet Generated
Packet::Addr=3,Data=38
Generator::Packet Put into Mailbox
Driver::Packet Recived
Driver::Addr=3,Data=38

Packet::Packet Generated
Packet::Addr=118,Data=92
Generator::Packet Put into Mailbox
Driver::Packet Recived
Driver::Addr=118,Data=92

------------------------------------------

Execute the above code on