基于FPGA的数字信号处理(12)--定点数的舍入模式(3)收敛取整convergent

news2024/10/5 8:36:56

前言

在之前的文章介绍了定点数为什么需要舍入和几种常见的舍入模式。今天我们再来看看另外一种舍入模式:收敛取整convergent

10进制数的convergent

convergent收敛取整。它的舍入方式和四舍五入非常类似,都是舍入到最近的整数,比如1.75 convergent到2,-0.25 convergent到0等。二者唯一的区别在于对0.5这类数据的处理上。

  • 0.5这种处于中间,舍入到两边的整数距离都一样近,所以可以把它叫做 “中间数”

  • round对于正的中间数的处理相当于向上取整,对于负的中间数相当于向下取整。例如0.5的round结果是1,-0.5的round结果是-1

  • convergent对于中间数的处理是将其舍入到最近的偶数。例如0.5舍入到0,1.5舍入到2,-0.5舍入到0,-1.5舍入到-2

以-2到1.75之间的16个数据(步长0.25)为例,它们的convergent结果是这样的:

2进制数的convergent

2进制数的convergent和10进制的convergent类似。以Q4.2格式的定点数(字长4位,小数2位的有符号数)为例,对于负数的小数部分的处理:

  • -2(d) = 10_00(b) convergent后的值为 -2,等价于 10,即舍弃小数部分后的值(10)
  • -1.75(d) = 10_01(b) convergent后的值为 -2,等价于 10,即舍弃小数部分后的值(10)
  • -1.5(d) = 10_10(b) convergent后的值为 -1,等价于 11,即舍弃小数部分(10)后再加1
  • -1.25(d) = 10_11(b) convergent后的值为 -1,等价于 11,即舍弃小数部分(10)后再加1
  • -1(d) = 11_00(b) convergent后的值为 -1,等价于 11,即舍弃小数部分后的值(11)
  • -0.75(d) = 11_01(b) convergent后的值为 -1,等价于 11,即舍弃小数部分后的值(11)
  • -0.5(d) = 11_10(b) convergent后的值为 0,等价于 00,即舍弃小数部分(11)后再加1
  • -0.25(d) = 11_11(b) convergent后的值为 0,等价于 00,即舍弃小数部分(11)后再加1

对于0的处理:

  • 直接舍弃小数部分。

对于正数的小数部分的处理:

  • 1.75(d) = 01_11(b) convergent后的值为 2,此时溢出了,需要扩展位宽,处理方式也是舍弃小数部分(001)后再加1即010
  • 1.5(d) = 01_10(b) convergent后的值为 2,此时溢出了,需要扩展位宽,处理方式也是舍弃小数部分(001)后再加1即010
  • 1.25(d) = 01_01(b) convergent后的值为 1,等价于 01,即舍弃小数部分后(01)的值
  • 1(d) = 01_00(b) convergent后的值为 1,等价于 01,即舍弃小数部分后(01)的值
  • 0.75(d) = 00_11(b) convergent后的值为 1,等价于 01,即舍弃小数部分后(00)的值再加1
  • 0.5(d) = 00_10(b) convergent后的值为 1,等价于 01,即舍弃小数部分后(00)的值再加1
  • 0.25(d) = 00_01(b) convergent后的值为 0,等价于 00,即舍弃小数部分后(00)的值

总结一下,就是:

  • 对于正数的convergent处理:首先舍掉小数位,然后加一个进位值:

    • 当小数部分的最高位为0时,说明这个数的小数部分是小于0.5的,所以不需要进位,此时的进位值为0。
    • 当小数部分的最高位为1且其他位不为全0时,说明这个数的小数部分是大于0.5的,所以需要进位,即此时的进位值为1。
    • 当小数部分的最高位为1且其他位为全0时,说明这个数的小数部分是等于0.5的,所以需要进位,因为进位是需要进到最近的偶数,所以还需要看整数部分的最低位,如果最低位为0,说明此时的整数部分就是最近的偶数整数,所以进位值为0;如果为1,则说明+1后的整数才是距离最近的偶数,所以进位值为1。
  • 对于0的convergent处理:首先舍掉小数位,然后加一个进位值,该进位值恒定为0。

  • 对于负数的convergent处理:首先舍掉小数位,然后加一个进位值:

    • 当小数部分的最高位为0时,说明这个数的小数部分是小于0.5的,而整数部分又是个负数,相当于二者的和的小数部分小于 -0.5。例如10.01是-1.75,它的小数部分.01是0.25,整数部分10是-2,二者相加是-2+0.25 = -1.75,所以它们的处理方式都是先舍弃小数位,然后加0。
    • 当小数部分的最高位为1且其他位不为全0时,说明这个数的小数部分是大于0.5的,而整数部分又是个负数,相当于二者的和的小数部分大于-0.5。例如10.11是-1.25,它的小数部分.11是0.75,整数部分10是-2,二者相加是-2+0.75 = -1.25。所以它们的处理方式都是先舍弃小数位,然后加1。
    • 当小数部分的最高位为1且其他位为全0时,说明这个数的小数部分是等于0.5的,此时需要舍入到最近的偶数,如果此时整数部分的最低位的值是1,说明此时最近的偶数还需要加1,;如果此时整数部分的最低位的值是0,说明最近的偶数就是这个整数部分。例如10_10是 -1.5,convergent后的值为 -2(10),10_10的整数部分为10,其最低位为0,所以最近的偶数就是整数部分的值,所以进位值为0,即10_10>>10+0>>10;或者11_10是 -0.5,convergent后的值为 0(00),11_10的整数部分为11,其最低位为1,所以最近的偶数是整数部分的值+1,所以进位值为1,即11_10>>11+1>>00。

