Main Content

ハードウェア効率に優れた Complex Divide HDL Optimized の実装

この例では、Simulink® モデルに組み込まれたハードウェア効率に優れた MATLAB® コードを使用して、複素数の除算を実行する方法を示します。この例で使用されるモデルは、固定小数点入力の HDL コード生成に適しています。アルゴリズムは、完全にパイプライン化されたアーキテクチャを採用しています。これは、スループットが懸念される FPGA デバイスや ASIC デバイスに適しています。この実装では使用可能なオンチップ リソースも適切に使用するため、リソースに配慮した設計にも適しています。

複素数の除算

2 つの複素数 a+bic+di の除算演算は、b0 とすると、z=a+bic+di と定義されます。これは、分母の複素共役を乗算することで、z=(ac+bd)+(bc-ad)ic2+d2 と書き換えることができます。

CORDIC アルゴリズム

CORDIC は、COordinate Rotation DIgital Computer の略語で、多くの三角関数、双曲線関数、および算術関数を効率的に計算するために使用できます。

完全にパイプライン化された固定小数点演算

Complex Divide HDL Optimized ブロックは、2 進小数点スケーリングをもつ固定小数点データの HDL コード生成をサポートしています。これはこの適用例に留意して設計されていて、ハードウェア固有のセマンティクスと最適化を採用します。これらの最適化の 1 つに内部回路全体のパイプライン化があります。これにより、非常に高いスループットが維持されます。

複雑なアルゴリズムを FPGA デバイスや ASIC デバイスに展開する場合、対象の計算のリソースの使用率とその合計スループットの間にトレードオフが発生することがよくあります。多くの場合、リソース共有では、設計で消費されるリソースは少なくなりますが、それと同時に処理におけるスループットが低下します。簡単な算術演算や三角関数演算は大規模な演算の一部として一般に使用されますが、それらの演算には、設計において回路をさらに駆動するために高いスループットが求められます。そのため、完全にパイプライン化された実装は、オンチップ リソースの消費は多くなりますが大規模な設計で有益です。

Complex Divide HDL Optimized ブロックでは、すべての主要な計算単位が内部で完全にパイプライン化されます。これには、ギブンス回転の実行に使用される CORDIC 回路だけでなく、設計のそれ以外の場所で使用される加算器とシフターも含まれます。これにより、スループットが最大になります。

Complex Divide HDL Optimized ブロックとのインターフェイス

Complex Divide HDL Optimized ブロックは、完全にパイプライン化されるという性質から、連続するサイクルを含む任意のサイクルで入力データを受け入れることができます。入力データをブロックに送信するには、validIn 信号を true に設定しなければなりません。ブロックが計算を終え、出力を送信する準備ができると、1 クロック サイクルの間、validOuttrue に設定します。連続するサイクルで送信される入力の場合、連続するサイクルでも validOuttrue に設定されます。分子と分母の両方を同じサイクルで一緒に送信しなければなりません。

protocolComplexDivide.png

モデルを開いて入力データを定義

モデル例を開くには、コマンド ラインで次のように入力します。

mdl = 'fxpdemo_complexDivide';
open_system(mdl)

モデルには、データ ソースに接続された Complex Divide HDL Optimized ブロックが含まれています。データ ソースは入力 (分子と分母) の配列を受け取り、各配列からブロックに連続するサイクルで入力値を渡します。各値について計算された出力は、ワークスペース変数に格納されます。すべての入力の処理が完了すると、シミュレーションは終了します。

入力の配列 complexDivideNumeratorscomplexDivideDenominators を定義します。この例では、入力は double です。分子と分母の両方でデータ型が同じでなければならないことに注意してください。

rng('default');
complexDivideNumerators = (9*rand(1000,1) + 1) + (9*rand(1000,1) + 1)*1i;
complexDivideDenominators = (9*rand(1000,1) + 1) + (9*rand(1000,1) + 1)*1i;

モデルで使用する出力のデータ型を定義します。この例では、出力も double です。固定小数点型の出力は固定小数点型の入力にしか使用できないことに注意してください。

OutputType = 'double';

モデルのシミュレーションと出力の確認

モデルをシミュレートします。

sim(mdl);

シミュレーションが完了すると、入力の各ペアの計算値を保持するために新しいワークスペース変数 complexDivideOutputs が作成されます。

Complex Divide HDL Optimized ブロックの出力と MATLAB® の組み込みの関数 divide の出力を比較して、計算の誤差を調べます。

expectedOutput = complexDivideNumerators./complexDivideDenominators;
actualOutput = complexDivideOutputs;
maxError = max(abs(expectedOutput - actualOutput))
maxError = 3.5958e-15