基于FPGA的数字信号处理(9)--定点数据的两种溢出处理模式:饱和(Saturate)和绕回(Wrap)

news2024/10/5 20:27:35

1、前言

在逻辑设计中,为了保证运算结果的正确性,常常需要对结果的位宽进行扩展。比如2个3bits的无符号数相加,只有将结果设定为4bits,才能保证结果一定是正确的。不然,某些情况如7+7 = 14(1110),如果结果只用3bits表示那么就成了110(6)了,这样运算的结果就是错的。同理,乘法操作需要扩展的位宽更大,是两个乘数的位宽之和,比如2个3bits的无符号数做乘法,结果需要设定为6bits。

如果在后续数据处理的过程中,一直都这样对结果的位宽进行扩展,那么在算法链很长的情况下,将会消耗大量的逻辑资源。因此在设计中,常常需要对数据进行的位宽进行处理。

数据的位宽处理分为两个部分:

  • 对整数的处理:例如原本用6bits表示的结果,下级模块规定只能用到4bits输入。因为6bits的表示范围大于4bits,就有可能出现4bits无法表示的情况(即溢出)
  • 对小数的处理:原理同上。四舍五入就是一种经典的对小数截位的方式,类似的方法还有ceili,floor,nearest等等。

本文只讨论整数部分的溢出截位处理,小数部分的处理下篇文章再说。对整数的截位处理,实际上就是对溢出的处理,其决定了当运算结果大于该数位宽所能表示的最大值时,如果对溢出部分处理。通常有两种对溢出的处理方式:

  • Saturate(饱和):一旦数据溢出,那么就将结果饱和处理为最大值或最小值(取决于正向溢出还是负向溢出)
  • Wrap(绕回/截断):一旦数据溢出,那么就直接将溢出的高位截断

将6bits的整数41截位到4bits,两种溢出模式的处理结果如下:

image-20240416110157962


2、Saturate

因为有符号数和无符号存在表示范围的区别,所以二者的溢出处理也存在一定的区别,接下来对两种情况分别进行讨论。

2.1、无符号数的Saturate

Saturate是当数据溢出时,就直接用最大值或最小值来表示。因为无符号数不能表示负数,因此不存在对于负数的饱和处理,只存在正向的饱和。例如要将1个6bits的数截断到4bits,因为4bits能表示的最大值是15,那么所有大于15的数,都直接用15来表示,示意图如下:

将1个6bits的输入Saturate为4bits的输出,用Verilog可以这么写:

module test(
	input		[5:0]	data_6bits,
	output  reg	[3:0]	data_4bits	
);

