【问题标题】:Verilog - Floating points multiplicationVerilog - 浮点乘法
【发布时间】:2015-01-03 19:23:01
【问题描述】:

Verilog 有问题。 我们必须使用两个浮点数(二进制)的乘法,但它不能 100% 完美地工作。

我们有一个请求 m[31:0]。第一个数字(逗号之前)是 m[31:16] 和逗号之后的数字 m[15:0] 所以我们有这样的:

m[31:16] = 1000000000000000; m[15:0] = 1000000000000000;

m[31:0] = 10000000000000000(.)10000000000000000;

问题是:我们想将数字与小数位相乘,但我们不知道怎么做。 例如:m = 2.5 二进制。 m*m 的结果是 6.25。

【问题讨论】:

  • 您似乎在描述“定点”而不是浮点。 LSB 是指数(浮动)还是小数位(固定)?

标签: verilog


【解决方案1】:

该问题并未完全涵盖对定点数的理解,因此将涵盖一些可能与 OP 无关的背景。

无符号二进制(以 2 为底)数的十进制加权,例如 4bit 遵循此规则:

2^3  2^2  2^1  2^0 (Base 2)
  8    4    2    1

仅供参考,权力保持不变,base 已更改。对于 4 hex,它将是:

16^3  16^2  16^1  16^0
4096   256    16     1

回到基数 2,对于二进制补码有符号数,MSB(最高有效位)变为负数。

-2^3  2^2  2^1  2^0 (Base 2, Twos complement)
  -8    4    2    1

当我们插入一个二进制点或小数位时,模式会继续。 4 个整数位 4 个小数位。

Base 2: Twos complement 4 integer, 4 bit frational
-2^3  2^2  2^1  2^0  .  2^-1    2^-2    2^-3    2^-4
  -8    4    2    1  .   0.5    0.25   0.125  0.0625

不幸的是,Verilog 没有定点格式,因此用户必须跟踪二进制点并使用缩放数字。小数点. 不能用于存储为reglogic 的verilog 数字,因为它们本质上是整数格式。然而,verilog 在数字声明中确实会忽略_,因此它可以用作数字中的二进制点。它的使用只是象征性的,对语言没有意义。

在上述格式中,2.5 将由 8'b0010_1000 表示,问题有 16 个小数位,因此您需要在 _ 之后放置 16 位以将二进制点保持在正确的位置。

定点乘法位宽

如果我们有两个数字 AB,结果 A*B 的宽度将为:

Integer bits    = A.integer_bits    + B.integer_bits.
Fractional bits = A.fractional_bits + B.fractional_bits.

因此 [4 Int, 4 Frac] * [4 Int, 4 Frac] => [8 Int, 8 Frac]

reg [7:0] a = 0010_1000;
reg [7:0] b = 0010_1000;
reg [15:0] sum;

always @* begin
  sum = a * b ;
  $displayb(sum); //Binary
  $display(sum);  //Decimal
end

// sum == 00000110_01000000; //Decimal->6.25

EDA Playground 上的示例。

据此,您应该能够更改深度以适应任何类型的定点数。并且可以通过部分选择正确的位来完成转换回 16 Int 16 小数。如果您需要饱和而不是溢出,请小心。

有一个相关的Q&A,它有 22 个小数位。

【讨论】:

  • 非常感谢。这就是我搜索的内容。 :)
  • @Aeonus 没问题,这是一个棘手的问题。跟踪二进制点可能很棘手。
猜你喜欢
  • 1970-01-01
  • 2014-02-14
  • 2011-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多