6

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?

supernun
  • 437
  • 1
  • 6
  • 16

5 Answers5

9

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.

CliffordVienna
  • 7,995
  • 1
  • 37
  • 57
dave_59
  • 39,096
  • 3
  • 24
  • 63
  • 1
    Is this distinction simulator specific or should this be standard across all simulators? – supernun Jul 19 '16 at 19:44
  • 1
    LRM 1800-2012 section 6.8 says _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_ – dave_59 Jul 19 '16 at 21:56
  • 1
    I think this is correct for system-verilog, but not correct for verilog. I think your second example will still give you a race in verilog (ignoring the fact that bit is not a verilog type). – Matthew Taylor Jul 20 '16 at 16:05
  • The SystemVerilog behavior is backward compatible with the Verilog behavior. SV just defines an undefined order. Any simulator that supports both SV and Verilog will likely just use the SV ordering. – dave_59 Jul 20 '16 at 16:31
  • @dave_59: but the 'Verilog' behaviour is not forward-compatible with SV; a 'Verilog' simulator has a race, and the question was tagged with both. – EML Jan 21 '21 at 13:08
4

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.

Matthew Taylor
  • 13,365
  • 3
  • 17
  • 44
3

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.

AndresM
  • 1,293
  • 10
  • 19
  • Does it then have any effect on signals dependent on 'a'? For example, b = #1 a; – supernun Jul 18 '16 at 21:22
  • 4
    Parameters get their value at compile time. Variable initializations happen at time 0, which is run time. – dave_59 Jul 18 '16 at 21:25
  • 1
    I think this is correct for verilog, but not correct for system-verilog. – Matthew Taylor Jul 20 '16 at 16:06
  • As per @dave_59's [response](http://stackoverflow.com/questions/38445246/what-is-the-difference-between-using-an-initial-block-vs-initializing-a-reg-vari/38446236#38446236), the SystemVerilog behavior should be backward compatible with Verilog. – AndresM Aug 04 '16 at 00:42
2

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).

Karan Shah
  • 1,912
  • 1
  • 29
  • 42
-2

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 ]

Rahul Menon
  • 792
  • 7
  • 12
  • 2
    That is not correct either. The order of static variable initialization is not defined. This is what's know as the [static variable fiasco](https://isocpp.org/wiki/faq/ctors#static-init-order). – dave_59 Jul 19 '16 at 03:19