2013-02-27 263 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