上面的内容可以再精简:

  • 当小数部分的最高位为0时,相当于整数部分 + 进位值,进位值等于0即小数部分的最高位
  • 当小数部分的最高位为1且其他位不为全0时,相当于整数部分 + 进位值,进位值等于1即小数部分的最高位
  • 当小数部分的最高位为1且其他位为全0时,相当于整数部分 + 进位值,进位值等于整数部分的最低位

image-20240421161601871

下面以 用convergent的方式来实现Q4.2格式定点数转Q2.0格式定点数为例,Verilog代码如下:

module test(
    input	[3:0]	data_4Q2,				//有符号数,符号1位,字长4位,小数2位	
    output	[1:0]	data_2Q0				//有符号数,符号1位,字长2位,小数0位	
);

wire	carry;

assign	carry = (data_4Q2[1] && ~data_4Q2[0]) ? data_4Q2[2] : data_4Q2[1];				
assign	data_2Q0 = data_4Q2[3:2] + carry;	//舍弃低位(即整个小数部分)后再加进位

endmodule

因为一共只有16个数,所以我们可以用穷举的方式来测试,TB如下:

`timescale 1ns/1ns
module test_tb();

reg	 [3:0]	data_4Q2;			//有符号数,符号1位,整数2位,小数2位	
wire [1:0]	data_2Q0;			//有符号数,符号1位,整数2位,小数0位	
	
integer i;						//循环变量

initial begin
	data_4Q2 = 0;				//输入赋初值	
	for(i=0;i<16;i=i+1)begin	//遍历所有的输入,共16个	
		data_4Q2 = i;						
		#5; 
		$display("data_4Q2:%h		data_2Q0:%h",data_4Q2,data_2Q0);
	end
	#20 $stop();				//结束仿真
end

//例化被测试模块
test	test_inst(
	.data_4Q2	(data_4Q2),	
	.data_2Q0	(data_2Q0)
);

endmodule

同时,我们也用matlab来实现同样的功能,观察两者的输出是否一致:

%--------------------------------------------------
% 关闭无关内容
clear;
close all;
clc;

%-------------------------------------------------------------------------------
% 生成数据并做convergent处理
x = -2:0.25:1.75;
F = fimath('RoundingMethod','convergent');         	% 设定舍入模式为convergent
%F_c = fimath('RoundingMethod','Convergent');      	% 设定舍入模式为convergent
data_4Q2 = fi(x,1,4,2,F);                         	% 生成Q4.2格式的定点数
data_2Q0 = fi(data_4Q2,1,2,0,F);                  	% 从Q4.2格式转换成Q2.0格式

下图是2者分别输出的数据(16进制),可以看到有2个数是对不上的:

image-20240421013707229

你如果记性不错的话,就会发现这两个数正是前面讨论的正数会出现溢出的情况。这2个数分别是0110/0111,即10进制数1.5/1.75,它们的convergent结果应该是2。从上图来看,好像是matlab错了,而RTL对了,但实际情况恰恰相反。现在想想结果是什么格式的?Q2.0!它能表示的最大的数是多少?是10进制的1!所以结果溢出了!

那为什么RTL的结果又 ”对“ 了呢?这纯属是乌龙。因为打印结果是16进制的,并不表示10进制数值,结合结果的2位位宽,可知 ”2“,实际上就是10,它是01的溢出产生的,这个数在Q2.0格式的定点数中并不表示 ”数字2“,而是数字 ”-1“。

matlab是有溢出处理进制的(saturate),它把溢出值把都饱和在了最大值,即01(10进制的1),所以为了防止这种情况的发生,我们也要设计对应的溢出处理机制。因为负数的最小值只取决于整数(小数部分是正的权重),而正数的最大值同时取决于小数和整数,例如Q4.2格式的最小值是-2即10_00,而最大值则是1.75即01_11,所以溢出只会是正向的溢出,那么就只要限定最大值即可。把Verilog代码改一下:

module test(
    input	[3:0]	data_4Q2,				//有符号数,符号1位,字长4位,小数2位	
    output	[1:0]	data_2Q0				//有符号数,符号1位,字长2位,小数0位	
);

wire	carry;
wire	[2:0]	data_temp;					//扩展1bit,防止溢出

assign	carry = (data_4Q2[1] && ~data_4Q2[0]) ? data_4Q2[2] : data_4Q2[1];	
assign	data_temp = {data_4Q2[3],data_4Q2[3:2]} + {2'b00,carry};		//中间变量,舍弃低位(即整个小数部分)后再加进位    
assign	data_2Q0 = (data_temp[2:1]==2'b01) ? 2'b01 : data_temp[1:0];	//data_2Q0的高2位为01说明产生了正向的进位,即溢出
			
endmodule

这样结果就是正确的了:

image-20240421121204033

定点数从Q4.2格式转Q2.0格式是一个比较特殊的例子,因为它相当于把小数部分全部舍弃掉了,如果舍入要求不是全部小数位,而是部分小数位,那么处理方式是一样的吗?

是一样的。对于其他情况则相当于把小数点移动到了对应的位置。例如Q5.3格式的定点数转Q3.1格式,则只需要把最后两位小数舍弃并加上进位即可即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1669581.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高校推免报名|基于SSM+vue的高校推免报名系统的设计与实现(源码+数据库+文档)

高校推免报名 目录 基于SSM&#xff0b;vue的高校推免报名的设计与实现 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2后台登录模块 5.2.1管理员功能模块 5.2.2考生功能模版 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八…

Cross-Image Attention for Zero-Shot Appearance Transfer——【代码复现】

本文发表于SIGGRAPH 2024&#xff0c;是一篇关于图像编辑的论文&#xff0c;Github官网网址如下&#xff1a; garibida/cross-image-attention&#xff1a; “Cross-Image Attention for Zero-Shot Appearance Transfer”的正式实现 (github.com) 一、基本配置环境准备 请确保…

国产之光:SmartEDA电路仿真软件何以超越传统,引领新潮流?

在当今电子工程领域&#xff0c;电路仿真软件的重要性不言而喻。它不仅是工程师们进行电路设计、分析和优化的得力助手&#xff0c;也是学生们深入理解电路原理、提高实践操作能力的关键工具。近年来&#xff0c;一款名为SmartEDA的国产电路仿真软件逐渐崭露头角&#xff0c;以…

Python 全栈系列244 nginx upstream 负载均衡 踩坑日记

说明 最初是因为租用算力机(Python 全栈系列242 踩坑记录:租用算力机完成任务)&#xff0c;所以想着做一个负载均衡&#xff0c;然后多开一些服务&#xff0c;把配置写在nginx里面就好了。 一开始租用了一个3080起了一个服务&#xff0c;后来觉得速度不够快&#xff0c;再起了…

el-menu 保持展开点击不收缩 默认选择第一个菜单

<el-menu:default-openeds"[/system]" 数组 默认展开第一个:collapse"isCollapse"close"handleClose" 点击关闭的时候 让菜单打开 就可以实现保持展开效果ref"menus":unique-opened"true":active-text-color"se…

笔记-跨域方式实现原理

websocket Websocket是HTML5的一个持久化的协议&#xff0c;它实现了浏览器与服务器的全双工通信&#xff0c;同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议&#xff0c;都基于 TCP 协议。但是 WebSocket 是一种双向通信协议&#xff0c;在建立连接之后&#xff…

振弦采集仪在岩土工程中的实时监测和预警作用

振弦采集仪在岩土工程中的实时监测和预警作用 河北稳控科技振弦采集仪被广泛应用于岩土工程中的实时监测和预警。它通过对地下振弦信号的连续监测和分析&#xff0c;能够提供准确的地下结构变形和应力变化信息&#xff0c;为岩土工程的安全和稳定提供重要的支持。 振弦采集仪主…

python爬虫(四)之九章智算汽车文章爬虫

python爬虫&#xff08;四&#xff09;之九章智算汽车文章爬虫 闲来没事就写一条爬虫抓取网页上的数据&#xff0c;现在数据已经抓完&#xff0c;将九章智算汽车文章的爬虫代码分享出来。当前代码采用python编写&#xff0c;可抓取所有文章&#xff0c;攻大家参考。 import r…

宝塔安装多个版本的PHP,如何设置默认的PHP版本

如何将默认的PHP版本设置为7.3.32&#xff0c; 创建软链接指向7.3版本&#xff0c;关键命令&#xff1a;ln -sf /www/server/php/73/bin/php /usr/bin/php 然后再查看PHP版本验证一下结果 [rootlocalhost ~]# ln -sf /www/server/php/73/bin/php /usr/bin/php [rootlocalho…

共享充电宝语音芯片ic方案支持远程4g无线更新语音

一、简介 共享充电宝语音芯片ic方案支持远程4g无线wifi蓝牙更新语音 共享充电宝已经是遍布在大街小巷的好产品&#xff0c;解决了携带充电宝麻烦的痛点 但是很多的共享充电宝在人机交互方便&#xff0c;还做得不够好&#xff0c;比如&#xff1a;借、还设备没有语音提示&…

开散列哈希桶

通过上面这幅图&#xff0c;读者应该能较为直观地理解何为开散列&#xff0c;以及闭散列与开散列的区别在哪里 —— 数据的存储形式不同&#xff0c;至于其他的&#xff0c;如确定每个元素的哈希地址等一概相同。 与闭散列相比&#xff0c;开散列能够更好地处理发生冲突的元素 …

知识付费行业数字化转型:转的是什么?你知道吗!

在知识付费的浪潮中&#xff0c;数字化转型正悄然改变着这个行业的格局&#xff01;那么&#xff0c;知识付费行业数字化转型到底转的是什么呢&#xff1f;这是一个值得我们深入探讨的问题。 1.转的是商业模式&#xff1a;从传统的销售模式转向多元化的盈利模式。从简单的买卖关…

数据结构(二) 线性表

2024年5月13日一稿 线性表的定义与基本操作 数据类型相同(各个元素占用空间相同) 是有限序列 基操

Netty源码分析二NioEventLoop 剖析

剖析方向 NioEventLoop是一个重量级的类&#xff0c;其中涉及到的方法都有很复杂的继承关系&#xff0c;调用链&#xff0c;要想把源码全部过一遍工作量实在是太大了&#xff0c;于是小编就基于下面的这些常见的问题来对NioEventLoop的源码来进行剖析 1.Seletor何时创建 1.1Se…

前端Vue架构

1 理解&#xff1a; 创建视图的函数&#xff08;render&#xff09;和数据之间的关联&#xff1b; 当数据发生变化的时候&#xff0c;希望render重新执行&#xff1b; 监听数据的读取和修改&#xff1b; defineProperty&#xff1a;监听范围比较窄&#xff0c;只能通过属性描…

基于SSM的计算机课程实验管理系统的设计与实现(源码)

| 博主介绍&#xff1a;✌程序员徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f44…

架构每日一学 5:拼多多如何通过洞察人性脱颖而出?

本文首发于公众平台&#xff1a;腐烂的橘子 上一篇文章&#xff0c;我们讲到架构活动一定要顺应人性&#xff0c;今天我们就来聊一聊&#xff0c;拼多多如何通过洞察人性在电商行业脱颖而出。 拼多多从诞生到现在&#xff0c;可以说是颠覆了整个互联网的认知。 2015 年&#…

JSON 转为json串后出现 “$ref“

问题描述 转为JSON 串时出现 "$ref":"$.RequestParam.list[0]" $ref&#xff1a; fastjson数据重复的部分会用引用代替&#xff0c;当一个对象包含另一个对象时&#xff0c;fastjson就会把该对象解析成引用 “$ref”:”..” 上一级 “$ref”:”” 当前对…

SpringBoot自动配置源码解析+自定义Spring Boot Starter

SpringBootApplication Spring Boot应用标注 SpringBootApplication 注解的类说明该类是Spring Boot 的主配置类&#xff0c;需要运行该类的main方法进行启动 Spring Boot 应用 SpringBootConfiguration 该注解标注表示标注的类是个配置类 EnableAutoConfiguration 直译&#…

日本率先研发成功6G设备,刺痛了谁?为何日本能率先突破?

日本率先研发成功6G设备&#xff0c;无线数据速率是5G的百倍&#xff0c;这让日本方面兴奋莫名&#xff0c;毕竟日本在科技方面从1990年代以来太缺少突破的创新了&#xff0c;那么日本为何如今在6G技术上能率先突破呢&#xff1f; 日本在1980年代末期达到顶峰&#xff0c;它的科…