草庐IT

【FPGA教程案例1】基于FPGA的串行FIR滤波器设计与实现

fpga和matlab 2023-08-22 原文

FPGA教程目录

MATLAB教程目录

---------------------------------------------------------------------------------------

目录

1.软件版本

2.本算法理论知识

3.核心代码

4.操作步骤与仿真结论

5.参考文献


0.完整源码获得方式

方式1:微信或者QQ联系博主

方式2:订阅MATLAB/FPGA教程,免费获得教程案例以及任意2份完整源码

1.软件版本

vivado2019.2、MATLAB2021a

2.本算法理论知识

        FIR(Finite Impulse Response)滤波器是一种有限长单位冲激响应滤波器,又称为非递归型滤波器。FIR 滤波器具有严格的线性相频特性,同时其单位响应是有限长的,因而是稳定的系统,在数字通信、图像处理等领域都有着广泛的应用。FIR 滤波器是有限长单位冲击响应滤波器。直接型结构如下:

FIR 滤波器本质上就是输入信号与单位冲击响应函数的卷积,表达式如下:

        我们可以看到,一个串行结构的FIR滤波器,其首先通过延迟模块得到延迟后的输入信号x,然后和对应的FIR系数相乘,然后再求和就可以输出滤波结果。

3.核心代码

       这里,我们设计一个低阶的滤波器,首先通过MATLAB来确定FIR滤波器的系数,运行如下的MATLAB程序:

clc;
clear;
close all;
warning off;

h = hamming(7);

figure;
plot(h,'b-o')

h2 = round(1023*h)

这里使用hamming汉明窗函数自动产生系数,7表示窗函数的长度。

运行这个程序,可以得到FIR汉明窗的系数:

可以看到,我们产生了7个点长度的汉明窗。

matlab中的最后一行h2 = round(1023*h),表示滤波器系数量化之后h变为h2:

h2 =

          82
         317
         788
        1023
         788
         317
          82

然后在vivado中,新建一个文件,命名为fir_tops.v,其代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/03/26 23:06:35
// Design Name: 
// Module Name: fir_tops
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module fir_tops(
input i_clk,
input i_rst,
input signed[1:0]i_din,
output signed[15:0]o_dout
    );
//滤波器系数
parameter b0 =  14'd82;
parameter b1 =  14'd317; 
parameter b2 =  14'd788;  
parameter b3 =  14'd1023;  
parameter b4 =  14'd788;   
parameter b5 =  14'd317;   
parameter b6 =  14'd82;

reg signed[1:0]x0;
reg signed[1:0]x1;
reg signed[1:0]x2;
reg signed[1:0]x3;
reg signed[1:0]x4;
reg signed[1:0]x5;
reg signed[1:0]x6;

