ΔΣ-ADC実験編 その14 1bitを使って、128tapsのfir fliter(fs=56.8MHz)が可能


128taps fir filtered 100KHz output

 1. 積和の結果は、全て >0

    1bitの場合、積和は、単純な和になります。

        Σ ( input[i] x coef[i] )

    この式の内、

        inputは1ビットですから、その値は 1 or 0 。

    ですので 積は無くて、和だけになり,

 

    積和は、上記のように表されます。

    この、sumの値は、一瞬たりとも、負には、なりません。
   
    と言うのも、今回の場合、fir filterは、Low pass Filterであり、

    その係数は、全て、正数になったからです。



    これは、1bitで計算する時に、

    一々、signedをunsignedに変換する手間が、省けて都合がいいです。

        以下は  sampling frequency である、clkop(56.8MHz)を使って積和を計算する部分です。

 always@(posedge clkop) begin
      if(reset==0) begin
/////////// need for 1bit bandpass ADC///////
       Qinner =D;
/////////// delay ///////////////////////////

    z=z<<1;  
  
     z[0]=mixed_sig_1bit;

      sum=0; 
 
      for(i=ORDER-1;i>=0;i=i-1) begin
        sum=sum+(z[i]?coef[i]:0);
      end

     sum_unsigned=sum[DATA_WIDTH-1:0];

   end
 
 end 
  
      そして

        sum_unsigned=sum[DATA_WIDTH-1:0];

    は、積和の結果 sum を 18bitに直す部分です。 

        今回のプログラムです。 

    尚、decimationを行ってない場合の、128taps fir filterを通した結果は、


    sampling周波数56.8MHz付近までの観測では


    あまり、結果がよくないのは、

    fir fliterの設計の際の、設定にも拠ります。

    decimationを、前提にしているからです。

      decimation比率:1/32

    だから、fir LPFの新しい fs/2の値は
    
      現fs/2 (56.8/2MHz) の 1/32   = 887.5KHz/56.8MHz =0.015625(正規化周波数に対して)

    に、設定せねばなりません。





2.どこで、1bitを使ったかと、言いますと

    1bit Delta Sigma A/D converterのoutputは、1bitです。

     fir filterを通す前に

    このoutputに、NCOで生成した、7.1MHz sin波をmixしますが

    このmixedされた信号を1bitに、前以って変換して置くのです。

//multiplier: sampled input D * sin wave
 assign mixed_signed= (Qinner ? sin_signed:-sin_signed);
 assign mixed_unsigned=mixed_signed+18'h1ffff;
 accum #(DATA_WIDTH)  accum3(clkop,mixed_unsigned,mixed_sig_1bit);

    そうすると、fir filterの入力は、1bit信号になります。

     ですので
、遅延器は、1bit単位になりますから

    データの移動は

 z=z<<1

        と、超簡単に、なります。



    尚、for文を使っても、ベタ書きでも、

    ispLeverでの、buildの結果は、ほとんど同じになりました。

3.FPGAの配線も大切

    ispLeverのdefaultの自動配線では、スピードが足りない時があります。





    そんな時は、赤丸の部分をいじってやると、

    改善される場合があります。

    具体的には、deci_z , resultの、wireの属性をregに変えて、その配置する位置を変えたりします。
 
    反対に、regの属性をwireに変えて、配置を替える事も、あります。

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

    例: 元のプログラム

       accum(clkop,result,output);
                 ..............
                 ..............
               always@(posedge clkop) begin
        result<=.....
               end
=========================================
               改良プログラム

       assign obj=result;
       accum(clkop,obj,output);
                 ..............
                 ..............
               always@(posedge clkop) begin
        result<=.....
               end
=========================================

    なんせ、原因が 36.5% logic  63.5% route と、ありますから

        routeも、大事ですね。

    その他、routingのdefaultの回数を、変える手も見つけました。




    Place & Route Design の所を、右クリックすると、Propertiesが表示されます。

    私は、 Placement Iterations のdefault値 1 を 3に変えました。

    0に設定すると、永遠に、終了しないかも....   (^_^;;

        その他


    そして、究極の手として、

    FPGAでの配置、配線を、直接いじる手もあるようです。


    まだ、そこまでは、できませんねん。

    次回は、decimationで感じた事を書いてみます。

H.22.8.15