Main Content

クロックレート パイプラインを使用したクロック周波数の向上

この例では、クロック レート パイプラインを適用して設計内の遅いパスを最適化することで、レイテンシを少なくし、クロック周波数を高め、使用面積を減らす方法を示します。クロックレート パイプラインの使用方法の詳細については、クロックレート パイプラインを参照してください。

はじめに

Simulink を使用したアルゴリズム設計により、生成された HDL 設計に多数の遅いレートのデータパスが導入されることがあります。これらの遅いパスは、Simulink の遅いサンプル時間の演算に対応したものであり、アルゴリズムのデータレートが HDL のクロック レートよりも遅いレートで動作することに起因している場合もあります。

クロックレート パイプラインは、モデル内で同じデータ レートで動作する、レート変更ブロックまたは遅延ブロックのいずれかで区切られた最大の部分領域を特定します。これらの部分領域は、クロックレート パイプラインの有力な候補となることから、クロックレート領域と呼ばれます。クロックレート領域の出力がデータ レートの Delay ブロックの場合、HDL Coder はその Delay ブロックを吸収します。これにより、データ レートとクロック レートの比に対応するいくつかのクロックレート パイプラインの割り当てが可能になります。

永久磁石同期機のベクトル制御のベクトル制御の例について考えてみます。FPGA にマッピングするモーター制御の設計を示したものです。この設計の入力サンプルは、20 $\mu s$ または 50 KHz の間隔で到達します。閉制御ループでは、コントローラーのレイテンシが目的の応答時間以内であることが不可欠です。このモデルでは、出力端子に遅延があり、結果としてレイテンシが 20 $\mu s$ になります。

タイミングや面積などの設計の制約を満たすために、入力/出力パイプライン、分散型パイプライン、ストリーミング/共有など、複数の最適化を適用することがあります。さらに、マルチサイクルのパイプライン化された演算として、sqrt や divide などの自明でない数学関数を実装しなければならないこともあります。上記のいずれかの機能や最適化によって導入されるパイプラインは、信号パスが動作するレートと同じ 20 $\mu s$ で適用されます。そのため、余分なパイプラインの導入により、望ましくないレイテンシ オーバーヘッドが発生し、閉ループのレイテンシの割り当てに違反することがあります。

ただし、FPGA では、このコントローラーを MHz の単位で実装できます。これは、導入されるパイプラインが MHz のレートで動作できるようになり、レイテンシへの影響が最小化されることを意味します。クロックレート パイプラインは、このレート差を利用してコントローラーをパイプライン化することで FPGA の面積とタイミングの特性を向上させる手法です。この例では、この設計を採用し、クロックレート パイプラインを使用してタイミングと面積の最適化を段階的に適用する手順を示します。

モデルの準備

クロックレート パイプラインを適用する最初の重要な手順は、クロックレート パイプラインを受け入れるためのモデルの準備です。主な手順の一部を次に示します。

  • レート差の定義: Simulink の信号パスが HDL で遅いパスになる理由は主に 2 つあります。まず、信号パスはモデルの基本サンプル時間よりも遅いサンプル時間で動作します。次に、Simulink の基本サンプル時間はクロックレートではなくデータレートに対応している場合があります。たとえば、hdlcoderFocCurrentFixptHdl モデルの基本サンプル時間は 20 $\mu$ 秒です。コントローラーの最終的な FPGA 実装では、ターゲットが 40 MHz (または 25 ナノ秒) の場合があります。

open_system('hdlcoderFocCurrentFixptHdl')

モデルのサンプル時間を 25 ナノ秒に設定した場合に問題になるのは、Simulink のシミュレーションのパフォーマンスが大幅に遅くなることです。この対策として、HDL Coder には、FPGA クロック レートを Simulink の基本サンプル時間の何倍の速度にするかを指定するオーバーサンプリング係数という設定が用意されています。したがって、この場合は 800 倍のオーバーサンプリングが必要です。

  • サブシステムの最適化の設定: 固定小数点設計では、サブシステムにクロックレート パイプラインが適用されるのは、パイプラインを挿入する必要がある場合だけになります。HDL Coder のオプションで結果としてパイプラインが導入されるものには、分散型パイプライン、共有、ストリーミング、入力/出力パイプライン、制約付き出力パイプライン、適応パイプライン、および浮動小数点実装などのマルチサイクル実装を導入するブロック実装があります (それぞれの HDL プロパティのレイテンシに対する影響の詳細については、個々のブロックのドキュメントを参照してください)。最適化は、サブシステムの階層を維持してローカルに適用するか、配下のサブシステムがすべてフラットであればグルーバルに適用できます。前者の場合は、パイプラインと最適化の設定を個々のサブシステムに適用し、グローバルの場合は、それらの設定を最上位のサブシステムに適用します。階層のフラット化の前提条件に関する詳細については、階層のフラット化を参照してください。

クロックレート パイプラインの適用

次に、クロックレート パイプラインを適用します。この機能のオプションは既定でオンになっており、自動的にクロックレート領域が検出されます。パイプラインの割り当てがどのように判別され、クロックレート領域がどのように形成されるかについては、クロックレート パイプラインを参照してください。

