verilog实现matlab的floor、ceil、round等小数处理

        首先是在verilog当中,可以用一个数来表示整数部分和小数部分,比如16bit的数据,高8bit表示整数,低8bit表示小数,eg:0880=8.5。

        可以自己定义一个data_in,例如位宽是WIDTH_IN,那么你可以把它当成一个浮点数,当需要对小数进行截位时,就可以设一个parameter CUT_BITS,只需要判断data_in[CUT_BITS-1]是不是1,如果是1,相当于对该位四舍五入时,这里是0.5,那么就把data_in[WIDTH_IN-1:CUT_BITS]+1,就得到了小数截掉之后的数据;如果是0,就说明该位后面是小于0.5的,就直接得到data_in[WIDTH_IN-1:CUT_BITS]。

        是因为在用二进制代表小数时,例如00FF,就表示0.5+0.25+0.125+0.0625+0.03125........所以只要小数的第一位是1,就表示全部小数一定大于等于0.5,再判断后面小数是否全为0(~(|data_in[CUT_BITS-2:0])=1),若全为0,就表示等于0.5,否则一定大于0.5。只要小数的第一位是0,就表示全部小数一定小于0.5。

        下面就是基于上面的原理,对data_in进行一些取整。

在MATLAB中,"floor(x)" 函数用于返回不大于 x 的最大整数值。具体来说,如果 x 是一个实数,则 "floor(x)" 将返回比 x 小但最接近 x 的整数值。也就是正数直接只要整数部分 负数是整数部分加一例如:

x = 3.8; result = floor(x); % result = 3

y = -2.5;result = floor(y); % result = -3

