なひたふ流 FPGAでFFT回路のまとめ
STFT(Short Time Fourier Transform)といって、短い時間のウィンドウをかけてフーリエ変換を行う機能をFPGAに実装する案件が来ました。
この案件の提案のために、特電が過去に作ったFFTの回路にどんなものがあるかを調べてまとめてみました。
まず、ハードウェアFFTなのですが、計測向けならば周波数間引きのアルゴリズムにするのがよいでしょう。周波数間引きというのは、ビットリバースの計算を変換した後で行い、時系列の計測データはビットリバースはせずにそのままFFT回路に与える方法です。
時間軸間引きだと、どうしても1フレーム分のデータが溜まってからビットリバースをしなければならないので、バッファする時間の遅延が発生してしまいます。
FFTを普通にソフトウェアで書くと3重のループになりますが、なひたふ製のFFTアルゴリズムを使うとこういう感じでデータを並べ替えて計算することで、ループが1重になります。
データの規模が小さければDRAMのような大きなメモリを使わずにBlock RAMに入ってしまうので、BlockRAMをデュアルポートメモリとして使えば1クロックで1回のバタフライ演算が可能になります。
バタフライ演算の回数は、2つずつのデータで計算するか、8つ組のデータで計算するかで、かなり変わります。
これをRadix-2やRadix-8というのですが、Radix-8にすると10倍程度早くなります。ただし、FPGA内のDSPを216個とか使うので激熱になります。
FPGAでFFTを行う場合、倍精度浮動小数点とかは使えません。高速性のため演算の精度は16bitになります。
そうすると、当然ながら誤差が出てくるのですが、スペクトラム上で固定周波数のノイズとして出てきてしまいます。
バタフライ演算、A+Bと、A-B×Wを計算するときに誤差を丸めるわけですが、↑の計算は切り捨てで行っています
これをA+Bの加算後で丸めた場合は下の図のようにノイズが減り、
これをA-Bの減算後でも丸めた場合は下の図のようにさらにノイズが減りました。
16bitですから-90dBcまで行ければ十分です。
ただし、B×Wを丸めるとなぜか誤差が増えてしまいます。
丸める場所に何かノウハウがありそうです。
出来上がったハードウェアFFTは、このようにちゃんと動いています。
| 固定リンク
コメント