srcHdlModel = 'hdlcoderFocCurrentFixptHdl';
dstHdlModel = 'hdlcoderFocClockRatePipelining';
dstHdlDut   = [dstHdlModel '/FOC_Current_Control'];
gmHdlModel  = ['gm_' dstHdlModel];
gmHdlDut    = ['gm_' dstHdlDut];

open_system(srcHdlModel);
save_system(srcHdlModel,dstHdlModel);

サブシステム FOC_Current_Control に、HDL コードを生成するアルゴリズムが含まれています。

open_system(dstHdlDut);

クロックレート パイプラインを使用するようにモデルを設定します。

hdlset_param(dstHdlModel, 'ClockRatePipelining', 'on');
hdlset_param(dstHdlModel, 'Oversampling', 800);
hdlset_param(dstHdlDut, 'DistributedPipelining', 'on');
set_param([dstHdlDut '/DQ_Current_Control/D_Current_Control'], 'TreatAsAtomicUnit', 'off');
set_param([dstHdlDut '/DQ_Current_Control/Q_Current_Control'], 'TreatAsAtomicUnit', 'off');

hdlset_param([dstHdlDut '/DQ_Current_Control/D_Current_Control'], 'DistributedPipelining', 'on');
hdlset_param([dstHdlDut '/DQ_Current_Control/Q_Current_Control'], 'DistributedPipelining', 'on');

hdlset_param([dstHdlDut '/Clarke_Transform'], 'DistributedPipelining', 'on');
hdlset_param([dstHdlDut '/Park_Transform'], 'DistributedPipelining', 'on');
hdlset_param([dstHdlDut '/Sine_Cosine'], 'DistributedPipelining', 'on');
hdlset_param([dstHdlDut '/Inverse_Park_Transform'], 'DistributedPipelining', 'on');
hdlset_param([dstHdlDut '/Inverse_Clarke_Transform'], 'DistributedPipelining', 'on');
hdlset_param([dstHdlDut '/Space_Vector_Modulation'], 'DistributedPipelining', 'on');

save_system(dstHdlModel);

クロックレート パイプラインの影響を確認するには、HDL コードを生成し、生成されたモデルの最上位のサブシステムを調べます。

makehdl(dstHdlDut);
### Generating HDL for 'hdlcoderFocClockRatePipelining/FOC_Current_Control'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoderFocClockRatePipelining', { 'HDL Code Generation' } )">hdlcoderFocClockRatePipelining</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoderFocClockRatePipelining'.
### Begin compilation of the model 'hdlcoderFocClockRatePipelining'...
### Applying HDL optimizations on the model 'hdlcoderFocClockRatePipelining'...
### Begin model generation.
### Model generation complete.
### Clock-rate pipelining results can be diagnosed by running this script: <a href="matlab:run('hdlsrc/hdlcoderFocClockRatePipelining/highlightClockRatePipelining')">hdlsrc/hdlcoderFocClockRatePipelining/highlightClockRatePipelining.m</a>
### To highlight blocks that obstruct distributed pipelining, click the following MATLAB script: <a href="matlab:run('hdlsrc/hdlcoderFocClockRatePipelining/highlightDistributedPipeliningBarriers')">hdlsrc/hdlcoderFocClockRatePipelining/highlightDistributedPipeliningBarriers.m</a>
### To clear highlighting, click the following MATLAB script: <a href="matlab:run('hdlsrc/hdlcoderFocClockRatePipelining/clearhighlighting.m')">hdlsrc/hdlcoderFocClockRatePipelining/clearhighlighting.m</a>
### Generating new validation model: <a href="matlab:open_system('gm_hdlcoderFocClockRatePipelining_vnl')">gm_hdlcoderFocClockRatePipelining_vnl</a>.
### Validation model generation complete.
### Begin VHDL Code Generation for 'hdlcoderFocClockRatePipelining'.
### MESSAGE: The design requires 800 times faster clock with respect to the base rate = 2e-05.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Saturate_Output as hdlsrc/hdlcoderFocClockRatePipelining/Saturate_Output.vhd.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control/DQ_Current_Control/D_Current_Control as hdlsrc/hdlcoderFocClockRatePipelining/D_Current_Control.vhd.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control/DQ_Current_Control/Q_Current_Control/Saturate_Output as hdlsrc/hdlcoderFocClockRatePipelining/Saturate_Output_block.vhd.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control/DQ_Current_Control/Q_Current_Control as hdlsrc/hdlcoderFocClockRatePipelining/Q_Current_Control.vhd.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control/DQ_Current_Control as hdlsrc/hdlcoderFocClockRatePipelining/DQ_Current_Control.vhd.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control/Sine_Cosine/Sine_Cosine_LUT as hdlsrc/hdlcoderFocClockRatePipelining/Sine_Cosine_LUT.vhd.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control/Sine_Cosine as hdlsrc/hdlcoderFocClockRatePipelining/Sine_Cosine.vhd.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control/Clarke_Transform as hdlsrc/hdlcoderFocClockRatePipelining/Clarke_Transform.vhd.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control/Park_Transform as hdlsrc/hdlcoderFocClockRatePipelining/Park_Transform.vhd.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control/Inverse_Park_Transform as hdlsrc/hdlcoderFocClockRatePipelining/Inverse_Park_Transform.vhd.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control/Inverse_Clarke_Transform as hdlsrc/hdlcoderFocClockRatePipelining/Inverse_Clarke_Transform.vhd.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control/Space_Vector_Modulation as hdlsrc/hdlcoderFocClockRatePipelining/Space_Vector_Modulation.vhd.
### Working on FOC_Current_Control_tc as hdlsrc/hdlcoderFocClockRatePipelining/FOC_Current_Control_tc.vhd.
### Working on hdlcoderFocClockRatePipelining/FOC_Current_Control as hdlsrc/hdlcoderFocClockRatePipelining/FOC_Current_Control.vhd.
### Generating package file hdlsrc/hdlcoderFocClockRatePipelining/FOC_Current_Control_pkg.vhd.
### Code Generation for 'hdlcoderFocClockRatePipelining' completed.
### Generating HTML files for code generation report at <a href="matlab:web('/tmp/Bdoc22a_1859087_172881/tpdae937e0/ex01953685/hdlsrc/hdlcoderFocClockRatePipelining/html/hdlcoderFocClockRatePipelining_codegen_rpt.html');">hdlcoderFocClockRatePipelining_codegen_rpt.html</a>
### Creating HDL Code Generation Check Report file:///tmp/Bdoc22a_1859087_172881/tpdae937e0/ex01953685/hdlsrc/hdlcoderFocClockRatePipelining/FOC_Current_Control_report.html
### HDL check for 'hdlcoderFocClockRatePipelining' complete with 0 errors, 1 warnings, and 3 messages.
### HDL code generation complete.

