FIR滤波器简述及FPGA仿真验证

news2025/1/18 2:13:36

数字滤波器的设计,本项目做的数字滤波器准确来说是FIR滤波器。

FIR滤波器(有限冲激响应滤波器),与另一种基本类型的数字滤波器——IIR滤波器(无限冲击响应滤波器)相对应,其实就是将所输入的信号都看成是离散的,用离散的冲击信号代替实际的信号。对于FIR滤波器而言,就是将有限个最近输入的冲击信号进行加权平均运算得到新的输出信号,用以滤除其他不需要的信号。而IIR滤波器不仅需要对输入信号进行加权平均,对输出信号也要进行加权平均,从而得到新的输出信号,滤除其他不需要的信号。

FIR滤波器的算法就是类似卷积的算法。核心其实就是加权平均,即:

Y(n)=h(0)*x(n)+h(1)*x(n-1)+h(2)*x(n-2)+h(3)*x(n-3)+……+ h(N-1)*x(n-N+1)

X(n)是我们待滤波的信号,h(n)是滤波器系数。

在用Verilog编程之前用MATLAB计算出h(k)(k=0~N-1)权重。

对于FPGA而言,有两种方法可以实现FIR滤波器的设计,一种是通过Verilog语言编写,另一种是通过IP核实现。

用Verilog语言编写需要通过Matlab的工具箱生成h(k)(k=0~N-1)权重。而用IP核的话直接在软件里生成就行,本文是以Quartus软件为例。

本文刚开始还不想用IP核来生成的,并介绍了使用Matlab中FDATOOL工具箱的方法,然后后面改用了IP核的方式来完成FIR滤波器的设计与仿真。

Fdatool生成FIR相关的系数

打开matlab的fdatool工具箱。

bde93c13cdcf4f7d989b4c8132ff8abb.png

然后选择设计需要的滤波器,低通,FIR滤波器,窗函数设计(Window),采用布莱克曼窗(Blackman),99阶(这样有100个系数),采样频率50MHz,通带频率1.5MHz。

afa9f33ae60e4bcb82e2c3f01f598b97.png

按照上图设定参数后,在上图中Specify order是阶数,Fc是截止频率,Fs是序列的采样频率。点击Design Filter。

82a5792a82dc4e9e97b46c4c7697d634.png

设计完成了,可以看到显示的频率为0~Fs/2的幅频响应,大概在2MHz左右幅度下降为原来的-60dB以下,也就是正常幅度的千分之一。

由于在FPGA中计算浮点数是一件很麻烦的事情,此处就设置成定点数,且位数越高越精确,这里设置的是16位定点数来量化。

07c795f59e824a86a8008f6bceb7b410.png

f7c253fc72a8458c953be07e2ea0a447.png

然后点击Apply。下方图片中实线是量化后的,虚线是未量化过的精准的。可以看到虽然5MHz之后的阻带衰减不如原来,但也可以衰减到-100dB,也就是原来的1/100000。这个衰减程度已经足够了。

ab2dcf42e5304849be1f35dbceeb01cb.png

最后是导出系数。直接通过file——export导出的是没有经过量化的系数,通过量化的系数要经过Targets———XILINX Coefficient file导出.coe文件就可以查看量化后的数了。

e97469835cbc463996391750e0eac1e6.png

新建Quartus工程设计FIR滤波器

首先创建好工程,这里不再赘述。

然后,生成FIR Compiler II 的IP核,随意先生成了一个,但是好像还不太对。后来才知道,应该选用FIR Complier v13.1的FIR IP核。首先进入step1,最开始要设置好滤波器系数,但是不知道为什么就是导不进去。如果可以导进去的话那么matlab中的fdatool工具箱我们就是用到了,但是问题就是导不进去。不过好在点击上面那个floating Coefficient Set可以自动生成浮点数的滤波器系数。

ee158fd3681a482781f572320408b0d2.png

于是我们简单设置以下,让IP核自动生成相应的系数。

ecce4767cf4e4f999fa33389a662c4df.png

然后设置一下数据位宽

f7a092eb076b465082bdb7b0ca5f5415.png

Step2的内容就全部勾选即可,然后进入step3自动生成IP核。

仿真

采用IP核的方式产生的FIR滤波器仿真的话直接通过编辑textbench仿真文件的方式仿真;采用Verilog语言编写方式产生的FIR滤波器在编辑textbench仿真文件之前还需对顶层.v文件进行编辑。

首先介绍采用IP核的方式仿真,一开始遇到的问题是关于FIR Compliter的IP核没有破解,后来需要改一下Licence文件才能使用。如下图所示,原来红框中是00A2,后来改成FIR Compliter的IP核的ID号,然后重启就能正常编译使用了。

49cf9f8950984a88b7ccbc7b8d81ae30.png

64604b519fec47699d27ec250fd7ccea.png

