Need help in understanding scheduling scemantics

Hello Everyone,
Can someone explain how update/evaluation event are added to event queue for following example?


module m1;
reg r1;
initial begin
r1 = 1'b1;
#5 r1 = 1'b0;
end
always@(r1) $display("Printing r1: %d",r1);
endmodule

Thanks in advance,
Naven

In reply to Naven8:

r1 starts out with its default value (x). At time 0 there are two things that happen – the always becomes senstivie to r1 and r1 changes state to 1’b1. If the “always” reaches the @(r1) event control first then the always will trigger when r1 changes at time 0. If the “initial” occurs first, the always will not trigger at time 0 since the update event occurs prior to the always becoming sensitive to the event.

At the end of time 0 the always will be blocked on the event control and r1 will have the value 1. So at time 5, the update to r1 occurs and causes the always to trigger.

The upshot is that you will get either a time 0 and a time 5 output from the always or just a time 5 output. Either result is legal.

In reply to GVreugdenhil:

Thanks GVreugdenhil,
I was trying to understand on how simulator puts event to event queue. Could you please let me know whether below sequence is proper or not?

  1. before starting simulation all variable are initialized with default values (ie: r1 = x)
  2. because of initial block simulator puts “evaluation event” in active region.
  3. While scheduling active region event(related to initial block) the procedural code(r1 = 1’b1) add a new “evaluation event” to active region.
  4. Then the delay cause process to suspend
  5. While scheduling the events in current timeslot r1=1’b1 causes “update event” to be added to active region.

In reply to Naven8:

Can someone help me with this?

In reply to Naven8:

It would help to know why you are asking this level of question. The LRM talks about things using a conceptual model that breaks things down into very small sub-steps. That is important only in the sense that it can be used to explain why simulation implementations differ. In reality, no implementation would do exactly what the LRM says; various aspects of the theoretical model are always “merged” into more efficient operations in the simulation kernels.

Here’s another way to think of it:

  1. At time 0, prior to the execution of any events, r1 has its default initial value; 1’b1. Had you written reg r1 = 1’b1; its initial value would have been 1’b1.
  2. All initial and always processes in the entire design are added to the active event queue. Processes implied by continuous assignments are also added to the queue. The order they are placed in the queue is indeterminate. You should never write any code that depends on any observed ordering. Also, the execution of individual statements within a process with respect to the event queue is not defined by the LRM. The LRM does guarantee ordering of statements within a begin/end block within one process, but the relative ordering of statements inbetween multiple processes is not determinate.
  3. Execution of the active queue continues until the active queue is empty. As has been stated, either the initial or always block may be picked to execute first. Lets start assuming the initial block first.
  4. The statement attached to the initial block is a begin/end block. This means execute each statement inside the block serially.
  5. The first statement of the begin end block is an assignment r1 = 1’b1. The assignment creates an update event for any processed sensitive to this update event that will be added to the end of the active queue. If nothing is sensitive to the update, nothing gets scheduled.
  6. The next statement has an delay control #5. This suspends the current process for 5 time units. The next assignment statement will be put on the inactive queue for 5 time unites later.
  7. The next event on the active queue is the always block. As mentioned before, there is no reason that this statement could not have started earlier. When simulators go through their optimizations, there is no way to predict the ordering between processes.
  8. The first statement in the always block has an event control @r1; wait for a change on r1. Since we assumed the initial block started first, the update to r1 has already happened, and this process will suspend waiting for another r1 event.
  9. The active event queue is now empty and all other queues in the current time slot are empty, so the simulator will advance time to the next scheduled time, 5 time units.
  10. The initial block process will be put on the active queue and resume executing.
  11. The next statement is an assignment which generate an update event to r1, and the always block process is put back on the active queue.
  12. There are no more statements in the initial block, so that process is terminated.
  13. The always block resumes, executing the $display statement.
  14. The are no more statements in the always block, so it goes back to the beginning of the block.
  15. The first statement in the always block has an event control @r1; wait for a change on r1. This process will suspend waiting for another r1 event.
  16. The active event queue is now empty and all other queues in the current time slot are empty, so the simulator will advance time to the next scheduled time, which does not exist, so the simulation terminates.

In reply to dave_59:

Thanks Dave for spending so much of time in writing this.