FM復調のFPGA実装(3)

前回までに、FM変調のキモであるarctanのところまでFPGA実装しました。

今回は、それに続く偏角の差分計算から、FIR3段とデエンファシスまでFPGA実装しました。

FM復調全体の流れは次の図のようになっています。

“FM flow”

前回までは、最初のFIRフィルタから160MHzで駆動するようにしていましたが、 FPGAのVivadoプロジェクトを2017.1にアップグレードしたら、CORDICが160MHzで動作しなくなってしまいました。 そのため、FM復調全体までは40MHzで行うようにしました。

おかげで、FIRに使用するDSPの数が増えてしまいました。リソース使用量の観点からすると、 できるだけ高速で動作させたほうが(リソース使用量が減って)望ましいのです。

前回までにFIRフィルタの使い方は分かったので、ひたすら必要な逓倍数のフィルタを作成し、 連結します。ただ、FIRフィルタの間は小さなFIFOを入れて、データ出力間隔が均等にならないのを埋め合わせています。

また、FM復調のための偏角の差分計算は、C#ではこちらの記事で書きましたが、 Verilogで書くにあたっては、

parameter signed[33:0] PI = (2.0 ** 29.0) * 3.1415926535897932384626433832795;
parameter signed[33:0] PI2 = (2.0 ** 30.0) * 3.1415926535897932384626433832795;

のようにπと2πを定義して、

assign  w_atan_tdata2   <=  {w_atan_tdata[31], w_atan_tdata[31], w_atan_tdata};
assign  r_atan_tdata2   <=  {r_atan_tdata[31], r_atan_tdata[31], r_atan_tdata};

always @(posedge w_fir_ck) begin
    if (w_atan_tvalid) begin
        r_atan_tdata    <=  w_atan_tdata;
        if (w_atan_tdata2 - r_atan_tdata2 > PI)
            r_atan_diff <=  w_atan_tdata2 - r_atan_tdata2 - PI2;
        else if (w_atan_tdata2 - r_atan_tdata2 < -PI)
            r_atan_diff <=  w_atan_tdata2 - r_atan_tdata2 + PI2;
        else
            r_atan_diff <=  w_atan_tdata2 - r_atan_tdata2;
    end
end

としています。w_atan_tdataは小数部29bitの符号付き32bit固定小数点数なので、 34bitに符号拡張してから、πを2^29乗したものと比較します。r_atan_diffは32bitに戻ります。 これが偏角の差分値になります。

最後のデエンファシスも小数点位置に気を付けてIIRフィルタを実装しました。 安直に実装したデエンファシスの回路は160MHzではタイミングエラーを起こしたため、 非同期FIFOで40MHzに落として運転しました。そう思うと純正IPのFIRが160MHzでも動作しているのは、 さすがによくできています。

計算結果の32bitはDMAしてPCに転送し、16bitにクリップしてwavファイルに出力しました。 これでFM復調のFPGA化は基本的に完成です。

あとは、上図の右下にDACへの点線が書いてありますが、基板上に実装している NAU8822 を動作させ、I2S出力回路も実装しないといけません。まだこちらのICは動作確認は一切できていないので、 音声出力まで、まだ少し作業が残っています。

comments powered by Disqus