0
\$\begingroup\$

Can anybody please explain why that's the order of the outputs for each case?

1.

event e1, e2 ;
 initial begin
 fork
 begin : WAITER_1
 $display ( "%m waiting event e1" ) ;
 @ e1
 $display ( "%m received event e1" ) ;
 end : WAITER_1
 begin : EMITTER_1
 $display ( "%m emitting event e1" ) ;
 -> e1 ;
 end : EMITTER_1
 
 begin : EMITTER_2
 $display ( "%m emitting event e2" ) ;
 -> e2 ;
 end : EMITTER_2
 begin : WAITER_2
 $display ( "%m waiting event e2" ) ;
 @ e2
 $display ( "%m received event e2" ) ;
 end : WAITER_2
 join_none
 #10ns;
 disable fork;

output:

event_m.WAITER_1 waiting event e1

event_m.EMITTER_1 emitting event e1

event_m.EMITTER_2 emitting event e2

event_m.WAITER_2 waiting event e2

event_m.WAITER_1 received event e1

2.

event e1, e2 ;
 initial begin
 fork
 
 begin : WAITER_1
 $display ( "%m waiting event e1" ) ;
 @ e1
 $display ( "%m received event e1" ) ;
 end : WAITER_1
 
 begin : EMITTER_1
 $display ( "%m emitting event e1" ) ;
 ->> e1 ;
 end : EMITTER_1
 
 begin : EMITTER_2
 $display ( "%m emitting event e2" ) ;
 ->> e2 ;
 end : EMITTER_2
 
 begin : WAITER_2
 $display ( "%m waiting event e2" ) ;
 @ e2
 $display ( "%m received event e2" ) ;
 end : WAITER_2
 join_none
 #10ns;
 disable fork;

output:

event_m.WAITER_1 waiting event e1

event_m.EMITTER_1 emitting event e1

event_m.EMITTER_2 emitting event e2

event_m.WAITER_2 waiting event e2

event_m.WAITER_1 received event e1

event_m.WAITER_2 received event e2

3.

event e1, e2 ;
 initial begin
 fork
 
 begin : WAITER_1
 $display ( "%m waiting event e1" ) ;
 wait(e1.triggered);
 $display ( "%m received event e1" ) ;
 end : WAITER_1
 
 begin : EMITTER_1
 $display ( "%m emitting event e1" ) ;
 ->> e1 ;
 end : EMITTER_1
 
 begin : EMITTER_2
 $display ( "%m emitting event e2" ) ;
 ->> e2 ;
 end : EMITTER_2
 
 begin : WAITER_2
 $display ( "%m waiting event e2" ) ;
 wait(e2.triggered);
 $display ( "%m received event e2" ) ;
 end : WAITER_2
 join_none
 #10ns;
 disable fork;

output:

event_m.WAITER_1 waiting event e1

event_m.EMITTER_1 emitting event e1

event_m.EMITTER_2 emitting event e2

event_m.WAITER_2 waiting event e2

event_m.WAITER_1 received event e1

event_m.WAITER_2 received event e2

Thanks!!!

asked Sep 13, 2021 at 20:55
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

A fork construct executes all included statements in an indeterminate order. Each tool might pick the order they appear in the source, or the reverse. But you cannot depend on the ordering.

Using events in SystemVerilog requires careful knowledge of simulation execution semantics. I usually recommend avoiding them if possible.

An event trigger ->e is an instantaneous event. The event control @e has to execute and block the current process before the trigger occurs in another process, and the block process resumes. Many times there are race conditions between the two processes and the trigger executes before the event control, and the event is missed, and the event control has to wait for another trigger.

The wait(e.triggered) statement says wait for the condition that event e has been triggered in the current time slot. Now you no longer have to worry which came first, the trigger or the wait statement. But you still have to execute the wait statement in the current time slot to catch the event.

Better options include using a mailbox or semaphore, as well as other options, depending on what you are trying to accomplish.

Your case 1) shows just one of many possible results—it is race condition.

Case 2) avoids the race by scheduling the event triggers in the non-blocking assignment region, so all the triggers are guaranteed to happen after execute the event control.

Case 3) also avoids the race condition because your triggers al happen in the same time slot as the wait statement.

answered Sep 13, 2021 at 21:59
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.