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

117 篇文章 384 订阅 ¥299.90 ¥399.90
本文介绍了基于FPGA的串行FIR滤波器设计过程,从理论知识、MATLAB确定滤波器系数到Vivado中的Verilog实现。通过汉明窗生成FIR滤波器系数,并在Vivado中利用乘法器IP核进行硬件加速。详细阐述了设计步骤与仿真结论,展示了滤波效果。
摘要由CSDN通过智能技术生成

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(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

4.操作步骤与仿真结论

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

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

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

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

 仿真后将得到:

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

 

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

 

得到如下滤波效果 

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

5.参考文献

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

基于MATLAB与FPGAFIR滤波器设计与仿真是一种常用的数字信号处理方法。首先,我们可以使用MATLAB来设计FIR滤波器的系数。通过指定滤波器的截止频率、滤波器类型和滤波器阶数等参数,MATLAB可以生成滤波器的系数。 接下来,我们可以使用MATLAB来进行FIR滤波器的仿真。通过输入信号和滤波器系数,我们可以得到滤波后的输出信号。MATLAB提供了丰富的信号处理工具箱,可以方便地进行滤波器的仿真和性能评估。 然后,我们可以将设计好的FIR滤波器用HDL Coder工具箱进行FPGA代码的生成。HDL Coder可以自动将MATLAB代码转换为适用于FPGA的硬件描述语言(如VHDL或Verilog)代码。通过使用FPGA开发工具,我们可以将生成的硬件描述语言代码下载到FPGA芯片中进行硬件实现。 最后,利用FPGA进行FIR滤波器的硬件实现。将输入信号传入FPGA芯片,并通过外部接口连接FPGA芯片与其他系统。FPGA会根据设计好的硬件描述语言代码进行滤波处理,并将滤波后的信号传递给输出接口。 综上所述,基于MATLAB与FPGAFIR滤波器设计与仿真可以实现高效的数字信号处理。MATLAB提供了强大的信号处理工具,可以方便地进行滤波器设计和仿真。而使用FPGA进行硬件实现,则可以获得更高的实时性能和处理能力。这种方法在许多领域,如通信、音频处理和图像处理等,都得到广泛应用。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fpga和matlab

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值