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

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

3天内不再提示

FPGA的数字信号处理:Verilog实现简单的FIR滤波器

OpenFPGA 来源:OpenFPGA 2023-06-07 14:51 次阅读

该项目介绍了如何使用 Verilog 实现具有预生成系数的简单 FIR 滤波器

31370594-04ff-11ee-90ce-dac502259ad0.png

绪论

不起眼的 FIR 滤波器是 FPGA 数字信号处理中最基本的模块之一,因此了解如何将具有给定抽头数及其相应系数值的基本模块组合在一起非常重要。因此,在这个关于 FPGA 上 DSP 基础实用入门的教程中,将从一个简单的 15 抽头低通滤波器 FIR 开始,在 Matlab 中为其生成初始系数值,然后转换这些值用于编写 Verilog 模块。

有限脉冲响应或 FIR 滤波器定义为脉冲响应在特定时间段内稳定为零值的滤波器。脉冲响应稳定到零所花费的时间与滤波器阶数(抽头数)直接相关,滤波器阶数是 FIR 的基础传递函数多项式的阶数。FIR 的传递函数不包含反馈,因此如果输入一个值为 1 的脉冲,然后输入一串零值,输出将只是滤波器的系数值。

滤波器的作用基本都是用于信号调节,主要集中在选择滤除或允许通过哪些频率。最简单的例子之一是低通滤波器,它允许低于某个阈值(截止频率)的频率通过,同时大大衰减高于该阈值的频率,如下图所示。

316a5534-04ff-11ee-90ce-dac502259ad0.png

该项目的主要重点是在 HDL(具体为 Verilog)中实现 FIR,它可以分解为三个主要逻辑组件:一个循环缓冲器,用于将每个样本计时到适当地考虑了串行输入的延迟、每个抽头系数值的乘法器以及每个抽头输出的求和结果的累加器。

31862822-04ff-11ee-90ce-dac502259ad0.png

由于本项目专注于 FPGA 逻辑中 FIR 的设计机制,所以只是使用 Simulink 中的 FDA 工具和 Matlab 为低通滤波器插入一些简单参数,然后使用生成的系数值放到 Verilog 模块中完成滤波器的设计(在后面的步骤中完成)。

31a8de8a-04ff-11ee-90ce-dac502259ad0.png

选择实现一个简单的 15 抽头低通滤波器 FIR,采样率为 1Ms/s,通带频率为 200kHz,阻带频率为 355kHz,得到以下系数:

-0.0265
0
0.0441
0
-0.0934
0
0.3139
0.5000
0.3139
0
-0.0934
0
0.0441
0
-0.0265

为 FIR 模块创建设计文件

在 Vivado 项目中添加源文件。

31b9cfb0-04ff-11ee-90ce-dac502259ad0.png

在确定 FIR 的顺序(抽头数)并获得系数值后,接下来需要定义的下一组参数就是输入样本、输出样本和系数本身的位宽。

对于这个 FIR,选择将输入样本和系数寄存器设置为 16 位宽,并将输出样本寄存器设置为 32 位,因为两个 16 位值的乘积是一个 32 位值(两个值的宽度相乘得到乘积的宽度,所以如果选择了 8 位抽头的 16 位输入样本,那么输出样本将为 24 位宽)。

这些值也都是带符号的,因此 MSB 用作符号位,在选择输入样本寄存器的初始宽度时一定要记住这一点。要在 Verilog 中将这些值设置为有符号数据类型,使用关键字signed :

regsigned[15:0]register_name;

接下来要解决的是如何在 Verilog 中处理系数值,小数点值需要转换为定点值。由于所有系数值都小于 1,因此寄存器的所有 15 位(总共 16 位,MSB 是有符号位)都可以用于小数位。通常,必须决定要将寄存器中的多少位用于数字的整数部分与数字的小数部分。因此,转换分数值抽头的数学是:(fractional coefficient value)*(2^(15))该乘积的小数值被四舍五入,并且如果系数为负,则计算该值的二进制补码:

