本シリーズのPart 1をご覧いただいた方や、DSPによる信号処理についてある程度経験のある方なら、DSPによるデジタル・フィルタの実装方法に関心を持っていらっしゃるでしょう。そこで、今回は以下に挙げるトピックについて解説することにします。
- フィルタの変換機能のモデリング
- モデルとDSPのアーキテクチャの関連づけ
- デジタル・フィルタの実装
本シリーズでは、DSPの設計について理解したいと考えているアナログ・システム設計者向けに、上記のトピックについて説明します。DSPを使用すれば、アナログ回路を使う場合よりも生産性を高められることがあります。本シリーズを入門用のドキュメントとして活用すれば、どのような場合にそのような効果が得られるのか判断することが可能になります。
フィルタの変換機能のモデリング
Part 1では、アナログ・フィルタとデジタル・フィルタの性質を比較しました。その上で、アナログ・フィルタと同等の回路を、(DSPを使用して)デジタルで実装する理由を明らかにしました。今回は、デジタル・フィルタのアプリケーションに焦点を絞ることにします。
デジタル・フィルタを使用する主な理由は、次の3つです。
- 理想的なフィルタに、より近い特性を得ることができる◦
- フィルタの特性の調整を、物理的な同調によって行うのではなく、ソフトウェアによって実現できる
- サンプリングされたデータと親和性を持つフィルタの応答が得られる
Part 1では、最もよく知られている2種類のフィルタとして、FIR(Finite Impulse Response:有限インパルス応答)フィルタとIIR(Infinite Impulse Response:無限インパルス応答)フィルタを紹介しました。FIRフィルタでは、その出力が、入力された有限個のサンプル・データのみによって決まります。そのため、有限という言葉が使われています。非再帰型のフィルタであり、s平面には極がなく、ゼロのみが存在します。一方、IIRフィルタは再帰型のフィルタです。出力値が入力と出力の両方に依存し、その応答は無限に続きます(不安定になる可能性もあります)。また、s平面には極とゼロの両方が存在します。図1に、両フィルタの標準的なアーキテクチャと、その処理内容を表す式を示しました(Part 1でも同じ図を示しました)。

これらのフィルタをデジタル的にモデル化するためには、2つのステップで作業を実施する必要があります。まず、フィルタによる処理に相当する数式をコンピュータ上で動作するプログラムとして捉えます。このステップでは、まず数式を数学的な手順(乗算と加算など)に分解します。その上で、得られた数式をソフトウェアとして実装するために、コンピュータで実行する必要があるすべての操作(命令とデータの処理、ステータスの判定など)を特定します。
次のステップでは、上記のすべての操作をプログラムとして記述します。これは、かなり骨の折れる作業になります。ただ、実際にはC言語などの高級言語(HLL:High-level Language)で記述された数多くの定型的なプログラムを利用できるケースが多いはずです。そのようにすれば、プログラミングの作業をある程度簡素化できます(但し、必ずある程度のプログラミングは行わなければなりません)。学習という観点からは、アセンブリ言語を使って記述するところから始めた方がためになるかもしれません。また、アセンブリ言語で記述したアルゴリズムは、システムの性能を最適化する必要がある場合、高級言語で記述したアルゴリズムよりも有用であるケースは少なくないはずです。一部の高級言語は抽象化のレベルが高く、プログラムから式を読み取ることも難しいかもしれません。図2に、C言語で実装したFIRフィルタのアルゴリズムの例を示しました*。
図2. C言語で記述したFIRフィルタのアルゴリズム
アルゴリズムのモデリング向けには、数多くの解析用パッケージが提供されています。よく使われているいくつかのパッケージについては、稿末に示した参考資料をご覧ください。本シリーズでは、折に触れてアルゴリズムのモデリングに立ち返ることにします。フィルタのアルゴリズムのモデリングが完了したら、既にDSPのアーキテクチャにプログラムを実装する準備が整ったことになります。以下では、具体的な作業内容について説明します。
モデルとDSPのアーキテクチャの関連づけ プログラミングを行うためには、DSPのアーキテクチャが備えるいくつかのセクションについて理解する必要があります。数値演算部、メモリ操作部、シーケンサ操作部、I/O操作部の4つです。以下で解説する内容は、一般的なDSPのアーキテクチャを前提としています。また、本稿で後述する具体的なプログラミングの例にも対応しています。図3に、以下の解説で前提とするDSPの一般的なアーキテクチャを示しました。
DSPのアーキテクチャ
ここからは、DSPのアーキテクチャが備える4つのセクションについて説明していきます。
数値演算部 DSPでは、積和演算、加算、減算、ビットシフトの操作を1つの命令サイクルで完了する必要があります。そのため、あらゆるDSPにおいては、数値演算向けに最適化されたハードウェアが中核的な役割を担っています。そうしたハードウェアの存在が、DSPと汎用マイクロプロセッサの違いだと説明することもできます。汎用マイクロプロセッサでそうした演算を実施しようとすると、多くのサイクルを費やしてしまうことがあります。通常、DSPでデジタル・フィルタ(または他の多くのデジタル信号処理)のアルゴリズムを実行する場合には、データと係数に関する複数のステップの算術演算を1サイクルで完了させます。それにより、汎用プロセッサでは不可能なリアルタイムの応答を生成します。
数値演算は、DSPのMAC(積和演算器)、ALU(算術論理演算ユニット)、バレル・シフタ(シフタ)によって行われます。MACは、ほとんどのデジタル信号処理のアルゴリズム(FIRフィルタやIIRフィルタ、FFTなど)で使われる積和演算を実行します。ALUの機能には、加算、減算、論理演算などがあります。ビットとワードに関する演算は、シフタによって行われます。図3は、MAC、ALU、シフタの並列処理について説明したものです。また、それらにデータがどのように入出力されるのかということも表しています。

