有符号数四舍五入的verilog实现
有符号数a[63:0], 其中小数位为低32-bit,假如说我们对小数部分进行四舍五入,取该数最接近的整数,则对应的verilog代码实现如下:
a_rounded = (a[63:0] + {!a[63],{31{a[63]}}}) >>32;
我们先研究有符号正数的变化规律(低4-bit为小数位):
06 = 8'b0110_0000
07 = 8'b0111_0000
08 = 8'b1000_0000
09 = 8'b1001_0000
10 = 8'b1010_0000
11 = 8'b1011_0000
由上图可知,当正数越小时,如果将其补码看做是无符号数,则该无符号数越小。
我们先研究有符号负数的变化规律(低4-bit为小数位):
-06 = 8'b1010_0000
-07 = 8'b1001_0000
-08 = 8'b1000_0000
-09 = 8'b0111_0000
-10 = 8'b0110_0000
-11 = 8'b0101_0000
由上图可知,当负数越小时,如果将其补码看做是无符号数,则该无符号数越小。
接着,我们再看下有符号数为正数时,小数部分的变化规律(低4-bit为小数位):
6.0625 = 8'b0110_0001
6.1250 = 8'b0110_0010
6.2500 = 8'b0110_0100
6.5000 = 8'b0110_1000
6.7500 = 8'b0110_1100
6.8750 = 8'b0110_1110
6.9375 = 8'b0110_1111
由上图可知,小数部分越大,其对应的无符号数也越大。
下面,我们再看下有符号数为负数时,小数部分的变化规律(低4-bit为小数位):
-6.0625 = 8'b1001_1111
-6.1250 = 8'b1001_1110
-6.2500 = 8'b1001_1100
-6.5000 = 8'b1001_1000
-6.7500 = 8'b1001_0100
-6.8750 = 8'b1001_0010
-6.9375 = 8'b1001_0001
由上图可知,小数部分越小,其对应的无符号数越大。
下面我们看下有符号数的舍入情况:
-6.0625 = 8'b1001_1111 + 8‘b0000_0111 = 8'b1010_0110 -> 8'b1010_0000 = -6
-6.1250 = 8'b1001_1110 + 8‘b0000_0111 = 8'b1010_0101 -> 8'b1010_0000 = -6
-6.2500 = 8'b1001_1100 + 8‘b0000_0111 = 8'b1010_0011 -> 8'b1010_0000 = -6
-6.5000 = 8'b1001_1000 + 8‘b0000_0111 = 8'b1001_1111 -> 8'b1001_0000 = -7
-6.7500 = 8'b1001_0100 + 8‘b0000_0111 = 8'b1001_1011 -> 8'b1001_0000 = -7
-6.8750 = 8'b1001_0010 + 8‘b0000_0111 = 8'b1001_1001 -> 8'b1001_0000 = -7
-6.9375 = 8'b1001_0001 + 8‘b0000_0111 = 8'b1001_1000 -> 8'b1001_0000 = -7
由上图可知,负数的小数部分越小,对应的补码值越大,此时加上8’b0000_0111后,会产生进位。