6

我尝试转储一个数组(reg [31:0] data [31:0]),但我无法成功。我已经尝试过iverilog wiki中的方式:

integer idx;
for (idx = 0; idx < 32; idx = idx + 1)
    $dumpvars(0,cpu_tb.cpu0.cpu_dp.cpu_regs.data[idx]);

它有效,但发生了两件事。

  1. 出现警告:VCD 警告:数组字 cpu_tb.cpu0.cpu_dp.cpu_regs.data[0] 将与转义标识符冲突。
  2. 在 GTKWave 中,我在 SST 窗口中有类似的内容:\data[0][31:0]

有什么解决办法吗?

在此先感谢并为我的英语感到抱歉。

4

2 回答 2

6

我已经通过电子邮件发送了 Icarus Verilog 的邮件列表。以下是一些答案:

要转储一个数组字,Icarus 需要对名称进行转义,以便与 VCD 转储格式兼容。这就是 \data[0][31:0] 是什么。它是数据数组的第 0 个 32 位字。因为转义名称和数组名称现在可能发生冲突,所以 Icarus 会产生警告。如果它可以检查转义的标识符冲突并仅在出现问题时打印一条消息,那将是最好的,但我记得这是不可能的。

我们选择使用转义标识符,以便所有转储程序都可以处理数组单词。另一种常见的选择是仅使用仅适用于某些转储格式的特殊转储命令来支持它们。

我同意如果我们可以使警告更准确会很好,但我们通常忙于处理其他事情,所以看起来很难修复的小烦恼通常不会得到修复。我记得,并且已经有很多年了,问题是如果您搜索转义标识符,它会找到数组元素,并且 VPI 中无法搜索下一次出现。在 Icarus 的按名称搜索中查找数组元素可能是一个错误。

卡里


“要转储一个数组字,Icarus 需要对名称进行转义,以便它与 VCD 转储格式兼容。这就是 \data[0][31:0]。它是第零个?数据数组的 32 位字。因为转义名称和数组名称现在可能发生冲突,Icarus 会产生警告。最好它可以检查转义标识符冲突并仅在出现问题时打印一条消息,但我记得这是不可能的。

...我认为没有必要逃避这些名字。VCS(后跟 fsdb2vcd)和 CVC 都直接发出名称,没有任何问题。剪切和粘贴示例如下所示:

$var wire 5 `' IC_DrAd0 [3][4:0] $end $var wire 5 a' IC_DrAd0 [2][4:0] $end $var wire 5 b' IC_DrAd0 [1][4:0] $结束 $var 线 5 c' IC_DrAd0 [0][4:0] $end

我意识到 VCD 规范没有定义这一点,但多年来我不得不将许多此类扩展折叠到 gtkwave 中,因为其他工具会生成这些构造。尝试在iverilog 与VCS 上进行模拟时,转义可能导致保存文件不兼容(缺少信号)。

随着时间的推移,SV 结构可能会导致更多的东西被添加到 VCD 文件中。AFAIK,自 Verilog-XL 以来,1364 规范的 VCD 部分根本没有更新。CVC 通过添加 +dump_arrays plusarg 来解决可能的不兼容问题(不,您也不必在每个数组元素上循环)。

-托尼

我还给 GTKWave 的创建者 Tony Bybell 发了一封邮件:

你好,

问题是编译器没有将这些值发送到转储文件中。您必须与iverilog 开发人员取得联系。如果我运行 sim 并与打开了 +dump_arrays 的另一个模拟器(例如 CVC)进行比较,我会看到同样的问题,它确实会转储数组并且它们在 gtkwave 中可见。

http://iverilog.wikia.com/wiki/Release_Notes_Icarus_Verilog_0_9_2 | 允许 $dumpvars 接受数组成员进行转储,

...看起来在“初始”期间,您可能需要为要转储的每个数组元素添加一个 $dumpvars 语句。我不知道数组名称本身是否有效。将每个元素分配给“电线”也可能有效。

我从来没有在iverilog中尝试过这个功能,所以我不知道它是否有效。您可能需要进行试验或询问开发人员。

-托尼

于 2014-03-14T02:49:20.160 回答
1

我最近有一个类似的问题:

当像问题一样使用 for 循环转储 vars 时,会发生此 vcd 错误:

ERROR: $dumpvars cannot dump a vpiConstant.

我的解决方法是使用assign语句生成n条线,为其分配相应的数组字,如下所示:

reg     [31:0]  registers [31:0];
generate
  genvar idx;
  for(idx = 0; idx < 32; idx = idx+1) begin: register
    wire [31:0] tmp;
    assign tmp = registers[idx];
  end
endgenerate

现在在 GTKWave 中,我已经正确转储了生成块。

于 2020-11-08T12:38:12.170 回答