0

我一直在使用 Xilinx ISE 14.2 在 VHDL 中处理数据包排序管道。为了使结构通用,我在一个包中编写了一些算法,这些算法将确定如何连接排序节点。有趣的是,当我围绕这些功能设计一个测试台时,结果是正确的。当我在项目中使用生成器和函数的组合来模拟我的设计时,硬件连接正确。(使用 'assert false report" & integer'image(layer);' 在模拟中进行验证)但是,当我生成 RTL 示意图时,我可以看到某些节点连接不正确。

我 90% 确定这是一个错误,但我说我不是这个软件的老手。功能有效,在这个阶段可能已经使用了 2% 的可用资源。是否有任何人知道的秘密标志或特性?

谢谢大家。问候,史蒂夫

4

3 回答 3

1

XST 相当可靠。

我在 XST 中看到的唯一真正的错误硬件错误与作为 OUT 参数传递给进程中的过程的信号有关……信号是使用变量赋值(立即赋值)语义分配的!

在 ISE14 中,此错误仍然存​​在 - 在针对 Spartan-3 和较旧设备时,但在针对 Spartan-6 和较新设备时不存在。事实证明,XST 有两种不同的 VHDL 解析器,新的似乎更好。

因此,您可以使用其他解析器重试(通过更改目标系列,或“use_new_parser”设置或命令行选项) - 有关详细信息,请参阅 Xilinx 文档。

您还可以将合成后网表插入您的测试平台并重现(或不重现!)仿真中的错误。(IMO 后合成器和后 PAR 仿真的唯一实际用途是确认或消除可能的工具错误!)

而且 - 正如菲利普所说 - 分而治之,直到你有一个小型演示器 - 或者找出真正的问题是什么!

编辑 :

添加以演示几点...

给定 l,n 的正确整数值,我们可以更详细地描述这个问题......从上面的断言,我们可以推断出 n=8,l=3。

    library IEEE;
    use ieee.math_real.all;

    entity count is
    end count;

    architecture Behavioral of count is

    constant n : integer := 8;
    constant l : integer := 3;

    begin

       report "n: " & integer'image(8) severity Note;
       assert false report "r: " & real'image(8.0) severity Note;
       report "Border a: " & real'image(real(n) + ( real(n) mod 2.0)) severity Note;
       report "Border b: " & real'image(2.0**(real(l+1) - 1.0)) severity Note;
       report "Border a/b: " & real'image((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0))) severity Note;
       report "Ceil a/b: " & real'image(ceil((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0)))) severity Note;
       report "Residual a/b: " & real'image((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0)) - 1.0 ) severity Note;

    end Behavioral;

1)“断言错误”不是必需的(自 1993 年以来)

2) 与流行的神话相反,只要条件是静态可确定的,就可以合成断言。因此在上面的代码中,其中 l,n 是常数,XST 综合,报告......

以 Spartan-3 为目标,我们得到:

INFO:Xst:1749 - "count.vhd" line 15: note: n: 8
INFO:Xst:1749 - "count.vhd" line 16: note: r: 0

所以使用旧的解析器,在综合中使用 Math.Real 并没有得到很好的支持。具体来说,real'image 返回 0!

以 Spartan-6 为目标,

Elaborating entity <count> (architecture <Behavioral>) from library <work>.
Note: "n: 8"
Note: "r: 8.0"
Note: "Border a: 8.0"
Note: "Border b: 8.0"
Note: "Border a/b: 1.0"
Note: "Ceil a/b: 2.0"
Note: "Residual a/b: 2.22044604925031E-16"

所以我们重现了“错误”。但至关重要的是,如果我从表达式中减去 1.0 而不是取其上限,我们可以看到残差(通过四舍五入引入)。我们可以看到,虽然它很小,但它是积极的。

因此 Ceil() 在返回 2.0 时表现正确,这绝对不是综合工具错误。

在模拟中尝试相同的方法,您可能会发现一个类似的小但负数,因此它也是正确的......

