Event scheduling with blocking assignments

Hi
I have the following piece of code:


`timescale 1ns/1ps

module tb2;

	reg clk = 0;

	reg a=0;
	reg b=0;
	reg c=0;

	initial forever #5 clk = ~clk;

	always @ (posedge clk) begin
		$display("updating a");
		a <= ~a;
	end

	always @(*) begin
		$display("updating c");
		c = b;
		$display("updating b");
		b = a;
	end
	
endmodule

After I simulate this, I get the following output wave:

Here is the transcript output:

updating a

updating c

updating b

updating a

updating c

updating b

Apparently, each time ‘a’ is inverted, the always block is evaluated once, which entails assigning the old value of ‘b’ to ‘c’, and then then the new value of ‘a’ to ‘b’. What makes me wonder is that, after ‘b’ is updated with the new value of ‘a’, shouldn’t the always block be evaluated one more time, causing the new value of ‘b’ to be assigned to ‘c’? I guess this would happen if the assignments were non-blocking. Why isn’t it the same with blocking assignments?

In reply to Farhad:

It won’t trigger since the 2nd always block hasn’t completed execution i.e it isn’t waiting via @(*) for any of the i/p signals ( b / a ) to change for it to trigger .

As you are using a blocking assignment the value gets assigned to LHS before executing the next statement .
Unlike Non - blocking assignment which doesn’t block execution and where the LHS update occurs later in NBA Region

Only after both the blocking assignments are made will the 2nd always block and wait for any of the i/p signals ( b / a ) to change again .

In reply to ABD_91:

Thank you for your answer, ABD_91
I don’t quite understand, why is it that “the 2nd always block hasn’t completed execution”? I mean, the last statement in the second always block is ‘b=a’. After this last statement is executed, can’t we say that both blocking assignments are actually made? Then what keeps the the always block from waiting for ‘a’ or ‘b’ to change again?

In reply to Farhad:

Your always @( * ) is an infinite loop that can unrolled as ::


 initial begin
 
   @( a , b ) ;             //  1st  event control  unblocks  due  to  1st  NBA  assignment  to  a 
   $display("updating c");
    c = b;
   $display("updating b");
    b = a;
    
 //  Above  4  statements  execute  in  the  order  they  appear  .
 //  These  complete  execution  and  the  RHS  value  is  assigned  to  LHS  prior  to  execution  of  below  statements

   @( a , b ) ;             //  2nd  event control  unblocks  due  to  2nd  NBA  assignment  to  a
   $display("updating c");
    c = b;
   $display("updating b");
    b = a;
   
    .....................
 end

Your 2nd @(a,b) is executed only after b = a ; completes execution .

By the time it blocks on @( a , b ) both the assignments are made .

So @( a , b ) won’t unblock due to the prior assignment to b .

In reply to ABD_91:

Thank you very much for sharing your wisdom, ABD_91. That was a subtle point.