概要

ザイリンクス SDx™ ツール (SDAccel™ 環境、SDSoC™ 環境、および Vivado® 高位合成 (HLS) ツールを含む) は、ソフトウェア アプリケーションの要素を分割してその一部を FPGA ベースのハードウェア カーネルで実行し、ハードウェアがプロセッサまたはエンベデッド プロセッサで実行されるアプリケーションとスムーズに機能するようにすることができるツールです。

デフォルトの状態でも多くのアプリケーションで十分な結果が得られますが、ハードウェア パーティションで最高の QoR (結果の品質) を引き出し、カーネルのパフォーマンスおよびデータ スループットを向上し、レイテンシおよびカーネルで使用されるリソースを削減するには、ハードウェア ロジックの最適化が必要な場合もあります。それには、ハードウェア カーネルのコンパイルおよび合成に指示を与えたり、プロセッサとハードウェア ロジック間のデータ ムーバーの機能を最適化したりするため、特定の属性、指示子、またはプラグマを使用できます。

このガイドでは、SDx 開発環境でシステム レベルのアプリケーションの OpenCL™ C 言語または標準 C/C++ 言語定義に使用可能なプラグマの形式とタイプを説明します。

  • OpenCL 属性は OpenCL 言語規格で定義され、ハードウェア カーネルに最適化が適用されます。
  • ザイリンクスでは追加の OpenCL 属性を提供しています。これらの属性には、名前の冒頭に xcl_ が付いています。
  • SDS プラグマは C または C++ 言語で定義され、SDSoC デザイン プロジェクトのインターフェイス、データ ムーバー、およびハードウェア カーネルに適用されます。
  • HLS プラグマは C または C++ 言語で定義され、Vivado HLS ツールのハードウェア カーネルに最適化を適用するために SDx フローで使用できます。
  • 指示子は Vivado HLS ツールの Tcl コマンドで、HLS プラグマのようにハードウェア パーティションに適用できますが、ここでは詳細は説明しません。詳細は、『Vivado Design Suite ユーザー ガイド: 高位合成』 (UG902) を参照してください。

カーネル最適化は、カーネル インターフェイスにデータが到達したらすぐにすべてのデータを消費できるプロセッシング ロジックを作成することを目的として実行されます。これは通常、関数のパイプライン処理、ループ展開、配列分割、データフローなどの手法を使用してデータパスを一致させるようにプロセッシング コードを展開することによって達成されます。このガイドでは、最適化を支援するため、属性およびプラグマについて説明します。

最適化プラグマおよび属性は、次のオブジェクトおよびスコープに適用できます。
  • インターフェイス: プラグマをインターフェイスに適用すると、インターフェイスは最上位関数に含まれるので、SDx 開発環境によりプラグマが最上位関数に適用されます。
  • 関数: プラグマを関数に適用すると、SDx 開発環境により関数のスコープ内のすべてのオブジェクトにプラグマが適用されます。プラグマの効果は、関数の次の階層レベルで停止します。ただし、階層のループを繰り返し展開する PIPELINE プラグマなど -recursive オプションをサポートまたは使用するプラグマは例外です。
  • ループ: プラグマをループに適用すると、SDx 開発環境によりループのスコープ内のすべてのオブジェクトにプラグマが適用されます。たとえば、LOOP_MERGE プラグマをループに適用すると、SDx 開発環境により、そのループ自体ではなくループ内の下位ループに適用されます。
  • 配列: プラグマを配列に適用すると、SDx 開発環境によりその配列を含むスコープに適用されます。
  • 領域: プラグマを領域に適用すると、SDx 開発環境によりその領域のスコープ全体に適用されます。領域は、次の例に示すような { } で囲まれたエリアです。
    {
    the scope between these braces is a region
    }
    ヒント: 最適化を領域に適用するには、関数およびループに適用するのと同じ方法を使用します。
  • ループおよび領域にラベルを付けて、コードで検索しやすくできます。次に、ラベル付きとラベルなしのループおよび領域の例を示します。
    // Example of a loop with a label
    My_For_Loop:for(i=0; i<3;i++ {
    printf("This loop has the label My_For_Loop \n");
    }
    
    // Example of a region with no label
    {
    printf("The scope between these braces has NO label");
    }
    
    // Example of a NAMED region
    My_Region:{
    printf("The scope between these braces HAS the label My_Region");
    }
  • 属性またはプラグマの引数の値を指定する際、リテラル値 (1、55、3.14 など) を使用するか、#define を使用してマクロを渡すことができます。次の例では、属性およびプラグマをリテラル値で指定しています。
    __attribute__((xcl_array_partition(cyclic,5,1)));
    
    #pragma HLS ARRAY_PARTITION variable = k_matrix_val  cyclic   factor=5
    

    次の例では、定義されているマクロを使用しています。

    #define E 5
    #pragma HLS ARRAY_PARTITION variable = k_matrix_val  cyclic   factor=E
    
    __attribute__((xcl_array_partition(cyclic,E,1)));
    
    重要: 属性およびプラグマでは、宣言された定数を使用して値を指定しないでください。宣言された定数はサポートされていません。