//xn延迟
always @(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
	  begin
	  x0 <= 2'd0;
	  x1 <= 2'd0;
      x2 <= 2'd0;
      x3 <= 2'd0;
      x4 <= 2'd0;
      x5 <= 2'd0;
      x6 <= 2'd0;
	  end
else begin
	  x0 <= i_din;
	  x1 <= x0;
      x2 <= x1;
      x3 <= x2;
      x4 <= x3;
      x5 <= x4;
      x6 <= x5;	 
     end
end

//使用乘法器IP核计算乘法
wire signed[15:0]r0;
multer multer_u0 (
  .CLK(i_clk),    // input wire CLK
  .A(x0),        // input wire [1 : 0] A
  .B(b0),        // input wire [13 : 0] B
  .SCLR(i_rst),  // input wire SCLR
  .P(r0)        // output wire [15 : 0] P
);

wire signed[15:0]r1;
multer multer_u1 (
  .CLK(i_clk),    // input wire CLK
  .A(x1),        // input wire [1 : 0] A
  .B(b1),        // input wire [13 : 0] B
  .SCLR(i_rst),  // input wire SCLR
  .P(r1)        // output wire [15 : 0] P
);



wire signed[15:0]r2;
multer multer_u2 (
  .CLK(i_clk),    // input wire CLK
  .A(x2),        // input wire [1 : 0] A
  .B(b2),        // input wire [13 : 0] B
  .SCLR(i_rst),  // input wire SCLR
  .P(r2)        // output wire [15 : 0] P
);


wire signed[15:0]r3;
multer multer_u3 (
  .CLK(i_clk),    // input wire CLK
  .A(x3),        // input wire [1 : 0] A
  .B(b3),        // input wire [13 : 0] B
  .SCLR(i_rst),  // input wire SCLR
  .P(r3)        // output wire [15 : 0] P
);


wire signed[15:0]r4;
multer multer_u4 (
  .CLK(i_clk),    // input wire CLK
  .A(x4),        // input wire [1 : 0] A
  .B(b4),        // input wire [13 : 0] B
  .SCLR(i_rst),  // input wire SCLR
  .P(r4)        // output wire [15 : 0] P
);


wire signed[15:0]r5;
multer multer_u5 (
  .CLK(i_clk),    // input wire CLK
  .A(x1),        // input wire [1 : 0] A
  .B(b5),        // input wire [13 : 0] B
  .SCLR(i_rst),  // input wire SCLR
  .P(r5)        // output wire [15 : 0] P
);


wire signed[15:0]r6;
multer multer_u6 (
  .CLK(i_clk),    // input wire CLK
  .A(x6),        // input wire [1 : 0] A
  .B(b6),        // input wire [13 : 0] B
  .SCLR(i_rst),  // input wire SCLR
  .P(r6)        // output wire [15 : 0] P
);

assign o_dout = r0+r1+r2+r3+r4+r5+r6;

endmodule

通过parameter语句,定义滤波器系数

然后通过多个乘法器,将延迟后的数据和滤波器系数相乘。 

其中,上述程序中multer乘法器模块,使用vivado的IP核实现,具体操作如下:

 点击IP calalog,然后点击multiplier

 乘法器的参数设置如下:

 

 点击ok,然后弹出

 点击generate

此时,在vivado中,可以看到:

 在vivado中,点击IP source

可以看到乘法器IP核的接口配置:

 双击multer.veo,就可以看到右侧的乘法器接口,将接口复制到verilog中,就有了上述程序

 调用方法和C语言中类似,()中为实际的信号名称,如上图,输入数据x0,系数b0,时钟i_clk,复位i_rst,输出乘积r0.。

FPGA的TB文件程序如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/03/26 23:21:32
// Design Name: 
// Module Name: test_fir
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module test_fir;
reg i_clk;
reg i_rst;
reg signed[1:0]i_din;
wire signed[15:0]o_dout;

fir_tops fir_tops_u(
.i_clk              (i_clk),
.i_rst              (i_rst),
.i_din              (i_din),
.o_dout             (o_dout)
);

initial
begin
i_clk=1'b1;
i_rst=1'b1;
i_din=2'b00;
#1000
i_rst=1'b0;

i_din=2'b01;
 

#10
i_din=2'b00;

#30
i_din=2'b01;
#10
i_din=2'b00;

#30
i_din=2'b01;
#10
i_din=2'b00;

#30
i_din=2'b01;
#10
i_din=2'b00;

#30
i_din=2'b11;
#10
i_din=2'b00;


#30
i_din=2'b01;
#10
i_din=2'b00;

#30
i_din=2'b11;
#10
i_din=2'b00;

#30
i_din=2'b11;
#10
i_din=2'b00;

#30
i_din=2'b11;
#10
i_din=2'b00;

#30
i_din=2'b01;
#10
i_din=2'b00;
#30
i_din=2'b01;
#10
i_din=2'b00;

#30
i_din=2'b01;
#10
i_din=2'b00;

#30
i_din=2'b01;
#10
i_din=2'b00;

#30
i_din=2'b11;
#10
i_din=2'b00;


#30
i_din=2'b01;
#10
i_din=2'b00;

#30
i_din=2'b11;
#10
i_din=2'b00;

#30
i_din=2'b11;
#10
i_din=2'b00;

#30
i_din=2'b11;
#10
i_din=2'b00;

#30
i_din=2'b01;
#10
i_din=2'b00;

end

always #5 i_clk=~i_clk;


endmodule

4.操作步骤与仿真结论

 在vivado中,选择fir_tops这个顶层文件,右击,设置set as top

然后再选择test_fir,右击,设置set as top

然后点击run simulation,选择行为仿真

然后点击如下三角形,进行仿真

 仿真后将得到:

 同时选中右击,设置进制,选择有符号十进制

 

 然后 同时选中右击,选择波形显示

 

得到如下滤波效果 

上述案例,也可以直接和博主联系,获得完整工程文件。

5.参考文献

[1]郭继昌, 李香萍, 滕建辅. 基于位串行分布式算法和FPGA实现FIR电路的研究[J]. 电子测量与仪器学报, 2001, 15(2):7.

有关【FPGA教程案例1】基于FPGA的串行FIR滤波器设计与实现的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  3. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  4. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  5. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  6. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  7. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  8. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  9. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  10. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

随机推荐