tap0=twos(-0.0265*32768)=0xFC9C
tap1=0
tap2=0.0441*32768=1445.0688=1445=0x05A5
tap3=0
tap4=twos(-0.0934*32768)=0xF40C
tap5=0
tap6=0.3139*32768=10285.8752=10285=0x282D
tap7=0.5000*32768=16384=0x4000
tap8=0.3139*32768=10285.8752=10285=0x282D
tap9=0
tap10=twos(-0.0934*32768)=0xF40C
tap11=0
tap12=0.0441*32768=1445.0688=1445=0x05A5
tap13=0
tap14=twos(-0.0265*32768)=0xFC9C

现在我们终于准备好关注 FIR 模块的逻辑,第一个是循环缓冲区,它引入串行输入样本流并为滤波器的 15 个抽头创建一个包含 15 个输入样本的数组。

always@(posedgeclk)
begin
if(enable_buff==1'b1)
begin
buff0<= in_sample;
                    buff1 <= buff0;        
                    buff2 <= buff1;         
                    buff3 <= buff2;      
                    buff4 <= buff3;      
                    buff5 <= buff4;       
                    buff6 <= buff5;    
                    buff7 <= buff6;       
                    buff8 <= buff7;       
                    buff9 <= buff8;       
                    buff10 <= buff9;        
                    buff11 <= buff10;       
                    buff12 <= buff11;       
                    buff13 <= buff12;       
                    buff14 <= buff13;    
                end
        end

接下来,乘法阶段将每个样本乘以每个系数值:

/*MultiplystageofFIR*/
always@(posedgeclk)
begin
if(enable_fir==1'b1)
begin
acc0<= tap0 * buff0;
                    acc1 <= tap1 * buff1;
                    acc2 <= tap2 * buff2;
                    acc3 <= tap3 * buff3;
                    acc4 <= tap4 * buff4;
                    acc5 <= tap5 * buff5;
                    acc6 <= tap6 * buff6;
                    acc7 <= tap7 * buff7;
                    acc8 <= tap8 * buff8;
                    acc9 <= tap9 * buff9;
                    acc10 <= tap10 * buff10;
                    acc11 <= tap11 * buff11;
                    acc12 <= tap12 * buff12;
                    acc13 <= tap13 * buff13;
                    acc14 <= tap14 * buff14;
                end
        end

乘法阶段的结果值通过加法累加到寄存器中,最终成为滤波器的输出数据流。

/*AccumulatestageofFIR*/
always@(posedgeclk)
begin
if(enable_fir==1'b1)
begin
m_axis_fir_tdata<= acc0 + acc1 + acc2 + acc3 + acc4 + acc5 + acc6 + acc7 + acc8 + acc9 + acc10 + acc11 + acc12 + acc13 + acc14;
                end
        end

最后,逻辑的最后一部分是将数据流进和流出 FIR 模块的接口。AXI Stream 接口是最常见的接口之一。关键方面是允许控制上游和下游设备之间的数据流的tready和tvalid信号。这意味着 FIR 模块需要向其下游设备提供tvalid信号以指示其输出是有效数据,并且如果下游设备解除其tready信号,则能够暂停(但仍保留)其输出。FIR 模块还必须能够与其主端接口上的上游设备以同样的方式运行。

31ec8e00-04ff-11ee-90ce-dac502259ad0.png

以下是 FIR 模块的逻辑设计概述:

3207c828-04ff-11ee-90ce-dac502259ad0.png

请注意tready和tvalid信号如何设置输入循环缓冲器的使能值和 FIR 的乘法级以及数据或系数通过的每个寄存器都被声明为有符号的。

FIR模块Verilog代码:

`timescale1ns/1ps

moduleFIR(
inputclk,
inputreset,
inputsigned[15:0]s_axis_fir_tdata,
input[3:0]s_axis_fir_tkeep,
inputs_axis_fir_tlast,
inputs_axis_fir_tvalid,
inputm_axis_fir_tready,
outputregm_axis_fir_tvalid,
outputregs_axis_fir_tready,
outputregm_axis_fir_tlast,
outputreg[3:0]m_axis_fir_tkeep,
outputregsigned[31:0]m_axis_fir_tdata
);


always@(posedgeclk)
begin
m_axis_fir_tkeep<= 4'hf;
        end
        
    always @ (posedge clk)
        begin
            if (s_axis_fir_tlast == 1'b1)
                begin
                    m_axis_fir_tlast <= 1'b1;
                end
            else
                begin
                    m_axis_fir_tlast <= 1'b0;
                end
        end
    
    // 15-tap FIR 
    reg enable_fir, enable_buff;
    reg [3:0] buff_cnt;
    reg signed [15:0] in_sample; 
    reg signed [15:0] buff0, buff1, buff2, buff3, buff4, buff5, buff6, buff7, buff8, buff9, buff10, buff11, buff12, buff13, buff14; 
    wire signed [15:0] tap0, tap1, tap2, tap3, tap4, tap5, tap6, tap7, tap8, tap9, tap10, tap11, tap12, tap13, tap14; 
    reg signed [31:0] acc0, acc1, acc2, acc3, acc4, acc5, acc6, acc7, acc8, acc9, acc10, acc11, acc12, acc13, acc14; 

    
    /* Taps for LPF running @ 1MSps with a cutoff freq of 400kHz*/
    assign tap0 = 16'hFC9C;  // twos(-0.0265 * 32768) = 0xFC9C
    assign tap1 = 16'h0000;  // 0
    assign tap2 = 16'h05A5;  // 0.0441 * 32768 = 1445.0688 = 1445 = 0x05A5
    assign tap3 = 16'h0000;  // 0
    assign tap4 = 16'hF40C;  // twos(-0.0934 * 32768) = 0xF40C
    assign tap5 = 16'h0000;  // 0
    assign tap6 = 16'h282D;  // 0.3139 * 32768 = 10285.8752 = 10285 = 0x282D
    assign tap7 = 16'h4000;  // 0.5000 * 32768 = 16384 = 0x4000
    assign tap8 = 16'h282D;  // 0.3139 * 32768 = 10285.8752 = 10285 = 0x282D
    assign tap9 = 16'h0000;  // 0
    assign tap10 = 16'hF40C; // twos(-0.0934 * 32768) = 0xF40C
    assign tap11 = 16'h0000; // 0
    assign tap12 = 16'h05A5; // 0.0441 * 32768 = 1445.0688 = 1445 = 0x05A5
    assign tap13 = 16'h0000; // 0
    assign tap14 = 16'hFC9C; // twos(-0.0265 * 32768) = 0xFC9C
    
    /* This loop sets the tvalid flag on the output of the FIR high once 
     * the circular buffer has been filled with input samples for the 
     * first time after a reset condition. */
    always @ (posedge clk or negedge reset)
        begin
            if (reset == 1'b0) //if (reset == 1'b0 || tvalid_in == 1'b0)
                begin
                    buff_cnt <= 4'd0;
                    enable_fir <= 1'b0;
                    in_sample <= 8'd0;
                end
            else if (m_axis_fir_tready == 1'b0 || s_axis_fir_tvalid == 1'b0)
                begin
                    enable_fir <= 1'b0;
                    buff_cnt <= 4'd15;
                    in_sample <= in_sample;
                end
            else if (buff_cnt == 4'd15)
                begin
                    buff_cnt <= 4'd0;
                    enable_fir <= 1'b1;
                    in_sample <= s_axis_fir_tdata;
                end
            else
                begin
                    buff_cnt <= buff_cnt + 1;
                    in_sample <= s_axis_fir_tdata;
                end
        end   

    always @ (posedge clk)
        begin
            if(reset == 1'b0 || m_axis_fir_tready == 1'b0 || s_axis_fir_tvalid == 1'b0)
                begin
                    s_axis_fir_tready <= 1'b0;
                    m_axis_fir_tvalid <= 1'b0;
                    enable_buff <= 1'b0;
                end
            else
                begin
                    s_axis_fir_tready <= 1'b1;
                    m_axis_fir_tvalid <= 1'b1;
                    enable_buff <= 1'b1;
                end
        end
    
    /* Circular buffer bring in a serial input sample stream that 
     * creates an array of 15 input samples for the 15 taps of the filter. */
    always @ (posedge clk)
        begin
            if(enable_buff == 1'b1)
                begin
                    buff0 <= in_sample;
                    buff1 <= buff0;        
                    buff2 <= buff1;         
                    buff3 <= buff2;      
                    buff4 <= buff3;      
                    buff5 <= buff4;       
                    buff6 <= buff5;    
                    buff7 <= buff6;       
                    buff8 <= buff7;       
                    buff9 <= buff8;       
                    buff10 <= buff9;        
                    buff11 <= buff10;       
                    buff12 <= buff11;       
                    buff13 <= buff12;       
                    buff14 <= buff13;    
                end
            else
                begin
                    buff0 <= buff0;
                    buff1 <= buff1;        
                    buff2 <= buff2;         
                    buff3 <= buff3;      
                    buff4 <= buff4;      
                    buff5 <= buff5;       
                    buff6 <= buff6;    
                    buff7 <= buff7;       
                    buff8 <= buff8;       
                    buff9 <= buff9;       
                    buff10 <= buff10;        
                    buff11 <= buff11;       
                    buff12 <= buff12;       
                    buff13 <= buff13;       
                    buff14 <= buff14;
                end
        end
        
    /* Multiply stage of FIR */
    always @ (posedge clk)
        begin
            if (enable_fir == 1'b1)
                begin
                    acc0 <= tap0 * buff0;
                    acc1 <= tap1 * buff1;
                    acc2 <= tap2 * buff2;
                    acc3 <= tap3 * buff3;
                    acc4 <= tap4 * buff4;
                    acc5 <= tap5 * buff5;
                    acc6 <= tap6 * buff6;
                    acc7 <= tap7 * buff7;
                    acc8 <= tap8 * buff8;
                    acc9 <= tap9 * buff9;
                    acc10 <= tap10 * buff10;
                    acc11 <= tap11 * buff11;
                    acc12 <= tap12 * buff12;
                    acc13 <= tap13 * buff13;
                    acc14 <= tap14 * buff14;
                end
        end    
        
     /* Accumulate stage of FIR */   
    always @ (posedge clk) 
        begin
            if (enable_fir == 1'b1)
                begin
                    m_axis_fir_tdata <= acc0 + acc1 + acc2 + acc3 + acc4 + acc5 + acc6 + acc7 + acc8 + acc9 + acc10 + acc11 + acc12 + acc13 + acc14;
                end
        end     

    
    
endmodule

创建仿真文件

要测试 FIR 模块,需要创建一个测试平台作为其仿真源:

3230e6d6-04ff-11ee-90ce-dac502259ad0.png

在 FIR 模块中有两个主要的东西需要测试:滤波器算法和 AXI 流接口。为实现这一点,测试台中创建了一个状态机,它生成一个简单的 200kHz 正弦波,并切换从属端的有效信号和 FIR 接口主控端的tready信号。

FIR 模块的测试平台:

`timescale1ns/1ps

moduletb_FIR;

regclk,reset,s_axis_fir_tvalid,m_axis_fir_tready;
regsigned[15:0]s_axis_fir_tdata;
wirem_axis_fir_tvalid;
wire[3:0]m_axis_fir_tkeep;
wire[31:0]m_axis_fir_tdata;

/*
*100Mhz(10ns)clock
*/
alwaysbegin
clk=1;#5;
clk=0;#5;
end

alwaysbegin
reset=1;#20;
reset=0;#50;
reset=1;#1000000;
end

alwaysbegin
s_axis_fir_tvalid=0;#100;
s_axis_fir_tvalid=1;#1000;
s_axis_fir_tvalid=0;#50;
s_axis_fir_tvalid=1;#998920;
end

alwaysbegin
m_axis_fir_tready=1;#1500;
m_axis_fir_tready=0;#100;
m_axis_fir_tready=1;#998400;
end

/*InstantiateFIRmoduletotest.*/
FIRFIR_i(
.clk(clk),
.reset(reset),
.s_axis_fir_tdata(s_axis_fir_tdata),
.s_axis_fir_tkeep(s_axis_fir_tkeep),
.s_axis_fir_tlast(s_axis_fir_tlast),
.s_axis_fir_tvalid(s_axis_fir_tvalid),
.m_axis_fir_tready(m_axis_fir_tready),
.m_axis_fir_tvalid(m_axis_fir_tvalid),
.s_axis_fir_tready(s_axis_fir_tready),
.m_axis_fir_tlast(m_axis_fir_tlast),
.m_axis_fir_tkeep(m_axis_fir_tkeep),
.m_axis_fir_tdata(m_axis_fir_tdata));

reg[4:0]state_reg;
reg[3:0]cntr;

parameterwvfm_period=4'd4;

parameterinit=5'd0;
parametersendSample0=5'd1;
parametersendSample1=5'd2;
parametersendSample2=5'd3;
parametersendSample3=5'd4;
parametersendSample4=5'd5;
parametersendSample5=5'd6;
parametersendSample6=5'd7;
parametersendSample7=5'd8;

/*Thisstatemachinegeneratesa200kHzsinusoid.*/
always@(posedgeclkorposedgereset)
begin
if(reset==1'b0)
begin
cntr<= 4'd0;
                    s_axis_fir_tdata <= 16'd0;
                    state_reg <= init;
                end
            else
                begin
                    case (state_reg)
                        init : //0
                            begin
                                cntr <= 4'd0;
                                s_axis_fir_tdata <= 16'h0000;
                                state_reg <= sendSample0;
                            end
                            
                        sendSample0 : //1
                            begin
                                s_axis_fir_tdata <= 16'h0000;
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample1;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample0;
                                    end
                            end 
                        
                        sendSample1 : //2
                            begin
                                s_axis_fir_tdata <= 16'h5A7E; 
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample2;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample1;
                                    end
                            end 
                        
                        sendSample2 : //3
                            begin
                                s_axis_fir_tdata <= 16'h7FFF;
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample3;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample2;
                                    end
                            end 
                        
                        sendSample3 : //4
                            begin
                                s_axis_fir_tdata <= 16'h5A7E;
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample4;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample3;
                                    end
                            end 
                        
                        sendSample4 : //5
                            begin
                                s_axis_fir_tdata <= 16'h0000;
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample5;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample4;
                                    end
                            end 
                        
                        sendSample5 : //6
                            begin
                                s_axis_fir_tdata <= 16'hA582; 
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample6;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample5;
                                    end
                            end 
                        
                        sendSample6 : //6
                            begin
                                s_axis_fir_tdata <= 16'h8000; 
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample7;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample6;
                                    end
                            end 
                        
                        sendSample7 : //6
                            begin
                                s_axis_fir_tdata <= 16'hA582; 
                                
                                if (cntr == wvfm_period)
                                    begin
                                        cntr <= 4'd0;
                                        state_reg <= sendSample0;
                                    end
                                else
                                    begin 
                                        cntr <= cntr + 1;
                                        state_reg <= sendSample7;
                                    end
                            end                     
                    
                    endcase
                end
        end
    
endmodule

运行行为仿真

FIR 模块及其测试平台文件就位后,从 Flow Navigator 窗口启动 Vivado 中的仿真器,选择 Run Behavioral Simulation 选项。

32368faa-04ff-11ee-90ce-dac502259ad0.png

如行为仿真所示,FIR 正确过滤信号并正确响应 AXI 流信号。

325a8626-04ff-11ee-90ce-dac502259ad0.png

总结

代码都在上面大家有兴趣可以自行运行,但是大家可能会注意到,这个 FIR 模块在设计上运行综合和实现时时序应该是不能通过的。我们将在下一篇文章中详细介绍如何在无法满足时序要求时重新设计你的设计~

审核编辑:汤梓红

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

    关注

    1603

    文章

    21331

    浏览量

    593302
  • 滤波器
    +关注

    关注

    158

    文章

    7335

    浏览量

    174831
  • 数字信号处理

    关注

    15

    文章

    520

    浏览量

    45308
  • FIR
    FIR
    +关注

    关注

    4

    文章

    137

    浏览量

    32726
  • Verilog
    +关注

    关注

    28

    文章

    1327

    浏览量

    109313

原文标题:FPGA 的数字信号处理:Verilog 实现简单的 FIR 滤波器

文章出处:【微信号:Open_FPGA,微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    【参考书籍】基于FPGA数字信号处理——高亚军著

    `《基于FPGA数字信号处理》是一本有关如何在FPGA实现数字信号
    发表于 04-24 09:33

    基于FPGAFIR滤波器设计与实现

    DSPBuilder设计了一个4阶FIR滤波器,并用QuartusII进行硬件仿真,仿真结果表明设计FIR滤波器的正确性。同时使用IPCore开发基于
    发表于 08-11 15:32

    fpga实现滤波器

    本帖最后由 eehome 于 2013-1-5 10:03 编辑 fpga实现滤波器在利用FPGA实现
    发表于 08-11 18:27

    fpga实现滤波器

    fpga实现滤波器fpga实现滤波器在利用FPGA
    发表于 08-12 11:50

    如何利用FPGA实现级联信号处理器

    作者:李慧敏 0 引 言 在数字信号处理领域,滤波器无疑是个非常重要的环节。而在数字滤波器中,有限脉冲响应(FIR)
    发表于 07-30 07:22

    基于DSPBuilder的FIR滤波器的系统该怎么设计?

    在信息信号处理过程中,如对信号的过滤、检测、预测等,都要使用滤波器数字滤波器数字信号
    发表于 08-30 07:18

    并行FIR滤波器Verilog设计

    节省一半的乘法器。FIR滤波器的设计方法有窗函数法、频率取样法、等波纹切比雪夫逼近法(也叫最优设计法)等等。以上所有的理论知识点在任意一本数字信号处理课本中都有详细的推论,本文节省篇幅
    发表于 09-25 17:44

    数字滤波器-IIR滤波器原理介绍&Verilog HDL设计

    利用对称性减少乘法器。上述两个模块设计可以参考“FPGA数字信号处理(二)并行FIR滤波器Verilog
    发表于 09-27 09:22

    数字信号处理FPGA实现

    的基础。随后几章阐述了计算机算法的概念、理论、FIR和IIR滤波器实现、多抽样率数字信号系统、DFT和FFT算法、未来很可能实现的高级算法
    发表于 09-19 06:38

    什么是fir数字滤波器 什么叫FIR滤波器

    什么是fir数字滤波器 Part 1: Basics1.1 什么是FIR滤波器?FIR 滤波器
    发表于 01-16 09:42 1.6w次阅读

    数字信号处理FPGA实现_刘凌译

    本书共分8章,主要内容包括典型fpga器件的介绍、vhdl硬件描述语言、fpga设计中常用软件简介、用fpga实现数字信号
    发表于 11-04 15:50 0次下载

    数字信号处理FPGA实现

    本书比较全面地阐述了fpga数字信号处理中的应用问题。本书共分8章,主要内容包括典型fpga器件的介绍、vhdl硬件描述语言、fpga设计
    发表于 12-23 11:07 44次下载

    基于FIR滤波器结构实现级联型信号处理FPGA的设计

    数字信号处理领域,滤波器无疑是个非常重要的环节。而在数字滤波器中,有限脉冲响应(FIR滤波器
    的头像 发表于 04-22 08:07 5102次阅读
    基于<b class='flag-5'>FIR</b><b class='flag-5'>滤波器</b>结构<b class='flag-5'>实现</b>级联型<b class='flag-5'>信号</b><b class='flag-5'>处理</b>器<b class='flag-5'>FPGA</b>的设计

    如何使用FPGA实现FIR抽取滤波器的设计

    FPGA实现抽取滤波器比较复杂,主要是因为在FPGA中缺乏实现乘法运算的有效结构,现在,FPGA
    发表于 09-25 10:44 3次下载
    如何使用<b class='flag-5'>FPGA</b><b class='flag-5'>实现</b><b class='flag-5'>FIR</b>抽取<b class='flag-5'>滤波器</b>的设计

    FPGA数字信号处理:重写FIR逻辑以满足时序要求

    在上一篇文章中(FPGA数字信号处理Verilog 实现简单
    的头像 发表于 06-09 09:39 611次阅读
    <b class='flag-5'>FPGA</b>的<b class='flag-5'>数字信号</b><b class='flag-5'>处理</b>:重写<b class='flag-5'>FIR</b>逻辑以满足时序要求