我试图编译我的设计,使用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本身有没有解决方法?
答案 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循环给出相同的结果,并且应该生成相同的硬件。