2013-02-27 289 views
3

我想在Verilog中實現FIR濾波器。我已經預先確定了MATLAB中的係數。但我不確定寄存器是否能夠正確地傳播這些代碼。在Verilog中實現FIR濾波器

module fir_filter(
    input clock, 
    input reset, 
    input wire[15:0] input_sample, 
    output reg[15:0] output_sample); 

parameter N = 13; 
reg signed[15:0] coeffs[12:0]; 
reg [15:0] holderBefore[12:0]; 
wire [15:0] toAdd[12:0]; 

always @(*) 
begin 
    coeffs[0]=6375; 
    coeffs[1]=1; 
    coeffs[2]=-3656; 
    coeffs[3]=3; 
    coeffs[4]=4171; 
    coeffs[5]=4; 
    coeffs[6]=28404; 
    coeffs[7]=4; 
    coeffs[8]=4171; 
    coeffs[9]=3; 
    coeffs[10]=-3656; 
    coeffs[11]=1; 
    coeffs[12]=6375; 
end 

genvar i; 

generate 
for (i=0; i<N; i=i+1) 
    begin: mult 
     multiplier mult1(
      .dataa(coeffs[i]), 
      .datab(holderBefore[i]), 
      .result(toAdd[i])); 
    end 
endgenerate 

always @(posedge clock or posedge reset) 
begin 
    if(reset) 
     begin 
      holderBefore[12] <= 0; 
      holderBefore[11] <= 0; 
      holderBefore[10] <= 0; 
      holderBefore[9]  <= 0; 
      holderBefore[8]  <= 0; 
      holderBefore[7]  <= 0; 
      holderBefore[6]  <= 0; 
      holderBefore[5]  <= 0; 
      holderBefore[4]  <= 0; 
      holderBefore[3]  <= 0; 
      holderBefore[2]  <= 0; 
      holderBefore[1]  <= 0; 
      holderBefore[0]  <= 0; 
      output_sample  <= 0; 
     end 
    else 
     begin    
      holderBefore[12] <= holderBefore[11]; 
      holderBefore[11] <= holderBefore[10]; 
      holderBefore[10] <= holderBefore[9]; 
      holderBefore[9]  <= holderBefore[8]; 
      holderBefore[8]  <= holderBefore[7]; 
      holderBefore[7]  <= holderBefore[6]; 
      holderBefore[6]  <= holderBefore[5]; 
      holderBefore[5]  <= holderBefore[4]; 
      holderBefore[4]  <= holderBefore[3]; 
      holderBefore[3]  <= holderBefore[2]; 
      holderBefore[2]  <= holderBefore[1]; 
      holderBefore[1]  <= holderBefore[0]; 
      holderBefore[0]  <= input_sample; 
      output_sample <= (input_sample + toAdd[0] + toAdd[1] + 
           toAdd[2] + toAdd[3] + toAdd[4] + toAdd[5] + 
           toAdd[6] + toAdd[7] + toAdd[8] + toAdd[9] + 
           toAdd[10] + toAdd[11] + toAdd[12]); 
     end 
end 



endmodule 

這是實現它的最好方法嗎?有沒有更好的方法來添加?

任何幫助,非常感謝!

此外,將有助於非常讚賞的資源。

回答

1

面積和功率效率FIR/IIR濾波器是一些聖盃。

使用generate實例化13個乘數的語句。乘數佔用了相當多的面積。通常只實例化一個時間複用它(TDM)。在這種情況下,提供比所需輸出速率快13倍的時鐘(滴答)。

您的加法器鏈雖然看起來很有效,但會變得非常大,並且可能會導致計時問題,因爲可能存在很長的連鎖反應。在多個週期中將其分解可能會導致面積和功耗降低。

如果將樣本的乘法與加法相結合,您將擁有更典型的MAC架構(乘法累加)。

我也將避免在always @*作爲論據沒有右手邊初始化常數改變,這可能不會觸發靈敏度名單。

對於這些我會用localparams,或者下降的TDM路線我會創建一個查找表(LUT)。

always @* begin 
    case(program_counter) 
    0 : coeff = 6375; 
    1 : coeff = 1 ; 
    ... 
    endcase 
end 
1

假設您的濾波器響應的選擇是有道理的(5.2分貝波動!)

然後,一個方法是使用收劍位表示[HTTP來權衡一些響應精度降低芯片資源:// EN .wikipedia.org/wiki/Canonical_signed_digit]來近似每個係數。這個減少強度[http://en.wikipedia.org/wiki/Strength_reduction](編譯器術語)允許有效的轉換,即路由和增加,而不是昂貴的乘法。

然後由於各樣品可以施加係數,其顯著下降所需要的芯片資源之前被求和的係數的對稱性。[1]

但隨後有可能在實施的係數,這對於芯片的目標可能會得到一些優化,但固件顯著可以改進的常見因素。

[1] = DSP技巧:建立一個簡化FIR濾波器結構理查德G.里昂

一種奇怪的方式嘗試http://www.embedded.com/design/embedded/4008837/DSP-Tricks-An-odd-way-to-build-a-simplified-FIR-filter-structure