【问题标题】:Easiest Way to Shift Down A Signed Number向下移动有符号号码的最简单方法
【发布时间】:2016-04-24 04:20:44
【问题描述】:

我将一个 2s 补码浮点数相乘并将其用于 DSP 中的一些数学运算。我得到了结果并希望将其移回,但我不确定最简单的方法。

例如:

constant b_const : integer := integer(real(1.0 / 3.0) / real((2.0**-10.0)));        
signal b : std_logic_vector(10 downto 0);

begin

b <= std_logic_vector(to_signed(b_const, b'length)) ; 

dsp: work.entity_dsp -- p = a * b
port map(
    clk => clk,
    a => a,
    b => b,
    p => p -- also signed
);

c <= p / 2**10; -- Isn't this very resource intensive ?

我查看了“resize”函数,但它似乎只是截断或填充位。我认为 FPGA 的一条黄金法则是永远不要使用“/”,除非它为我正在尝试做的事情实现了一个简单的解决方案?

有什么建议吗?

【问题讨论】:

  • 除法是 2 的幂,在有符号整数或定点算术中作为右移(如果操作数为负,则加上校正)和浮点中的指数减法很容易实现算术。
  • 也许不清楚在有符号整数/定点算术中操作时负值的校正应该是什么?算术右移是除以 2 的幂,将结果向负无穷大舍入,而整数除以 2 的幂 截断(向零舍入) 结果(在 C、C++ 中)。所以必要的修正是:if (x &lt; 0) x = x + 2**n-1; r = x &gt;&gt; n;,其中&gt;&gt;表示算术右移。

标签: floating-point vhdl fpga twos-complement


【解决方案1】:

如果要截断 LSB,可以使用 numeric_std 中定义的 shift_right 函数,然后调整大小。

c <= resize(shift_right(p, 10), c'length);

或者,您可以切片:

c <= p(c'length+10 downto 10);

【讨论】:

  • 但这会改变 2s 恭维有符号数的值
  • 是的,除法和位移时负值的处理方式不同。另请参阅此答案:stackoverflow.com/a/24145443/5900503 您可以按照@njuffa 的建议进行操作。在右移之前有条件地为负数添加一个常数。根据 FPGA,这可以使用 DSP 块内的后加法器来完成,而无需使用额外的 LUT。
猜你喜欢
  • 2010-12-08
  • 1970-01-01
  • 2010-10-14
  • 2020-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
相关资源
最近更新 更多