我正在实现一个VHDL 8位定点乘法模块,该模块返回一个8位截断的数字,但当我手工乘法运算来测试它时,我遇到了一个问题。当我想要乘以两个负数时出现问题。二进制定点乘法
我试着乘以两个正值1.67 * 0.625〜1.04(二进制乘法为0.906)。
001.10101 -> 1.67
000.10100 -> 0.625
------------
000000.1110111010 = 000.11101 (truncated to 8bits = 0.906)
我试过乘正数和负数(-0.875 * 3〜2.62)
111.00100 -> -0.875
011.00000 -> 3
----------
010101.0110000000 = 101.01100 (truncated to 8bits = -2.625)
到目前为止everythng工作正常。问题出现在我试图乘以两个负数的情况下。根据我所知道的(除非我错了): - 将两个数相乘将得到两倍分辨率的结果(将两个8位数相乘,得到一个16位数) - 固定点也会错位。在这个例子中,固定之前有3个位,之后有5个位。这意味着在结果数字中,固定点将在点之前有6位数,在点之后有10位。
通过假设这以上计算正常工作。但是,当我试图乘两个负值(-0.875 * -1.91〜1.67)
110.00010 -> -1.91 (1.9375)
111.00100 -> -0.875
------------
101011.0011001000 = 011.00110(truncated to 8 bits = 3.1875)
当然,我尝试另一个负乘法(-2.64 * -0.875 = 2.31)
101.01011 -> -2.64
111.00100 -> -0.875
----------
100110.0001001100 = 110.00010 (truncated to 8bits = -1.9375)
显然,我我做错了什么,但我不明白我做错了什么。
PS:我还没有实现它。我想到了我想要做的事情,然后试着用一些简单的例子手工测试它。我也尝试了更多的乘法。我认为,也许他们工作是因为我很幸运,但显然不是,我尝试了几次乘法,他们的工作。所以也许我在做两个负数的时候做错了什么,也许我把它截断了?大概。
编辑: 好吧,我发现指出乘法是怎么做时,两个操作数是负Xilinx的文件,here是链接。根据这个文件,为了这个文件,这只能在扩展乘法时完成。乘法的最后部分和必须反转,然后加1,它会得到正确的数字。
为了乘法运算,我在程序员模式下使用windows'calculator,这意味着为了乘以8位,我把数字放到计算器中,然后得到结果并截断它。如果他们为其他情况工作,则意味着Windows计算器正在进行直接乘法(将所有部分和相加,而不是反转最后的部分和)。因此,这意味着,为了获得真实的结果,我应该从最后的结果。减去第一个操作数,然后添加倒第一个操作数+ 1
110.00010 -> -1.91 (1.9375)
111.00100 -> -0.875
------------
101011.0011001000
Which gave me the result: 000010.0111001000 = 010.01110(truncated to 8bits =2.43)
而且与我想出了结果的另一个为1.875。这些产出并不是很好,但至少它们更接近我的预期。有没有其他方法可以以更简单的方式实现此目的?
无符号或无符号您必须允许结果大小的两倍或小一大。在十进制中1000 * 1000 = 1000000可以与9999接近,但很容易看出您必须查看最高有效数字的功率,并且只有这两个数字的结果在1的范围内确定结果的大小2^7 * 2^7 = 2 * 14 8位数的乘法将需要15或16位结果,或者只是尝试0xFF * 0xFF,您将得到0xFE01。如果msbits是例如2^7 * 2^0 = 2^7那么你需要一个8或9位数的答案,在这种情况下8 0xFF * 0x01 = 0xFF。 –
@RyanVincent对不起,花了我很长的时间来回答。我正在做我的平行研究并张贴我的结果。无需检测并处理溢出。我知道通过忽略这些标志来做到这一点是可行的,但我想知道是否有其他方式可以做到而不忽视它们。根据我的研究,有但是更难。我想我必须在if语句中做。如果操作数[7] ='1'且操作数2 [7] ='1',那么输入到乘法器的两个位都接收到'0',如果它们不同,则放入整个操作数。这很糟糕..我认为 – morcillo
@dwelch我知道这一点。但是我知道我想应用这个特定的系统永远不会输出高于3且低于-4的结果,这就是我为什么要截断的原因。我知道结果的数字可以用8位数字表示,三位在点之前,5位在点之后。我也有两个系统来测试。其中一个将永远不会乘以两个负面投入,而另一个会。我知道我的一个系统会以这种方式工作。另一个不会。这就是为什么我想解决这个问题。我很久以前测试了截断,它为第一个系统工作(工作“完美”)。 – morcillo