#0 statements

as per my understanding #0 statements will executing in in-active region of event queue And $display will executing in active region.
Now come to the below code, first the #0 statement is completed in “in-active region” after that $display.

module main();
  bit a;
initial
begin
      #0 a = 1'b1;
         $display("a = %b",a);
  end
endmodule

how the display is recorded the “a” value because of display will completed in active region?

In reply to anvesh dangeti:

Within a begin/end block, each statement executes in serial order, regardless of any region.

Nothing executes in the inactive region. What happens is the #0 executes as part of the active region, and that suspends the initial block process by placing it on the inactive queue. Once the current active queue of events is empty, the inactive queue becomes the active queue and execution of those events continue.

I got you are point. But as per initial block all statements will execute in serial order.
i.e. first #0 statement will complete in “in-active region”. Next the display will execute in active region. But active region doesn’t having updated "a’ values than how display will recorded that updated “a” value.

like non-blocking assignments evaluation is done in active region and assignment will done in NBA region of event queue. That’s why display only will record what are the values is there in active region.it will not record the NBA region values.

In reply to anvesh dangeti:

In a blocking assignment statement, the statement is not complete until updating the LHS. When the next statement executes, “a” has been updated. The #0 or any other delay is irrelevant.

Hello Dave, I need a bit more explanation in this scenario like the lines in between begin and end execute in sequential and always in stratfied event queue the active region excute first then inactive and NBA if any thing in NBA or inactive triggers active it goes back to active region. Now in this case at first we seeing #0 a=1 , then it’s line excutes in inactive after completion of active region. But u mentioning it’s done in sequential like even it’s in inactive region. Due to blocking assignment the updation and evaluation has to be done at first line itself and then it moved to $display statement but how inactive excutes first without completing active region. And in case blocking assignments evaluation and updation both done at inactive region itself without need of active region

And I have a code relevant to this

module tb;
 logic a;
 initial a=0;
 initial #0  a=1;
endmodule

in this code we are get a=1 as output as second initial block runs after completion of active

I’m having trouble understanding your question. In your example code, both initial blocks begin executing in the active region, and it is indeterminate which one starts executing first. However, this doesn’t really matter in this context. And as I said above procedural statements only execute in the active region.

When the first initial block starts, it has one statement that executes in the active region, and then its process terminates. The second initial block starts executing and encounters a #0 delay, which suspends its process to the inactive region. Regardless of the ordering by the time we get to this point, there’s nothing left to do in the active region; it is an empty region.

Now, we move the inactive region events into the active region. There’s only one event in this region: the resumption of the second initial block.

Hello Dave, Pardon me for not conveying well in previous message. Here below I am sharing you two codes with outputs. Can you pls fill me what’s happening with them.

module tb;
logic a;

initial begin
#0  a=1;
a = 0;
#1;
$display(a);

end

endmodule.

Output: 0

module tb;

 logic a;

 initial begin

   a=0;

   #1;

   $display(a);

 end

initial begin

   #0  a=1;

 end

endmodule

Output : 1

In your first example, there’s only one process, and the delay values don’t matter. The statements between begin and end execute sequentially. The final value assigned to a is 0, which is what gets displayed.

In your second example, there are two processes. One process assigns 0 to a in the active region and then suspends itself for one time unit. The other process immediately suspends itself to the inactive region. Regardless of the process ordering, both processes are now suspended, and the inactive region becomes active. Therefore, the #0 resumes and assigns 1 to a. This process is terminated. Now, the active region is empty, and there’s nothing in the inactive region, so the simulation can proceed to the next time unit. The remaining process resumes and displays the value of a, which is now 1.

If that doesn’t answer your question it would be helpful if you could explain how the outputs differ from what you expected and the reasons behind them. That way we can correct any mistakes your reasoning if needed.

Thanks for your Explanation Dave, I got clarified

Hello Dave , Can you pls explain what happening with eah of these codes.

module tb;

logic a, b;
initial begin
a=0;
#0 $display(a,b);
end
always@(a)
b=a;
endmodule

output : 00

module tb;

logic a, b;
initial begin
a=0;

$display(a,b);
end
always@(a)
b=a;
endmodule

output : 0x

module tb;

logic a, b;
initial begin
#0 a=0;
#0 $display(a,b);
end
always@(a)
b=a;
endmodule

output : 00

module tb;

logic a, b;
initial begin
#0 a=0;
$display(a,b);
end
always@(a)
b=a;
endmodule

Output : 0,x

It would be helpful if you could explain the results you expected and the reasons why they differ from the actual results. This will allow us to address any potential misunderstandings you may have.

module tb;

logic a, b;
initial begin
a=0;
#0 $display(a,b);
end
always@(a)
b=a;
endmodule

output : 00

As you mentioned earlier all stmts between begin and end execute sequentially and delay values no matter . Then why display suspends to inactive region in above code. And why the same not happening in below code.

module tb;

logic a, b;
initial begin
#0 a=0;
$display(a,b);
end
always@(a)
b=a;
endmodule

Output : 0,x

I said since there’s only one process, the delays don’t matter. Statements executed sequentially between the begin and end of a process are only relevant to that process. However, once another process is introduced, the ordering of statements between those processes becomes indeterminate.

Both your latest examples illustrate race conditions.

In the first example, both the initial and always blocks begin in the active region. Your simulator chose to execute the always block first and then suspend it before the initial block made the assignment a=0. Subsequently, the #0 suspends the process, giving the always process an opportunity to execute the assignment b=a. However, if the initial block makes the assignment a=0 before the always block begins executing, it will miss the @(a) event and indefinitely wait for a to change, which never occurs.

In the second example, the order in which the initial and always blocks begin doesn’t matter. The initial block will suspend itself in the inactive region, while the always block suspends itself waiting for a change in the value of a. Then the initial block becomes active again and executes the assignment a=0. That means the always process can resume, but it’s a race to whether or not that process starts executing its assignment a=b before or after the$display executes.

You could make your life a lot easier by avoiding the #0 construct.