FPGA数字信号处理(21)多级半带(HB)滤波器设计

本篇是FPGA数字信号处理的第21篇,上一篇介绍了半带滤波器的相关知识以及单级半带滤波器的设计方法。单级半带滤波器只能实现2倍抽取,本文将介绍可实现2^N倍抽取的多级半带滤波器的设计方法。


多级半带滤波器

多级半带滤波器是一个级联系统,设计需要考虑的最大问题就是如何分配各级的参数以实现整体的性能指标要求。这里假设抽取滤波的总体要求为:通带截止频率fp,通带波纹δp,阻带截止频率fs,阻带波纹δs。N级半带滤波器的抽取倍数D=2^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为:fi=f0/2^i,f0为原始信号的频率。每一级半带滤波器的通带频率都应取fp;设第i级半带滤波器的阻带频率为fsi。

(1).当仅需保护通频带内(0~fp)不发生频谱混叠时,即允许fp~fsi范围内有频谱混叠,各级半带滤波器的参数应设置为:

◎通带截止频率:fp;
◎阻带截止频率:f(i-1)/2-fp=fi-fp(结合半带滤波器频率响应的对称性理解);
◎波纹:δp/N(通带波纹平均分配到各级);

(2).当需要保护整个频带0~fsi内都不发生频谱混叠时,各级半带滤波器的参数应设置为:

◎通带截止频率:fs(将系统阻带作为各级通带,保证过渡带也不会混叠);
◎阻带截止频率:f(i-1)/2-fs=fi-fs(结合半带滤波器频率响应的对称性理解);
◎波纹:δp/N(通带波纹平均分配到各级);


MATLAB设计

设计一个6级半带滤波器,实现64倍抽取。假设输入信号采样率为3.2GHz,则输出信号采样率为50MHz。通带截止频率设置为20MHz,阻带截止频率为25MHz,通带、阻带波纹均为0.001。根据上节的公式计算出各级半带滤波器的参数,最后一级为普通的FIR滤波器(注意由于半带滤波器频率响应的对称性,在MATLAB中只需要设置通带截止频率即可,无需设置阻带截止频率)。

设置一个10MHz+25MHz+400MHz+1GHz的正弦叠加信号,使用该多级滤波器系统对其做抽取滤波(具体代码请参考杜勇老师《数字滤波器的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_valid
    output 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(1'b1),    // 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设计小节中的10MHz+25MHz+400MHz+1GHz的正弦叠加信号保存到txt文件中。编写testbench读取txt文件对信号抽取滤波,文件操作方法参考“Testbench编写指南(一)文件的读写操作https://blog.csdn.net/fpgadesigner/article/details/80470972 ”。

Vivado中仿真结果如下图所示:
这里写图片描述
data11-data55为前五级半带滤波器的输出,可以看到数据采样率不断降低。Yout为64倍抽取后的最终信号,与MATLAB中结果做对比完全一致。各级滤波器的输出有效信号如下图所示:
这里写图片描述
0~5分别对应第一级到第六级滤波器,每一级之间保持2倍关系,结果正确。

猜你喜欢

转载自blog.csdn.net/fpgadesigner/article/details/80915055