pragma HLS dataflow - 2023.2 日本語

Vitis 高位合成ユーザー ガイド (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 日本語

説明

DATAFLOW プラグマは、タスク レベルのパイプライン処理をイネーブルにして関数およびループを重複できるようにし、RTL インプリメンテーションでの同時実行性を増加してデザイン全体のスループットを向上します。

C 記述では、すべての演算が順次に実行されます。pragma HLS allocation などのリソースを制限する指示子を指定しない場合、Vitis HLS ツールではレイテンシを最小限に抑え、同時実行性を向上するように処理されます。ただし、データ依存性のためにこれが制限されることがあります。たとえば、配列にアクセスする関数またはループは、完了する前に配列への読み出し/書き込みアクセスをすべて終了する必要があります。そのため、そのデータを消費する次の関数またはループの演算を開始できません。DATAFLOW 最適化を使用すると、前の関数またはループがすべての演算を完了する前に、次の関数またはループの演算を開始できるようになります。

図 1. DATAFLOW プラグマ

DATAFLOW プラグマを指定した場合、HLS ツールで順次関数またはループ間のデータフローが解析され、プロデューサー関数またはループが完了する前にコンシューマー関数またはループの演算を開始できるように、ピンポン RAM または FIFO に基づいてチャネルが作成されます。これにより関数またはループを並列実行でき、レイテンシが削減されて RTL のスループットが向上します。

開始間隔 (II) (関数またはループの開始から次の関数またはループの開始までのサイクル数) が指定されていない場合は、HLS ツールで開始間隔が最小になるようにし、データが使用可能になったらすぐに演算を開始できるようにすることが試みられます。

ヒント: config_dataflow コマンドは、データフロー最適化で使用されるデフォルトのメモリ チャネルと FIFO の深さを指定します。

DATAFLOW 最適化が機能するようにするには、デザイン内でデータが 1 つのタスクから次のタスクに流れる必要があります。次のコーディング スタイルを使用すると、HLS ツールでデータフロー最適化が実行されなくなります。詳細は、制御駆動型のタスク レベル並列処理の制限 を参照してください。

  • シングル プロデューサー コンシューマー違反
  • タスク間のフィードバック
  • タスクの条件付き実行
  • 複数の exit 条件を持つループ
重要: これらのコーディング スタイルのいずれかが使用されている場合、HLS ツールでメッセージが表示され、DATAFLOW 最適化は実行されません。

最後に、DATAFLOW 最適化には階層インプリメンテーションはありません。サブ関数またはループに DATAFLOW 最適化が有益な可能性のあるタスクが含まれる場合、DATAFLOW 最適化をそのループまたはサブ関数に適用するか、サブ関数をインライン展開する必要があります。

構文

C ソースの領域、関数、またはループ内に配置します。

#pragma HLS dataflow [disable_start_propagation]
  • disable_start_propagation: 開始トークンを内部プロセスに伝搬する開始 FIFO の作成をディスエーブルにします (オプション)。このような FIFO がパフォーマンスのボトルネックとなることがあります。

次の例では、ループ wr_loop_j 内で DATAFLOW 最適化を指定しています。

        wr_loop_j: for (int j = 0; j < TILE_PER_ROW; ++j) {
#pragma HLS DATAFLOW
            wr_buf_loop_m: for (int m = 0; m < TILE_HEIGHT; ++m) {
                wr_buf_loop_n: for (int n = 0; n < TILE_WIDTH; ++n) {
#pragma HLS PIPELINE
                    // should burst TILE_WIDTH in WORD beat
                    outFifo >> tile[m][n];
                }
            }
            wr_loop_m: for (int m = 0; m < TILE_HEIGHT; ++m) {
                wr_loop_n: for (int n = 0; n < TILE_WIDTH; ++n) {
#pragma HLS PIPELINE
                    outx[TILE_HEIGHT*TILE_PER_ROW*TILE_WIDTH*i+TILE_PER_ROW*TILE_WIDTH*m+TILE_WIDTH*j+n] = tile[m][n];
                }
            }