std_logic_vector与浮点的多表示

时间:2015-05-05 11:41:54

标签: floating-point vhdl fixed-point

我有32位std_logic_vector信号,想要将它乘以浮点。

e.g

     signal Input : std_logic_vector (31 downto 0 );
     signal number = 0.2 ;
     signal Output: std_logic_vector (31 downto 0 ); 
     Output <= 0.2 * Input ;

进行这种乘法的最佳解决方案是什么?我在某处读过浮点算术运算不可合成,所以更好地使用定点数。怎么做?

如果有人能告诉我做这种操作的正确想法,我将不胜感激。

由于

1 个答案:

答案 0 :(得分:3)

“最佳”解决方案取决于您所需的精度和您可以承受的资源(逻辑与DSP)。使用浮点需要将input转换为浮点,在此过程中最多丢失8位,执行乘法并转换回来。如果你问我,它会花很多钱,太多了。

使用固定点非常简单。将number乘以2 ^ N,舍入该数字,使用它乘以input并将结果除以2 ^ N.以N = 8为例:

number = 0.2
number_fixed = round(0.2*2^8) = 51
output = floor(51*input/2^8) -- If you add 2^N-1 before floor, you reduce your error

That last comment is because floor(m + 0.5) = round(m),这样做通常很便宜,特别是在Xilinx中,因为它们的乘法器也有一个嵌入式加法器/累加器。

定点问题是错误。我们乘以51/256而不是0.2,产生0.00078125的差异。如果input1000000,则提交的错误为781.这可以通过使用更大的N来修复,这会花费更多的硬件。此外,0.2没有二进制的封闭形式:0.2 = 0.0011001100110011...。顺便说一下,同样的问题会影响浮点。

第三个解决方案是使用分频器5.根据算法,它将花费大约32个3位加法器,这实际上并没有那么糟糕。它还为您提供完整的精度,即仅在lsb上出现错误。 Xilinx拥有分部核心。

更新

如果我的定点解释不清楚,我很抱歉,我会自由地承认我不确定最好的解释方法。

首先,不要按 10 或任何其他非幂2进行缩放。虽然没有错,但你通常需要乘以/除以你的比例因子,这对于2的幂是微不足道的,但对于其他数字则不是。

首先考虑理论。假设您有实数ab,您应该看到:

a * b = c
a*2^N * b*2^M = d = c * 2^(N+M)

因此,如果在乘法之前缩放2个数字,它只会将结果更改为另一个缩放因子。这是定点算术的基础,缩放操作数并跟踪输出的缩放。但是,我们仅对整数进行操作,因此我们不使用abcd,而是使用这些值的修正,舍入或近似版本:

round(a*2^N) * round(b*2^N) = e approx d approx round(c*2^(N+M))

在后续计算中,您保留e。当您需要获取实数时,通常在解释数据时在FPGA外部,您可以将e除以2 ^(N + M)。当然,您通过使用固定点(或浮点数)产生错误,它等于c - e/2^(N+M),使用更大的NM将减少错误。

回到你的例子,使用2 ^ 8的缩放。无论你乘以0.2,你都乘以51(round(0.2 * 2 ^ 8))。您的结果将按2 ^ 8进行缩放,如果您希望保持这种方式或缩放到另一个缩放因子(如2 ^ 0),则由您决定。