Always block modyfing variables that are on its sensitivity list

How does it work when always @(*) block itself modifies the variable that is on its sensitivity list?

I wrote a piece of code like below:

module tb();
  integer a;
  
  initial begin
    a = 1;
  end
  
  always @* begin
    a = a + 1;
    $display("a: %0d", a);
  end
endmodule

and the output was:

a: 2
DONE

And I’m wondering why the display appeared only one time. Shouldn’t it be executed infinitely cause the variable “a” changes itself?

Let’s say I have an event queue, with active and inactive regions.

  • At first the initial gets into active and all the statements inside initial are copied to inactive.
  • Next all those steps from inactive are copied to active and executed, which means “a” changes from x to 1.
  • This triggers the always block which is copied to inactive.
  • The always block is copied to active, evaluated, and all the statements inside are copied to inactive.
  • All steps from inactive are copied to active and executed, which means “a” changes from 1 to 2.
  • This triggers the always block which is copied to inactive… and so on. the loop is infinite.

Please say where exactly I made a mistake when analyzing this problem. Is there anything preventing the statements inside the always block from triggering the block itself again?

In reply to Aneta:

You are missing the fact that @(expr) is part of a procedural statement and means "wait for the expression to change. @(*) is a shortcut for “wait for any signal in block that follows to change”. It does not mean execute this block every time any signal changes.

See event @(posedge clk) | Verification Academy