我已经制作了一个计数器模块,我似乎无法掌握计数器模块和testbench模块的初始块的执行顺序。
据我所知,我认为在Verilog中,初始块始终会首先执行。
在这种情况下,我将执行testbench模块,并假设initial
块
testbench_counter
将首先执行。
接下来,我认为计数器模块C
将被执行,并且x_in
的值将更新为temp
,而模块{{1}中的#1
则不需要延迟}。
但是没有C
,或者没有将#1
更改为initial
,我看到了redline。
所以问题是
在测试平台的always@(x_in)
块之前会先执行计数器模块initial
的{{1}}块吗?
如果我使用C
为什么会起作用?
谢谢。
柜台代码
initial
测试平台代码
always@(x_in)
答案 0 :(得分:2)
接下来,我认为计数器模块C将被执行...
您认为的主要缺陷是,当计数器被“执行”时,将执行计数器中的初始语句。不是这种情况。 所有初始语句在程序启动时运行,并且仅运行一次。因此,您的两个初始语句构成了竞争条件。
通过使用#1或always@(x_in)
,您可以将对temp1的分配延迟到定义x_in之后。
更好的做法是在您的计数器上添加一个“加载”信号,该信号会在激活时获取x_in的值。
您的y_out也要延迟另一个时钟周期。
通常,可加载的计数器如下所示:
always@(posedge clk)
begin
if (load)
y_out <= x_in;
else
y_out <= y_out + 1;
end
答案 1 :(得分:1)
回答您的问题1:在initial
块之间绝对有保证的执行顺序。 Verilog仿真以任意不可预测的顺序启动它们。同步的唯一方法是#delays和其他wait和delay语句。
Verilog保证任何过程性块(包括初始块和始终块)的执行将在等待条件下停止,直到满意为止。
Verilog还保证所有初始块在任何总是块之前开始。
在始终块敏感度列表中指定的任何信号都扮演“ delay”语句的作用,从而使always块一直等到任何信号值发生变化。之后它将继续执行该块。
因此,回答第二个问题时,always@(x_in)
将等到信号值改变。
所以,在您的情况下:
initial begin << will start execution at time '0' before any always block
clk=1'b0; << change value of clk from 'x' -> '1'
x_in=32'd0; << change value of x_in 'x' -> '0'
#0 << makes absolutely no sense here. It is a special statement
#10000 << pauses execution for 10000 time units
$stop; << stopps execution
end
在上面的初始块产生时,其他块开始执行。
initial begin << starts execution at time 0, befor or after the block above
#1 temp=x_in; << pauses for 1 time unit, then assigns temp
end
上面的分配发生在第一个初始块等待#10000时。
如果您使用always块
always @(x_in)
temp = x_in;
当x_in更改并且第一个初始块开始等待时,它将执行assignemt。当信号被建立时,该总是块将以相同的周期“ 0”执行。它与您使用的#1不同。根据您的情况,更改将在周期“ 1”发生。