在 systemverilog 中使用初始块与初始化 reg 变量有什么区别?

What is the difference between using an initial block vs initializing a reg variable in systemverilog?

下面两个例子在模拟方面有什么区别?

A)

reg a;
initial a = 1'b0;

B)

reg a = 1'b0;

逻辑变量有什么不同吗?

最终结果是一样的,即从最终用户的角度来看不会有任何区别。不同之处在于,在第一种情况下,您在 运行 期间分配值,而在第二种情况下,您在编译期间分配值。

区别在于初始化作为变量声明的一部分在任何 initialalways 构造启动的任何进程之前执行。如果您写道:

bit clk;
initial clk = 1;
always #5 clk++;
always @(posedge clk) ...;

关于 @(posedge clk) 是在时间 0 还是在时间 10 触发存在竞争条件。 然而:

bit clk = 1;
always #5 clk++;
always @(posedge clk) ...;

以上没有比赛。第一个 posedge 将在 10 个时间单位出现。

类似说明:

int val = 0 ; 
int val1 = val + 10 ; 

将产生一致的结果,因为结果在编译时是固定的,而

initial val = 0 ; 
initial val1 = val + 10; 

将产生不一致的结果[因为赋值顺序发生在 运行 时间并且取决于模拟器]

有一个重要区别:您已将问题标记为 "verilog" 和 "system-verilog"。你是什​​么意思?答案取决于您的意思,因为两者的行为不同。

在verilog中:

两者都

reg a;
initial a = 1'b0;

reg a = 1'b0;

将以相同的方式运行。在两种情况下,a将在时间0初始化,即在运行时间。这可能导致模拟竞赛和非确定性行为。例如:

reg a;
initial a = 1'b1;
initial $display(a);

可能显示 0 或可能显示 1 - 初始块之间存在竞争。 完全同样的事情会发生在这段代码中:

reg a = 1'b1;
initial $display(a);

在 system-verilog 中:

reg a;
initial a = 1'b0;

reg a = 1'b0;

行为会有所不同。在第一种情况下,a 将在时间 0 处初始化,即在 运行 时间 处初始化,这会再次导致模拟竞争和非确定性行为。但是这段代码就没有这个问题:

reg a = 1'b1;
initial $display(a);

在这种情况下,a 将在 编译时初始化 ,因此没有竞争,因此 1 将始终显示。

变量初始化在任何其他程序块执行之前完成。

根据系统 Verilog LRM 1800-2012,主题 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).