VHDL XST无法正确合成

时间:2012-12-28 11:59:30

标签: vhdl xilinx synthesis

我一直在使用Xilinx ISE 14.2开发VHDL的数据包排序管道。为了使结构通用,我在一个包中编写了一些算法来确定如何连接排序节点。 有趣的是,当我围绕功能设计测试平台时,结果是正确的。 当我使用生成和功能的组合在项目中模拟我的设计时,硬件正确连线。 (使用'断言错误报告'& integer'image(图层);'在模拟中验证) 但是,当我生成RTL原理图时,我可以看到某些节点没有正确连接。

我90%肯定这是一个错误,但我说我不是这个软件的老手。功能起作用,在这个阶段可能有2%的可用资源被使用。有没有人知道的秘密旗帜或特殊情况?

非常感谢大家。 问候, 史蒂夫

3 个答案:

答案 0 :(得分: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)“Assert False”不是必需的(自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时表现正确,这绝对不是综合工具错误。

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

请参阅this以及Professor Kahan关于浮点的其他文章 - 这不是工具问题,甚至不是VHDL问题,而是更大的蠕虫病毒......

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

答案 1 :(得分:0)

您可能无法正确理解生成的RTL原理图。用于FPGA的现代综合工具进行了优化的 LOT ,包括跨越触发器边界推送逻辑,复制逻辑以及各种其他技巧以提高速度和速度。减小编译逻辑的大小。虽然有可能在这个优化逻辑中存在一个错误,但我怀疑如果你的设计完全不重要,那么你只是没有完全理解合成工具对“改进”事物的破坏。如果行为有差异,那么工具中存在错误,或者代码模糊不清,合成器和模拟器正在做不同的事情......你必须为我们发布一些代码来帮助解决这个问题。< / p>

答案 2 :(得分:0)

非常感谢你们的时间和想法。 最后,在IEEE.MATH_REAL中使用CEIL函数导致“故障”,因为它在Simulation和Synthesis中的表现不同。

我通过使用ASSERT语句填充我的代码来解决这个问题(注意:这些只能在SIMULATION中工作)。 我有一个想法,它可能会出错,因此使用如下所示的ASSERT语句来解决其中一个函数。 因此,这种调试方法的目的是比较合成前函数输出和后合成输出,我使用正常的行为模拟然后“生成后合成模拟” 使用assert语句将在模拟初始化期间将值输出到控制台窗口。

断言代码示例:(注意:integer'image将数字转换为字符串。断言false force to print statement(在早期的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))));

结果:

这是前合成器输出,看一下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: ""

这是post synth输出,再看一下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) 分辨率(至少在我的情况下)是从馈送到ceil的值中减去0.01(例如1 - > 0.99 - > 1) 在我遇到的任何文件中都没有注意到这一点,我也不相信这是有意的。 Verilog支持$ display命令,这在这种情况下非常有用,我所做的就是创建一个解决方案。

如果没有人要添加任何内容,我会向XILINX支持团队提出这个问题。

再次感谢。 史蒂夫