​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 滤波器是有限长单位冲击响应滤波器。直接型结构如下:

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

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

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

        我们可以看到,一个串行结构的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汉明窗的系数:

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

可以看到,我们产生了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语句,定义滤波器系数

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

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

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

 点击IP calalog,然后点击multiplier

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

 乘法器的参数设置如下:

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

 

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

 点击ok,然后弹出

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

 点击generate

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

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

 在vivado中,点击IP source

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

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

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

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

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

 调用方法和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.操作步骤与仿真结论

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

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

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

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

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

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

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

 仿真后将得到:

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

 同时选中

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

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

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

 然后 同时选中

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

右击,选择波形显示 

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

得到如下滤波效果 

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

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

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

5.参考文献

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