我正在使用 Icarus verilog 来模拟一个相当复杂的设计。我发现在极少数情况下,我的模拟会“卡住”,即时钟不再滴答作响,并且没有任何信号似乎发生变化。我怀疑这是因为我的设计中有一个组合逻辑循环。当然,问题是我不知道在哪里。
有没有系统的方法调试这个?我只是非常努力地盯着代码,但我无法取得任何进展。任何关于我可以尝试的事情的建议都非常感谢。
所以事实证明,Icarus Verilog 有一个特定的编译标志“-pfileline = 1”。打开此标志运行 vvp 会打印出大量有关正在执行的确切内容的调试信息。
运行模拟时,转储 VCD 文件。如果您有一个无限循环,您将看到 VCD 文件大小继续增长而没有新的时间被写入文件。时间#
在一行的开头用 表示。您将能够确定哪些信号正在发生变化,而无需时间提前。
IMO,大多数情况下无限循环发生在时钟生成上。特别是如果您将它们设置为生成可变频率。例如,如果您的时钟设置如下:
`timescale 1ns / 1ns
real period;
reg clk;
initial begin
period = 5.0;
clk = 1'b0;
forever begin
#(period/2) clk = !clk;
end
end
如果您更改,则如果您意外更改为 0.0,period
则可能会发生无限循环。period
更棘手的是,有时period / 2
可能会超出您的时间刻度精度。例如,如果您设置period = 1.0
, thenperiod / 2
为 0.5,并且由于您的时间精度为 1ns,这将捕捉到 0,从而导致无限循环。如果我怀疑这一点,我通常会在我进入延迟之前设置一个守卫时间(再次,小心精确......)。
...
half_period_ns = period_ns / 2.0;
if( half_period_ns == 0 )
half_period_ns = 1;
#(half_period_ns) clk = !clk;
...
另一件事是在交互模式下运行模拟并随机按 Ctrl-C,输入命令以询问模拟器它在哪里(不幸的是,模拟器特定于模拟器,但where
我认为在 Incisive 中它是),然后恢复模拟。这样做几次,您将能够了解代码占用了模拟器的所有时间。