天天看點

【HB filter】基于FPGA的半帶濾波器(HB) 的設計

1.軟體版本

Quartusii12.1

2.本算法理論知識

       HBF子產品由半帶濾波器(HBF)和抽取子產品組成。該子產品的任務是實作2倍抽取進一步降低信号采樣速率。由于HBF的沖激響應h(k)除零點外其餘偶數點均為零,是以用HBF實作2倍抽取可以節省一半的運算量,對增強軟體無線電的實時性非常重要,HBF還具有參數限制少,設計容易、友善的特點。半帶濾波器的主要作用是濾除信号高頻部分,防止抽取過程後信号發生頻譜混疊。

       在實際中,需要将輸入信号進行多次濾波和抽取,并逐次降低采樣率,同時也降低對每一級抗混疊濾波器的要求,是以需要使用半帶濾波器進行設計與實作。

阻帶衰減:    ≥50dB

通帶不平坦度:≤2dB

       通常情況下,半帶濾波器的有三種基本的結構,一般結構,轉置結構以及複用結構,下面我們将針對這三種結構的濾波效果以及硬體占用情況進行分析,進而選用最佳的設計方案。

★半帶濾波器的系數确定

【HB filter】基于FPGA的半帶濾波器(HB) 的設計

 通常情況下,半帶濾波器的頻譜特性如圖1所示:

【HB filter】基于FPGA的半帶濾波器(HB) 的設計

       頻譜對稱性的特點使得半帶濾波器的時域沖擊響應除極值點以外,在其餘所有偶數點都為零,利用該性質,可以将運算量降低一半。

       本系統,我們将設計的濾波器,首先,我們可以使用和FIR濾波器設計方法相同的方法進行設計。根據的設計要求,輸入的信号帶寬為20M,前面設計的NCO,其載波頻率為20M,是以,在進行下變頻的時候,會産生兩倍的頻率分量,具體如下所示:

【HB filter】基于FPGA的半帶濾波器(HB) 的設計

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

【HB filter】基于FPGA的半帶濾波器(HB) 的設計

       是以,需要設計一個濾波器,其截止頻率可以設定為20M,即大于20M的全部濾除,是以,通過上式,可以将其中的高頻分量濾除掉。

       此外,由于你的要求中提高通帶通帶不平坦度≤2dB,那麼通常情況下,濾波器的階數需要設計為中高階,這裡,我們選用65階的濾波器。

3.部分源碼

在MATLAB指令行中輸入FDAtool,然後顯示如下的界面,進行濾波器的設計:

【HB filter】基于FPGA的半帶濾波器(HB) 的設計

将通帶和阻帶放大,可以看到如下的結果:

可以看到,這麼一個效果,通帶的不平坦度和阻帶的衰減基本滿足設計需求。産生的濾波器系數如下所示:

【HB filter】基于FPGA的半帶濾波器(HB) 的設計

其系數如下所示:

-0.00155965846190849

-0.00952583660975731

-0.0192068330061876

-0.0179259709192058

0.000712959523136487

0.0188957029356946

0.0105047070598809

-0.0188943413581846

-0.0266507867913233

0.0101837262873298

0.0460875556113994

0.0147245607722628

-0.0647700808685521

-0.0724069698055561

0.0782875722309085

0.306295132489419

0.416802321987223

0.306295132489419

0.0782875722309085

-0.0724069698055561

-0.0647700808685521

0.0147245607722628

0.0460875556113994

0.0101837262873298

-0.0266507867913233

-0.0188943413581846

0.0105047070598809

0.0188957029356946

0.000712959523136487

-0.0179259709192058

-0.0192068330061876

-0.00952583660975731

-0.00155965846190849

在FPGA中,需要将系數進行量化,我們乘以一個量化系數2^16。量化後的系數如下所示:

-102

-624

-1259

-1175

47

1238

688

-1238

-1747

667

3020

965

-4245

-4745

5131

20073

27316

20073

5131

-4745

-4245

965

3020

667

-1747

-1238

688

1238

47

-1175

-1259

-624

-102

module hb_filter_01(
                    i_clk,
              i_rst,
              i_din,
              o_clk2,
              o_dout
                   );
             
parameter h16 = -102;            
parameter h15 = -624; 
parameter h14 = -1259;  
parameter h13 = -1175;  
parameter h12 = 47; 
parameter h11 = 1238; 
parameter h10 = 688;  
parameter h9  = -1238;  
parameter h8  = -1747;               
parameter h7  = 667;  
parameter h6  = 3020; 
parameter h5  = 965;  
parameter h4  = -4245;  
parameter h3  = -4745;  
parameter h2  = 5131; 
parameter h1  = 20073;  
parameter h0  = 27316;

  
input              i_clk;
input              i_rst;
input signed[15:0] i_din;
output             o_clk2;
output signed[31:0]o_dout;