always@(*)
begin
	if(data_6bits > 4'd15)			//溢出了
		data_4bits = 4'd15;			//饱和到最大值
	else				
		data_4bits = data_6bits;	//没溢出则直接赋值
end
  
endmodule 

除了直接用大于符号(data_6bits > 4’d15)来判断是否溢出外,也可以这样判断:

if(|data_6bits[5:4]) //判断高2位是否存在1,若存在则该数的值必定大于15

再写个TB测试一下:因为输入比较少,所以可以用穷举法来测试,把输入从最小值0开始累加最大值63,观察输出是否会被Saturate

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

reg		[5:0]	data_6bits;
wire	[3:0]	data_4bits;

//例化被测试模块
test	test_inst(
	.data_6bits		(data_6bits),
	.data_4bits		(data_4bits)
);

initial begin
	data_6bits = 0;
	while(~(&data_6bits))begin			//当输入不全为1,即非最大值
		data_6bits = data_6bits + 1;	//从0开始累加1
		#5;
	end
	#20 $stop();
end

endmodule

仿真结果是这样的:

image-20240416121238935

当输入超过4bits位宽能表示的最大值15时,就会都饱和处理,即输出为最大值15。

2.2、有符号数Saturate

对于有符号数的Saturate处理有两种情况:

  • 正数太大无法表示,只能饱和到最大值。例如4bits有符号数最大只能表示 7,那么大于7的数就只能饱和处理为 7。
  • 负数太小无法表示,只能饱和到最小值。例如4bits有符号数最小只能表示 -8,那么小于-8的数就只能饱和处理为 -8。

当数据溢出时,就直接用最大值或最小值来表示。因为无符号数不能表示负数,因此不存在对于负数的饱和处理,只存在正向的饱和。例如要将1个6bits的数截断到4bits,因为4bits能表示的最大值是15,那么所有大于15的数,都直接用15来表示,示意图如下:

5

例如,将1个6bits的有符号数Saturate为4bits,对于数据的正向溢出判断和无符号数的Saturate是类似的,只要判断除了符号位的多出来的高位是否有1即可。

对于数据的负数方向溢出判断要麻烦一点,首先我们要知道,对于一个有符号的负数,在其高位扩展符号位,其数值是不会改变的。例如:

10\110\1110\11110,它们表示的都是 -2。

把6bits截位到4bits,只要判断它的高三位(因为讨论的是负数,所以最高位肯定是1)是否都为1就行了,如果是的话,说明高3位可是视为是1位符号位的扩展,数据的表示范围等价于4bits的表示范围。如果不为全1,则说明比4bits的表示范围要大,即数据产生了溢出。

综上,用Verilog可以这么写:

module test(
	input		[5:0]	data_6bits,
	output  reg	[3:0]	data_4bits	
);

always@(*)
begin
	if(~data_6bits[5] && (|data_6bits[4:3]))			//判断条件(正数 && 溢出),即正向溢出了
		data_4bits = 4'b0111;							//饱和到最大值7
	else if(data_6bits[5] && ~(&data_6bits[4:3]))		//判断条件(负数 && 溢出),即负向溢出了			
		data_4bits = 4'b1000;							//饱和到最小值-8
	else	
		data_4bits = data_6bits;						//没溢出则直接赋值
end
  
endmodule 

仍然用上面的TB,仿真结果如下:

image-20240416132626605


3、Wrap

Wrap从字面上理解是绕回,什么是绕回呢?比如一块手表,它只能表示0点~12点,超出了12点的话,它就会绕回到0点再重新开始。比如13点的表示就是到了12点后,再走到了1点。

对数据的Wrap处理也是类似的,比如4bits的无符号数最多只能表示1111(15),这个时候如果再加1就是16了,16是表示不了的。Saturate是直接表示最大值15,而Wrap则是重新回到开始表示0。类似的,17就Wrap到1,18就Wrap到2,19就Wrap到3,依此类推。示意图如下:

对于有符号数的Wrap处理也是一样的截掉高位,但是因为有符号数可以表示负数,所以它的绕回是从最小的负数开始的,例如最大的4bits有符号数是0111即7,溢出后是1000即-8,示意图如下:

Wrap处理用Verilog是很好实现的,因为它本质上相当于截掉高位,而截掉高位这个操作是可以被综合工具自动实现的,它甚至都不需要消耗任何逻辑资源。比如,将1个6bits的输入Wrap为4bits的输出,用Verilog可以这么写:

module test(
	input		[5:0]	data_6bits,
	output  	[3:0]	data_4bits	
);
			
assign	data_4bits = data_6bits;		//直接赋值即可,工具会自动截位
//等价于下面的语句
//assign	data_4bits = data_6bits[3:0];
  
endmodule 

用上面的TB测试就行,无符号数的测试结果如下:

image-20240416135556104

有符号数的测试结果如下:

image-20240416135211386

可以看到当输入大于4bits能表示的最大值后,就会回到最小值重新开始,相当于截掉了高位。


4、总结

  • Saturate相当于溢出时,将结果保留在最大值或最小值;而Wrap则是溢出时重新绕回到起点。
  • 相对来说Saturate损失的精度比较小,结果较为准确,但是消耗的硬件资源比Wrap方式要多;Wrap不需要消耗硬件资源,因为它实际上相当于截掉高位,等于是没有什么处理,精度损失大,结果不太准确(尤其是有符号数的Wrap),只适用于特定场合。

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

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

相关文章

FileBird Pro插件下载:革新您的WordPress媒体库管理

WordPress媒体库是您网站的重要组成部分,它存储了所有的图片、视频、文档等文件。但随着网站的扩展,媒体库的管理变得越来越复杂。FileBird Pro插件,作为一款专为WordPress用户设计的媒体库管理工具,以其直观的界面和强大的功能&a…

嵌入式系统应用-拓展-FLASH之操作 SFUD (Serial Flash Universal Driver)之KEIL移植

1 SFUD介绍 1.1 初步介绍 SFUD 是一个开源的串行 SPI 闪存通用驱动库。由于市面上有各种类型的串行闪存设备,每种设备都具有不同的规格和指令,因此 SFUD 的设计目的是解决这些差异。这使得我们的产品可以支持不同品牌和规格的闪存,增强了软…

幻兽帕鲁游戏主机多少钱?幻兽帕鲁游戏服务器一个月仅需32元

随着游戏产业的蓬勃发展,腾讯云紧跟潮流,推出了针对热门游戏《幻兽帕鲁Palworld》的专属游戏服务器。对于广大游戏爱好者来说,这无疑是一个激动人心的消息。那么,腾讯云幻兽帕鲁游戏主机到底多少钱呢?让我们一起来揭晓…

施耐德EOCR3BZ2-WRAUH数显型马达保护器

施耐德EOCR3BZ2-WRAUH数显型马达保护器 ◆ 高性能多功能电动机保护器 ◆ 实时监测/高精度 ◆ 可为单相或三相交流负载提供可靠保护 ◆ 保护功能:过电流、欠电流、反转、缺相、失速、电流不平衡和接地保护功能 ◆ 附加功能:掉电保护、运行时间累计、…

太阳能4G/5G无线视频监控系统解决方案(下)

目录 一、系统简介 (一)系统概述 (二)系统特点 (三)应用场景 二、系统原理和架构 (一)系统原理 1、拓扑图 2、系统组成介绍 (二)太阳能供电子系统 …

计算机SCI期刊,中科院2区,IF=6+,自引率低,专业认可度高!

一、期刊名称 Journal of King Saud University-Computer and Information Sciences 二、期刊简介概况 期刊类型:SCI 学科领域:计算机科学 影响因子:6.9 中科院分区:2区 出版方式:开放出版 版面费:$…

ADS基础教程9-理想模型和厂商模型实现及对比

目录 一、概要二、厂商库使用1.新建cell2.调用厂商库中元器件3.元器件替换及参数选择4.完成参数选择5.导入子图 三、仿真实现注意事项 一、概要 本文将介绍在ADS中调用厂商提供的库,来进行原理图仿真,并实现与ADS系统提供的理想元器件之间的比较。 二、…

Linux服务器常用巡检命令

在Linux服务器上进行常规巡检是确保服务器稳定性和安全性的重要措施之一。以下是一些常用的巡检命令和技巧: 1. 查看系统信息 1.1 系统信息显示 命令:uname -a ​​​​ [rootlinux100 ~]# uname -a Linux linux100 4.15.0-70-generic #79-Ubuntu SMP…

Java特性之设计模式【享元模式】

一、享元模式 概述 享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式 享元模式尝试重用现有的同类对…

腾讯地图商业授权说明一篇文章讲清楚如何操作

最近在使用腾讯地图,发现我要上架应用商店APP需要我有地图的授权书。 认真研究了一下原来腾讯地图现在要收费了,如果你打算以商业目的使用它,比如对第三方用户收费或者进行项目投标等,就需要先获取腾讯位置服务的商业授权许可。申…

Linux网络部分——DNS域名解析服务

目录 1. 域名结构 2. 系统根据域名查找IP地址的过程 3.DNS域名解析方式 4.DNS域名解析的工作原理【☆】 5.域名解析查询方式 6.搭建主从DNS域名服务器 ①初始化操作主服务器和从服务器,安装BIND软件 ②修改主服务器的主配置文件、区域配置文件、区域数…

(数据分析方法)长期趋势分析

目录 一、定义 二、目的 三、方法 1、移动平均法 (1)、简单移动平均法 (2)、加权移动平均法 (3)、指数平滑法 2、最小二乘法 3、线性回归 1、数据预处理 2、观察数据分布建立假设模型 3、定义损失函数 4、批量梯度下降 5、优化 4、LSTM 时序分析 5、特征工程 一…

线程详解(接上篇博客)

目录 1.生产者消费者模型; 2.基于环形队列的生产者消费者模型; 3.线程池; 4.STL, 智能指针, 线程安全; 5.读者写者问题. 前言: 本篇博客博主五一假期都在肝的一篇, 希望xdm点点三连, 博主感谢了 onz !!! 1.生产者消费者模型 321原则:(便于记忆) 3是指3种关系: 生产者和生产…

Chat2DB Pro 重磅发布 !!!

在过去的几个月中,我们的团队一直默默耕耘,全心投入到Chat2DB Pro版本的开发之中。这段时间里,我们暂停了新动态的发布,以至于有趣的误解在社群中出现,有人调侃我们是否“倒闭”了。然而,我们今天携带着全新…

Java-(乘法表之后)增强for循环

这里我们先做个了解,之后我会在数组中进行详细介绍Java5引入了一种主要用于数组或集合的增强型for循环Java增强型for循环语法格式如下 For(声明语句:表达式){ //代码语句 } 声明语句:声明新的局部变量,该变量的类型…

【智能算法】PID搜索算法(PSA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2023年,Y Gao受到PID控制理论启发,提出了PID搜索算法(PID-based Search Algorithm, PSA)。 2.算法原理 2.1算法思想 PID算法是控制领域的…

CTF(Web)中关于执行读取文件命令的相关知识与绕过技巧

在我遇到的题目中,想要读取文件必然是要执行cat /flag这个命令,但是题目当然不会这么轻松。让你直接cat出来,必然会有各种各样的滤过条件,你要做的就是尝试各种方法在cat /flag的基础上进行各种操作构建出最终的payload。 下面我…

Redis学习汇总

目录 1.Linux环境下安装redis 2.redis的数据结构及命令 3.redis.conf配置文件常用配置 3.redis的事务操作 4.redis实现乐观锁 5.通过jedis操作redis 6.Springboot集成redis 7.自定义一个RedisTemplate 8.持久化策略 RDB和AOF 9.redis集群环境搭建 10.哨兵模式 11.缓…

Java面试题:多线程2

如何停止正在运行的线程 1,使用退出标志,使线程正常退出(run方法中循环对退出标志进行判断) 2,使用stop()方法强行终止(不推荐) 3,调用interrupt()方法中断线程 打断阻塞线程(sleep,wait,join),线程会抛出InterruptedException异常 打断正常的线程,可以根据打断状态来标记…

奶爸预备 |《P.E.T.父母效能训练:让亲子沟通如此高效而简单:21世纪版》 / 托马斯·戈登——读书笔记

目录 引出致中国读者译序前言第1章 父母总是被指责,而非受训练第2章 父母是人,不是神第3章 如何听,孩子才会说:接纳性语言第4章 让积极倾听发挥作用第5章 如何倾听不会说话的婴幼儿第6章 如何听,孩子才肯听第8章 通过改…