生成されたモデルから、設計全体にクロックレート パイプラインが適用され、速いレートで実行されていることがわかります。生成されたモデルにクロック レート パイプラインが適用されていないサブシステムがある場合は、元のモデルでサブシステムに最適化が設定されていたかどうかを確認します (上記を参照)。

open_system(gmHdlDut);
set_param(gmHdlModel, 'SimulationCommand', 'update');
set_param(gmHdlDut, 'ZoomFactor', 'FitSystem');

さらに、設計の入力でレート変換が発生してクロックレートになります。クロックレートは、元の基本サンプル時間をオーバーサンプリング係数で除算して特定され、2e-5/800 = 2.5e-8、つまり 25 ns となります。すべてのパイプラインがこのレートで導入されるため、クロックレートで動作します。最後に、出力側の遅延がダウンサンプリング レート変換で置き換えられ、信号がデータレートに戻っていることを確認します。パイプラインをクロックレートで挿入することで、サンプル時間の追加遅延を発生させることなく、設計のクロック周波数が向上しています。

いずれの最適化についても同様ですが、検証モデルとコシミュレーション モデルが生成されたら、設計の機能的な動作に変更がないかをユーザーが確認することをお勧めします。これらの概念については、検証で詳しく説明しています。

サブシステムのオプションによるローカルの最適化

遅いパスのレート差は、このパスに沿った計算に複数のクロック サイクルが必要になる可能性があることを意味します。具体的には、許容されるレイテンシがクロックレートの割り当てで定義されます (クロックレート パイプラインを参照)。パイプラインの追加によるクロック周波数の向上に加え、レイテンシの割り当てを利用したハードウェア リソースの再利用が可能です。遅いパス内に StreamingFactor オプションや SharingFactor オプションなどを設定して、リソース共有の最適化を適用します。この節では、リソース共有がクロックレート領域内でどのように適用されるかを示します。

リソース共有がクロックレート パスに適用された場合、HDL Coder は、面積の最適化のためのリソース共有で説明しているように、時間多重化のために共有リソース アーキテクチャをオーバーサンプリングします。ただし、遅いデータパスで共有またはストリーミングが要求された場合は、HDL Coder はオーバーサンプリングなしでリソース共有を実装します。リソース共有またはストリーミングを適用するサブシステムで共有またはストリーミングのいずれかを設定します。

srcHdlModel = 'hdlcoderFocClockRatePipelining';
dstHdlModel = 'hdlcoderFocSharing';
dstHdlDut   = [dstHdlModel '/FOC_Current_Control'];
gmHdlModel  = ['gm_' dstHdlModel];
gmHdlDut    = ['gm_' dstHdlDut];

open_system(srcHdlModel);
save_system(srcHdlModel,dstHdlModel);

open_system(dstHdlDut);
hilite_system([dstHdlDut '/Park_Transform']);
hilite_system([dstHdlDut '/Inverse_Park_Transform']);
hilite_system([dstHdlDut '/Clarke_Transform']);

Park_Transform サブシステムと Inverse_Park_Transform サブシステムの中で、それぞれ 4 つの乗算器が使用されており、これらを共有できる可能性があります。さらに、Clarke_Transform サブシステムと Inverse_Clarke_Transform サブシステムでそれぞれ使用されている 2 つのゲインは、単なる 2 のべき乗のゲインでない限り、共有される可能性があり、結果は乗算ではなくシフトになります。そのため、Inverse_Clarke_Transform のゲインは共有できません。ここで、リソース共有を適用する各サブシステムに適切な共有係数を設定できます。

hdlset_param([dstHdlDut '/Park_Transform'], 'SharingFactor', 4);
hdlset_param([dstHdlDut '/Inverse_Park_Transform'], 'SharingFactor', 4);
hdlset_param([dstHdlDut '/Clarke_Transform'], 'SharingFactor', 2);

