Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
31 views33 pages

10.events and IP Comm 1up

The document discusses events and interprocess communication in Verilog and SystemVerilog, focusing on synchronization mechanisms such as events, semaphores, and mailboxes. It explains how events can be triggered and waited upon, the properties of persistent triggers, and the use of semaphores for mutual exclusion and resource access. Additionally, it provides examples of using mailboxes for communication between processes in a testbench environment.

Uploaded by

karan2004sss
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views33 pages

10.events and IP Comm 1up

The document discusses events and interprocess communication in Verilog and SystemVerilog, focusing on synchronization mechanisms such as events, semaphores, and mailboxes. It explains how events can be triggered and waited upon, the properties of persistent triggers, and the use of semaphores for mutual exclusion and resource access. Additionally, it provides examples of using mailboxes for communication between processes in a testbench environment.

Uploaded by

karan2004sss
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

Fall 2008

Dr. Meeta Yadav


Prof. Paul Franzon

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 1


Topics

• Events
• Interprocess Communication
 Semaphores
 Mailboxes
• Building a testbench with Threads and Interprocess
Communication

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 2


Event
• Events in Verilog
 A Verilog event synchronizes threads
 A thread waits for an event with the @ operator
 The @ operator is edge sensitive, so it always blocks waiting for the event to change
 A thread triggers the event with the -> operator
 The -> operator unblocks the thread
 There is a possibility of race condition in Verilog, if the triggering thread executes before
the blocking thread

event e1,e2;
initial begin
Triggers e1 is triggered
$display (“@%0d: 1: before trigger”, $time);
event e1
-> e1; First block waits on e2
Blocks on @e2;
event e2 $display (“@%0d:1: after trigger”, $time); e2 is triggered
end Second block waits on e1
initial begin
Triggers $display (“@%0d: 2: before trigger”, $time); First block waiting on e2 is unblocked
event e2 -> e2;
Second block waiting on e1 misses
@e1;
Blocks on the trigger and stays blocked
$display (“@%0d:2: after trigger”, $time);
event e1 end
Example: Blocking on an event in Verilog

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 3


Events

• Events in SystemVerilog
 SystemVerilog events are used for synchronization
 Event is a handle to a synchronization object that can be passed around to
routines
 This feature allows events to be shared across objects without having to make
events global
 Events are triggered using the -> or ->> operator
 Processes can wait for an event to be triggered using the @ and wait()
operator
 The triggered state persists throughout the time-step in which the event was
triggered
 triggered function lets a verification engineer check whether an event has
been triggered or not

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 4


Events
• Triggering an event
 Named events are triggered via the -> operator
 Triggering an event unblocks all processes currently waiting on that event
 When triggered, named events behave like a one-shot, that is, the trigger state
itself is not observable, only its effect

• Non blocking event trigger


 Non blocking events are triggered via the ->> operator
 The statement executes without blocking and it creates a nonblocking assign
update event in the time in which the delay control expires or the event-control
occurs
 The effect of this update event shall be to trigger the referenced event in the
nonblocking assignment region of the simulation cycle

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 5


Events
• Waiting for an event
 @ operator is used to wait for an event
 @ operator blocks the calling process until the given event is triggered
 For a trigger to unblock a process waiting on an event, the waiting process
must execute the @ statement before the triggering process executes the
trigger operator
 If the trigger executes first then the waiting process remains blocked

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 6


Events

• Persistent Trigger: triggered property


 SystemVerilog can distinguish event trigger (which is instantaneous) from event
trigger state (which persists through the time step)
 The triggered event property evaluates to true if the given event has been
triggered in the current time-step and false otherwise
 Triggered property is most useful when used in context of wait construct

wait (hierarchical_event_identifier.triggered)

 Triggered property can be used to unblock a process whether the wait executes
before or at the same simulation time as the trigger operation
 The triggered event property is useful in avoiding race conditions that occur when