请参阅Kahan 教授关于浮点的这篇论文和其他论文——这不是工具问题,甚至不是 VHDL 问题,而是更大的蠕虫罐......

所以最后一句话是:如果你能找到任何方法来完成整数运算中的相同任务,那将是一个更好的解决方案。

于 2012-12-28T21:36:19.117 回答
0

谢谢你们的时间和想法。最后,它归结为 IEEE.MATH_REAL 中 CEIL 函数的“故障”,因为它在模拟和综合中的行为不同。

我通过使用 ASSERT 语句粘贴我的代码来解决这个问题(注意:这些仅在 SIMULATION 中有效)。我知道它可能在哪里出错,因此用如下所示的 ASSERT 语句剖析了其中一个函数。所以这种调试方法的目的是比较前合成器功能输出和后合成器输出,我使用正常的行为模拟,然后“生成合成后模拟”使用断言语句将在模拟期间将值输出到控制台窗口初始化期。

断言代码示例:(注意:integer'image 将数字转换为字符串。断言错误强制打印语句(在早期 VHDL 版本中需要))

assert false report "Border Value: " & integer'image(Border(l+1, n));
assert false report "Border a: " & real'image(real(n) + ( real(n) mod 2.0));
assert false report "Border b: " & real'image(2.0**(real(l+1) - 1.0));
assert false report "Border a/b: " & real'image((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0)));
assert false report "Ceil a/b: " & real'image(ceil((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0))));

结果:

这里是pre synth输出,看ceil函数

Error: ""
Error: "(3,8)"
Error: "Node Port-ID (In.Port 0 then 1): 46 - 47"
Error: "Next Node (Out.Port 0 then 1): 4 - 8"
Error: "Dst Port: 1"
Error: "Border Value: 4"
Error: "Border a: 8.0"
Error: "Border b: 8.0"
Error: "Border a/b: 1.0"
Error: "Ceil a/b: 1.0"
Error: "Next Node Port-ID(Out.Port 0 then 1): 55 - 63"
Error: ""

这里是合成后的输出,再看ceil函数

Error: "(3,8)"
Error: "Node Port-ID (In.Port 0 then 1): 46 - 47"
Error: "Next Node (Out.Port 0 then 1): 8 - 12"
Error: "Dst Port: 0"
Error: "Border Value: 12"
Error: "Border a: 8.0"
Error: "Border b: 8.0"
Error: "Border a/b: 1.0"
Error: "Ceil a/b: 2.0"
Error: "Next Node Port-ID(Out.Port 0 then 1): 62 - 70"
Error: ""

结论:

在模拟中,如果将一个整数(例如 1.0)输入 CEIL,它将返回 1.0。然而,在合成过程中,1.0 被舍入到下一个整数 (2.0),因为它去除了非整数部分并添加 1(例如 0.75 -> 0 -> 1)分辨率(至少在我的情况下)是从值中减去 0.01喂到 ceil (例如 1 -> 0.99 -> 1) 这在我遇到的任何文档中都没有提到,我也不相信这是有意的。Verilog 支持 $display 命令,这在这种情况下非常有用,我所做的是创建一个解决方法。

如果没有人有什么要补充的,我会向 XILINX 支持团队提出这个问题。

再次感谢。史蒂夫

于 2012-12-28T22:59:31.673 回答
0

您可能没有正确理解生成的 RTL 原理图。用于 FPGA 的现代综合工具进行了大量优化,包括推动逻辑跨越触发器边界、复制逻辑以及各种其他技巧,以提高速度并减小编译逻辑的大小。虽然此优化逻辑中可能存在错误,但我怀疑如果您的设计根本不重要,那么您只是没有完全理解综合工具为“改进”事物所做的修改。如果行为有所不同,则可能是工具中存在错误,或者您的代码不明确,并且合成器和模拟器正在做不同的事情......您必须发布一些代码让我们帮助解决这个问题。

于 2012-12-28T20:17:17.090 回答