然后遇到的问题是待滤波的数据和滤波后的数据分别是怎样输入进去以及怎样输出保存起来的。先做一种尝试,待滤波的数据通过Matlab生成并存放在.txt文档中,然后在仿真文件里调用该文档的数据,不过要注意采样周期和采样数据点的问题,也就是时序的问题。输出的数据的话先不用管,直接通过仿真看滤波后输出数据的变化即可。

编写Matlab程序产生待滤波信号,产生两个信号0.5MHz和5MHz,采样频率50MHz,采样5个周期,进行16-bit量化,并把量化后的数据写到.txt文件中。目前的问题在于怎么转换成16位二进制数。最后还是选择一种比较好的方法。首先判断读取的一个数是否大于零,如果大于零,直接采用dec2bin函数转换成16位的二进制数;如果小于零,则用216e6d082af578d47f7b6508a01a67adef0.png减去该数的绝对值,再用dec2bin函数将其转换成16位的二进制数。主要卡在如何分别读取每一个数上面,还是对matlab的操作不太熟悉。不过好在最后还是弄出来了。Matlab相关程序如下图所示。

2be0c13300904812bfbced6ada833411.png

最终生成的十进制数和二进制数的txt文件内容如下图所示。

b8b2b76f7a7749588404afefb5d3c702.png0c40aed2ff264864b2b428692edaf2c6.png

然后再学习一下FFT算法,利用matlab先对输入的数据进行频谱分析。有两种方法,一种是编写程序的方法,在MATLAB中,FFT的调用函数主要有两个,即:Y=FFT(X)和Y=FFT(X,N)。网上的例子:

clf;
fs=100;N=128;   %采样频率和数据点数
n=0:N-1;t=n/fs;   %时间序列
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t); %信号
y=fft(x,N);    %对信号进行快速Fourier变换
mag=abs(y);     %求得Fourier变换后的振幅
f=n*fs/N;    %频率序列
subplot(2,2,1),plot(f,mag);   %绘出随频率变化的振幅
xlabel('频率/Hz');
ylabel('振幅');title('N=128');grid on;

一种是利用Simulink仿真模型的方法。首先导入数据,然后进入Simulink。利用Powergui模块进行FFT分析,加上一个Form warkspace和一个示波器就可以了,具体就不介绍。

905f05e37ff4412c91f78b34a4cb4bfa.png

我们只需要知道FFT输入的是按时间来划分的采样点数据,经过FFT运算之后得出的是按频率来划分的同样数据长度的数据。

    之后我们进入最关键的阶段,即仿真阶段。我们只需要导入Matlab生成的待滤波信号,然后在仿真软件中观察滤波后的信号即可。

我们先编写好仿真文件。

f0720594272c4aed90a2ebd54ac12d02.png

然后联合Modelsim仿真。右键data_in和data_out设置radix为decimal十进制,format为analog。

b7f71364ce5e4058896a8b41fed61112.png

得到仿真结果,可以看到其周期为2000ns,即0.5MHz,表示5MHz干扰滤除干净了。

523ccb64df0340e49f5d76d830cafa7f.png

本文大部分内容都属于原创,如需转载,请附上本文网站,

如果需要相关的仿真图、程序代码等资料可以直接私信我,我会及时回复。

 

 

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

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

相关文章

算法通关村第十九关——动态规划是怎么回事(青铜)

算法通关村第十九关——动态规划是怎么回事(青铜) 前言1 什么是动态规划2 动态规划的解题步骤3 简单入门3.1 组合总和3.2 最小路径和3.3 三角形最小路径和 4 理解动态规划 前言 动态规划是一种解决复杂问题的算法思想,它将一个大问题分解为多…

Apache HTTPD 多后缀名解析漏洞复现