save_system(dstHdlModel);

makehdl(dstHdlDut);
### Generating HDL for 'hdlcoderFocSharing/FOC_Current_Control'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoderFocSharing', { 'HDL Code Generation' } )">hdlcoderFocSharing</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoderFocSharing'.
### Begin compilation of the model 'hdlcoderFocSharing'...
### Applying HDL optimizations on the model 'hdlcoderFocSharing'...
### Begin model generation.
### Model generation complete.
### Clock-rate pipelining results can be diagnosed by running this script: <a href="matlab:run('hdlsrc/hdlcoderFocSharing/highlightClockRatePipelining')">hdlsrc/hdlcoderFocSharing/highlightClockRatePipelining.m</a>
### To highlight blocks that obstruct distributed pipelining, click the following MATLAB script: <a href="matlab:run('hdlsrc/hdlcoderFocSharing/highlightDistributedPipeliningBarriers')">hdlsrc/hdlcoderFocSharing/highlightDistributedPipeliningBarriers.m</a>
### To clear highlighting, click the following MATLAB script: <a href="matlab:run('hdlsrc/hdlcoderFocSharing/clearhighlighting.m')">hdlsrc/hdlcoderFocSharing/clearhighlighting.m</a>
### Generating new validation model: <a href="matlab:open_system('gm_hdlcoderFocSharing_vnl')">gm_hdlcoderFocSharing_vnl</a>.
### Validation model generation complete.
### Begin VHDL Code Generation for 'hdlcoderFocSharing'.
### MESSAGE: The design requires 800 times faster clock with respect to the base rate = 2e-05.
### Working on hdlcoderFocSharing/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Saturate_Output as hdlsrc/hdlcoderFocSharing/Saturate_Output.vhd.
### Working on hdlcoderFocSharing/FOC_Current_Control/DQ_Current_Control/D_Current_Control as hdlsrc/hdlcoderFocSharing/D_Current_Control.vhd.
### Working on hdlcoderFocSharing/FOC_Current_Control/DQ_Current_Control/Q_Current_Control/Saturate_Output as hdlsrc/hdlcoderFocSharing/Saturate_Output_block.vhd.
### Working on hdlcoderFocSharing/FOC_Current_Control/DQ_Current_Control/Q_Current_Control as hdlsrc/hdlcoderFocSharing/Q_Current_Control.vhd.
### Working on hdlcoderFocSharing/FOC_Current_Control/DQ_Current_Control as hdlsrc/hdlcoderFocSharing/DQ_Current_Control.vhd.
### Working on Clarke_Transform_shared as hdlsrc/hdlcoderFocSharing/Clarke_Transform_shared.vhd.
### Working on hdlcoderFocSharing/FOC_Current_Control/Clarke_Transform as hdlsrc/hdlcoderFocSharing/Clarke_Transform.vhd.
### Working on hdlcoderFocSharing/FOC_Current_Control/Sine_Cosine/Sine_Cosine_LUT as hdlsrc/hdlcoderFocSharing/Sine_Cosine_LUT.vhd.
### Working on hdlcoderFocSharing/FOC_Current_Control/Sine_Cosine as hdlsrc/hdlcoderFocSharing/Sine_Cosine.vhd.
### Working on Park_Transform_shared as hdlsrc/hdlcoderFocSharing/Park_Transform_shared.vhd.
### Working on hdlcoderFocSharing/FOC_Current_Control/Park_Transform as hdlsrc/hdlcoderFocSharing/Park_Transform.vhd.
### Working on Inverse_Park_Transform_shared as hdlsrc/hdlcoderFocSharing/Inverse_Park_Transform_shared.vhd.
### Working on hdlcoderFocSharing/FOC_Current_Control/Inverse_Park_Transform as hdlsrc/hdlcoderFocSharing/Inverse_Park_Transform.vhd.
### Working on hdlcoderFocSharing/FOC_Current_Control/Inverse_Clarke_Transform as hdlsrc/hdlcoderFocSharing/Inverse_Clarke_Transform.vhd.
### Working on hdlcoderFocSharing/FOC_Current_Control/Space_Vector_Modulation as hdlsrc/hdlcoderFocSharing/Space_Vector_Modulation.vhd.
### Working on FOC_Current_Control_tc as hdlsrc/hdlcoderFocSharing/FOC_Current_Control_tc.vhd.
### Working on hdlcoderFocSharing/FOC_Current_Control as hdlsrc/hdlcoderFocSharing/FOC_Current_Control.vhd.
### Generating package file hdlsrc/hdlcoderFocSharing/FOC_Current_Control_pkg.vhd.
### Code Generation for 'hdlcoderFocSharing' completed.
### Generating HTML files for code generation report at <a href="matlab:web('/tmp/Bdoc22a_1859087_172881/tpdae937e0/ex01953685/hdlsrc/hdlcoderFocSharing/html/hdlcoderFocSharing_codegen_rpt.html');">hdlcoderFocSharing_codegen_rpt.html</a>
### Creating HDL Code Generation Check Report file:///tmp/Bdoc22a_1859087_172881/tpdae937e0/ex01953685/hdlsrc/hdlcoderFocSharing/FOC_Current_Control_report.html
### HDL check for 'hdlcoderFocSharing' complete with 0 errors, 1 warnings, and 3 messages.
### HDL code generation complete.

