4

如何在 Verilog 中计算浮点被乘数?到目前为止,我通常使用 shift << 1024 ,然后浮点数变为整数。然后我做一些操作,然后 >> 1024 再次得到一个分数。

例如 0.3545 = 2^-2 + 2^-4 + ...

我对另一种方式有疑问,比如这样。我不知道减号(-)从何而来:

0.46194 = 2^-1 - 2^-5 - 2^-7 + 2^-10。

我只是从某人那里看到的。但是按照你的方式,就是这样表示的

0.46194 = 2^-2 + 2^-3 + 2^-4 + 2^-6 + 2^-7 + 2^-10 + .... .

我不明白它是如何知道使用负号的呢?

我们怎么知道什么时候需要减号呢?另外我如何申请verilog RTL?

更新:我理解在操作中使用减号的概念。但是有没有其他方法来方程或方法来减少表达式乘以 2 的幂?

更新:我们如何在verilog中使用这种方法?例如,我倾斜了 0.46194 = 2^-1 - 2^-5 - 2^-7 + 2^-10。然后这段代码在verilog中是这样写的。0.011101101 ='hED ='d237。所以问题的重点是我们如何将它应用到verilog中的应用程序中?


更新:先生,请您检查一下这个吗?结果略有不同。

0.46194 = 0.011101101。我只是这样尝试

0.011101101

0.100T10T01

= 2^-1 - 2^-4 + 2^-5 - 2^-7 + 2^-9。= 0.462890625

有些不同。我错了什么?

4

2 回答 2

3

变量乘以常数通常是通过将变量添加到自身的移位版本来实现的。与接受两个变量的乘法器电路相比,这在 FPGA 上要便宜得多。

当常量中有一系列 1 位时,您也可以通过使用减法来获得进一步的节省。(减法电路与加法一样昂贵。)

考虑数字30 = 11110。它等于 16 + 8 + 4 + 2,但也等于 32 - 2。

一般来说,被乘数 1 位的序列,或几个连续的 2 次方之和,可以通过在最高有效位之后加上 2 的第一个幂并减去最低有效位来形成。因此,代替16x + ... + 2x,使用32x - 2x

1 位序列是分数还是整数的一部分并不重要。2^a = 1 + ∑2^0 ... 2^(a-1)换句话说,您只是在应用身份∑2^0 ... 2^a = 2^(a+1) - 1

于 2015-02-07T04:49:25.063 回答
2

在 4 位基数 2 中,数字可以具有以下值:

Base 2: Unsigned 4 bit integer, 
2^3  2^2  2^1  2^0  
  8    4    2    1 

如果我们有 a0111它代表 7。如果我们使用移位相加架构乘以这个数字,则需要 3 个时钟周期(3 个移位和相加)。

对此的优化称为CSD(Canonical Signed Digit。它允许在“二进制数”中出现减一。我们将 -1 表示为一个条形图,或T表示它看起来像一个顶部有一个条形图。

100T表示8 - 1与 相同0111。可以观察到,1 的长运行可以替换为结束运行的 0 变为 1,运行的第一个 1 变为 -1,(T)。

转换示例:

00111101111
01000T1000T

但是如果在两个部分中通过,我们会得到:

00111101111
0011111000T
010000T000T

我们取了一个需要 8 个时钟周期或 8 个逻辑块来计算的数字,并将其变成 3。

Verilog x精度二进制定点表示中的定点值的相关问题?和verilog-floating-points-multiplication

涵盖后续问题:

回答有关 CSD 转换问题的后续部分。我会将它们视为纯整数以简化数字,这与将值乘以 2^9(9 个小数位)相同。

256  128 64 32 16 8 4 2 1
  0    1  1  1  0 1 1 0 1

128 + 64 +32 + 8 +4 +1 => 237

现在进行 CSD 转换:

256  128 64 32 16 8 4 2 1
  1    0  0  T  1 0 T 0 1

256  -32 + 16 - 4 + 1 => 237

你可以看到你的转换是正确的。我得到 237* 2^-9 为 0.462890625,当转换回小数时,它与您的答案相匹配。你开始的0.46194那个必须是一个四舍五入的版本,或者当量化为 9 个小数位时会被截断。这种误差称为量化误差。不过,这里最重要的是您正确地进行了 CSD 转换。

于 2015-02-07T10:20:24.360 回答