Events in  System Verilog

Welcome to the System Verilog tutorial series! If you have any doubts / suggestions, please let us know!  Dear visitor, please Sign up / Login for Free and get privileged access! You can copy code, download free tutorials and do more when you’re logged in!

An identifier declared as an event data type is called a named event. Named event is a data type which has no storage. In verilog, a named event can be triggered explicitly using “->” . Verilog Named Event triggering occurrence can be recognized by using the event control “@” . Named events and event control give a powerful and efficient means of describing the communication between, and synchronization of,
two or more concurrently active processes.

SystemVerilog named events support the same basic operations as verilog named event, but enhance it in several ways.

Triggered:

The “triggered” event property evaluates to true if the given event has been triggered in the current time-step and false otherwise. If event_identifier is null, then the triggered event property evaluates to false. Using this mechanism, an event trigger shall unblock the waiting process whether the wait executes before or at the same simulation time as the trigger operation.

In the following example, event “e” is triggered at time 20,40,60,80 . So the Value of “e.triggered” should be TRUE at time 20,40,60,80 and FALSE at rest of the time.

EXAMPLE:

module main;
event e;
initial
repeat(4)
begin
#20;
->e ;
$display(" e is triggered at %t ",$time);
end
initial
#100 $finish;
always
begin
#10;
if(e.triggered)
$display(" e is TRUE at %t",$time);
else
$display(" e is FALSE at %t",$time);
end
endmodule

RESULT:
e is FALSE at 10
e is triggered at 20
e is TRUE at 20
e is FALSE at 30
e is triggered at 40
e is TRUE at 40
e is FALSE at 50
e is triggered at 60
e is TRUE at 60
e is FALSE at 70
e is triggered at 80
e is TRUE at 80
e is FALSE at 90

Wait():

In SystemVerilog , Named Event triggering occurrence can also be recognized by using the event control wait(). Wait() statement gets blocked until it evaluates to TRUE. As we have seen in the previous example, that “event_name.triggered” returns the trigging status of the event in the current time step.

EXAMPLE:

module event_m;
event a;
initial
repeat(4)
#20 -> a;
always
begin
@a;
$display(" ONE :: EVENT A is triggered ");
end
always
begin
wait(a.triggered);
$display(" TWO :: EVENT A is triggered ");
#1;
end
endmodule

RESULT:
ONE :: EVENT A is triggered
TWO :: EVENT A is triggered
ONE :: EVENT A is triggered
TWO :: EVENT A is triggered
ONE :: EVENT A is triggered
TWO :: EVENT A is triggered
ONE :: EVENT A is triggered
TWO :: EVENT A is triggered

Race Condition:

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.

Using event_name.triggered statement, an event trigger shall unblock the waiting process whether the wait executes before or at the same simulation time as the trigger operation. The triggered event property, thus, helps eliminate a common race condition that occurs when both the trigger and the wait (using @) happen at the same time. A process that blocks waiting for an event might or might not unblock, depending on the execution order of the waiting and triggering processes (race condition) .

However, a process that waits on the triggered state always unblocks, regardless of the order of execution of the wait and trigger operations.

In the following example, event “e1” is triggered and a process is waiting on “e1” in the same time step. The process can never catch the triggering of “e1” as it occurs after the event “e1” triggering. Event “e2” triggering occurrence can be recognized by wait (e2.triggered) in spite of the above condition.

EXAMPLE:

module main;
event e1,e2;
initial
repeat(4)
begin
#20;
->e1 ;
@(e1)
$display(" e1 is triggered at %t ",$time);
end
initial
repeat(4)
begin
#20;
->e2 ;
wait(e2.triggered);
$display(" e2 is triggered at %t ",$time);
end
endmodule

RESULT:
e2 is triggered at 20
e2 is triggered at 40
e2 is triggered at 60
e2 is triggered at 80

Nonblocking Event Trigger:

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

Merging Events:

An event variable can be assigned to another event variable. When a event variable is assigned to other , both the events point to same synchronization object. In the following example, Event “a” is assigned to event “b” and when event “a” is triggered, event occurrence can be seen on event “b” also.

EXAMPLE:

module events_ab;
event a,b;
initial begin
#1 -> b; // trigger both always blocks
-> a;
#10 b = a; // merge events
#20 -> a; // both will trigger , 3 trigger events but have 4 trigger responses.
end
always@(a) begin
$display(" EVENT A is triggered ");
#20;
end
always@(b) begin
$display(" EVENT B is triggered ");
#20;
end
endmodule

RESULTS:
EVENT B is triggered
EVENT A is triggered
EVENT B is triggered
EVENT A is triggered

When events are merged, the assignment only affects the execution of subsequent event control or wait operations. If a process is blocked waiting for event1 when another event is assigned to event1, the currently waiting process shall never unblock. In the following example, “always@(b)” is waiting for the event on “b” before the assignment “b = a” and this waiting always block was never unblocked.

EXAMPLE:

module events_ab;
event a,b;
initial
begin
#20 -> a;
b = a;
#20 -> a;
end
always@(a)
$display(" EVENT A is triggered ");
always@(b)
$display(" EVENT B is also triggered ");
endmodule

RESULTS:
EVENT A is triggered
EVENT A is triggered

Null Events:

SystemVerilog event variables can also be assigned a null object, when assigned null to event variable, the association between the synchronization object and the event variable is broken.

EXAMPLE:

program main;
event e;
initial
begin
repeat(4)
#($random()%10) -> e;
e = null;
repeat(4)
#($random()%10) -> e;
end
initial
forever
begin
@e ;
$display(" e is triggered at %t",$time);
end
endprogram

RESULT:
e is triggered at 348
e is triggered at 4967
e is triggered at 9934
e is triggered at 14901
** ERROR ** Accessed Null object

Wait Sequence:

The wait_order construct suspends the calling process until all of the specified events are triggered in the given order (left to right) or any of the un-triggered events are triggered out of order and thus causes the operation to fail. Wait_order() does not consider time, only ordering in considered.

EXAMPLE:

module main;
event e1,e2,e3;
initial
begin
#10;
-> e1;
-> e2;
-> e3;
#10;
-> e3;
-> e1;
-> e2;
#10;
-> e3;
-> e2;
-> e3;
end
always
begin
wait_order(e1,e2,e3)
$display(" Events are in order ");
else
$display(" Events are out of order ");
end
endmodule

RESULT:
Events are in order
Events are out of order
Events are out of order

Events Comparison:

Event variables can be compared against other event variables or the special value null. Only the following operators are allowed for comparing event variables:

  • — Equality (==) with another event or with null.
  • — Inequality (!=) with another event or with null.
  • — Case equality (===) with another event or with null (same semantics as ==).
  • — Case inequality (!==) with another event or with null (same semantics as !=).
  • — Test for a Boolean value that shall be 0 if the event is null and 1 otherwise.

EXAMPLE:

module main;
event e1,e2,e3,e4;
initial
begin
e1 = null;
e2 = e3;
if(e1)
$display(" e1 is not null ");
else
$display(" e1 is null ");
if(e2)
$display(" e2 is not null");
else
$display(" e2 is null");
if(e3 == e4)
$display( " e3 and e4 are same events ");
else
$display( " e3 and e4 are not same events ");
if(e3 == e2)
$display( " e3 and e2 are same events ");
else
$display( " e3 and e2 are not same events ");
end
endmodule

RESULT:
e1 is null
e2 is not null
e3 and e4 are not same events
e3 and e2 are same events