生成されたモデルを確認すると、HDL Coder が遅いデータパスで使用可能なレイテンシの割り当ての情報を使用してクロックレートで時間多重化を実装していることがわかります。

open_system(gmHdlDut);
set_param(gmHdlModel, 'SimulationCommand', 'update');
set_param(gmHdlDut, 'ZoomFactor', 'FitSystem');
hilite_system([gmHdlDut '/ctr_799']);
hilite_system([gmHdlDut '/ctr_7991']);
hilite_system([gmHdlDut '/Clarke_Transform/Clarke_Transform_shared']);
hilite_system([gmHdlDut '/Park_Transform/Park_Transform_shared']);
hilite_system([gmHdlDut '/Inverse_Park_Transform/Inverse_Park_Transform_shared']);

時間多重化アーキテクチャは、シングルレート共有アーキテクチャとも呼ばれます。これについては、シングルレートのリソース共有アーキテクチャで説明しています。設計のさまざまな領域を Enabled Subsystem を使用してイネーブルおよびディセーブルにするために、グローバル スケジューラが作成されます。イネーブル/ディセーブル制御は、レイテンシの割り当て (0 ~ 799) までカウントする制限カウンター ctr_799 および ctr_7991 を使用して実装されています。共有領域は、自動で判別されるスケジュールの順序に従ってイネーブルになる Enabled Subsystem として実装されます。この設計には、4 か所で共有された乗算器のグループを含むサブシステムが 2 つ、2 か所で共有された乗算器のグループを含むサブシステムが 1 つあります。リソース共有の結果、設計の乗算器の数は、レイテンシのペナルティなしで 20 から 13 に減少しています。

フラット化によるグローバルな最適化

グローバルなサブシステム間の最適化は、サブシステム フラット化機能を利用して適用できます。フラット化を使用すると、より多くの数のリソースを階層の同じレベルで共有できます。そのような共有をトリガーするには、最上位のサブシステムで共有またはストリーミングのいずれかを設定します。選択する共有係数の値は上限でなければなりません。適切な値を判断するには、設計のリソース使用率の解析が必要になります。

srcHdlModel = 'hdlcoderFocCurrentFixptHdl';
dstHdlModel = 'hdlcoderFocSharingWithFlattening';
dstHdlDut   = [dstHdlModel '/FOC_Current_Control'];
gmHdlModel  = ['gm_' dstHdlModel];
gmHdlDut    = ['gm_' dstHdlDut];

open_system(srcHdlModel);
save_system(srcHdlModel,dstHdlModel);

open_system(dstHdlDut);

hdlset_param(dstHdlModel, 'ClockRatePipelining', 'on');
hdlset_param(dstHdlModel, 'Oversampling', 800);
hdlset_param(dstHdlDut, 'FlattenHierarchy', 'on');
hdlset_param(dstHdlDut, 'DistributedPipelining', 'on');

hilite_system([dstHdlDut '/Park_Transform']);
hilite_system([dstHdlDut '/Inverse_Park_Transform']);
hilite_system([dstHdlDut '/Clarke_Transform']);
hilite_system([dstHdlDut '/Inverse_Clarke_Transform']);

Park_Transform サブシステムと Inverse_Park_Transform サブシステムの中で、それぞれ 4 つの乗算器が使用されており、これらを共有できる可能性があります。さらに、Clarke_Transform サブシステムと Inverse_Clarke_Transform サブシステムでそれぞれ使用されている 2 つのゲインは、単なる 2 のべき乗のゲインでない限り、共有される可能性があり、結果は乗算ではなくシフトになります。したがって、SharingFactor の値として上限の 4 を選択し、HDL コードを生成できます。

hdlset_param(dstHdlDut, 'SharingFactor', 4);
save_system(dstHdlModel);

