Definitions of the regions from IEEE Std 1800-2012:
4.4.2.2 Active events region
The Active region holds the current active region set events being evaluated and can be processed in any order.
4.4.2.3 Inactive events region
The Inactive region holds the events to be evaluated after all the Active events are processed.
If events are being executed in the active region set, an explicit#0
delay control requires the process to be suspended and an event to be scheduled into the Inactive region of the current time slot so that the process can be resumed in the next Inactive to Active iteration.
...
4.4.2.9 Postponed events region
$monitor
,$strobe
, and other similar events are scheduled in the Postponed region. No new value changes are allowed to happen in the current time slot once the Postponed region is reached.
Within this region, it is illegal to write values to any net or variable or to schedule an event in any previous region within the current time slot.
Diagram see a diagram of scheduler on Figure 4-1—Event regions
You are correct in your understanding that the #0
puts the x = 5;
into the inactive region. However, this #0
also blocks the x = 3;
from executing in the first time entering in the active region. It is executed in the second pass to the active region rigged by the Inactive region. This is because blocking statements are always always sequential. $monitor()
is always displayed at the end to the time step, after all other regions have completed, hence you will only get the final value if x
.
By placing the statements inside of a fork-join, then the two statements will execute in parallel. This will allow the x = 3;
to execute the first time the active region is entered.
module main;
int x;
initial begin
$monitor("From $monitor: x is %0d",x);
#0 x = 5; // inactive event
x = 3; // active event (after inactive event)
#1; // go to next time stamp
fork
#0 x = 7; // inactive event
x = 11; // active event
join
end
// reactive event, x value from the observed region
always @* $display("From @* $display: x is %0d",x);
endmodule
Outputs:
From @* $display: x is 3
From $monitor: x is 3
From @* $display: x is 11
From @* $display: x is 7
From $monitor: x is 7