@ FRob对我最近的问题(to_float() and dividing errors)的回答让我分析了float_pkg_c.vhdl,特别是to_float方法。
尝试以下操作时:
variable denum : integer;
variable num : integer;
variable dividend : float (4 downto -27);
begin
dividend := to_float(num, 4, 27) / to_float(denum, 4, 27);
...
我一直收到此错误:“错误(10454):float_pkg_c.vhdl(3840)上的VHDL语法错误:范围的右边界必须是常量”
现在,在上述行:
for I in fract'high downto maximum (fract'high - shift + 1, 0) loop
变量fract是根据参数fraction_width
计算的,在我的情况下是27,因此是常量。
但是,shift
变量是根据arg
参数(基本上是arg
的绝对值的log2)计算的,在我的情况下是num
变量,因此不是常数。
所以,错误是明确的,但我的问题是:如何将整数变量转换为浮动?
这是to_float的定义:
function to_float (
arg : INTEGER;
constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent
constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction
constant round_style : round_type := float_round_style) -- rounding option
对我来说更令人困惑的是,上述定义中arg
不是必需的。{/ p>
答案 0 :(得分:1)
使用您正在使用的to_float
函数重载进行浮动。
您的变量num
和denum
未初始化,默认为integer'left
-2**31
。 to_float
函数尝试将负数转换为正数以保持在arg_int
的自然范围内,但integer'high
仅限于2**31-1
且不能代表-integer'low
。将它们设置为默认值以外的初始值,看看会发生什么。
来自float_pkg_c.vhdl:
if arg < 0 then
result (exponent_width) := '1';
arg_int := -arg; -- Make it positive.
答案 1 :(得分:1)
花了几个小时阅读合成循环并试图用整数arg翻译to_float后我有一个想法:
library ieee;
library ieee_proposed;
use ieee_proposed.float_pkg.all;
use ieee.numeric_std.all;
entity SM is
end entity;
architecture foo of SM is
-- From float_pkg_c.vhdl line 391/3927 (package float_pkg):
-- -- to_float (signed)
-- function to_float (
-- arg : SIGNED;
-- constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent
-- constant fraction_width : NATURAL := float_fraction_width; -- length of FP output fraction
-- constant round_style : round_type := float_round_style) -- rounding option
-- return UNRESOLVED_float is
begin
UNLABELLED:
process
variable denum : integer;
variable num : integer;
variable dividend : float (4 downto -27);
begin
denum := 42;
num := 21;
dividend := to_float(TO_SIGNED(num,32), 4, 27) / to_float(TO_SIGNED(denum,32), 4, 27);
assert dividend /= 0.5
report "dividend = " & to_string(dividend)
severity NOTE;
wait;
end process;
end architecture;
我认为你真的不想合成to_float的整数版本。展开循环会为您提供一堆纹波添加,以便递减shiftr
并调整arg_int
。试图摆脱这些操作会导致你得到一个整数的数组样式表示。
请注意,to_float中没有循环,其arg类型已签名。很可能TO_SIGNED调用被视为定义表示整数大小的位数而不是暗示额外的硬件。你最终得到了一些转换位域和标准化,钳位到无限等的东西。