FM復調のFPGA実装(3)
前回までに、FM変調のキモであるarctanのところまでFPGA実装しました。
今回は、それに続く偏角の差分計算から、FIR3段とデエンファシスまでFPGA実装しました。
FM復調全体の流れは次の図のようになっています。
前回までは、最初の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は動作確認は一切できていないので、 音声出力まで、まだ少し作業が残っています。