プログラミングの観点から言えば、独立した数値演算部を使用するDSPのアーキテクチャからは柔軟性と効率の高さというメリットが得られます。競合のないデータ・パスが数多く存在することから、数値演算を1サイクルで完了することが可能になります。また、DSPのアーキテクチャでは、MACによる演算向けに広いダイナミック・レンジが確保されています。入力の2倍の幅に達する乗算結果に対応したり、累積処理を行うアキュムレータの出力がオーバーフローしないようにしたりする能力が必要になるからです(例えば、16ビットのDSPであれば、16ビットの入力データと、MACからの40ビットの出力結果に対応できるようになっています)。ほとんどのDSPは、フィルタなどのアルゴリズムを適切に処理するために、このようなダイナミック・レンジを備えています。
数値演算部のその他の機能を使用すれば、リアルタイム・システム向けのプログラミングが容易になります。様々な条件/状態に応じた数値演算を行うことで、プログラムの実行時にそれらの結果を変数として使用し、キャリー、オーバーフロー、飽和、フラグなどの状態を判定することが可能になります。各種の条件文を使用することにより、DSPは、数値演算に基づいてプログラムの処理フローに関する判定を迅速に行うことができます。数値演算部に常にデータが供給されるということは、DSPのメモリや内部バスの構造に関する設計に対して重要な影響を及ぼします。
メモリ操作部 DSPのメモリとバスのアーキテクチャの設計は、速度に関する要件に左右されます。DSPの数値演算部とシーケンサ操作部には、命令サイクルごとにデータと命令を引き渡す必要があります。そのため、遅延やボトルネックが顕在化してはなりません。設計に関するあらゆる事柄は、スループットに焦点を絞って決定されます。
バージニア工科大学コンピュータ・サイエンス学部のJohn A.N. Lee氏によるハーバード・アーキテクチャとフォン・ノイマン型アーキテクチャの語源の説明 「ハーバード・シリーズのマシンの開発者であるHowardAiken氏は、開発したすべてのマシンでデータとプログラムを分離することにこだわっていました。私が最もよく知っている『Mark III』では、それぞれに異なるサイズの磁気ドラムを用意していたほどです。」 「フォン・ノイマンのコンセプトは、命令をデータとして取り扱うことにより、プログラムに変更を加えられるようにするというものでした。このようにすることで、プログラムが『学習する』能力を高めることができます。」 「どういうわけか、後者にはフォン・ノイマンの名前がつけられ、前者にはマシンのシリーズ名であるハーバードという名前がつけられました。」 |
DSPでは、スループットが非常に重要になります。その全体像を把握するためには、DSPと他のマイクロプロセッサにおけるメモリの設計にどのような違いがあるのかを理解する必要があります。ほとんどのマイクロプロセッサは、データと命令の両方を格納する単一のメモリ空間を使用します。また、1つのバスをアドレス用に、もう1つのバスをデータまたは命令用に使用します。このアーキテクチャは、フォン・ノイマン型のアーキテクチャと呼ばれています。同アーキテクチャでは、各サイクルにおいてデータ、命令のうちいずれかを選択する必要があるため、スループットが制限されます。それに対し、一般的なDSPでは、メモリはプログラム・メモリとデータ・メモリに分割されています。そして、それぞれには個別のバスが設けられます。この種のアーキテクチャは、ハーバード・アーキテクチャと呼ばれています。DSPでは、データと命令を分けることにより、各サイクルにおいて複数の要素をフェッチできるようになっています。そのため、スループットが2倍になります。それ以外に、命令キャッシュ、結果のフィードバック、コンテキスト・スイッチといった最適化手法も用いられます。それらによって、DSPのスループットは更に高められています。
DSPのメモリ・アーキテクチャには、それ以外の最適化も施されています。それらは、メモリ・アクセスの繰り返しに関連するものです。デジタル・フィルタなど、DSPで使われるほとんどのアルゴリズムでは、メモリに繰り返しアクセスしてデータを取得する必要があります。通常、この種のアクセスでは、データをある範囲のアドレスからフェッチするということが行われます。その範囲内は、処理すべき実世界の信号から得たデータによって埋め尽くされています。DSPでは、メモリ・アクセスの管理に必要な命令数(オーバーヘッド)を減らすことによって命令サイクルを節約します。その結果、各サイクルの本来の役割である信号処理に、より多くの時間を割けるようになります。オーバーヘッドを削減し、この種のアクセスを自動的に管理するために、DSPでは専用のデータ・アドレス・ジェネレータ(DAG:Data Address Generator)が利用されます。
DSPで使用するほとんどのアルゴリズムでは、1サイクルでメモリから2つのオペランドをフェッチする必要があります。それらは演算ユニットに入力されます。2つのオペランドのアドレスを柔軟に指定できるようにするために、DSPは2つのDAGを備えています。DSPの修正ハーバード・アーキテクチャでは、一方のDAGによってデータ・メモリに対応するアドレス・バス上のアドレスを指定します。もう一方のDAGは、プログラム・メモリに対応するアドレス・バス上のアドレスを指定します。次の数値命令に間に合うようにそれら2つのフェッチを実行することにより、DSPは単一のサイクルで命令を実行し続けることができます。
通常、デジタル・フィルタのようなアルゴリズムでは、ある範囲のアドレス(バッファ)のデータについて、次のようにしてアドレスを指定する必要があります。すなわち、アドレス・ポインタがバッファの末尾からバッファの先頭に(バッファ長)戻って1周するような形でアドレスを指定するというものです。このポインタの動きを循環バッファリングと呼びます(フィルタの式における各総和の演算は、基本的にデータ・ポイントの循環バッファと係数の循環バッファの積和シーケンスによって得られます)。一部のアプリケーションでは、循環バッファリングにもバリエーションが必要になります。例えば、1ステップあたりに、アドレス1つ分よりも大きな値でアドレス・ポインタを進めるといった具合です。それでも、所定の長さを1周することに変わりはありません。この方法は、モジュロ循環バッファリングと呼ばれています。
DSPは、DAGによって各種のバッファリングに対応します。つまり、ハードウェアによってアドレスの変更と比較操作を実行し、最適な効率を実現します。このような機能を(汎用プロセッサで行われるように)ソフトウェアで実行した場合、プロセッサのリアルタイムでの信号処理能力が制限されてしまいます。
バッファリングは特殊な概念ですが、デジタル信号処理においてはこれが鍵になります。そこで、簡単な例を挙げてもう少し詳しく説明しておくことにしましょう。図4に示したのはモジュロ循環バッファリングの例です。ご覧のように、アドレス30から始まるメモリには8つのロケーションのバッファが存在しています。この場合、DAGは、このバッファの範囲内に留まるように次のアドレスを算出する必要があります。また、ロケーションを2つスキップするように適切なデータ間隔が保たれるようにしなければなりません。DAGは、アドレス・バスにアドレス30を出力すると共に、次のサイクルのメモリ・アクセスのためにアドレスを33に書き換えます。このプロセスを繰り返すことで、アドレス・ポインタをバッファ内で移動させます。ここで、アドレス36が39に書き換えられるケースは少し特殊なものになります。この例の場合、アドレス39はバッファの外にあります。アドレスがバッファの外に出たことを検出したDAGは、バッファの末尾がバッファの先頭につながっているかのようにアドレスを31に書き換えます。この更新、比較、書き換えに伴ってオーバーヘッドが生じることはありません。あるサイクルで、アドレス36がアドレス・バスに出力されるとします。すると、その次のサイクルでは、アドレス31がアドレス・バスに出力されます。このモジュロ循環バッファリングにより、インターポレーション・フィルタなどのアルゴリズムのニーズに応え、処理に必要な命令サイクルを節約することが可能になります。

