有符号数的表达方式见上篇:有符号小数的表示、扩展和计算_weixin_42330305的博客-CSDN博客
对于有符号数,正数和负数的四舍五入有些许不同,需要区别对待
一、正数
对于正数来说,如果被截掉的数的最高位为1,则结果为保留的数+1,否则等于保留的数
以舍弃最低2 bit为例,2 bit可表示的数值为:0、1、2、3
低2 bit的值如果为0、1(2‘b00、2‘b01),则保留的数不需要加+1
低2 bit的值如果为2、3(2‘b10、2‘b11),则保留的数需要加+1
例如:
1、
8Q6 8‘b01.110101 需要四舍五入到6Q4,舍弃的2bit为“2‘b01”,高位为0,因此结果为6‘b01.1101
2、
若需要将8Q6 8‘b01.110110 需要四舍五入到6Q4,舍弃的2bit为“2‘b10”,高位为1,因此结果为6‘b01.1101+1‘b1 = 6‘b01.1110
二、负数
对于负数,最高位和其余位的符号想反,所以是“五舍四入”
如图所示:
对于5 bit 负数,舍弃低2 bit数据来说,数据可以分为3部分
蓝色是符号位,若为1则-8
绿色是被舍弃的部分
假设蓝色部分的值是-x,黄色部分的和是y,绿色部分的和为z,则最终结果为
-x+y+z=-(x-y-z)=-((x-y)+(-z))=-((x-y-1)+(1-z))
-z的取值范围为:0、-1、-2、-3
除以4后:0、-0.25、-0.5、-0.75
1-z/4 = 1、0.75、0.5、0.25
四舍五入后为:1、1、1、0
注意z=2时,-z/4 = - 0.5 四舍五入为-1,但是应用时是1 - z/4 = 0.5,变成了不需要进位
我们带入一个完整的过程
还以舍弃最低2bit为例,假设一个4bit数,高2 bit为2‘b10,那么它可能的取值是:
4‘b1000(-8)、4‘b1001(-7)、4‘b1010(-6)、4‘b1011(-5)
舍弃2bit相当于除以4
(-8)/4 = -2,(-7)/4 = -1.74,(-6)/4 = -1.5,(-5)/4 = -1.25,
上述结果四舍五入之后为:-2、-2、-2、-1
从而得出:
如果被截掉的数的最高位为0,则等于保留的数;如果被截掉的数的最高位为1,且被截掉的其他数均为0,则等于保留的数,否则结果为保留的数+1
三、实现
module round (
input [M-1:0] a,
output [N-1:0] b
);
reg [N-1:0] b;
always @ (*) begin
if(((a[M-1]==1'b1) && (a[M-N-1:0]=={1'b1,{(M-N-1){1'b0}}})) || //a为负数,且被截位不需要进位
(a[M-1:M-N]=={1'b0,{(N-1){1'b1}}})) //a为正数,且截位后数据饱和,不能在进位
b = a[M-1:M-N];
else
b = a[M-1:M-N] + {{(N-1){1'b0}},a[M-N-1]}; //根据截掉是的数据的最高位来判断是否需要进位
end
endmodule