makehdl(dstHdlDut);
### Generating HDL for 'hdlcoderFocSharingWithFlattening/FOC_Current_Control'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoderFocSharingWithFlattening', { 'HDL Code Generation' } )">hdlcoderFocSharingWithFlattening</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoderFocSharingWithFlattening'.
### Begin compilation of the model 'hdlcoderFocSharingWithFlattening'...
### Applying HDL optimizations on the model 'hdlcoderFocSharingWithFlattening'...
### Begin model generation.
### Model generation complete.
### Clock-rate pipelining results can be diagnosed by running this script: <a href="matlab:run('hdlsrc/hdlcoderFocSharingWithFlattening/highlightClockRatePipelining')">hdlsrc/hdlcoderFocSharingWithFlattening/highlightClockRatePipelining.m</a>
### To highlight blocks that obstruct distributed pipelining, click the following MATLAB script: <a href="matlab:run('hdlsrc/hdlcoderFocSharingWithFlattening/highlightDistributedPipeliningBarriers')">hdlsrc/hdlcoderFocSharingWithFlattening/highlightDistributedPipeliningBarriers.m</a>
### To clear highlighting, click the following MATLAB script: <a href="matlab:run('hdlsrc/hdlcoderFocSharingWithFlattening/clearhighlighting.m')">hdlsrc/hdlcoderFocSharingWithFlattening/clearhighlighting.m</a>
### Generating new validation model: <a href="matlab:open_system('gm_hdlcoderFocSharingWithFlattening_vnl')">gm_hdlcoderFocSharingWithFlattening_vnl</a>.
### Validation model generation complete.
### Begin VHDL Code Generation for 'hdlcoderFocSharingWithFlattening'.
### MESSAGE: The design requires 800 times faster clock with respect to the base rate = 2e-05.
### Working on crp_temp_shared as hdlsrc/hdlcoderFocSharingWithFlattening/crp_temp_shared.vhd.
### Working on crp_temp_shared_block as hdlsrc/hdlcoderFocSharingWithFlattening/crp_temp_shared_block.vhd.
### Working on crp_temp_shared_block1 as hdlsrc/hdlcoderFocSharingWithFlattening/crp_temp_shared_block1.vhd.
### Working on crp_temp_shared_block2 as hdlsrc/hdlcoderFocSharingWithFlattening/crp_temp_shared_block2.vhd.
### Working on crp_temp_shared_block3 as hdlsrc/hdlcoderFocSharingWithFlattening/crp_temp_shared_block3.vhd.
### Working on FOC_Current_Control_tc as hdlsrc/hdlcoderFocSharingWithFlattening/FOC_Current_Control_tc.vhd.
### Working on hdlcoderFocSharingWithFlattening/FOC_Current_Control as hdlsrc/hdlcoderFocSharingWithFlattening/FOC_Current_Control.vhd.
### Generating package file hdlsrc/hdlcoderFocSharingWithFlattening/FOC_Current_Control_pkg.vhd.
### Code Generation for 'hdlcoderFocSharingWithFlattening' completed.
### Generating HTML files for code generation report at <a href="matlab:web('/tmp/Bdoc22a_1859087_172881/tpdae937e0/ex01953685/hdlsrc/hdlcoderFocSharingWithFlattening/html/hdlcoderFocSharingWithFlattening_codegen_rpt.html');">hdlcoderFocSharingWithFlattening_codegen_rpt.html</a>
### Creating HDL Code Generation Check Report file:///tmp/Bdoc22a_1859087_172881/tpdae937e0/ex01953685/hdlsrc/hdlcoderFocSharingWithFlattening/FOC_Current_Control_report.html
### HDL check for 'hdlcoderFocSharingWithFlattening' complete with 0 errors, 1 warnings, and 3 messages.
### HDL code generation complete.

生成されたモデルを確認すると、HDL Coder が遅いデータパスで使用可能なレイテンシの割り当ての情報を使用してクロックレートで時間多重化を実装していることがわかります。

open_system(gmHdlDut);
set_param(gmHdlModel, 'SimulationCommand', 'update');
set_param(gmHdlDut, 'ZoomFactor', 'FitSystem');
hilite_system([gmHdlDut '/ctr_799']);
hilite_system([gmHdlDut '/crp_temp_shared']);
hilite_system([gmHdlDut '/crp_temp_shared1']);
hilite_system([gmHdlDut '/crp_temp_shared2']);
hilite_system([gmHdlDut '/crp_temp_shared3']);
hilite_system([gmHdlDut '/crp_temp_shared4']);

この設計には、モデル全体で 4 か所以内で共有された乗算器のグループを含むサブシステムが 5 つあります。これらの 5 つのサブシステムは、名前の一部に crp_temp_shared を含みます。

要約すると、設計の乗算器の数は、設計をフラット化していないときは 13 だったのに対し、レイテンシのペナルティなしで 20 から 7 に減少しています。

レイテンシの最小化

高度な操作として、出力 Delay_Register を削除し、代わりに DUT 出力端子のクロックレート パイプラインを許可するオプションを使用することで、出力レイテンシを減らすことができます。

srcHdlModel = 'hdlcoderFocSharing';
dstHdlModel = 'hdlcoderFocMinLatency';
dstHdlDut   = [dstHdlModel '/FOC_Current_Control'];
gmHdlModel  = ['gm_' dstHdlModel];
gmHdlDut    = ['gm_' dstHdlDut];

open_system(srcHdlModel);
save_system(srcHdlModel,dstHdlModel);

delete_line(dstHdlDut,'Space_Vector_Modulation/1','Delay_Register/1');
delete_line(dstHdlDut,'Delay_Register/1','Phase_Voltage/1');
delete_block([dstHdlDut,'/Delay_Register'])
add_line(dstHdlDut,'Space_Vector_Modulation/1','Phase_Voltage/1');

open_system(dstHdlDut);

出力端子のクロックレート パイプラインのオプションは、コンフィギュレーション パラメーター ダイアログにあります。[HDL コード生成][最適化][パイプライン] タブで、[DUT 出力端子のクロック レート パイプラインを許可] オプションをオンにします。このオプションのコマンド ライン プロパティの名前は、ClockRatePipelineOutputPorts です。ClockRatePipelineOutputPorts オプションをオンにし、出力レジスタを削除すると、生成された HDL コードは完全なサンプル ステップを待たずに出力を生成するようになります。代わりに、データの準備ができた時点で、数クロック サイクル以内に出力を生成します。生成された HDL コードは、次のサンプル ステップを待たずにクロックレートで出力を生成します。

