该篇是FPGA数字信号处理的第二篇,选题为DSP系统中极其常用的FIR滤波器。本文将简单介绍FIR滤波器的原理,详细介绍使用Verilog HDL设计并行FIR滤波器的流程和方法。接下来几篇会介绍串行结构FIR的Verilog设计、使用Quartus和Vivado的IP核设计FIR的方法。
数字滤波器
数字滤波器从实现结构上划分,有FIR和IIR两种。FIR的特点是:线性相位、消耗资源多;IIR的特点是:非线性相位、消耗资源少。由于FIR系统的线性相位特点,设计中绝大多数情况都采用FIR滤波器。

线性相位系统的意义 ,这里的线性相位指的是在设计者关心的通带范围内,LTI系统满足线性相位要求:

1、从延时的角度看:保证了输入信号的相位响应是线性的,即保证了输入信号的延时特性。
2、从相位的角度看:输入的各频率成分的信号之间,相对相位是固定的。通过线性相位系统后,相对相位关系保持不变。

对于关心相位的系统,比如调制解调系统,需要使用FIR滤波器;对于只关心频率成分的系统,比如只是提取某一频率分量,为了节省资源,使用IIR滤波器即可。
FIR滤波器
FIR的最大特点就是其系统响应 h(n)是一个N点的有限长序列,FIR的输出y(n)本质上就是输入信号x(n)和h(n)的卷积(根据傅里叶变换性质,时域卷积等于频域相乘,因此卷积相当于筛选频谱中的各频率分量的增益倍数,某些频率分量保留,某些频率分量衰减,从而实现滤波效果)。FIR在实现上的本质是带抽头延迟的加法器和乘法器的组合,每一个乘法器对应一个系数。

由理论知识可知,只有当FIR的h(n)对称时,FIR滤波器才具有线性相位特性。使用MATLAB等工具设计FIR时,得到的h(n)也都是具有对称性的。

FIR滤波器的实现结构主要有直接型、级联型、频率取样型、格型四种。其中最适合FPGA实现的是直接型。“直接”是指直接由卷积公式得到:

由上图可知,n阶FIR滤波器就需要n个乘法器。如果设计的是线性相位FIR,则h(n)是对称的,利用对称性可以节省一半的乘法器。

FIR滤波器的设计方法有窗函数法、频率取样法、等波纹切比雪夫逼近法(也叫最优设计法)等等。以上所有的理论知识点在任意一本数字信号处理课本中都有详细的推论,本文节省篇幅不再赘述。

MATLAB设计
虽然Quartus和Vivado的FIR IP核中都提供了设计FIR滤波器的功能,但远没有MATLAB设计便捷和强大。设计中通常都是在MATLAB中设计好FIR的单位脉冲响应h(n),或者说滤波器系数,量化后应用到FPGA设计中。

MATLAB提供了基于窗函数设计法的fir1函数、设计任意响应滤波器的fir2函数、最优设计法的firpm函数,以及两个应用程序包“Filter Builder”和“Filter Design&Analysis”,后者通常也被称作FDATOOL。现在最受欢迎的设计方式恐怕就是使用FDATOOL工具,功能强大、界面便捷,且可以直接导出xilinx公司IP核所需的coe文件。

本系列主要是讲述FPGA设计,不详细讨论上述函数及工具的使用,具体情况可以的MATLAB的help中查询。(Ps:博主目前的几个系列都处于开篇阶段,篇幅不多,暂未成体系,目前不再开新坑,等后期应该会出一个“MATLAB数字信号处理系列”)

FPGA设计
从MATLAB到FPGA最重要的工作便是滤波器系数的量化。现在的计算机大多都是64位的,然而为了节省资源,FPGA中进行如此高位宽的运算步进浪费资源而且也没有必要。在MATLAB中将滤波器系数量化为指定位宽,会改变滤波器的频率特性,因此需要做好仿真,确定量化后的系数也能满足FIR的设计需求。

由上节可知FPGA最方便实现的是直接型结构FIR,实现时可以采用并行结构、串行结构、分布式结构,也可以直接使用Quartus和Vivado提供的FIR IP核。本篇先介绍并行FIR滤波器的Verilog设计。设计参考自杜勇老师的《数字滤波器的MATLAB与FPGA实现》。本设计将在Vivado环境下进行仿真。

使用MATLAB设计一个2kHz采样,500Hz截止的15阶低通滤波器(h(n)长度为16),量化位数为12bit,输入信号位宽也为12bit。Verilog设计代码如下。

模块接口:

module Xilinx_FIR_Guide_liuqi
(input rst,                    //复位信号,高电平有效input clk,                    //FPGA系统时钟,频率为2kHzinput signed [11:0] Xin,      //数据输入频率为2khZoutput signed [28:0]Yout      //滤波后的输出数据
);