both the trigger and wait happen at the same time

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 7


Events
• Example of Events

event done, blast; Declare 2 events


event done_too=done; done_too is an alias to done
task trigger (event ev); Generic task to trigger an event
-> ev; Two event identifiers done and done_too refer to the same
endtask synchronization object and an event is passed to the generic task
. . . that triggers that event
fork
@ done_too; Wait for done through done_too
#1 trigger(done); Trigger done through task trigger
join

fork
-> blast; Trigger the event blast
wait(blast.triggered); Waits for the event. Even though the two processes are spawned
join at the same time, the second process can wait on the event since
the triggered state holds for the entire duration of time-step
Example: Triggered property

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 8


Events

• Example of Events

event done, blast;


event done_too=done; clk

task trigger (event ev);


-> ev; @done_too
endtask
. . . done
fork
@ done_too;
#1 trigger(done); blast
join

fork
blast.triggered
-> blast;
wait(blast.triggered); state
join wait(blast.
triggered)
Example: Triggered property

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 9


Events
• Event sequencing: wait_order()
 The wait_order construct suspends the calling process until all of the specified
events are triggered in the given order (left to right)

wait_order (a,b,c)

a->b->c

 If the events are triggered out of order the operation fails

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 10


Events
• Event variables
 Merging Variables
 Events are a unique data type and can be assigned to one another
 When events are assigned to one another the synchronization queue of the source event
is shared by both the source and the destination events
 When events are assigned to each another, the two become merged

event a,b,c
a=b;
->a; //also triggers b
->b; //also triggers a
a=c;
->a //also triggers b and c
->b; //also triggers a and c
->c; //also triggers a and b
Example: Merging variables

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 11


Events
• Event variables
 When events are merged the assignment only affects the execution of
subsequent event control or wait operations
 If a process is waiting for event1 when another event is assigned to event1, the
currently waiting process shall never unblocks. For example:

fork @E2 T1 blocks forever


T1: while(1) @ E2;Thread 1 because E2 is now E1
T2: while(1) @ E1;Thread 2
T3: begin @E1
E2 = E1; Thread 3 T2 unblocks
while(1) -> E2;
end -> E2
E2=E1
join
Example: Effect of merging variables

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 12


Events
• Event variables

To unblock both threads the merger of E1 and E2 should take place outside the fork and join

E2=E1
Parent
E2 = E1;
fork @E2
T1: while(1) @ E2; Thread 1
T2: while(1) @ E1; Thread 2
T3: begin @E1
while(1) -> E2;Thread 3
end
join -> E2

Example: Effect of merging variables

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 13


Events
• Reclaiming Events
 When an event variable is assigned a special null value, the association between the
event variable and the underlying synchronization queue is broken
 When no event variable is associated with an underlying synchronization queue, the
resources of the queue become available for reuse
 Triggering a null event should have no effect
 The outcome of waiting on a null event is undefined and implementations can issue a
run-time warning

event E1=null Undefined: might block forever or not at all


@E1
wait (E1.triggered) Undefined
-> E1 No effect

Example: Reclaiming an event using null construct

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 14


Events
• Event Comparison
 Event variables can be compared against other values, some of them are as follows:
 Equality (==) with another event or null
 Inequality (!=) with another event or null
 Case equality (===) with another event or null
 Case inequality (!==) with another event or null
 Test for boolean value that shall be 0 if the event is null and 1 otherwise

event E1, E2;


if ( E1 ) // same as if ( E1 != null )
E1 = E2;
if ( E1 == E2 )
$display( "E1 and E2 are the same event" );

Example: Event comparison

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 15


Interprocess Communication: Semaphores
• Semaphores
 Conceptually, a semaphore is a bucket
 Semaphores are typically used for mutual exclusion, access control to shared resources,
and for basic synchronization
 When a semaphore is allocated, a bucket that contains a fixed number of keys is created
 Processes using semaphores must first procure a key from the bucket before they can