シーケンサ操作部 通常、DSPで実行されるほとんどのアルゴリズム(フィルタなど)では、繰り返しの処理が多用されます。DSPのプログラム・シーケンサは、ループの末尾からループの先頭に戻る間にオーバーヘッドを生じさせることなく、ループのコードを繰り返し実行します。この機能は、ゼロ・オーバーヘッド・ループと呼ばれています。この機能の有無も、DSPと汎用マイクロプロセッサの大きな違いになります。通常、マイクロプロセッサでは、プログラムのループをソフトウェアとして維持し、ループの末尾には条件命令を配置するということが行われます。この条件命令により、アドレス・ポインタをループの先頭に戻す(ジャンプ)か、別のアドレスに移動させるかが決まります。そして、これらのアドレスをメモリから取得するためには時間がかかります。一方、DSPのアプリケーションでは信号処理のための時間を確保することが不可欠です。そのため、マイクロプロセッサとは異なり、DSPでは、条件付きのプログラム・シーケンス(分岐)のアドレスを取得するためにサイクルを無駄にすることはできません。そこで、DSPでは、必要なアドレスをハードウェアによって保持しておき、そうした条件判定と分岐の機能を実行します。
図5に示すように、DSPがあるサイクルにおいてループの最後の命令を実行したとします。その次のサイクルでは、DSPは条件文を評価し、ループの先頭の最初の命令またはループ外の最初の命令のうちいずれかを実行します。DSPでは、これらの処理を専用のハードウェアが担います。そのため、ソフトウェアによる条件文の評価、アドレスの取得、分岐プログラムの実行によって余分な時間を浪費することはありません。

