Interprocess Communication
Interprocess communication through event, semaphores and mailboxes
Methods for iInterprocess Communication
Components/threads in a testbench communicate with each other to exchange data and
check output values. The various mechanisms are:
Events Different threads synchronize with each other via event handles in a testbench
Semaphore Different threads might need to access the same resource; they take turns by
s using a semaphore
Mailbox Threads/Components need to exchange data with each other; data is put in a
mailbox and sent
EVENT
Event
An ‘event’ is a handle created to synchronize the actions between processes. One
process triggers an event while another waits for it.
• ‘@’ implies instantaneous waiting ( Here, the event should have been triggered
before this statement. Then only it will be recognized as being triggered. If there
are parallel processes happening, we can’t predict which one will occur first and
so race conditions possible with this kind of ‘waiting’.
• ‘wait (e.triggered)’ results in persistent trigger that last for the full time step ie:
as long as the trigger has happened during the particular time step, it considers
as being triggered.
Either E1 or
E2 can be
triggered first.
Accordingly
the sequence
will change.
Multiple
sequences are
possible.
Note: All statements in a process execute in same time step, unless any kind of wait
state is encountered
More examples using EVENT
Waiting using ‘@’ and ‘triggered’
No race conditions with both
types of wait statements
Waiting using ‘@’ and ‘triggered’
Possible race conditions with
@wait since waiting and
triggering happening in same
time step at #20
Thread 2 never detected the event since thread 2
might have executed before thread 1 in the given
timestep. But thread 3 is able to detect the event
since it checks during the entire time step.
Semaphores
Inbuilt methods in semaphore class
Name Description
function new (int keyCount); Specifies number of keys initially
allocated to the semaphore Semaphore key;
bucket Key = new (2)
task get (int keyCount); Specifies the number of keys to
obtain from the semaphore Key.get(1)
function void put (int keyCount); Specifies the number of keys
being returned to the semaphore Key.put(1)
Semaphore Example
Forking parallel processes
Key.get() will wait till the key is
released by previous process.
MAILBOX
Mailbox example
Note:
Before we look at mailbox example, we will see one slide on randomization to see
how data can be generated randomly for assigning to variables. This kind of data
generation is used in the mail box example. Hence randomization is being introduced
here.
A complete topic on constraint random generation will be dealt with later.
Introduction to Randomization
Example: (Creating a transactor and assigning random values)
class transaction;
//declaring the transaction items
rand bit [3:0] a;
class generator;
rand bit [3:0] b;
// create object handle for transactions transaction
bit [6:0] c;
trans;
//c is output. Hence not defined as random
task main();
function display()
trans = new();
$display(“ a = %0d, b = %0d",a,b);
trans.randomize(); //randomly generate a and b
$display(“ c = %0d",c);
endtask
endfunction;
endclass
endclass;
Example Program of using Mailbox
A program to illustrate the use of mailbox in system Verilog. The top level module instantiates a mailbox
and the mailbox handle is passed as argument to the generator and the driver classes. The mailbox
handles are used by the local mailboxes, thus ensuring that a common mailbox object is used by all.
//------------------------------------------------------------------
------- //----------------------------------------------------------------------
// Packet ---
//------------------------------------------------------------------ //Generator - Generates the transaction packet and
------- send to driver
class packet; //----------------------------------------------------------------------
rand bit [7:0] addr; ---
class generator;
rand bit [7:0] data;
packet pkt;
mailbox m_box;
//Displaying randomized values //constructor, getting mailbox handle
function void post_randomize(); function new(mailbox m_box);
$display("Packet::Packet Generated");
this.m_box = m_box;
$display("Packet::Addr=%0d,Data=
endfunction
%0d",addr,data);
endfunction task run;
endclass 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
// tbench_top
m_box.get(pkt); //getting packet from mailbox //-------------------------------------------------------------------------
$display("Driver::Packet Recived"); module mailbox_ex;
$display("Driver::Addr=%0d,Data=%0d\
generator gen;
n",pkt.addr,pkt.data);
driver dri;
end
mailbox m_box; //declaring mailbox m_box
endtask
endclass
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