What is the difference between the following two examples with regards to simulation?
A)
reg a;
initial a = 1'b0;
and
B)
reg a = 1'b0;
Is it different for logic variables?
What is the difference between the following two examples with regards to simulation?
A)
reg a;
initial a = 1'b0;
and
B)
reg a = 1'b0;
Is it different for logic variables?
The difference is initialization as part of a variable declarations execute before any process started by any initial
or always
constructs. If you wrote:
bit clk;
initial clk = 1;
always #5 clk++;
always @(posedge clk) ...;
There is a race condition as to whether the @(posedge clk)
gets triggered at time 0 or time 10.
However with:
bit clk = 1;
always #5 clk++;
always @(posedge clk) ...;
There is no race with the above. The first posedge will come at 10 time units.
There is an important distinction: You have tagged your question "verilog" and "system-verilog". Which do you mean? The answer depends on which you mean because the behaviour is different in both.
In verilog:
Both
reg a;
initial a = 1'b0;
and
reg a = 1'b0;
will behave the same way. In both cases, a
will be initialised at time 0, ie at run time. This can lead to simulation races and non-deterministic behaviour. For example:
reg a;
initial a = 1'b1;
initial $display(a);
might display 0
or might display 1
- there is a race between the initial blocks. And exactly the same thing will happen with this code:
reg a = 1'b1;
initial $display(a);
In system-verilog:
reg a;
initial a = 1'b0;
and
reg a = 1'b0;
will behave differently. In the first case, a
will be initialised at time 0, ie at run time which again can lead to simulation races and non-deterministic behaviour. However, there is no such problem with this code:
reg a = 1'b1;
initial $display(a);
In this case, a
will be initialised at compile time and therefore there is no race and therefore 1
will always be displayed.
The end result is the same, i.e., there won't be any difference from the end user perspective. The difference is that in the first case you are assigning the value during run time, and in the second case you are assigning the value during compile time.
Variable initialization is done before any other procedural block execution.
As per system Verilog LRM 1800-2012, Topic 6.8
A variable can be declared with an initializer, for example:
int i = 0;
Setting the initial value of a static variable as part of the variable declaration (including static class members) shall occur before any initial or always procedures are started (also see 6.21 and 10.5 on variable initialization with static and automatic lifetimes).
On similar note :
int val = 0 ;
int val1 = val + 10 ;
will produce a consistent result as the result is fixed at compile time , where as
initial val = 0 ;
initial val1 = val + 10;
will produce a inconsistent result [ as the ordering of assignment happens at run time and is simulator dependent ]