输出信号的29bit位宽是全分辨率输出,没有截位。“并行”FIR指的是多个乘法器并行地进行滤波器系数与输入数据之间的乘法计算,因此代码中我们需要缓存16个数据:

reg signed[11:0] Xin_Reg[15:0];   //[11:0]指单数据12bit位宽;[15:0]指共有16个数据
reg [3:0] i,j;
always @(posedge clk or posedge rst)if (rst)//初始化寄存器值为0begin for (i=0; i<15; i=i+1)Xin_Reg[i]=12'd0;endelsebeginfor (j=0; j<15; j=j+1)  //每个时钟移位一个数据Xin_Reg[j+1] <= Xin_Reg[j];Xin_Reg[0] <= Xin;end

由FIR系数的对称性可知,16个系数只需要8个乘法器即可,因此应该将对称系数多对应的输入数据相加:

reg signed [12:0] Add_Reg[7:0];
always @(posedge clk or posedge rst)if (rst)//初始化寄存器值为0begin for (i=0; i<8; i=i+1)Add_Reg[i]=13'd0;endelsebeginfor (i=0; i<8; i=i+1)   //对称系数相加Add_Reg[i]={Xin_Reg[i][11],Xin_Reg[i]}+{Xin_Reg[15-i][11],Xin_Reg[15-i]};end

由于加法会增加一个bit位宽,因此相加结构扩充为13bit。由于输入数据为二进制补码带符号数,因此在相加前需要先使用Verilog中的拼接运算符{}扩展符号位到最高位。接下来例化8个乘法器IP核进行乘法运算:

wire signed [11:0] coe[7:0] ;    //滤波器为12比特量化数据wire signed [24:0] Mout[7:0];   //乘法器输出为25比特数据assign coe[0]=12'h000;assign coe[1]=12'hffd;assign coe[2]=12'h00f; assign coe[3]=12'h02e;   assign coe[4]=12'hf8b;assign coe[5]=12'hef9;    assign coe[6]=12'h24e;assign coe[7]=12'h7ff; mult_gen_0 Umult0 (.CLK (clk),.A (coe[0]),.B (Add_Reg[0]),.P (Mout[0]));           mult_gen_0  Umult1 (.CLK (clk),.A (coe[1]),.B (Add_Reg[1]),.P (Mout[1]));       mult_gen_0  Umult2 (.CLK (clk),.A (coe[2]),.B (Add_Reg[2]),.P (Mout[2]));       mult_gen_0  Umult3 (.CLK (clk),.A (coe[3]),.B (Add_Reg[3]),.P (Mout[3]));       mult_gen_0  Umult4 (.CLK (clk),.A (coe[4]),.B (Add_Reg[4]),.P (Mout[4]));       mult_gen_0  Umult5 (.CLK (clk),.A (coe[5]),.B (Add_Reg[5]),.P (Mout[5]));       mult_gen_0  Umult6 (.CLK (clk),.A (coe[6]),.B (Add_Reg[6]),.P (Mout[6]));               mult_gen_0  Umult7 (.CLK (clk),.A (coe[7]),.B (Add_Reg[7]),.P (Mout[7]));

12bit的滤波器系数与13bit的输入信号数据相乘结果为25bit。乘法结果累加即为滤波器的输出结果:

reg signed [28:0] sum;
reg signed [28:0] yout;
reg [3:0] k;
always @(posedge clk or posedge rst)if (rst)begin sum = 29'd0; yout <= 29'd0;endelsebeginyout <= sum;sum = 29'd0;for (k=0; k<8; k=k+1)sum = sum+Mout[k];  //相加输出结果end
assign Yout = yout;

8个25bit的数相加,结果可能扩展到29bit,这也是全分辨率输出的结果。可以看到并行结构的FIR乘法、加法运算都是在一个时钟内完成,因此每个时钟都能获得一个输出。
仿真
使用MATLAB生成一个200Hz+800Hz的混合频率信号,写入txt文件,再生成一个噪声信号写入txt文件。编写Testbench读取txt文件对信号滤波。

明显看到经过500Hz低通滤波器滤波后,输入的200Hz+800Hz信号只剩下200Hz的频率分量。

对噪声信号的滤波如下图所示:

第二篇 FPGA数字信号处理_并行FIR滤波器Verilog设计相关推荐

  1. FPGA数字信号处理(二)并行FIR滤波器Verilog设计

    该篇是FPGA数字信号处理的第二篇,选题为DSP系统中极其常用的FIR滤波器.本文将简单介绍FIR滤波器的原理,详细介绍使用Verilog HDL设计并行FIR滤波器的流程和方法.接下来几篇会介绍串行 ...

  2. 数字信号处理_只有FIR滤波器才能做到线性相位,对于IIR滤波器做不到线性相位?

    错误的,IIR滤波器加上一个相位矫正滤波器后,也可以实现线性相位. 对于线性相位滤波器,经常使用FIR滤波器.可以证明,FIR滤波器的单位脉冲响应满足一定条件时,其相位特性在整个频带是严格线性的,这是 ...

  3. FPGA数字信号处理(三)串行FIR滤波器Verilog设计

    该篇是FPGA数字信号处理的第三篇,选题为DSP系统中极其常用的FIR滤波器.本文将在上一篇"FPGA数字信号处理(二)并行FIR滤波器Verilog设计" https://blo ...

  4. 数字信号处理5:FIR滤波器设计

    文章目录 1. 滤波器初识 2. 最直观的滤波方式:频域滤波 3. 傅里叶变换中的加窗 4. FIR滤波器设计 5. 总结 之前的一系列博客中,详细分解了从卷积到FFT的相关知识,不过那些属于理论,是 ...

  5. 数字信号处理——串行FIR滤波器MATLAB与FPGA实现

    前言 本文介绍了设计滤波器的FPGA实现步骤,并结合杜勇老师的书籍中的串行FIR滤波器部分进行一步步实现硬件设计,对书中的架构做了简单的优化,并进行了仿真验证. FIR滤波器的FPGA实现步骤 从工程 ...

  6. FPGA数字信号处理(四)Quartus FIR IP核实现

    该篇是FPGA数字信号处理的第四篇,选题为DSP系统中极其常用的FIR滤波器.本文将在前两篇的基础上,继续介绍在Quartus开发环境下使用Altera(或者叫Intel)提供的FIR IP核进行FI ...

  7. FPGA数字信号处理(六)直接型IIR滤波器Verilog设计

    该篇是FPGA数字信号处理的第六篇,2-5篇介绍了DSP系统中极其常用的FIR滤波器.本文将简单介绍另一种数字滤波器--IIR滤波器的原理,详细介绍使用Verilog HDL设计直接型IIR滤波器的方 ...

  8. FPGADesigner《FPGA数字信号处理系列》目录与传送门

    FPGA数字信号处理(1)数字混频(NCO与DDS的使用): https://blog.csdn.net/fpgadesigner/article/details/80512067 FPGA数字信号处 ...

  9. FIR数字滤波器的FPGA实现(三)-并行FIR滤波器设计

    (三)FIR数字滤波器的FPGA实现-并行FIR滤波器设计 文章目录 (三)FIR数字滤波器的FPGA实现-并行FIR滤波器设计 0 并行FIR滤波器基本原理 1 基于直接型结构的全并行 FIR 滤波 ...

  10. FPGA数字信号处理(十五)多速率FIR滤波器

    该篇是FPGA数字信号处理的第15篇,选题为多速率信号处理系统中用到的多速率FIR滤波器.本文将简单介绍多速率信号处理系统的基本概念,以及使用Quartus和Vivado的IP核设计多速率FIR滤波器 ...

最新文章

  1. 涉密计算机格式化维修,涉密计算机中的涉密信息被删除或格式化后,不可复原,可以连接互联网 - 作业在线问答...
  2. windows修改mac地址表
  3. Ubuntu11.10配置Eclipse下Android开发环境
  4. centos7安装rabbitmq简单方式
  5. 小故事分享:千里马与苍蝇的故事
  6. python文件のpandas操作
  7. iOS开发日记24-详解RunLoop
  8. 集合 (二) ----- Map集合详解
  9. linux 0.11 源码学习(十四)
  10. Android 笔记
  11. 5.网络层(3)---路由选择协议
  12. 【问题导向】GWR与MGWR——以南京市中心城区住宅小区为例
  13. MAC中安装Navicat Premium
  14. unity替换鼠标图标
  15. TimePicker使用全解
  16. 计算机休眠会断电吗,电脑「睡眠」和「休眠」原来有这么大区别,下次别用错了。...
  17. 迁移学习具体场景与方法
  18. 杜比AC-3与DTS的音效对比 浅解
  19. C++复习炒剩饭(1)心一意
  20. Rodrigues' Rotation Matrix(罗德里格旋转矩阵)

热门文章

  1. 安装linux下显卡驱动
  2. 修改sql数据库服务器名称,如何更改sql数据库服务器名称
  3. 在计算机上格式u盘启动,U盘制作dos启动盘几种简单方法
  4. 装机员Ghost一键备份还原使用方法(硬盘装系统)
  5. echarts雷达图
  6. WIN10使用 NetSpeedMonitor
  7. 几种物流仿真软件的比较
  8. sql格式化工具-SQL Pretty Printer
  9. C++——WebServer服务器项目
  10. 基于Vue结合高德地图api做的一个坐标拾取组件