Icarus Verilog转储内存数组($dumpvars)

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 warning: array word cpu_tb.cpu0.cpu_dp.cpu_regs.data[0] will conflict with an escaped identifier。
  2. 在GTKWave中,SST窗口里会显示类似于这样的内容:\data[0][31:0]

这个问题有解决方案吗?

提前感谢您的帮助,对我英语不好表示抱歉。

2个回答

6

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

为了转储数组元素,Icarus需要对名称进行转义,以便与VCD转储格式兼容。这就是\data [0] [31:0]的含义。它是数据数组的第零个32位元素。因为转义名称和数组名称可能会发生冲突,所以Icarus会产生警告。最好能够检查是否存在已转义标识符的冲突,并且仅在出现问题时打印消息,但据我所知,这是不可能的。
我们选择使用转义标识符,以使所有转储工具都能处理数组元素。另一种常见选择是仅使用特定的转储命令来支持它们,该命令仅适用于某些转储格式。
我同意如果我们能使警告更准确,那会很好,但我们通常忙于其他事情,因此不经常修复看起来很复杂的次要问题。据我所记得(已经过了多年),问题在于如果您搜索转义的标识符,则会找到数组元素,而在VPI中没有办法搜索下一个出现的元素。在Icarus搜索实现中找到数组元素可能是一个错误。
Cary
“为了转储数组元素,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] $end $var wire 5 c' IC_DrAd0 [0][4:0] $end
我知道VCD规范没有定义这一点,但多年来,我已经将许多这些扩展合并到gtkwave中,因为其他工具生成了这些构造。当尝试在iverilog与VCS上模拟时,这些转义可能会导致保存文件不兼容(缺少信号)。
随着时间的推移,SV结构可能会导致进一步添加到VCD文件中。据我所知,1364规范的VCD部分自Verilog-XL以来没有任何更新。 CVC通过添加+dump_arrays plusarg来解决可能的不兼容性问题(否则,您不必在每个数组元素上循环)。
-Tony

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

你好,

问题在于编译器没有将这些值发射到转储文件中。你需要联系iverilog的开发人员。如果我运行sim并与打开+dump_arrays的另一个模拟器(如CVC)进行比较,则会看到相同的问题,它确实转储了数组并且在gtkwave中可见。

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

......在“initial”时间期间,您可能需要为要转储的每个数组元素添加一个$dumpvars语句。我不知道仅使用数组名称是否有效。将每个元素分配给“wire”也可能有效。

我从未在iverilog中尝试过此功能,因此不知道它是否有效。您可能需要进行实验或询问开发人员。

-Tony


1
我最近遇到了一个类似的问题: 当像这个问题一样使用for循环来转储变量时,会出现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中,我已经正确地转储了生成块。

哇,真的成功了。我只需要将 reg 名称更改为 tmp 而不是 reg。 - Lucas Teske

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接