县电子政务办网站建设工作思路,图片做视频在线观看网站,瓜子二手车网站开发,wordpress python采集器本篇是FPGA数字信号处理的第21篇#xff0c;上一篇介绍了半带滤波器的相关知识以及单级半带滤波器的设计方法。单级半带滤波器只能实现2倍抽取#xff0c;本文将介绍可实现2^N倍抽取的多级半带滤波器的设计方法。 多级半带滤波器 
多级半带滤波器是一个级联系统#xff0c;设…本篇是FPGA数字信号处理的第21篇上一篇介绍了半带滤波器的相关知识以及单级半带滤波器的设计方法。单级半带滤波器只能实现2倍抽取本文将介绍可实现2^N倍抽取的多级半带滤波器的设计方法。 多级半带滤波器 
多级半带滤波器是一个级联系统设计需要考虑的最大问题就是如何分配各级的参数以实现整体的性能指标要求。这里假设抽取滤波的总体要求为通带截止频率fp通带波纹δp阻带截止频率fs阻带波纹δs。N级半带滤波器的抽取倍数D2^N在设计多级半带滤波器时主要考虑3个方面的问题。 
1前N-1级与第N级的差别 
由上一篇介绍可知多级抽取滤波的最后一级会加入一个普通的高性能FIR滤波器非半带滤波器以弥补前级半带滤波器过渡带较宽的问题。这样在设计前级的半带滤波器时便可以尽量减小阶数过渡带会增宽减小系统的整体资源消耗。 
最后一级FIR滤波器的参数要求应设置为 
◎通带截止频率fp  ◎阻带截止频率fs  ◎通带波纹δp/N通带波纹平均分配到各级  ◎阻带波纹δs 
由半带滤波器的频率特性可知使用半带滤波器进行2倍抽取时通带范围内不会发生混叠但过渡带范围内会有频谱混叠。因此前面几级半带滤波器的设计根据在级联时是否允许过渡带混叠会分为不同的情况。 
2波纹参数的分配 
由上一篇可知半带滤波器的频率特性具有对称性其通带波纹与阻带波纹相同都为δ。N-1级半带滤波器的δ取δp的1/N第N级FIR滤波器的通带波纹也取δp的1/N阻带波纹取δs。 
3频率参数的分配 
多级半带滤波器每经过一级采样率就会降低1/2。第i级输出信号的采样率fi为fif0/2^if0为原始信号的频率。每一级半带滤波器的通带频率都应取fp设第i级半带滤波器的阻带频率为fsi。 
(1).当仅需保护通频带内0~fp不发生频谱混叠时即允许fp~fsi范围内有频谱混叠各级半带滤波器的参数应设置为 
◎通带截止频率fp  ◎阻带截止频率f(i-1)/2-fpfi-fp结合半带滤波器频率响应的对称性理解  ◎波纹δp/N通带波纹平均分配到各级 
(2).当需要保护整个频带0~fsi内都不发生频谱混叠时各级半带滤波器的参数应设置为 
◎通带截止频率fs将系统阻带作为各级通带保证过渡带也不会混叠  ◎阻带截止频率f(i-1)/2-fsfi-fs结合半带滤波器频率响应的对称性理解  ◎波纹δp/N通带波纹平均分配到各级 MATLAB设计 
设计一个6级半带滤波器实现64倍抽取。假设输入信号采样率为3.2GHz则输出信号采样率为50MHz。通带截止频率设置为20MHz阻带截止频率为25MHz通带、阻带波纹均为0.001。根据上节的公式计算出各级半带滤波器的参数最后一级为普通的FIR滤波器注意由于半带滤波器频率响应的对称性在MATLAB中只需要设置通带截止频率即可无需设置阻带截止频率。 
设置一个10MHz25MHz400MHz1GHz的正弦叠加信号使用该多级滤波器系统对其做抽取滤波具体代码请参考杜勇老师《数字滤波器的MATLAB与FPGA实现》P208-209。结果如下所示    经过抽取滤波后只剩下10MHz的单频信号符合预期设计。 FPGA设计 
半带滤波器本质上仍是FIR滤波器多级半带滤波器中的每一级都可以用“并行FIR结构https://blog.csdn.net/fpgadesigner/article/details/80594627”或“串行FIR结构https://blog.csdn.net/fpgadesigner/article/details/80598992”实现也可以使用Quartus或Vivado自带的FIR IP核实现。 
本文使用Vivado的FIR Compiler IP核完成多级半带滤波器的设计具体设置方法请参考第20篇。首先使用MATLAB的FDATOOL工具将各级滤波器的系数导出到coe文件参数与上节相同12位定点量化。 
由于多级半带滤波器每一级都是2倍抽取因此整个级联系统中存在多个采样率在FPGA设计时要考虑这一点博主总结了三种设计方法。 
1生成多个时钟 
使用Clock Wizard IP核生成各级半带滤波器所需的采样时钟频率该方法不需要考虑各级FIR之间的级联方式但是时钟太多会消耗不少FPGA内部的时钟线资源在实际工程中不现实。 
2设置过采样模式 
多级半带滤波器的时钟频率固定比如为50MHz每一级的输入采样频率依次降低1/2。比如第一级“Input Sampling Frequency“与时钟相同为50MHz第二级为25MHz第三级为12.5MHz……依次类推。在”Hardware Oversampling Specification“中设置    本设计中第六级的输入采样频率为1.5625MHz每32个时钟周期输入1个有效数据每64个时钟周期输出1个有效数据实现64倍抽取。 
3借助AXI4总线接口 
Vivado的FIR Compiler IP核采用的是AXI4总线接口协议其中包括一个输入数据有效信号s_axis_data_tvalid一个输出数据有效信号m_axix_data_tvalid。可以将上一级FIR滤波器的输出数据有效信号作为下一级FIR滤波器的输入数据有效信号实现输入数据速率的控制。 
本设计采用上述方法2与方法3结合的设计方式既设置过采样模式又级联滤波器之间的有效信号Verilog HDL代码如下 
timescale 1ns / 1ps
//-------------------------------------------------------------
//  六级半带滤波器完成64倍抽取
//-------------------------------------------------------------
module MultiHB_liuqi
(input clk,input signed [7:0] Xin,   //待抽取数据输入output signed [47:0] Yout,//64倍抽取滤波后数据输出//output out_validoutput signed [23:0]data11,output signed [31:0]data22,output signed [47:0] data33,output signed [47:0] data44,output signed [47:0] data55,output [5:0] valid
);//第一级半带滤波器
wire [23:0] data1;
hb_filter U0 
(.aclk(clk),                   // input wire aclk.s_axis_data_tvalid(1b1),    // input wire s_axis_data_tvalid.s_axis_data_tready(),        // output wire s_axis_data_tready.s_axis_data_tdata(Xin),      // input wire [7 : 0] s_axis_data_tdata.m_axis_data_tvalid(valid[0]),// output wire m_axis_data_tvalid.m_axis_data_tdata(data1)     // output wire [23 : 0] m_axis_data_tdata
);//第二级半带滤波器
wire [31:0] data2;
hb_filter1 U1
(.aclk(clk),                   // input wire aclk.s_axis_data_tvalid(valid[0]),// input wire s_axis_data_tvalid.s_axis_data_tready(),        // output wire s_axis_data_tready.s_axis_data_tdata({{4{data1[19]}},data1[19:0]}),.m_axis_data_tvalid(valid[1]),// output wire m_axis_data_tvalid.m_axis_data_tdata(data2)     // output wire [31 : 0] m_axis_data_tdata
);//第三级半带滤波器
wire [47:0] data3;
hb_filter2 U2
(.aclk(clk),                   // input wire aclk.s_axis_data_tvalid(valid[1]),// input wire s_axis_data_tvalid.s_axis_data_tready(),        // output wire s_axis_data_tready.s_axis_data_tdata(data2),    // input wire [31 : 0] s_axis_data_tdata.m_axis_data_tvalid(valid[2]),// output wire m_axis_data_tvalid.m_axis_data_tdata(data3)     // output wire [47 : 0] m_axis_data_tdata
);//第四级半带滤波器
wire [47:0] data4;
hb_filter U3
(.aclk(clk),                   // input wire aclk.s_axis_data_tvalid(valid[2]),// input wire s_axis_data_tvalid.s_axis_data_tready(),        // output wire s_axis_data_tready.s_axis_data_tdata(data3[40:9]),// input wire [31 : 0] s_axis_data_tdata.m_axis_data_tvalid(valid[3]),// output wire m_axis_data_tvalid.m_axis_data_tdata(data4)     // output wire [47 : 0] m_axis_data_tdata
);//第五级半带滤波器
wire [47:0] data5;
hb_filter4 U4
(.aclk(clk),                   // input wire aclk.s_axis_data_tvalid(valid[3]),// input wire s_axis_data_tvalid.s_axis_data_tready(),        // output wire s_axis_data_tready.s_axis_data_tdata(data4[42:11]),// input wire [31 : 0] s_axis_data_tdata.m_axis_data_tvalid(valid[4]),// output wire m_axis_data_tvalid.m_axis_data_tdata(data5)     // output wire [47 : 0] m_axis_data_tdata
);//第六级半带滤波器(使用普通的FIR滤波器)
wire [47:0] data6;
hb_filter5 U5
(.aclk(clk),                   // input wire aclk.s_axis_data_tvalid(valid[4]),// input wire s_axis_data_tvalid.s_axis_data_tready(),        // output wire s_axis_data_tready.s_axis_data_tdata(data5[42:11]),// input wire [31 : 0] s_axis_data_tdata.m_axis_data_tvalid(valid[5]),// output wire m_axis_data_tvalid.m_axis_data_tdata(data6)     // output wire [47 : 0] m_axis_data_tdata
);assign data11  data1;
assign data22  data2;
assign data33  data3;
assign data44  data4;
assign data55  data5;
assign Yout  data6;endmodule 
级联系统需要考虑数据截位的问题否则计算过程中位宽不断累积会大量增加资源的消耗。该从哪一位开始截取有效数据作为下一级的输入最好的确定方式就是仿真。在仿真图中观察待截位信号截位时只保留一个符号位即可。举一个具体的例子    截取32Bits作为下一级滤波器的输入。观察40~47bit都是符号位保留1个符号位截取40~9位作为有效数据。截位使切不可丢失有效数据否则会造成计算错误。 仿真与测试 
将MATLAB设计小节中的10MHz25MHz400MHz1GHz的正弦叠加信号保存到txt文件中。编写testbench读取txt文件对信号抽取滤波文件操作方法参考“Testbench编写指南一文件的读写操作https://blog.csdn.net/fpgadesigner/article/details/80470972 ”。 
Vivado中仿真结果如下图所示    data11-data55为前五级半带滤波器的输出可以看到数据采样率不断降低。Yout为64倍抽取后的最终信号与MATLAB中结果做对比完全一致。各级滤波器的输出有效信号如下图所示    0~5分别对应第一级到第六级滤波器每一级之间保持2倍关系结果正确。