0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

并行FIR滤波器MATLAB与FPGA实现

CHANBAEK 来源:FPGA and ICer 作者:Vuko 2023-05-24 10:57 次阅读

前言

本文介绍了设计滤波器FPGA实现步骤,并结合杜勇老师的书籍中的并行FIR滤波器部分进行一步步实现硬件设计,对书中的架构做了复现以及解读,并进行了仿真验证。

并行FIR滤波器FPGA实现

FIR滤波器的结构形式时,介绍了直接型、级联型、频率取样型和快速卷积型4种。在FPGA实现时,最常用的是最简单的直接型结构。FPGA实现直接型结构的FIR滤波器,可以采用串行结构、并行结构等不同中的结构设计,上文根据书中提供的架构完成了串行 FIR滤波器的实现,本文沿用上文的基本代码结构,按照并行FIR滤波器的架构完成电路描述。

FIR滤波器需求

设计一个15阶(长度为16)的低通线性相位FIR滤波器,采用窗函数设计,截止频率为500 Hz,采样频率为2 000 Hz;采用FPGA实现并行结构的滤波器,系数的量化位数为12比特,输入数据位宽为12比特,输出数据位宽为29比特,系统时钟为16 kHz。

滤波器系数确定与量化

确定滤波器的结构后,就根据滤波器进行设计代码仿真,这里引用书中的仿真设计,并将滤波器参数系数量化。确定滤波器系数的方法有很多,可以使用MATLAB中丰富的函数实现,或者使用相关滤波器设计的软件工具,定制满足当前需求的窗函数的滤波器系数。具体量化系数确定可参考上文《数字信号处理-09-串行FIR滤波器MATLAB与FPGA实现》中的相关内容,或者参考杜勇老师的书中的内容。

硬件架构

下图为杜勇老师的《数字滤波器的MATLAB与FPGA实现》实现的并行FIR滤波器的结构图。因为FIR滤波器参数对称,所以同时计算相应的对称结构的值,将对称系数的X(n)相加后,可调用8个乘法器,完成对滤波器的乘法运算,所以针对并行滤波器的架构数据的输入速率和时钟可以相同,每一个时钟周期流水输出一个滤波后的信号值。图中的8输入的加法器,可以替换成N/2;这样就得到了一个通用化的并行FIR滤波器结构图。

图片
并行FIR滤波器

并行实现FIR滤波器,虽然浪费了加法器和乘法器的资源,但是提升了整个滤波器实现的性能,当滤波器的系数长度N增大时,数据的吞吐速率不变(暂且不考虑面积增大对性能的影响),但带来的坏处就是会用掉相应倍数的逻辑资源和运算资源,速度和面积本来就是鱼和熊掌的关系,在实际应用中应当做相应的权衡和割舍。

根据架构描述电路

根据杜勇老师书中提供的架构,对电路进行描述,同样沿用了前文的通用化的模板,后期可根据参数输入来适配不同滤波器长度的设计。

图片
实现模块框图

接口描述如下:

图片
接口描述

参数描述如下:

图片
参数描述

代码如下:

`timescale 1ns / 1ps
module Fir_Parallel(

        input clk,//!系统时钟
        input rst,//!复位信号
        input signed [SIGN_IN_WIDTH-1:0] signal_in,//!信号输入
        output signed [SIGN_OUT_WIDTH-1:0] signal_out//!信号输出,信号输出速度和输入速度相同
    );

    //
    parameter  integer SIGN_IN_WIDTH    = 12   ;//!信号输入位宽
    parameter  integer SIGN_OUT_WIDTH = 29   ;//!信号输出位宽
    parameter  integer FIR_COE_WIDTH = 12   ;//!滤波器系数位宽
    parameter  integer FIR_COE_NUM = 16   ;//!滤波器长度
    localparam integer FIR_WIDTH_DIV_2 = FIR_COE_NUM/2 ;

    function [FIR_COE_WIDTH-1:0] coe_data;
    input [FIR_WIDTH_DIV_2-1:0] index;
    begin
        case(index)
        'd0:coe_data='h000;
        'd1:coe_data='hffd;
        'd2:coe_data='h00f;
        'd3:coe_data='h02e;
        'd4:coe_data='hf8b;
        'd5:coe_data='hef9;
        'd6:coe_data='h24e;
        'd7:coe_data='h7ff;
        endcase
    end
    endfunction
    integer i;
    genvar j;
    //!滤波器系数加载
    wire signed [FIR_COE_WIDTH-1:0] coe[FIR_WIDTH_DIV_2-1:0]; 
    generate
        for (j=0; j

代码解读

关于加载滤波器系数的部分,我这里使用了function做了包装,以便于后续修改滤波器长度时,可以通过脚本生成function去增加滤波器系数的长度。

function [FIR_COE_WIDTH-1:0] coe_data;
    input [FIR_WIDTH_DIV_2-1:0] index;
    begin
        case(index)
        'd0:coe_data='h000;
        'd1:coe_data='hffd;
        'd2:coe_data='h00f;
        'd3:coe_data='h02e;
        'd4:coe_data='hf8b;
        'd5:coe_data='hef9;
        'd6:coe_data='h24e;
        'd7:coe_data='h7ff;
        endcase
    end
    endfunction

针对乘法运算,这里没有使用IP,但是为了使得该部分运算使用DSP资源,更好地提升性能,因此该信号的运算使用dsp48资源,所以在信号声明时前面加了(*use_dsp48="yes"*)

关于杜勇老师书中写的信号与系数相乘后的结果针对sum信号使用了阻塞赋值的部分,个人觉得这个在时序逻辑中是不太好的设计,使用的代码如下,虽然会简化乘累加的过程,但是针对实际使用的工程来说,这个是不好的代码风格。

always @(posedge clk)begin
        if (rst=='b1)begin 
				sum = 'd0; 
				sign_out <= 'd0;
		end
		else begin
            sign_out <= sum;
            sum = 'd0;
			for (i=0; i

所以这里我直接做了展开处理,将8个结果做了加法。

电路架构优化

我认为在随着滤波器规模变大运算的数据位宽增加时,信号与系数相乘后的结果进行累加操作的部分,组合逻辑的延时相对会增加很多,为了进一步提升电路架构的性能,可对该部分进行加法树的平衡,打拍优化加法树结构,应该有可能进一步提升电路架构的性能。

仿真设计

仿真数据设计

为了验证并行设计代码的正确性。这里使用MATLAB脚本产生了一个混频信号,混频的频率为100hz和700hz的叠加,然后将混频信号进行量化处理并导出txt文件以供仿真文件读取。

clc;close all;clear all;
 Fs = 2000; %采样频率
N = 2^10; %采样点数
f1=300; %正弦波1频率
f2=400; %正弦波1频率
t=[0:N-1]/Fs; %时间序列
s1 = sin(2*pi*f1*t) ;
s2 = sin(2*pi*f2*t) ;
s = s1 .* s2;
figure(1);
subplot(1,2,1);
plot(t,s,'r','LineWidth',1.2);
title('时域波形');
axis([0,100/Fs,-3,3]);
set(gca,'LineWidth',1.2);
%转化为位宽12bit数据
s_12bit=s./max(s).*(2.^11 - 1); % DA输入波形,量化到16bit
s_12bit(find(s_12bit<0) ) = s_12bit(find(s_12bit<0) ) + 2^12 - 1;
s_12bit = fix(s_12bit);
s_12bit = dec2hex(s_12bit);
% %生成文件
fid= fopen('sin_data.txt','w+');
%生成十六进制
for i=1:N
    fprintf(fid,'%s',s_12bit(i,:));
    fprintf(fid,'\\r\\n');
end
fclose(fid);
%% 设计验证
N=16;      %滤波器长度
fs=2000;   %采样频率
fc=500;    %低通滤波器的截止频率
B=12;      %量化位数
%生成各种窗函数
w_kais=blackman(N)';
%采用fir1函数设计FIR滤波器
b_kais=fir1(N-1,fc*2/fs,w_kais);
ss=conv(b_kais,s);
subplot(1,2,2);
plot(t(20:1000),ss(20:1000));
title('滤波后信号');
axis([0,100/Fs,-1,1]);
set(gca,'LineWidth',1.2);

运行仿真后,根据设计的滤波器系数进行仿真,发现可以正常滤波除去高频分量。

图片
滤波仿真效果

仿真激励文件编写

`timescale 1ns / 1ps
module Fir_Parallel_tb;

    // Parameters
    localparam integer SIGN_IN_WIDTH = 12;
    localparam integer SIGN_OUT_WIDTH = 29;
    localparam integer FIR_COE_WIDTH = 12;
    localparam integer FIR_COE_NUM = 16;

    // Ports
    reg clk = 1;
    reg rst = 1;
    reg [SIGN_IN_WIDTH-1:0] signal_in;
    wire [SIGN_OUT_WIDTH-1:0] signal_out;

    Fir_Parallel #(
                       .SIGN_IN_WIDTH(SIGN_IN_WIDTH ),
                       .SIGN_OUT_WIDTH(SIGN_OUT_WIDTH ),
                       .FIR_COE_WIDTH(FIR_COE_WIDTH ),
                       .FIR_COE_NUM (FIR_COE_NUM )
                   )Fir_Parallel_dut (
                       .clk (clk ),
                       .rst (rst ),
                       .signal_in (signal_in ),
                       .signal_out  ( signal_out)
                   );

    reg  [11:0] mem [0:99];
    reg  [9:0] addr ;
    // reg  [11:0]data_out ;
    always #(10*1)
    begin
        if(rst==0)
            addr = addr + 10'd1;
        signal_in  =  mem[addr][11:0];
    end

    always
        #5  clk = ! clk ;

    initial
    begin
        signal_in =0;
        $readmemh("sin_data.txt",mem);
        addr  = 10'd0;
        #10;
        rst   = 0;
    end

