1,小数的运算
在数字电路的运算中,没有小数点概念的,小数你知道在哪个位置,但是电路不知道小数点的位置,所以你要想法让电路在不知道小数点的情况下仍然能够运算出你想要的结果。这里就要进行小数点对齐。
举例说明:
两个无符号小数:a3a2a1a0.a-1a-2
b3b2b1b0.b-1b-2b-3
其中a有6bits,其中4位为整数,2位为小数,而b有4bits整数,3bits小数,这个小数点是认为点的。
比如说我要做两者的乘法,那么应该怎么做呢?
从理论上来说a*b的结果有13bits,其中8bits整数,5bits小数
结果是:c7c6c5c4c3c2c1c0.c-1c-2c-3c-4c-5
一个减数为d3d2d1d0.d-1d-2,要从c中减去,应该如何操作呢?
f=a*b - c
a*b的结果是8bits整数,5bits小数,而d为4bits整数,2bits小数,
如果在rtl描述中,直接写成
f = c-d;
那么结果就变成:
c7c6c5c4c3c2c1c0.c-1c-2c-3c-4c-5
- d3d2d1d0.d-1d-2
很显然得出的结果是错误的,正确的结果应该是:
c7c6c5c4c3c2c1c0.c-1c-2c-3c-4c-5
- d3d2d1d0.d-1d-2 00 0
也就是(没有小数点了)
c7c6c5c4c3c2c1c0c-1c-2c-3c-4c-5
- d3d2d1d0d-1d-2 00 0
很明显需要将减数左移3位将其小数点和被减数对齐。
这样得到的结果就是8bits整数,和5bits小数。
当然也可以将c右移3位,这样就损失了精度。得到结果是6bits整数和2bits小数。小数点的位置你自己是知道的。
所以如果要RTL描述的话需要如下:
wire [5:0] a;
wire [6:0] b;
wire [12:0] mul_result;
assign mul_result = a *b;
wire [13:0] result;
assign result = mul_result - {5'b0,d,3'b0}
这样得到的结果就是9bits整数,和5bits小数。