hdlset_param(dstHdlModel, 'ClockRatePipelineOutputPorts', 'on');
save_system(dstHdlModel);

makehdl(dstHdlDut);
### Generating HDL for 'hdlcoderFocMinLatency/FOC_Current_Control'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoderFocMinLatency', { 'HDL Code Generation' } )">hdlcoderFocMinLatency</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoderFocMinLatency'.
### Begin compilation of the model 'hdlcoderFocMinLatency'...
### Applying HDL optimizations on the model 'hdlcoderFocMinLatency'...
### Clock-rate pipelining was applied on signals connected to the DUT's output ports. The DUT output port values are therefore updated at the clock-rate. The following ports are phase-offset by the stated number of clock cycles.
### Phase of output port 1: 10 clock cycles.
### Begin model generation.
### Model generation complete.
### Clock-rate pipelining results can be diagnosed by running this script: <a href="matlab:run('hdlsrc/hdlcoderFocMinLatency/highlightClockRatePipelining')">hdlsrc/hdlcoderFocMinLatency/highlightClockRatePipelining.m</a>
### To highlight blocks that obstruct distributed pipelining, click the following MATLAB script: <a href="matlab:run('hdlsrc/hdlcoderFocMinLatency/highlightDistributedPipeliningBarriers')">hdlsrc/hdlcoderFocMinLatency/highlightDistributedPipeliningBarriers.m</a>
### To clear highlighting, click the following MATLAB script: <a href="matlab:run('hdlsrc/hdlcoderFocMinLatency/clearhighlighting.m')">hdlsrc/hdlcoderFocMinLatency/clearhighlighting.m</a>
### Generating new validation model: <a href="matlab:open_system('gm_hdlcoderFocMinLatency_vnl')">gm_hdlcoderFocMinLatency_vnl</a>.
### Validation model generation complete.
### Begin VHDL Code Generation for 'hdlcoderFocMinLatency'.
### MESSAGE: The design requires 800 times faster clock with respect to the base rate = 2e-05.
### Working on Clarke_Transform_shared as hdlsrc/hdlcoderFocMinLatency/Clarke_Transform_shared.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control/Clarke_Transform as hdlsrc/hdlcoderFocMinLatency/Clarke_Transform.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Saturate_Output as hdlsrc/hdlcoderFocMinLatency/Saturate_Output.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control/DQ_Current_Control/D_Current_Control as hdlsrc/hdlcoderFocMinLatency/D_Current_Control.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control/DQ_Current_Control/Q_Current_Control/Saturate_Output as hdlsrc/hdlcoderFocMinLatency/Saturate_Output_block.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control/DQ_Current_Control/Q_Current_Control as hdlsrc/hdlcoderFocMinLatency/Q_Current_Control.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control/DQ_Current_Control as hdlsrc/hdlcoderFocMinLatency/DQ_Current_Control.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control/Inverse_Clarke_Transform as hdlsrc/hdlcoderFocMinLatency/Inverse_Clarke_Transform.vhd.
### Working on Inverse_Park_Transform_shared as hdlsrc/hdlcoderFocMinLatency/Inverse_Park_Transform_shared.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control/Inverse_Park_Transform as hdlsrc/hdlcoderFocMinLatency/Inverse_Park_Transform.vhd.
### Working on Park_Transform_shared as hdlsrc/hdlcoderFocMinLatency/Park_Transform_shared.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control/Park_Transform as hdlsrc/hdlcoderFocMinLatency/Park_Transform.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control/Sine_Cosine/Sine_Cosine_LUT as hdlsrc/hdlcoderFocMinLatency/Sine_Cosine_LUT.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control/Sine_Cosine as hdlsrc/hdlcoderFocMinLatency/Sine_Cosine.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control/Space_Vector_Modulation as hdlsrc/hdlcoderFocMinLatency/Space_Vector_Modulation.vhd.
### Working on FOC_Current_Control_tc as hdlsrc/hdlcoderFocMinLatency/FOC_Current_Control_tc.vhd.
### Working on hdlcoderFocMinLatency/FOC_Current_Control as hdlsrc/hdlcoderFocMinLatency/FOC_Current_Control.vhd.
### Generating package file hdlsrc/hdlcoderFocMinLatency/FOC_Current_Control_pkg.vhd.
### Code Generation for 'hdlcoderFocMinLatency' completed.
### Generating HTML files for code generation report at <a href="matlab:web('/tmp/Bdoc22a_1859087_172881/tpdae937e0/ex01953685/hdlsrc/hdlcoderFocMinLatency/html/hdlcoderFocMinLatency_codegen_rpt.html');">hdlcoderFocMinLatency_codegen_rpt.html</a>
### Creating HDL Code Generation Check Report file:///tmp/Bdoc22a_1859087_172881/tpdae937e0/ex01953685/hdlsrc/hdlcoderFocMinLatency/FOC_Current_Control_report.html
### HDL check for 'hdlcoderFocMinLatency' complete with 0 errors, 1 warnings, and 3 messages.
### HDL code generation complete.

