在Altera Quartus Prime

时间:2016-02-27 13:17:04

标签: vhdl point floating quartus

我试图编译我的设计,使用fphdl库http://www.eda.org/fphdl/进行浮点运算。虽然在modelsim模拟很好,但在Quartus hdl编译器中进行合成时会抱怨声明:

result := to_integer (fract (frac'high downto frac'high-base))

有理由:'表达不是恒定的' 从查看类似的帖子我明白这个编译器不喜欢frac'high-base不受约束。我试图将所有相关信号约束如下:

variable frac    : UNSIGNED (23 downto 0);  
variable base    : INTEGER range 0 to 23;

但仍然会出现错误...... 在hdl级别或Quartus本身有没有解决方法?

2 个答案:

答案 0 :(得分:2)

请注意,错误消息显示:

  

表达式不是常量

而不是:

  

... 约束

因此,错误消息的原因是to_integer函数在fract的范围在运行时是可变的,而不是在精化时修复时无法合成。

Quartus的解决方法可以是:

variable part : UNSIGNED(23 downto 0);
...
part := (others => '0');
part(base downto 0) := frac(frac'high downto frac'high - base);
result := to_integer(part);

然后将来自frac的提取部分置零,然后将给定to_integer的矢量长度固定,从而允许Quartus合成。

答案 1 :(得分:1)

问题中的代码片段似乎与fphdl包没有直接关系。它不依赖于任何类型中声明的任何类型。

该表达式给出result的整数frac,其精度为frac'HIGH - base'位'。

原始表达式的等效物可以是:

    variable dist:  integer range 0 to 23;

    dist := frac'HIGH - base;
    result := to_integer (SHIFT_RIGHT(frac, dist));

SHIFT_RIGHT来自IEEE库包numeric_std,因为frac是无符号的。

精明的观察者可能会注意到这相当于一个整数除以2的幂,这通常会被综合所支持,提供或多或少相同的硬件。

关于这里,你可能会认为你的陈述是一个多路复用器,其输入为零填充,整个事情需要优化。

历史上IEEE Std 1076.6-2004(撤回) 8.6.5切片名称提供 -

  

对于作为切片名称的一部分出现的离散范围,离散范围的边界应直接或间接指定为属于整数类型的静态值。

Morten告诉我们Quartus Prime可以处理

    part := (others => '0');
    part(base downto 0) := frac(frac'high downto frac'high - base);
    result := to_integer(part);

其中base不是静态的(尽管您认为它应该受到约束)。

对于那些无法处理非静态离散范围的综合工具,可以在for循环中完成相同的操作,具体取决于循环参数,它是展开循环中的常量

    part := (others => '0');
    for i in part'range loop
        if i = b then
            part(i downto 0) := frac(frac'high downto frac'high - i);
        end if;
    end loop;
    result := to_integer(part);

IEEE Std 1076 = 2008 10.10循环声明告诉我们:

  

对于具有 for 迭代方案的循环语句,循环参数规范是具有给定标识符的循环参数的声明。 loop参数是一个对象,其类型是离散范围的基本类型。在语句序列中,循环参数是常量。

for循环给出相同的结果,并且应该生成相同的硬件。