将整数变量转换为float

时间:2014-04-06 09:34:20

标签: casting floating-point vhdl

@ 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>

2 个答案:

答案 0 :(得分:1)

使用您正在使用的to_float函数重载进行浮动。

您的变量numdenum未初始化,默认为integer'left -2**31to_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调用被视为定义表示整数大小的位数而不是暗示额外的硬件。你最终得到了一些转换位域和标准化,钳位到无限等的东西。