当前位置:   article > 正文

FPGA实现FIR滤波_fpga fir

fpga fir

FPGA实现FIR滤波

什么是FIR滤波?

FIR(Finite Impulse Response) Filter:有限冲激响应滤波器。
FIR滤波器这里就不赘述其原理了,晚上有很多解释的。我这里给两个我参考的,并且认为还不错的

  1. 一个视频教你理解两种数字滤波器,学数字信号处理必看

  2. FIR数字信号滤波器

FIR滤波器的verilog实现

源代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/05/10 10:23:52
// Design Name: 
// Module Name: FIR
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module FIR(
    input   clk,
    input   rst_n,
    input  [DATA_WIDTH:1] data_in,
    
    output reg [DATA_WIDTH + 8:1] filtered_data,
    output reg filtered_data_valid 
    );
//定义parameter
    parameter DATA_WIDTH = 8;   //数据位宽
    parameter b0 = 0;   //FIR抽头参数
    parameter b1 = 8;
    parameter b2 = 22;
    parameter b3 = 38;
    parameter b4 = 50;
    parameter b5 = 38;
    parameter b6 = 22;
    parameter b7 = 8;
    parameter b8 = 0;
//将数据缓存
    reg [DATA_WIDTH:1] data_reg [9:0];
    integer i,j;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            for (i = 0;i <=9 ;i = i + 1 ) begin
                data_reg[i] <= 0;
            end
        end
        else begin
            data_reg[0] <= data_in;
            for (j = 1; j <= 9 ;j = j + 1) begin
                data_reg[j] <= data_reg[j-1];
            end
        end
    end

//进行FIR处理
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            filtered_data <= 0;
            filtered_data_valid <= 0;
        end
        else begin
            filtered_data <= b0 * data_reg[0] + b1 * data_reg[1] + b2 * data_reg[2] + b3 * data_reg[3] + 
                             b4 * data_reg[4] + b5 * data_reg[5] + b6 * data_reg[6] + b7 * data_reg[7] + 
                             b8 * data_reg[8];
            filtered_data_valid <= 1;
        end
    end


endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

测试代码

MATLAB生成信号源
clc;
clear all;

s_p = 0:255; %正弦波一个周期的采样点
N = 2^8;
sin_data = sin(2*pi*s_p/N);

%生成噪声信号
y2=randn(1, N);%生成一个白噪声数组(白噪声的随机数范围是[-3,3]),数组长度为N
subplot(3,1,2);
plot(1:N, y2);

%生成正弦波信号和噪声信号复合的信号
y=sin_data+y2/10;
subplot(3,1,3);
plot(1:N, y);

%定点化
fix_y = fix(y*127) + 150;
plot(1:N,fix_y);

%写到文件
fid = fopen('sin_sp_ram_256X8.coe','wt');
fprintf(fid,'MEMORY_INITIALIZATION_RADIX=10;\n'); 
fprintf(fid,'MEMORY_INITIALIZATION_VECTOR=\n');
for i=1:1:N
    fprintf(fid, "%d",fix_y(i));
    if i == N
        fprintf(fid,';');
    else 
        fprintf(fid,',\n');
    end
end
fclose(fid);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
Testbench

当然,抽头数据是随便设的

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/05/10 21:27:44
// Design Name: 
// Module Name: FIR_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module FIR_tb;
  // Parameters
  localparam  DATA_WIDTH = 32;
  localparam  b0 = 0;
  localparam  b1 = 0;
  localparam  b2 = 1;
  localparam  b3 = 3;
  localparam  b4 = 8;
  localparam  b5 = 3;
  localparam  b6 = 1;
  localparam  b7 = 0;
  localparam  b8 = 0;

  // Ports
  reg clk = 0;
  reg rst_n = 0;
  wire  [DATA_WIDTH:1] data_in;
  wire [DATA_WIDTH:1] filtered_data;
  wire filtered_data_valid;

  FIR 
  #(
    .DATA_WIDTH(DATA_WIDTH ),
    .b0(b0 ),
    .b1(b1 ),
    .b2(b2 ),
    .b3(b3 ),
    .b4(b4 ),
    .b5(b5 ),
    .b6(b6 ),
    .b7(b7 ),
    .b8(b8 )
  )
  FIR_dut (
    .clk (clk ),
    .rst_n (rst_n ),
    .data_in (data_in ),
    .filtered_data (filtered_data ),
    .filtered_data_valid  ( filtered_data_valid)
  );

reg [7:0] addra;
always @(posedge clk or negedge rst_n) begin
  if (!rst_n) begin
    addra <= 0;
  end
  else begin
    addra <= addra + 1; 
  end
end

wire [31:0] douta;
//调用FIFO
  FIR_tb_ram your_instance_name (
  .clka(clk),    // input wire clka
  .wea(0),      // input wire [0 : 0] wea
  .addra(addra),  // input wire [7 : 0] addra
  .dina(0),    // input wire [31 : 0] dina
  .douta(douta)  // output wire [31 : 0] douta
);
assign data_in[DATA_WIDTH:1] = douta[31:0];

  initial begin
    begin
      #500 rst_n = 1;
    end
  end

  always
    #5  clk = ! clk ;

endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

测试波形

请添加图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/819557
推荐阅读
相关标签
  

闽ICP备14008679号