IIR滤波器的FPGA实现中出现直流分量(波形不停下移)问题的原因和解决方法

本文主要是介绍IIR滤波器的FPGA实现中出现直流分量(波形不停下移)问题的原因和解决方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

      最近用FPGA实现一个带通IIR滤波器,采用matlab的fdatool设计得到滤波器的系数,然后根据杜勇的《数字滤波器的matlab与FPGA实现》中介绍的方法进行零点和极点系数量化,采用的结构是直接I型IIR滤波器。刚开始用modelsim进行的功能仿真得到的结果是这样的。

      刚开始看起来效果还可以,因为我只让它对2000个点滤波,这些点输入完后滤波就仿真就结束了。

      后来,放了一段时间后,对更多的点滤波,突然发现出问题了,如下图所示。

      滤波器还是原来的滤波器,系数也没变,滤的波也没变,只是长度加长了,但是可以看到滤波后的波形不停下移,像是滤波结果减了一个具体的数值一样。刚开始以为是对原始数据加长时用的粘贴复制,导致每段数据的开头的数据都是0,导致了这个问题,但是后来完美镶嵌后还是这样。

      后面把滤完波的数据送到matlab中

      蓝色虚线是原始混合信号,橙黄色实线是滤波后信号。   

      20Hz的200Hz的混合信号,带通滤完波后,200Hz的信号得到抑制,但是在0Hz附近出现了信号,也就是说带通滤波后出现了直流,也就导致了在modelsim中出现波形下移的情况。

     那么问题找了,如何解决呢?

     https://blog.csdn.net/hunterlew/article/details/50710129

     在这篇博客中,我发现了博主提到的一个问题和我的情况很相似

  我们最后的除法是用移位处理代替的,这样就存在一个问题,移位运算相当于MATLAB中的floor,也就是向下取整,此时就存在比较大的误差,于是我赶紧去测了下最开始两个相邻波形的峰值差,与极点系数非常接近,于是赶紧用四舍五入的方法试了下,FPGA的四舍五入方法见这里:http://bbs.21ic.com/icview-2626038-1-1.html

为了防止原网页丢失,这里给复制出来了,

floor, round和saturation是进行bit位削减时常用的方法,floor 和round用于削减低位,saturation用于削减高位。floor和round的区别在于,floor是将低位直接丢掉,而round则是在丢掉低位前先进行四舍五入。round和saturation的使用范例如下:

假设有一个32bit有符号数a[31:0], 其低10bit为小数部分,高22bit为整数部分。如果现在我们需要用一个16bit的整数来尽可能精确地表示a[31:0]。则需要截去全部的小数部分和高6位的整数部分,具体步骤如下:

step1. 用round去掉小数部分并进行四舍五入。

  1. assign add_bit          = a[31] ? (a[9] & (|a[8:0]) ) : a[9];
  2. assign temp[22:0] = {a[31],a[31:10]} + add_bit;

复制代码

分析:第一句判断是否需要进位。设要舍弃部分的值为d, (-1.0<d<1.0)。当a为正,即a[31] = 0时,若a[9]=1, 则说明d>0.5,故可以产生进位。当a为负,即a[31] = 1时,由于负数用补码表示,若直接舍弃d则意味着round up, 即向高位进位。然而,当0>d>-0.5时,不需要进位,而对于补码表示的负数而言,add_bit=1即表示不产生进行。另外,0>d>-0.5即a[9] & (|a[8:0]),因为 - 0.5的补码是10_0000_0000, d>-0.5即a[8:0]不全为0。考虑到四舍五入时可能产生进位,故需要扩展1bit的符号位。

step2. 用saturation去掉temp[22:0]的高7位从而得到16bit的最终结果。

  1. assign res[15:0] = (&temp[22:15]) | !(|temp[22:15]) ? temp[15:0] : {temp[22], {15 { !temp[22] } } }

复制代码

分析:首先判断temp[22:15]是否为全0或全1,若是,则说明其全部为符号位,我们只需要保留temp[15]作为符号位,其余高位bit可以直接丢掉。若temp[22:15]既不是全0又不是全1,则说明temp[22:15]包含数据位,即此时temp[22:0]的值已经超出了16bit有符号数所能表示的最大,此时必然会引入精度丢失问题,为了尽可能提高精度,只能将res[15:0]设置为其所能表示的最大值0x7FFF(temp[22] = 0)或0x8000(temp[22] = 1)。

 

     于是我根据自己的需要,对数据进行了四舍五入处理:

   之后进行了功能仿真,此时令人愉快的图形终于出来了,问题得到了解决

这篇关于IIR滤波器的FPGA实现中出现直流分量(波形不停下移)问题的原因和解决方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/Whistle0602/article/details/103091210
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/289568

相关文章

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu

Java Optional避免空指针异常的实现

《JavaOptional避免空指针异常的实现》空指针异常一直是困扰开发者的常见问题之一,本文主要介绍了JavaOptional避免空指针异常的实现,帮助开发者编写更健壮、可读性更高的代码,减少因... 目录一、Optional 概述二、Optional 的创建三、Optional 的常用方法四、Optio

在Android平台上实现消息推送功能

《在Android平台上实现消息推送功能》随着移动互联网应用的飞速发展,消息推送已成为移动应用中不可或缺的功能,在Android平台上,实现消息推送涉及到服务端的消息发送、客户端的消息接收、通知渠道(... 目录一、项目概述二、相关知识介绍2.1 消息推送的基本原理2.2 Firebase Cloud Me

Spring Boot项目中结合MyBatis实现MySQL的自动主从切换功能

《SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能》:本文主要介绍SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能,本文分步骤给大家介绍的... 目录原理解析1. mysql主从复制(Master-Slave Replication)2. 读写分离3.

Redis实现延迟任务的三种方法详解

《Redis实现延迟任务的三种方法详解》延迟任务(DelayedTask)是指在未来的某个时间点,执行相应的任务,本文为大家整理了三种常见的实现方法,感兴趣的小伙伴可以参考一下... 目录1.前言2.Redis如何实现延迟任务3.代码实现3.1. 过期键通知事件实现3.2. 使用ZSet实现延迟任务3.3

基于Python和MoviePy实现照片管理和视频合成工具

《基于Python和MoviePy实现照片管理和视频合成工具》在这篇博客中,我们将详细剖析一个基于Python的图形界面应用程序,该程序使用wxPython构建用户界面,并结合MoviePy、Pill... 目录引言项目概述代码结构分析1. 导入和依赖2. 主类:PhotoManager初始化方法:__in

idea maven编译报错Java heap space的解决方法

《ideamaven编译报错Javaheapspace的解决方法》这篇文章主要为大家详细介绍了ideamaven编译报错Javaheapspace的相关解决方法,文中的示例代码讲解详细,感兴趣的... 目录1.增加 Maven 编译的堆内存2. 增加 IntelliJ IDEA 的堆内存3. 优化 Mave

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

springboot filter实现请求响应全链路拦截

《springbootfilter实现请求响应全链路拦截》这篇文章主要为大家详细介绍了SpringBoot如何结合Filter同时拦截请求和响应,从而实现​​日志采集自动化,感兴趣的小伙伴可以跟随小... 目录一、为什么你需要这个过滤器?​​​二、核心实现:一个Filter搞定双向数据流​​​​三、完整代码