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没有定点格式,所以用户必须跟踪二进制点并使用缩放数字。 小数点.
不能用于存储为reg
或logic
verilog数字,因为它们基本上是整型格式。 然而,Verilog在数字声明中忽略_
,所以它可以用作数字中的二进制点。 它的使用只是象征性的,对语言没有意义。
在上面的格式中,2.5将由8'b0010_1000
表示,问题有16 8'b0010_1000
数位,因此您需要在_
之后放置16位,以将二进制点保留在正确的位置。
定点乘法位宽度
如果我们有两个数字A和B ,结果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个小数位。