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 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.
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;
initialbegin #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.
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