Verilog – 浮点乘法

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

我们有一个Req m [31:0]。 第一个数字(逗号前)是m [31:16]和逗号m [15:0]后面的数字,所以我们有:

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

m [31:0] = 10000000000000000(。)1000000000000000;

问题是:我们想要用小数点数乘以数字,但我们不知道如何。 例如:二进制m = 2.5。 m * m的结果是6.25。

这个问题并没有完全涵盖对定点数字的理解,因此会涉及到一些可能与OP不相关的背景。

无符号二进制(基数2)数字的小数加权(例如4bit)遵循以下规则:

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

仅供参考,权力保持不变, 基地改变。 四个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 8'b0010_1000数位,因此您需要在_之后放置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游乐场的例子。

从这里你应该能够改变深度,以适应任何types的定点数字。 并且可以通过部分select正确的位来完成重新转换为16位的16位小数。 如果您需要饱和而不是溢出,请小心。

有一个相关的问答有22个小数位。