赞
踩
---------------------------------------------------------------------------------------
目录
方式1:微信或者QQ联系博主
方式2:订阅MATLAB/FPGA教程,免费获得教程案例以及任意2份完整源码
vivado2019.2、MATLAB2021a
FIR(Finite Impulse Response)滤波器是一种有限长单位冲激响应滤波器,又称为非递归型滤波器。FIR 滤波器具有严格的线性相频特性,同时其单位响应是有限长的,因而是稳定的系统,在数字通信、图像处理等领域都有着广泛的应用。FIR 滤波器是有限长单位冲击响应滤波器。直接型结构如下:
FIR 滤波器本质上就是输入信号与单位冲击响应函数的卷积,表达式如下:
我们可以看到,一个串行结构的FIR滤波器,其首先通过延迟模块得到延迟后的输入信号x,然后和对应的FIR系数相乘,然后再求和就可以输出滤波结果。
这里,我们设计一个低阶的滤波器,首先通过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(x5), // 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
在vivado中,选择fir_tops这个顶层文件,右击,设置set as top
然后再选择test_fir,右击,设置set as top
然后点击run simulation,选择行为仿真
然后点击如下三角形,进行仿真
仿真后将得到:
同时选中右击,设置进制,选择有符号十进制
然后 同时选中右击,选择波形显示
得到如下滤波效果
[1]郭继昌, 李香萍, 滕建辅. 基于位串行分布式算法和FPGA实现FIR电路的研究[J]. 电子测量与仪器学报, 2001, 15(2):7.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。