makehdl コマンドで生成された ### Phase of output port 0: というメッセージに注目してください。このメッセージは、DUT の出力をサンプリングする方法をユーザーに示すものです。ここに示されるクロック サイクル数は DUT の出力をサンプリングできる速度に対応し、つまり、これが設計のレイテンシです。したがって、設計の合計レイテンシは、データレートのサンプル ステップ 20 $\mu s$ から数ナノ秒まで減少しています。

生成されたモデルを確認すると、出力がクロックレートの 25 ナノ秒で動作する新しい DUT サブシステムが作成されていることがわかります。

open_system(gmHdlDut);
set_param(gmHdlModel, 'SimulationCommand', 'update');
set_param(gmHdlDut, 'ZoomFactor', 'FitSystem');

このオプションを使用すると、生成された HDL コードに元のシミュレーション モデルにはなかった追加のレイテンシが導入されます。その際に、出力端子のサンプル時間がクロックレートに変更されています。テストハーネスでは設計の出力はデータレートで生成されると想定しているため、これによって妥当性確認と検証のフローで結果に誤差が生じる可能性があります。この問題に対処するために、検証モデルではダウンサンプリング レート変換を挿入して出力をデータレートに戻します。そのため、検証モデルでは、引き続きデータレートで出力を比較します。一方、HDL テストベンチでは、生成された HDL の出力がクロックレートであるため、新しい DUT の出力をクロックレートで比較します。

パフォーマンスの微調整

この例では、クロックレート パイプラインを使用して設計のレイテンシを最小化する基本的なワークフローについて説明していますが、ほかにも HDL のパフォーマンスを微調整するためのさまざまなオプションがあります。機能を最大限に活用するためのヒントを次に示します。これらのガイドラインは、適切なモデル化の方法には対応しないこともあり、HDL コード生成と最適化のための実装モデルの準備に関する推奨される方法を示したものである点に注意してください。

  • マルチレート設計: この例では、ソース モデルはシングル レート (データレート) で動作しています。[オーバーサンプリング係数] オプションでクロックレートとの関係を指定しています。設計のレイテンシを最小化するには、この設定が最も効果的です。クロックレート パイプラインは、マルチレート設計でも遅いパスを最適化して適切に機能しますが、レート変換の境界でサンプル遅延が発生することがあります。そのため、レイテンシを最小化するには、設計全体でシングルレート (データレート) を使用します。

  • クロック周波数: この設計では、分散型パイプライン方式でデータパス全体のパイプライン化は行われていないことがわかります。これは、特定のブロック間でのリタイミングの影響で数値の不一致が発生する可能性があることを最適化が認識しているためです。詳細については、分散型パイプライン方式のドキュメントを参照してください。多くの場合、このような数値の整合性の問題は境界条件で発生します。それらの境界条件に設計がヒットしなければ、[分散型パイプライン方式の優先順位] パラメーターを有効にできます。この場合は、検証を通じて、設計が適切に機能しており、すべての操作条件に対してロバストであることを確認しなければなりません。

  • 階層のフラット化: 階層のフラット化をオンにすることで、グローバルなサブシステム間での最適化を最大化したり、フィードバック ループがある場合のクロック レート パイプラインの効果を高めたりできます。特に、サブシステムの境界を越えるフィードバック ループがある場合は、フィードバック ループを含む最上位のサブシステムで階層のフラット化をオンにすることをお勧めします。ただし、効果を高めるため、下位のサブシステムで階層のフラット化のすべての要件を満たしていることを確認してください。

  • 十分な割り当ての指定: 適用されるクロックレート パイプラインの総数が使用可能なオーバーサンプリングの割り当て以上になると、タイミングの影響を把握するのが難しくなることがあります。そのため、クロックレート パイプラインに対しては十分な割り当て ([オーバーサンプリング係数] の値) を指定してください。オーバーサンプリングの値が大きすぎても、タイミング コントローラーとスケジューラで使用されるカウンターが大きくなること以外に欠点はありません。したがって、面積のオーバーヘッドはごくわずかです。

概要

クロックレート パイプラインは、設計の遅いパスを最適化してパイプライン化する手法です。クロックレート パイプラインでは、HDL Coder の次の構造と機能に対するパイプラインが必ずクロックレートで導入されます。

  • パイプライン化された数学演算: sqrt または recip のニュートン・ラフソン法、三角関数の CORDIC アルゴリズムなど、いくつかの数学ブロックはマルチサイクルのパイプライン化された HDL 実装を実装します。ブロックが遅いパスで動作する場合、これらのパイプラインはクロックレートで導入されます。

  • 浮動小数点マッピング: 上記のように、浮動小数点ライブラリ マッピングでは、浮動小数点演算の実装時にクロックレート パイプラインを利用します。

  • パイプライン方式の最適化: 入力/出力パイプライン、適応パイプライン、分散型パイプラインなど、すべてのパイプライン方式の最適化で、遅いパスにクロックレートのレジスタが使用されます。

  • リソース共有とストリーミング: リソース共有アーキテクチャの時間多重化はクロックレートで実装されます。

パスが遅いパスとして識別されるのは、Simulink の遅いサンプル時間を使用している場合と、HDL Coder の設定で [オーバーサンプリング係数] が設定されている場合です。クロックレート パイプラインを使用すると、設計の合計レイテンシを損なわずに設計の速度と面積の特性を改善できます。