continue to execute
 If a specific process requires a key, only a fixed number of occurrences of that process
can be in progress simultaneously
 Semaphore is a built-in class that provides the following methods:
 Create a semaphore with a specified number of keys: new()
 Obtain one or more keys from the bucket: get()
 Return one or more keys into the bucket: put()
 Try to obtain one or more keys without blocking: try_get()
 Semaphores can be used in a testbench when you have a resource, such as a bus, that
may have multiple requestors from inside the testbench but as a part of a physical
design, can only have one driver

semaphore smTx;

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 16


Interprocess Communication: Mailboxes
How do you pass information between two threads?
• Mailboxes
 A mailbox is a communication mechanism that allows
messages to be exchanged between processes. Data
can be sent to a mailbox by one process and retrieved by
another
 From a hardware point of view a mailbox is nothing but a
FIFO with a source and a sink
 The source puts the data into the mailbox and the sink 4
3
2
1
source
gets values from the mailbox
 Mailboxes can have a maximum size or can be unlimited Full!!!
 Mailboxes are created either having a bounded or mailbox
unbounded queue size
 A bounded mailbox becomes full when it contains the
bounded number of messages
 A process that attempts to place a message in into a full
mailbox shall be suspended until enough room
becomes available in the mailbox queue sink
 If a sink tries to retrieve data from a mailbox that is
empty it blocks it until data is put in the mailbox

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 17


Interprocess Communication: Mailboxes

• Mailboxes
 Mailbox is an inbuilt class that provides the following methods:
 Creae a mailbox: new()
 Place a message in a mailbox: put()
 Try to place a message in a mailbox without blocking: try_put()
 Retrieve a message from a mailbox: get() or peek()
 Try to retrieve a message from a mailbox without blocking: try_get() or
try_peek()
 Retrieve the number of messages in the mailbox: num()

mailbox mbxRcv;

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 18


Interprocess Communication: Mailboxes
• Mailbox in a testbench
 How do you pass information between two threads?
 The generator creates many transactions and passes them to a driver
 The generator and driver must operate asynchronously

program mailbox_example (bus_if.TB bus,…);

class Generator Class Generator


Transaction tr; Instantiate class Transaction
mailbox mbx; Create unbounded mailbox

function new(mailbox mbx);


this.mbx=mbx;
endfunction

task run;
repeat (10) begin
tr=new; Create 10 transactions
assert(tr.randomize);
Send out the transaction
mbx.put(tr);
end
endtask
endclass cont…
Example: Exchanging objects using a mailbox: the Generator class
©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 19
Interprocess Communication: Mailboxes
• Mailbox in a testbench

class Driver
Transaction tr;
mailbox mbx;

function new(mailbox mbx);


this.mbx=mbx;
endfunction

task run;
repeat (10) begin
mbx.get(tr); Fetch next transaction
@(posedge busif.cb.ack)

end
endtask
endclass cont…

Example: Example of using a mailbox in a testbench

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 20


Interprocess Communication: Mailboxes
• Mailbox in a testbench

Mailbox containing gen and drv


mailbox mbx;
Generator gen;
Driver drv;
initial begin 4
3
2
1
generator
mbx=new;
gen=new(mbx);
drv=new(mbx);
fork mbx
gen.run(); Spawn the generator
drv.run(); Spawn the driver
join
end
endprogram driver

Example: Example of using a mailbox in a testbench, continued

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 21


Interprocess Communication: Mailboxes
• Bounded Mailboxes

program automatic bounded;


mailbox mbx;
initial begin
mbx = new(1); Size of mailbox is 1
fork
for (int i=1; i<4; i++) begin Producer
$display("@%0d: Producer: putting %0d", $time, i);
mbx.put(i);
$display("@%0d: Producer: put(%0d) done %0d",$time, i);
end
repeat(3) begin
Consumer
int j;
#1ns mbx.get(j);
$display("@%0d: Consumer: got %0d", $time, j);
end
join_any
end
endprogram