I/O操作部 ここまでに何度も触れたとおり、DSPではデータのスループットが非常に重要です。その設計においては、数値演算部、メモリ操作部、シーケンサ操作部に対するデータの入出力に重点が置かれます。データの供給元と出力(信号処理の結果)先は、DSPと実世界をつなぐ接点になります。信号処理のタスクを完了するためには、数多くのI/O機能が必要になります。DSP外部のメモリ・アレイは、プロセッサの命令とデータを格納するために使用されます。また、通信チャンネル(シリアル・ポート、I/Oポート、DMA[Direct Memory Access]チャンネルなど)は、DSPとの間でデータを高速に転送するために使われます。その他の機能(タイマーやプログラムのブート用ロジックなど)は、DSPベースのシステム開発を容易にするためのものです。DSPを使用するシステムには数多くのI/Oタスクが存在しますが、代表的な例としては以下のようなものが挙げられます。
- ブート・ローディング:リセットをかける際、DSPは、通常は外部メモリ・インターフェースを介して外部ソース(EPROMやホスト)から命令をロードします。
- シリアル通信:DSPは、同期シリアル・ポート(SPORT)を介してデータを送受信することにより、コーデック、A/Dコンバータ(ADC)、D/Aコンバータ(DAC)などのデバイスとの通信を実現します。
- メモリ・マップドI/O:DSPは、外部デバイスによってデコードされたDSP外部のメモリ・ロケーションを介してデータを送受信します。
デジタル・フィルタの実装例
ここまでで、フィルタのアルゴリズムのモデリングを行うと共に、DSPのアーキテクチャが備える各種の機能について確認することができました。これにより、DSPのアセンブリ言語によってデジタル・フィルタをどのようにコーディングすればよいのか検討する準備が整ったことになります。ここまでに行った説明や示した例は、ほぼすべてのDSPに当てはまる一般的なものでした。それに対し、ここではアナログ・デバイセズの「ADSP-2181」という固有の製品を例にとることにします。同製品は、16ビットに対応する固定小数点のDSPです。固定小数点というのは、整数部と小数部を分ける小数点のビット位置が、算術演算中に変化しないという意味です。この種のDSP製品の場合、プログラミングが難しくなる可能性がありますが、浮動小数点に対応するDSP製品と比べて、傾向としては安価です。16ビットというのは、DSPのデータ・ワードのサイズのことを表しています。ADSP-2181では、16ビットのデータ・ワードと24ビット幅の命令ワードを使用します。このように、DSP製品は、命令の幅ではなくデータのサイズによって規定されます。DSP製品が最も効率的に処理できるデータの幅は、データ・ワードのサイズによって表されるからです。
図6に示したコードの例をご覧ください。これは、ADSP-2181のアセンブリ言語によってFIRフィルタの機能を記述したものです。このプログラムは、大きく2つの部分から成ります。メイン・ルーチンには、レジスタとバッファの初期化、割り込みベクトル・テーブル、サンプル・データが準備できた際に実行する割り込みルーチンが定義されています。DSPは、初期化が行われたらメイン・ルーチンの命令を実行していくつかのバックグラウンドのタスクやコードのループ処理を実行するか、またはADCから割り込みがかかるまで消費電力の少ないスタンバイ・モードに移行してアイドル状態になります。この例では、プロセッサはスタンバイ・モードに移行し、アイドル状態で割り込みを待ちます。
コードの最後の部分には、FIRフィルタの割り込みサブルーチンが定義されています。この部分が、このフィルタのプログラムの心臓部になります。プロセッサは割り込みに応答し、メイン・ルーチンのコンテキストを保存して割り込みルーチンにジャンプします。この割り込みルーチンは、フィルタの入力サンプルを処理し、データとフィルタ係数をメモリから読み出してDSPのデータ・レジスタに格納します。入力サンプルの処理を行った後、DSPは出力サンプルをDACに送信します。
図6. FIRフィルタのプログラム。ADSP-2181のアセンブリ言語で記述しています。
なお、このプログラムでは、通常であれば条件文によって発生するオーバーヘッドを生じさせることなく演算を実行するDSPの機能を使用しています。特に、プログラムのループとデータ・バッファが、オーバーヘッドがない状態で保持されます。フィルタのループの中核となる多機能命令により、積和演算を実行すると同時に、次のデータ・ワードとフィルタの係数がメモリからフェッチされます。
このプログラムでは、フィルタ演算の最終結果にオーバーフローがないかどうかが確認されます。最終的な値がオーバーフローしていた場合、アナログ信号のクリッピングのように信号波形(データ)を飽和させる処理が適用されます。最後に、メイン・ルーチンのコンテキストが復元され、割り込みからの復帰(RTI)命令によって命令フローがメイン・ルーチンに戻ります。
まとめ
本稿の目的の1つは、フィルタの理論とデジタル・フィルタの実装を結びつけることです。それに向けて、高級言語をベースとするフィルタのモデリング、DSPのアーキテクチャの詳細、フィルタ用プログラムの実装例について説明しました。すなわち、以下のようなトピックを紹介しました。
- プログラムによるフィルタの表現
- DSPの一般的なアーキテクチャ
- DSPのアセンブリ言語
各トピックの概要についてはご理解いただけたと思います。しかし、DSPシステムの設計に挑むにはそれだけで十分だとは言えません。DSPについてより詳細に学びたい方は、稿末に参考資料として挙げた「Digital Signal Processing in VLSI(VLSIにおけるデジタル信号処理)」や「C Algorithms for Real-Time DSP(C言語で実現するリアルタイムDSP向けのアルゴリズム)」をぜひご一読ください。これらの書籍では、DSPに関する理論の全体像、実装上の問題点、具体的な実装方法(それぞれの発行時点で入手可能だったデバイスを使用)などについて解説しています。また、演習や例題なども提供されています。他の参考資料も活用すれば、本稿で網羅しきれなかった内容についても理解できます。特に、本シリーズのPart 3をご覧になる前に、「ADSP-2100 Family User's Manual(ADSP-2100ファミリのユーザ・マニュアル)」と「ADSP-21060/62 SHARC User's Manual(ADSP-21060/62 SHARCのユーザ・マニュアル)」を入手しておくとよいでしょう(いずれも無料)。これらにより、本シリーズの主要なトピックに関する情報を得ることができます。注目していただきたいのは、アナログ・デバイセズが提供するDSP製品が採用している固定小数点/浮動小数点のアーキテクチャについてです。本シリーズを読破していただけば、DSPシステムの開発に役立つ機能についての知識や情報を得ることができます。Part 3では、ADSP-2181の開発プラットフォーム(EZ-KIT LITE)について解説します。また、DSP開発に関連するその他の話題も取り上げます。
参考資料
- G. Dearborn(編)「Digital Signal Processing Applications Using the ADSP-21000 Family- Volume 1(ADSP-21000ファミリを使用したDSPアプリケーション 第1巻)」Norwood、MA:Analog Devices、1994年。アナログ・デバイセズから購入することができます。
- P. M. Embree「C Algorithms for Real-Time DSP(C言語で実現するリアルタイムDSP向けのアルゴリズム)」Upper Saddle River、NJ、 Prentice Hall(1995年)。アナログ・デバイセズからは購入はできません。
- R. J. Higgins「Digital Signal Processing in VLSI(VLSIにおけるデジタル信号処理)」Englewood Cliffs、NJ: Prentice Hall、1990年。DSPの基礎について解説しており、数多くの参考文献が取り上げられています。アナログ・デバイセズから購入することができます。
- A. Mar(編)「Digital Signal Processing Applications Using the ADSP-2100 Family- Volume 1(ADSP-2100ファミリを使用したDSPアプリケーション 第1巻)」Englewood Cliffs、NJ:Prentice Hall、1992年。アナログ・デバイセズから購入することができます。
- A. Mar、J. Babst(編)「Digital Signal Processing Applications Using the ADSP-2100 Family- Volume 2(ADSP-2100ファミリを使用したDSPアプリケーション 第2巻)」Englewood Cliffs、NJ: Prentice Hall、1994年。アナログ・デバイセズから購入することができます。
- A. Mar、H. Rempel(編)「ADSP-2100 Family User's Manual(ADSP-2100ファミリのユーザ・マニュアル)」Norwood、MA:Analog Devices、1995年、無料
- A. Mar、H. Rempel(編)「ADSP-21020 Family User's Manual(ADSP-21020ファミリのユーザ・マニュアル)」Norwood、MA:Analog Devices、1995年、無料
- 「MATLAB For DSP Design (an analysis and design package for DSP)(MATLABを活用したDSP設計(DSP用の解析/設計パッケージ))」電話:(508)647-7000、fax:(508)647-7101、またはウェブサイト(https://www.mathworks.com)でThe MathWorksにお問い合わせください。
- 「QEDesign (digital filter design software)(QEDesign(デジタル・フィルタ設計用のソフトウェア)」電話:(714)557-6884、fax:(714)557-6969、またはウェブサイト(https://www.mds.com)でMomentum Data Systemsにお問い合わせください。
- H. Rempel(編)「ADSP-21060/62 SHARC User's Manual(ADSP-21060/62 SHARCのユーザ・マニュアル)」Norwood、MA: Analog Devices、1995年、無料
- *P. M. Embree「C algorithms for real-time DSP(C言語で実現するリアルタイムDSP向けのアルゴリズム)」Upper Saddle River、NJ、 Prentice Hall( 1995年)