在 Icarus Verilog 中调试组合逻辑循环

Posted

技术标签:

【中文标题】在 Icarus Verilog 中调试组合逻辑循环【英文标题】:Debugging combinational logic loops in Icarus Verilog 【发布时间】:2012-05-10 06:18:46 【问题描述】:

我正在使用 Icarus verilog 来模拟一个相当复杂的设计。我发现在极少数情况下,我的模拟会“卡住”,即时钟不再滴答作响,并且没有任何信号似乎发生变化。我怀疑这是因为我的设计中有一个组合逻辑循环。当然,问题是我不知道在哪里。

有没有系统的方法调试这个?我只是非常努力地盯着代码,但我无法取得任何进展。非常感谢任何关于我可以尝试的事情的建议。

【问题讨论】:

原因是Verilog没有提供任何组合延迟默认,你必须明确写#5 a = b;描述传播不需要瞬时时间。 【参考方案1】:

运行模拟时,转储 VCD 文件。如果您有一个无限循环,您将看到 VCD 文件大小继续增长而没有新的时间被写入文件。时间由行首的# 表示。您无需时间提前就能确定哪些信号正在发生变化。

【讨论】:

除了在商业模拟器中使用 step 函数之外,很高兴知道这项技术。【参考方案2】:

所以事实证明,Icarus Verilog 有一个编译标志“-pfileline=1”用于这个特定的。打开此标志运行 vvp 会打印出大量有关正在执行的确切内容的调试信息。

【讨论】:

【参考方案3】:

IMO,大多数情况下无限循环发生在时钟生成上。特别是如果您将它们设置为生成可变频率。例如,如果您的时钟设置如下:

`timescale 1ns / 1ns
 real period;
 reg clk;

 initial begin
     period = 5.0;
     clk = 1'b0;
     forever begin
         #(period/2) clk = !clk;
     end
end

如果您更改了period,那么如果您不小心将period 更改为0.0,就会发生无限循环。

更棘手的是,有时period / 2 可能会超出您的时间刻度精度。比如你设置period = 1.0,那么period / 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,输入命令以询问模拟器它在哪里(不幸的是,模拟器特定于模拟器,但在 Incisive 中它是 where 我认为),然后恢复模拟。这样做几次,您就会知道代码占用了模拟器的所有时间。

【讨论】:

以上是关于在 Icarus Verilog 中调试组合逻辑循环的主要内容,如果未能解决你的问题,请参考以下文章

Icarus Verilog和GTKwave使用简析

如何在icarus verilog中包含文件?

如果有条件,icarus verilog 指定不遵守延迟

icarus verilog 中的多维数组端口支持

Icarus Verilog:多位数组解析错误

Icarus Verilog 模拟:范围索引表达式不是常数:i