Example: Bounded mailbox

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 22


Interprocess Communication: Mailboxes
• Bounded Mailboxes
program automatic bounded;
mailbox mbx;
initial begin
mbx = new(1);
fork
for (int i=1; i<4; i++) begin Producer
$display("@%0d: Producer: putting %0d", $time, i);
mbx.put(i);
$display("@%0d: Producer: put(%0d) done %0d",$time, i);
end
repeat(3) begin Consumer Producer runs ahead
int j;
#1ns mbx.get(j);
of consumer!!!
$display("@%0d: Consumer: got %0d", $time, j);
end
join_any
end
endprogram
Example: Bounded mailbox

@0 Producer: putting 1 @1 Consumer: got(1)


@0 Producer: put(1) done @2 Consumer: got(2)
@0 Producer: putting 2
@1 Producer: 3 2 done
put(2) 1
@1 Producer: putting 3
Mailbox

@2 Producer: put(3) done


Producer Consumer
©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 23
Interprocess Communication: Mailboxes
• Unsynchronized threads communicating with the testbench

Construct mailbox mailbox mbx;


program automatic unsynchronized;
class Producer; Instantiate Producer Producer p;
Instantiate Consumer Consumer c;
task run;
for(int i=1; i<4; i++) begin
intial begin
$display(“Producer: before
mbx=new;p=new;c=new;
put(%0d)”,i);
Put integer in mailbox fork
mbx.put(i);
Run producer and p.run;
end
consumer in parallel c.run;
endtask
join
endclass
end
class Consumer;
endprogram
task run;
int i;
repeat(3) begin Example: Producer-consumer
mbx.get(i); Get integer from mailbox without synchronization, continued
$display(“Consumer: after
get(%0d)”,i);
end
endtask
endclass
cont…
Example: Producer-consumer without synchronization

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 24


Interprocess Communication: Mailboxes
• Unsynchronized threads communicating with the testbench
program automatic unsynchronized;
class Producer;
task run; Producer
for(int i=1; i<4; i++) begin
$display(“Producer: before
Producer: before put(1)
put(%0d)”,i);
mbx.put(i);
3
end Producer: 2
before put(2)
endtask
endclass Producer: 1
before put(3)
class Consumer; There is no synchronization
task run;
int i; so the producer puts all
repeat(3) begin three integers into the
mbx.get(i);

Mailbox
$display(“Consumer: after
mailbox before the
get(%0d)”,i); consumer can get the first
end one. This is because the
endtask
endclass thread continues running
mailbox mbx; until there is a blocking
Producer p;
Consumer c;
statement and the Producer
intial begin has none
mbx=new;p=new;c=new; Consumer: after get(1)
fork
p.run; Consumer: after get(2)
c.run;
join Consumer: after get(3)
end
endprogram Consumer
Example: Producer-consumer without synchronization

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 25


Interprocess Communication: Mailboxes
• Synchronized threads using a mailbox and events
 An additional handshake is required if the producer and the consumer are to be run in
lock-step
The two threads should use a handshake so
program automatic mbx_evt; that the Producer does not get ahead of the
event handshake;
class Producer; Consumer. This is done by blocking the
task run; Producer on the handshake event (the
for(int i=1; i<4; i++) begin consumer already blocks on the mailbox)
$display(“Producer: before put(%0d)”,i);
mbx.put(i);
@handshake; Producer blocks on the handshake event to
$display(“Producer: after put(%0d)”,i); ensure that the producer stops after sending
end the transaction
endtask
endclass
class Consumer;
task run;
int i;
repeat(3) begin
mbx.get(i);
$display(“Consumer: after get(%0d)”,i);
-> handshake; Consumer triggers the handshake event to
end allow the Producer to advance
endtask
endclass