endmodule

运行仿真,查看波形可见,滤波效果和仿真结果一致。

图片
仿真波形

延迟分析

该架构的数据输入后,每四个时钟周期后输出一个数据,其中,一个时钟周期用于X(n)的加和,一个时钟周期用于计算信号和滤波器系数相乘的结果,一个时钟周期用于乘法输出后的数据做累加处理,一个时钟用于读取累加后的结果。

图片
延时分析

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1625

    文章

    21663

    浏览量

    601670
  • matlab
    +关注

    关注

    182

    文章

    2963

    浏览量

    230129
  • 滤波器
    +关注

    关注

    160

    文章

    7725

    浏览量

    177630
  • FIR
    FIR
    +关注

    关注

    4

    文章

    146

    浏览量

    33104
  • 函数
    +关注

    关注

    3

    文章

    4303

    浏览量

    62411
收藏 人收藏

    评论

    相关推荐

    matlabFPGA数字信号处理系列 Verilog 实现并行 FIR 滤波器

    FPGA 实现 FIR 滤波器时,最常用的是直接型结构,简单方便,在实现直接型结构时,可以选择串行结构/
    发表于 05-24 07:48

    基于FPGAFIR滤波器设计与实现

    本帖最后由 eehome 于 2013-1-5 09:50 编辑 基于FPGAFIR滤波器设计与实现   文章研究基于FPGA、采用
    发表于 08-11 15:32

    并行FIR滤波器Verilog设计

    宽的运算步进浪费资源而且也没有必要。在MATLAB中将滤波器系数量化为指定位宽,会改变滤波器的频率特性,因此需要做好仿真,确定量化后的系数也能满足FIR的设计需求。由上节可知
    发表于 09-25 17:44

    怎么利用FPGA实现FIR滤波器

    并行流水结构FIR的原理是什么基于并行流水线结构的可重配FIR滤波器FPGA
    发表于 04-29 06:30

    MATLAB设计FIR滤波器的方法

    MATLAB设计FIR滤波器的方法 摘  要 介绍了利用MATLAB信号处理工具箱进行FIR滤波器
    发表于 01-16 18:12 1.5w次阅读
    用<b class='flag-5'>MATLAB</b>设计<b class='flag-5'>FIR</b><b class='flag-5'>滤波器</b>的方法

    基于MATLABFPGAFIR低通滤波器的设计

    充分利用有限冲击响应数字滤波器(Finite Impulse Response digital filter ,FIR)系数的对称特性,借助于MATLAB语言和现场可编程门阵列(FPGA
    发表于 08-05 14:23 82次下载
    基于<b class='flag-5'>MATLAB</b>及<b class='flag-5'>FPGA</b>的<b class='flag-5'>FIR</b>低通<b class='flag-5'>滤波器</b>的设计

    基于MatlabFIR带通滤波器设计与实现

    本文通过介绍一种借助Matlab的FDATOOL滤波器设计分析软件,设计了一种FIR数字带通滤波器,并对一段含噪语音信号进行滤波。利用汇编语
    发表于 07-26 10:45 2.9w次阅读
    基于<b class='flag-5'>Matlab</b>的<b class='flag-5'>FIR</b>带通<b class='flag-5'>滤波器</b>设计与<b class='flag-5'>实现</b>

    基于MATLABFPGAFIR滤波器设计与仿真

    数字滤波器是数字信号处理领域内的重要组成部分。FIR滤波器又以其严格的线性相位及稳定性高等特性被广泛应用。本文结合MATLAB工具软件介绍了FIR
    发表于 09-25 11:34 120次下载
    基于<b class='flag-5'>MATLAB</b>与<b class='flag-5'>FPGA</b>的<b class='flag-5'>FIR</b><b class='flag-5'>滤波器</b>设计与仿真

    基于Matlab/Simulink的FIR数字滤波器的设计与实现

    基于Matlab/Simulink的FIR数字滤波器的设计与实现
    发表于 01-15 15:16 39次下载

    基于matlabfpgaFIR滤波器设计

    基于matlabfpgaFIR滤波器设计,有兴趣的同学可以下载学习
    发表于 04-27 15:51 58次下载

    基于FPGAFIR滤波器设计与实现

    基于FPGAFIR滤波器设计与实现,下来看看
    发表于 05-10 11:49 39次下载

    基于MATLABFIR滤波器设计与滤波

    基于MATLABFIR滤波器设计与滤波
    发表于 12-14 22:08 64次下载

    FIR滤波器FPGA设计与实现

    ,结合MATLAB软件提供的专用数字滤波器设计工具包FDATOOL,以及QuartusⅡ软件提供的FIR实现快速、便捷的设计FIR
    发表于 12-21 14:53 14次下载
    <b class='flag-5'>FIR</b><b class='flag-5'>滤波器</b>的<b class='flag-5'>FPGA</b>设计与<b class='flag-5'>实现</b>

    如何使用FPGA实现实现高速并行FIR滤波器

    提出了一种基于多相滤波器并行有限脉冲响应(finite impulse response,FIR滤波器结构,可以有效提高滤波器运算的吞吐
    发表于 01-28 17:22 15次下载
    如何使用<b class='flag-5'>FPGA</b><b class='flag-5'>实现实现</b>高速<b class='flag-5'>并行</b><b class='flag-5'>FIR</b><b class='flag-5'>滤波器</b>

    如何使用FPGA实现实现高速并行FIR滤波器

    提出了一种基于多相滤波器并行有限脉冲响应(finite impulse response,FIR滤波器结构,可以有效提高滤波器运算的吞吐
    发表于 01-28 17:22 7次下载
    如何使用<b class='flag-5'>FPGA</b><b class='flag-5'>实现实现</b>高速<b class='flag-5'>并行</b><b class='flag-5'>FIR</b><b class='flag-5'>滤波器</b>