3

VerilogにFIRフィルターを実装しようとしています。MATLABで係数を事前に決定しました。しかし、レジスタがこのコードで適切に伝播するかどうかはわかりません。

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

これはこれを実装するための最良の方法ですか?追加を行うためのより良い方法はありますか?

どんな助けでも大歓迎です!

また、役立つリソースも大歓迎です。

4

2 に答える 2

2

エリアおよび電力効率の高いFIR/IIRフィルターは、一部の人にとっては聖杯です。

generateステートメントを使用して、13個の乗数をインスタンス化しました。乗数はかなりの面積を占めます。1回だけインスタンス化し、それを時分割多重化(TDM)するのが一般的です。この場合、必要な出力レートの13倍の速度でクロック(ティック)を供給します。

再び有効に見える場合の加算器チェーンは非常に大きくなり、非常に長いリップルチェーンが存在する可能性があるため、タイミングの問題が発生する可能性があります。これを複数のサイクルに分割すると、面積と電力が低下する可能性があります。

サンプルの乗算と加算を組み合わせると、より一般的なMACアーキテクチャ(積和)が得られます。

always @*また、引数の右側が変更されないため、定数を初期化することは避けます。これにより、感度リストがトリガーされない場合があります。

これらにはlocalparams、を使用します。または、TDMルートをたどる場合は、ルックアップテーブル(LUT)を作成します。

always @* begin
  case( program_counter )
    0 : coeff = 6375;
    1 : coeff = 1   ;
    ...
  endcase
end
于 2013-02-27T09:06:42.820 に答える
1

フィルタ応答の選択が正当であると仮定します(5.2dBリップル!)

次に、Canonical符号付き桁表現[http://en.wikipedia.org/wiki/Canonical_signed_digit]を使用して各係数を概算することにより、応答精度とチップリソースの削減をトレードオフする方法があります。この強度低下[http://en.wikipedia.org/wiki/Strength_reduction](コンパイラ用語)により、効率的なシフト、つまりルーティングと加算が、高価な乗算の代わりに使用できるようになります。

次に、係数の対称性により、係数を適用する前にそれぞれのサンプルを合計できます。これにより、必要なチップリソースが大幅に削減されます。[1]

ただし、実装された係数には共通の要因がある可能性があります。これは、チップターゲットの場合はある程度最適化される可能性がありますが、ファームウェアの場合は大幅な改善が可能です。

[1] = DSPトリック:単純化されたFIRフィルター構造を構築する奇妙な方法Richard G. Lyons

http://www.embedded.com/design/embedded/4008837/DSP-Tricks-An-odd-way-to-build-a-simplified-FIR-filter-structureを試してください

于 2013-03-02T10:57:29.780 に答える