//delay 33 units
integer i;
reg signed[15:0]men_delay[33:1];
always @(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
    begin
         for(i=1;i<=33;i=i+1)
       begin
       men_delay[i] <= 16'd0;
       end
    end
else begin
          men_delay[1] <= i_din;
       
         for(i=2;i<=33;i=i+1)
       begin
       men_delay[i] <= men_delay[i-1];
       end       
     end
end


//level 1
reg signed[31:0]reg_adder01[33:1];
always @(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
    begin
         for(i=1;i<=33;i=i+1)
       begin
       reg_adder01[i] <= 32'd0;
       end
    end
else begin
         reg_adder01[1] <= 32'd0;
       reg_adder01[2] <= h15 *  men_delay[2];
       reg_adder01[3] <= 32'd0;
       reg_adder01[4] <= h13 *  men_delay[4];
       
         reg_adder01[5] <= 32'd0;
       reg_adder01[6] <= h11 *  men_delay[6];
       reg_adder01[7] <= 32'd0;
       reg_adder01[8] <= h9  *  men_delay[8];    
    
         reg_adder01[9] <= 32'd0;
       reg_adder01[10]<= h7  *  men_delay[10];
       reg_adder01[11]<= 32'd0;
       reg_adder01[12]<= h5  *  men_delay[12];

         reg_adder01[13]<= 32'd0;
       reg_adder01[14]<= h3  *  men_delay[14];
       reg_adder01[15]<= 32'd0;
       reg_adder01[16]<= h1  *  men_delay[16];
       
//============================================================
         reg_adder01[17]<= h0  *  men_delay[17];
//============================================================  
     
       reg_adder01[18]<= h1  *  men_delay[18];
       reg_adder01[19]<= 32'd0;
       reg_adder01[20]<= h3  *  men_delay[20]; 
         reg_adder01[21]<= 32'd0;
       
       reg_adder01[22]<= h5  *  men_delay[22];
       reg_adder01[23]<= 32'd0;
       reg_adder01[24]<= h7  *  men_delay[24];
         reg_adder01[25]<= 32'd0;
       
       reg_adder01[26]<= h9  *  men_delay[26];
       reg_adder01[27]<= 32'd0;
       reg_adder01[28]<= h11 *  men_delay[28];
         reg_adder01[29]<= 32'd0;
       
       reg_adder01[30]<= h13 *  men_delay[30];
       reg_adder01[31]<= 32'd0;
       reg_adder01[32]<= h15 *  men_delay[32];
       reg_adder01[33]<= 32'd0;     
     end
end


//level 2
reg signed[31:0]reg_adder02[9:1];

always @(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
    begin
         for(i=1;i<=9;i=i+1)
       begin
       reg_adder02[i] <= 32'd0;
       end
    end
else begin
         reg_adder02[1] <= reg_adder01[2] + reg_adder01[32];
       reg_adder02[2] <= reg_adder01[4] + reg_adder01[30];
       reg_adder02[3] <= reg_adder01[6] + reg_adder01[28];
       reg_adder02[4] <= reg_adder01[8] + reg_adder01[26];
       
         reg_adder02[5] <= reg_adder01[17];
       
       reg_adder02[6] <= reg_adder01[10]+ reg_adder01[24];
       reg_adder02[7] <= reg_adder01[12]+ reg_adder01[22];
       reg_adder02[8] <= reg_adder01[14]+ reg_adder01[20];   
         reg_adder02[9] <= reg_adder01[16]+ reg_adder01[18];
     end
end


//level 3
reg signed[31:0]reg_adder03[5:1];

always @(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
    begin
         for(i=1;i<=5;i=i+1)
       begin
       reg_adder03[i] <= 32'd0;
       end
    end
else begin
         reg_adder03[1] <= reg_adder02[1] + reg_adder02[9];
       reg_adder03[2] <= reg_adder02[2] + reg_adder02[8];
       reg_adder03[3] <= reg_adder02[3] + reg_adder02[7];
       reg_adder03[4] <= reg_adder02[4] + reg_adder02[6];
         reg_adder03[5] <= reg_adder02[5];
     end
end

//level 4
reg signed[31:0]reg_adder04[3:1];

always @(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
    begin
         for(i=1;i<=3;i=i+1)
       begin
       reg_adder04[i] <= 32'd0;
       end
    end
else begin
         reg_adder04[1] <= reg_adder03[1] + reg_adder03[5];
       reg_adder04[2] <= reg_adder03[2] + reg_adder03[3];
       reg_adder04[3] <= reg_adder03[4];
     end
end

//level 5
reg signed[31:0]r_dout = 32'd0;
reg signed[31:0]o_dout = 32'd0;      
always @(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
    begin
    r_dout <= 32'd0; 
    end
else begin
    r_dout <= reg_adder04[1] + reg_adder04[2] + reg_adder04[3];
     end
end
  

reg[3:0]cnt = 4'b00000;
always @(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
    begin
    cnt <= 4'b0000;
    end
else begin
     cnt <= cnt + 4'b0001;
     end
end

assign o_clk2 = cnt[0];

always @(posedge o_clk2 or posedge i_rst)
begin
     if(i_rst)
    begin
    o_dout <= 32'd0; 
    end
else begin
    o_dout <= r_dout;
     end
end


  
endmodule                  

4.仿真分析

該子產品的硬體占用資源為:

【HB filter】基于FPGA的半帶濾波器(HB) 的設計

繼續閱讀