ハードウェアFFTの精度向上
FPGAを使ってハードウェアでFFTする回路を作ったのですが、ノイズに悩まされています。
そのノイズというのは、決まった周波数にいつもノイズがいるというものです。単一の正弦波(10kHz)をFFTすると下の図のような結果になります。
1本立っているのが真のスペクトラムなのですが、全域にわたってフロアノイズが出ています。なお、16bitの演算精度なので、結果が1LSBなら-90dB、2LSBなら-84dB程度のところになります。
つまり、スペクトラムの全域にわたって±2LSB程度の誤差が出ているというわけです。その中でも特に1.2MHzと0.6MHzの値に特徴的な盛り上がりがあります。
このFFT結果を何度も積算して平均化してみると、ノイズの構造が見えてきます。
このように周期的なFixed Patternなノイズが見えてきます。
ノイズが生じる原因は、FFTの演算精度を16bitの固定小数点(つまり整数)で行っていて、バタフライ演算の後で生じる除算をした際にLSBを単純に切り捨ててしまっているから、その誤差が積み重なったのだと考えられます。
そこで、FPGAではなく、パソコンのソフトウェアを作ってFFT計算誤差を調べてみました。
最初は1024ポイントのFFTで、浮動小数点で計算します。入力データは正弦波なのですが、周波数が整数ではない場所に設定されていて、サイドローブが広がるようにしています。
f=20あたりにピークがあって、あとは滑らかに減衰するだけです。
16bitの固定小数点で、誤差を単純に切り捨てた場合の結果を以下に示します。まさにFPGAでの計算のときのようなギザギザが生じてしまっています。このような形のギザギザは演算精度の問題であることがわかります。
そこで、最近接偶数丸めというのを使ってみました。
浮動小数点計算ほど滑らかではありませんが、特徴的なギザギザはなくなったようです。
FPGAのハードウェアでFFTを行う際にも、誤差は最近接丸めで処理すれば、もっと良い結果が出るかもしれないという知見が得られました。
| 固定リンク
コメント