pragma HLS inline - 2023.2 日本語

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

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

説明

関数を階層の別エンティティとして削除します。インライン展開された関数は呼び出し関数に分解され、RTL で別の階層として表示されなくなります。

重要: 関数をインライン展開すると、その関数に適用されているプラグマまたは指示子も解除されます。Vitis HLS では、インライン展開された関数に適用されたプラグマまたは指示子が無視されます。

関数をインライン展開すると、関数内の演算が共有され、呼び出し関数とより効率的に最適化できるようになる場合があります。ただし、インライン展開された関数は共有または再利用できないので、親関数がインライン展開された関数を複数回呼び出す場合、RTL のインプリメントに必要なエリアが増加する可能性があります。

INLINE プラグマは、その指定方法によって、定義されているスコープに異なる方法で適用されます。

INLINE
引数を指定しない場合、関数は呼び出し関数に上向きにインライン展開されます。
INLINE off
プラグマを指定した関数を呼び出し関数にインライン展開しないよう指定します。これにより、自動的にインライン展開、または再帰の一部としてインライン展開される関数のインライン展開がディスエーブルになります。
INLINE recursive
プラグマを関数の本体に適用します。関数の内容が下向きに再帰的にインライン展開されます。

デフォルトでは、インライン展開は関数階層のすぐ下の階層でのみ実行され、サブ関数では実行されません。recursive オプションを使用すると、階層全体でインライン展開が指定されます。

構文

C ソースの関数本体内またはコードの領域内に配置します。

#pragma HLS inline <recursive | off>

説明:

recursive
デフォルトでは、関数のインライン展開は 1 つの階層レベルでのみ実行され、指定の関数内の関数はインライン展開されません。recursive オプションを使用すると、指定の関数または領域内のすべての関数が再帰的にインライン展開されます。
重要: データフロー領域内の関数を再帰的にインライン処理すると、データフローの条件を満たさない領域内に関数が 1 つできてしまうことがあります。この場合、INLINE recursive プラグマまたは指示は無視されます。
off
関数のインライン展開をオフにし、指定の関数がインライン展開されないようにします。たとえば、関数に recursive オプションが指定されている場合、ほかの関数はインライン展開されても、特定の呼び出された関数がインライン展開されないようにできます。
ヒント: Vitis HLS ツールでは小型の関数が自動的にインライン展開されますが、INLINE プラグマを off に設定すると、この自動インライン展開が実行されないようにできます。

例 1

次の例では、func_top の本体内のすべての関数がインライン展開され、この関数に含まれる階層すべてで再帰的にインライン展開が実行されます。ただし、関数 func_sub はインライン展開されません。recursive プラグマは関数 func_top に配置されています。関数 func_sub にはインライン展開をディスエーブルにするプラグマが配置されています。

func_sub (p, q) {
#pragma HLS inline off
int q1 = q + 10;
func(p1,q);// foo_3
...
}
void func_top { a, b, c, d} {
  #pragma HLS inline recursive 
  ...
  func(a,b);//func_1
  func(a,c);//func_2
  func_sub(a,d);
  ...
}
ヒント: この例では、INLINE RECURSIVE が func_top 関数の内容に下位に適用されますが、INLINE OFF は func_sub に直接適用されます。

例 2

次の例では、copy_output 関数が copy_output を呼び出す関数または領域にインライン展開されます。

void copy_output(int *out, int out_lcl[OSize * OSize], int output) {
#pragma HLS INLINE
    // Calculate each work_item's result update location
    int stride = output * OSize * OSize;
    
    // Work_item updates output filter/image in DDR
    writeOut: for(int itr = 0; itr < OSize * OSize; itr++) {
    #pragma HLS PIPELINE
        out[stride + itr] = out_lcl[itr];
    }