[1chipMSX]
5タップFIRフィルタの不都合
※情報の正確さは保証できません。
各種音源(PSG, SCC, OPLL)から出力される波形は、EMSX_TOP.VHD でミキシングされたあと、
PWM の回路へ渡されます。PWM の回路は、5tap の FIR フィルタに掛けてから、入力信号を
1bit 出力に変換しています。
その 5tap の FIR フィルタですが、おそらく下記のような伝達関数のフィルタを想定している
と思います。
H(Z) = 9 * Z^(-4) + 61 * Z^(-3) + 116 * Z^(-2) + 61 * Z^(-1) + 9
※Z^(-1) は遅延素子。3.58MHz のサイクル。
しかし、実際のところ、この伝達関数通りにはなっておらず、おかしなことになってます。
実際にテストベンチを作成し、インパルス応答を見てみると、左右対称になっていません。
遅延素子 Z^(-1) の実現に RAM を使っており、回路自体は 21MHz のクロックで動作しています。
これを、5サイクル掛けて H(Z) の各項を処理し、6サイクル目で出力しています。
遅延素子への記憶は、6サイクル目で行っていますが、H(Z)計算用の RAM読み出しアドレスと、
書き込みを行うための RAM描き込みアドレスは共通の FF (tapidx) を使っており、本来 6サイクル目
で示される tapidx の位置に書き込みたいところが、wr を FF にしてしまったために RAM の wr が
1 になるのは1サイクル遅延した 1サイクル目となっています。そのために、書き込まれるアドレス
が期待と異なっており、上に示すような伝達関数を実現できていませんでした。
タイミングを確認し直して、ソースを全般的に書き直して、この問題を修正。
修正後のインパルス応答を見てみると、左右対称で、期待通りの値が出力されるようになりました。
効果のほどは?
FIR タイプのローパスフィルタではありますが、3.58MHz に対してたったの5タップ。
振幅特性は確認していませんが、5サンプルに広がったとしても 716kHz くらいまでしか影響しません。
人間の可聴領域は 20kHz 程度と言われているので、どんなに耳がいい人でも、716kHz は聞き分けられな
いでしょう (^^;
ただ、もしかすると後に続く PWM に高周波が入ったときにエイリアスが出ないようにするための安全策
かもしれないので、念のため残しておきます。5tapFIR の 3.58MHz 動作に対して PWM は 21MHz の
オーバーサンプリングなので、エイリアスは出ないと思いますが・・。
修正版ソースは、上に戻ってダウンロードできる最新版ソースに組み込まれています。
[▲上へ]