什么是多后缀名解析漏洞加粗样式: 多后缀名解析漏洞(Multiple Extension Handling Vulnerability)指的是一种安全漏洞,发生在某些操作系统或网络服务中的文件扩展名处理机制中。 这种漏洞的本质是当文件具有多个后缀名(例如file.…

l8-d12 IP协议与ethernet协议

一、IP协议作用和意义 分组在互联网中的传送 分组传输路径 二、IP 数据报首部格式 1.IP 数据报的格式 版本——占 4 位,指 IP 协议的版本。目前的 IP 协议版本号为 4 (即 IPv4)。 首部长度——占 4 位,可表示的最大数值是 15 个单位(一个单位为 4 字…

【Spring】手动实现Spring底层机制-问题的引出

🎄欢迎来到边境矢梦的csdn博文🎄 🎄本文主要梳理手动实现Spring底层机制-问题的引出 🎄 🌈我是边境矢梦,一个正在为秋招和算法竞赛做准备的学生🌈 🎆喜欢的朋友可以关注一下&#x1…

【实践篇】Redis最强Java客户端(四)之Ression分布式集合使用指南

文章目录 0. 前言1.Ression分布式集合1.1 分布式列表1.1.1 使用场景和实现原理:1.1.2 基本概念和使用方法: 1.2 分布式集合1.2.1 使用场景和实现原理:1.2.2 基本概念和使用方法: 1.3 分布式映射1.3.1 使用场景和实现原理&#xff…

CSS三种样式表、样式表优先级、CSS选择器

一、CSS介绍: 1.1、CSS介绍: CSS,全称是:Cascading Style Sheets,层叠样式表,用于修饰HTML页面的。 CSS编写规则如下所示: CSS编写的规则分为两部分,分别是:选择器、声…

SpringMVC学习简要

学习资料: SpringMVC-03-入门案例工作流程解析_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1ZF411G7eP/?p3&spm_id_frompageDriver&vd_source4ac53f52a57eb96a3c8406b971b038ae 常用MYSQL命令:http://t.csdn.cn/zshCP 学习要求 什么是…

微信小程序Day4笔记

1. 组件的创建与引用 创建组件 在项目的根目录中,鼠标右键,创建components -> test文件夹在新建的test文件夹上,鼠标右键,点击新建Component键入组件的名称之后回车,会自动生成组件对应的4个文件,后缀…

《服务器无状态设计:为什么如何实现无状态API?》

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

3.1 栈和队列的定义和特点

3.1.1 栈的定义和特点 主要内容: 3.1 栈和队列的定义和特点 3.1.1 栈的定义和特点 定义: 栈是一种特殊的线性表,只允许在一端进行插入或删除操作。这一端被称为栈顶,而另一端则称为栈底。不包含任何元素的栈被称为空栈。 特点…

分布式调度 Elastic-job

分布式调度 Elastic-job 1.概述 1.1什么是任务调度 我们可以思考一下下面业务场景的解决方案: 某电商平台需要每天上午10点,下午3点,晚上8点发放一批优惠券某银行系统需要在信用卡到期还款日的前三天进行短信提醒某财务系统需要在每天凌晨0:10分结算…

Java虚拟机(JVM)解析:内存区域、类加载、垃圾回收和选型考虑

目录 一、JVM内存区域划分 二、JVM类加载 三、JVM垃圾回收(GC) 一、JVM内存区域划分 栈堆方法区(元数据区)程序计数器 1.栈 举个例子: 那具体是怎么分的呢?如下图 本地方法栈:给JVM内部的方法准备的栈空间 虚拟…

在MySQL客户端使用Tab健进行命令补全

在MySQL客户端中,你可以使用Tab键进行命令补全,这将提高我们的效率,这与Linux命令行中的行为类似。例如,如果你输入SEL然后按Tab键,MySQL客户端会自动补全为SELECT。 然而,需要注意的是,这个功能…

数据结构 - 栈

目录 二、栈的实现 1.数组模拟实现栈 设计思想: 方法实现: Peek(): 偷窥栈顶元素 pop(): 栈顶出栈 push(): 2.链表模拟实现 3 . 栈的继承体系 总结 前言 大家好,这篇博客带大家了解一下栈是什么? 并且用两种方式为大家实现一下栈 一、栈是什么? 栈是一种数…

npm介绍

npm介绍 npm(Node Package Manager的缩写)是一个软件包管理器,主要进行JavaScript的包管理。通过npm,我们可以很方便地进行JavaScript包的下载、升级,我们也可以把我们开发的JavaScript包共享给其他使用者。 在npm没…

大数据-玩转数据-Flink状态后端(下)

一、状态后端 每传入一条数据,有状态的算子任务都会读取和更新状态。由于有效的状态访问对于处理数据的低延迟至关重要,因此每个并行任务(子任务)都会在本地维护其状态,以确保快速的状态访问。 状态的存储、访问以及维护,由一个…

goweb入门

创建gomod项目 go mod init web01新建main.go package mainimport ("fmt""net/http" )func handler(writer http.ResponseWriter, request *http.Request) {fmt.Fprintf(writer, "Hello World,%s!", request.URL.Path[1:]) } func main() {fmt…

Mysql基于成本选择索引

本篇文章介绍mysql基于成本选择索引的行为,解释为什么有时候明明可以走索引,但mysql却没有走索引的原因 mysql索引失效的场景大致有几种 不符合最左前缀原则在索引列上使用函数或隐式类型转换使用like查询,如 %xxx回表代价太大索引列区分度过…

PHP8中获取并删除数组中最后一个元素-PHP8知识详解

在php8中&#xff0c;array_pop()函数将返回数组的最后一个元素&#xff0c;并且将该元素从数组中删除。语法格式如下&#xff1a; array_pop(目标数组) 获取并删除数组中最后一个元素&#xff0c;参考代码&#xff1a; <?php $stu array(s001>明明,s002>亮亮,s…

Ansible数组同步至Shell脚本数组中

1、ansible中定义数组&#xff0c;我以 ccaPojectList 数组为例子,如下图数组内容 2、需要写一个j2模板的Shell脚本&#xff0c;在j2模板的Shell脚本中引用ansible的 ccaPojectList 数组&#xff0c;大致如下图&#xff1a; {% for item in ccaPojectList %} "{{ item }…