VHDL XST合成不正确

VHDL XST合成不正确,vhdl,xilinx,synthesis,Vhdl,Xilinx,Synthesis,我一直在使用Xilinx ISE 14.2用VHDL编写数据包排序管道。为了使结构通用,我在一个包中编写了一些算法,用于确定如何连接排序节点。 有趣的是,当我围绕函数设计测试台时,结果是正确的。 当我在项目中使用生成和功能组合模拟我的设计时,硬件接线正确。(使用“断言错误报告”和“整型”图像(层);在模拟中进行验证) 但是,当我生成RTL示意图时,我可以看到一些节点没有正确连接 我90%确定这是一个bug,但我说我不是这个软件的老手。功能正常,在这个阶段可能有2%的可用资源被使用。有没有任何人知

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

我90%确定这是一个bug,但我说我不是这个软件的老手。功能正常,在这个阶段可能有2%的可用资源被使用。有没有任何人知道的秘密标志或特性

谢谢大家。 当做
Steve

您可能没有正确理解生成的RTL原理图。现代FPGA合成工具进行了大量优化,包括跨触发器边界推送逻辑、复制逻辑以及各种其他技巧,以提高速度并减小编译逻辑的大小。但也有可能存在错误在这个优化逻辑中,我怀疑如果你的设计是非常重要的,你只是没有完全理解合成工具对“改进”事物所做的破坏。如果行为有差异,要么工具中有缺陷,要么你的代码是不明确的,合成器和模拟器正在做不同的事情……你必须为我们提供一些代码来帮助完成这一任务。

XST非常可靠

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

在ISE14中,这个错误仍然存在——当目标是Spartan-3和更早的设备时,但当目标是Spartan-6和更新的设备时,这个错误就不存在了。事实证明XST有两个不同的VHDL解析器,更新的似乎更好

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

您还可以将post synth网络列表插入测试台,并在模拟中再现(或不再现!)错误。(在我看来,post synth和post 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合成,报告

针对斯巴达-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

以斯巴达-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"
从库中细化实体(架构)。
注:“编号:8”
注:“r:8.0”
注:“边框a:8.0”
注:“边界b:8.0”
注:“边界a/b:1.0”
注:“Ceil a/b:2.0”
注:“剩余账款:2.22044604925031E-16”
所以我们复制了“误差”。但至关重要的是,如果我从表达式中减去1.0,而不是取其上限,我们可以看到残差(通过四舍五入引入)。我们可以看到,尽管它很小,但它是正的

因此,Ceil()在返回2.0时表现正常,这肯定不是合成工具的错误

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

请参阅和其他关于浮点的文章-这不是一个工具问题,甚至不是一个VHDL问题,而是一个更大的蠕虫罐


最后一句话是:如果你能找到任何方法用整数运算完成同样的任务,这将是一个更好的解决方案。

谢谢大家花时间和心思。 最后,它归结为IEEE.MATH_REAL中CEIL函数的“小故障”,因为它在模拟和合成中的行为不同

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

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

结果:

这是预合成输出,看看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: ""
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: ""
这是合成后的输出,再看看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: ""
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支持团队提出