CICフィルタのアキュームレーター長

CICフィルタは前半に積分器が並びます。積分器は低域に向かってゲインが単調に増加し、DCで発散します。もちろん、離散信号の場合はゲインが無限大とは行きませんが、DC付近で不安定になります。したがって、CICフィルタを安定に動かすには

  • DCをカットしておく
  • 希望信号がDCに近づき過ぎないようにしておく
  • 1段ごとに適切なビット数ずつアキュームレーターを大きくする

ことが必要だと思っていました。
なんと、違うそうです。
今読んでいるディジタル信号処理による通信システム設計―演算の実装から信号の変復調・誤り訂正まで (ディジタル信号処理シリーズ)によれば、積分器はオーバーフローするに任せておけばよく、長大な精度は無用とのこと。コツは飽和を使わないことです。
このようなことが出来るのは、CICフィルタに以下のような特徴があるためです。

  • トータルのゲインは最大で1である決まっている。
  • 加算と減算しか使わず、しかも線形である。

トータルのゲインが最大1決まっているということは、信号範囲[-1,+1)から中間結果が逸脱しても、かならず[-1,+1)固有の範囲*1に戻ってくるということです。また、加算と減算しか使わないということは、中間結果の絶対値の大きさが最終結果に影響しないということです。
このため、完全なダイナミックレンジを与えず、出力範囲の剰余系の中で計算しても最後にはきちんと正しい結果が得られます。剰余系を使うには飽和をやめてラップアラウンドであふれさせます。頭のいい方法ですね。
直感的にはわかるのですが、一度プログラムを組んで様子を観察してみたくもあります。

scilabで実験してみたものの

なんだか出力が変です。よくよく考えて、modulo()関数が望む特性をもっていないことに気づきました。たとえばmodulo 4だと、[0,4)を返しますが、私がほしいのは[-4,4)です。「デジタル信号処理による…」にも、「2の補数系で回路を組め」とちゃんと書いています。実機かそのシミュレータで組まないと実験にならないようです。とはいえ、それっぽい値がちゃんと出ていますので、ふむふむと納得はしています。

*1:デシメーション率と微分器の遅延線の長さで決まる固有のゲインがある