“Variables declared in a static task, function, or procedural block default to a static lifetime and a local scope. However, an explicit static keyword shall be required when an initialization value is specified as part of a static variable’s declaration to indicate the user’s intent of executing that initialization only once at the beginning of simulation.”
In Usage 1, the initialization is performed every time the begin-end block is entered. In Usage 2, the initialization is performed only once, at the beginning of simulation.
By chance, since this is an initial procedure, Usage 1 will be performed only once also, but in the general case, that might not be so.
There are other, more subtle potential differences. For example, in Usage 2, it is not guaranteed in principle that the initialization of obj_2 will be performed after that of obj_1. In Usage 1, it is.
Your confusion with this is main reason the LRM requires an error message.
Static vs. automatic declaration is manly a difference in a variable’s lifetime, but also affects its initialization. Static variables initialize before time 0, and automatic variable initialize at the time when the block is procedurally activated.
In most programming languages, variables declared inside of procedural blocks are automatic by default, but in Verilog, the default is static. SystemVerilog was able to change the default for class methods to match C/C++, but could not do it for backward compatibility with legacy Verilog blocks.
Variable initialization was a relatively new feature in Verilog, but so many people missed the fact that when they declared a variable inside a procedural looping construct, the variable only got initialized once at time 0, not each iteration of the loop.
Hi Dave :
Then in usage one, let us see the block is not INITIAL procedure block, is
simple obj_1;
simple obj_2;
initialized once at time 0 or initialized every time the block is entered ?
In usage 1), the variables are still initialized to null before time 0. Then the procedural assignment statements execute when the begin block is entered.
Some more clarifications,
all static variables get initialized before time 0, that is, before any initial, always, assign, or anything else that might represent an independent thread of execution.
all automatic variables get initialized when procedural code enters the scope where the variable is declared.
All variables have a default initialization value that you can override with ‘= expression’ in its declaration.