本文主要是介绍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去掉小数部分并进行四舍五入。
- assign add_bit = a[31] ? (a[9] & (|a[8:0]) ) : a[9];
- 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的最终结果。
- 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实现中出现直流分量(波形不停下移)问题的原因和解决方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!