在verilog当中实现:{(CUT_FLOAT_BITS){1'b1}}表示复制CUT_BITS个1,如果是负数,就把截掉之后的高位补1,正数补0。

assign data_in_reg = data_in[DATA_W-1] ? ((~(|data_in[CUT_BITS-1:0]))? {{(CUT_BITS){1'b1}},data_in[DATA_W-1:CUT_BITS]} : {{(CUT_BITS){1'b1}},{data_in[DATA_W-1:CUT_BITS]+1'b1}} )                
											  : {{(CUT_BITS){1'b0}},data_in[DATA_W-1:CUT_BITS]};  

"round(x)":该函数是将数 x 进行四舍五入操作,返回最接近 x 的整数值。如果 x 与两个整数的距离相等,则返回偶数值。例如:

x = 3.6;result = round(x); % result = 4

y = 2.5;result = round(y); % result = 2

x = -3.6;result = round(x); % result = -4

y = -2.2;result = round(y); % result = -2

assign data_in_reg = data_in[CUT_BITS-1] ? {{(CUT_BITS){data_in[DATA_W-1]}},{data_in[DATA_W-1:CUT_BITS]+1'b1}} : {{(CUT_BITS){data_in[DATA_W-1]}},data_in[DATA_W-1:CUT_BITS]};  

"floor(x+0.5)":该函数是将 x 加上 0.5 后再向下取整,即返回不大于 x+0.5 的最大整数值。这种方法常用于实现四舍五入。例如:

x = 3.6;result = floor(x+0.5); % result = 4

y = 2.5;result = floor(y+0.5); % result = 3

/*************************************************floor(x+0.5)*******************************************************/
reg		[DATA_W-1:0]  	data_round_pos;
always @(*) begin
    if (data_in[CUT_BITS-1]) 
	begin
        if(data_in[DATA_W-1])
		begin
			if(~(|data_in[CUT_BITS-2:0]))   
				data_round_pos = {{(CUT_BITS){1'b1}},data_in[DATA_W-1:CUT_BITS]     };  //-8.5
			else
				data_round_pos = {{(CUT_BITS){1'b1}},data_in[DATA_W-1:CUT_BITS]+1'b1};  //-8.75
		end
		else
			data_round_pos     = {{(CUT_BITS){1'b0}},data_in[DATA_W-1:CUT_BITS]+1'b1};  //8.5  8.75
	end
	else  
        data_round_pos = {{(CUT_BITS){data_in[DATA_W-1]}},data_in[DATA_W-1:CUT_BITS]}; //8.125  -8.125  8  -8
	 
end                    
/*************************************************floor(x+0.5)*******************************************************/

"ceil(x)":该函数是将 x 向上取整,即返回不小于 x的最小整数值。这种方法也可以用于实现四舍五入。例如:

x = 3.6;result = ceil(x); % result = 4

y = 2.5;result = ceil(y); % result = 3

assign	data_in_reg = data_in[DATA_W-1] ? {{(CUT_BITS){1'b1}},data_in[DATA_W-1:CUT_BITS]} : 
												((~(|data_in[CUT_BITS-1:0]))? {{(CUT_BITS){1'b0}},data_in[DATA_W-1:CUT_BITS]} :{{(CUT_BITS){1'b0}},data_in[DATA_W-1:CUT_BITS]+1'b1} );
	

"ceil(x+0.5)":该函数是将 x 减去 0.5 后再向上取整,即返回不小于 x+0.5 的最小整数值。这种方法也可以用于实现四舍五入。例如:

x = 3.6;result = ceil(x+0.5); % result = 5

y = 2.5;result = ceil(y+0.5); % result = 3

/*************************************************ceil(x+0.5)*******************************************************/

reg		[DATA_W-1:0]  	data_round_neg  ;
always @(*) begin
    if (data_in[CUT_BITS-1]) 
	begin
        if(data_in[DATA_W-1])
			data_round_neg = {{(CUT_BITS){1'b1}},data_in[DATA_W-1:CUT_BITS]};  //-8.5  -8.75  
		else
		begin
			if(~(|data_in[CUT_BITS-2:0]))   
				data_round_neg = {{(CUT_BITS){1'b0}},data_in[DATA_W-1:CUT_BITS]+1'b1}; //8.5   
			else
				data_round_neg = {{(CUT_BITS){1'b0}},data_in[DATA_W-1:CUT_BITS]+2'b10}; //8.75 
		end
	end
	else  
	begin
        if(data_in[DATA_W-1])
			data_round_neg = {{(CUT_BITS){1'b1}},data_in[DATA_W-1:CUT_BITS]-1'b1};  //-8.125  -8 
		else
			data_round_neg = {{(CUT_BITS){1'b0}},data_in[DATA_W-1:CUT_BITS]+1'b1};   //8.125  8
	end 
	 
end               
/*************************************************ceil(x+0.5)*******************************************************/

"ceil(x-0.5)":该函数是将 x 减去 0.5 后再向上取整,即返回不小于 x-0.5 的最小整数值。这种方法也可以用于实现四舍五入。例如:

x = 3.6;result = ceil(x-0.5); % result = 3

y = 2.5;result = ceil(y-0.5); % result = 2

/*************************************************ceil(x-0.5)*******************************************************/
reg		[DATA_W-1:0]  	data_round_neg;
always @(*) begin
    if (data_in[CUT_BITS-1]) 
	begin
        if(data_in[DATA_W-1])
			data_round_neg = {{(CUT_BITS){1'b1}},data_in[DATA_W-1:CUT_BITS]+1'b1};  //-8.5  -8.75  
		else
		begin
			if(~(|data_in[CUT_BITS-2:0]))   
				data_round_neg = {{(CUT_BITS){1'b0}},data_in[DATA_W-1:CUT_BITS]}; //8.5   
			else
				data_round_neg = {{(CUT_BITS){1'b0}},data_in[DATA_W-1:CUT_BITS]+1'b1}; //8.75 
		end
	end
	else  
	begin
        data_round_neg = {{(CUT_BITS){data_in[DATA_W-1]}},data_in[DATA_W-1:CUT_BITS]}; //8.125  -8.125  8  -8
	end 
	 
end
/*************************************************ceil(x-0.5)*******************************************************/

        还有一种直接截取,直接丢掉全部小数

x = 3.6; % result = 3

y = 2.5; % result = 2

FULL_PREC直接截取:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值