endprogram
Example: Producer-consumer synchronized with an event
©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 26
Interprocess Communication: Mailboxes
• Synchronized threads using a mailbox and events

Producer
program automatic mbx_evt;
Producer: before put(1)
event handshake;
class Producer;
Producer: 3
after put(1)
Producer: before put(2)
task run; Producer: 2
after put(2)
for(int i=1; i<4; i++) begin Producer: before put(3)
$display(“Producer: before put(%0d)”,i); Producer: 1
after put(3)
mbx.put(i);
@handshake;
$display(“Producer: after put(%0d)”,i);
end

Mailbox
endtask
endclass
class Consumer;
task run;
int i;
repeat(3) begin
mbx.get(i);
$display(“Consumer: after get(%0d)”,i);
-> handshake; Consumer: after get(1)
end
endtask Consumer: after get(2)
endclass
… Consumer: after get(3)
endprogram
Example: Producer-consumer synchronized with an event Consumer

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 27


Building a Testbench with Threads and IPC

Testbench

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 28


Building a Testbench with Threads and IPC
• Basic Tansactor

class Agent;
mailbox gen2agt, agt2drv; Create mailboxes to send transactions
from generator to agent, agent to driver
Transaction tr;
function new(mailbox gen2agt, agt2drv);
this.gen2agt = gen2agt;
this.agt2drv = agt2drv;
endfunction
function build;
// Empty for now
endfunction
task run;
forever begin
Get transaction from upstream block
gen2agt.get(tr);
//Do some processing
Send transaction to downstream block
agt2drv.put(tr);
end
endtask
task wrapup;
// Empty for now
endtask
endclass

Example: Basic Transactor for Agent that sits between Generator and Driver

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 29


Building a Testbench with Threads and IPC
• Environment Class
 The Generator, Agent, Monitor, Checker and function void Environment::gen_cfg;
Scoreboard classes are instantiated in the assert(cfg.randomize);
endfunction
Environment class function void Environment::build;
Instantiate Generator, gen.build;
class Environment;
Agent, Monitor, Checker agt.build;
Generator gen;
Agent agt; and Scoreboard classes drv.build;
Driver drv; mon.build;
Monitor mon; chk.build;
Create mailboxes to send scb.build;
Checker chk;
transactions from endfunction
Scoreboard scb;
Config cfg; generator to agent, agent task Environment::run;
mailbox gen2agt, agt2drv, mon2chk; to driver and monitor to fork
gen.run(run_for_n_trans);
extern function new; checker
extern function void gen_cfg; agt.run;
extern function void build; Run Generator, agent, drv.run;
extern task run; driver, monitor and mon.run;
extern task wrapup; chk.run;
checker in parallel scb.run(run_for_n_trans);
endclass
join
function Environment::new; endtask
gen2agt = new; task Environment::wrapup;
agt2drv = new; Initialize mailboxes fork
mon2chk = new; gen.wrapup;
gen = new(gen2agt); agt.wrapup;
agt = new(gen2agt, agt2drv); drv.wrapup;
Initialize transactors mon.wrapup;
drv = new(agt2drv);
mon = new(mon2chk); chk.wrapup;
chk = new(mon2chk); scb.wrapup;
scb = new; join
cfg = new; endtask
endfunction
Example: Environment Class Example: Environment Class, continued

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 30


Building a Testbench with Threads and IPC
• Test Program
 The main test goes in the top level program

program automatic test;


Environment env;
initial begin
env = new;
env.gen_cfg;
env.build;
env.run;
env.wrapup;
end
endprogram
Example: Basic Test Program

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 31


Building a Testbench with Threads and IPC
• Conclusion
 Model your testbench to generate multiple stimulus streams and check the
responses using parallel threads
 Organize your testbench in a layered fashion and orchestrate it by the top-level
environment

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 32


Thank You

©2008, Dr. Meeta Yadav, www4.ncsu.edu/~myadav/Research 33

You might also like