pragma HLS inline - 2019.2 Japanese

Vitis 統合ソフトウェア プラットフォームの資料: アプリケーション アクセラレーション開発 (UG1393)

Document ID
UG1393
Release Date
2020-02-28
Version
2019.2 Japanese

説明

関数を階層の別エンティティとして削除します。インライン展開された関数は呼び出し関数に分解され、RTL で別の階層として表示されなくなります。関数をインライン展開すると、関数内の演算が共有され、周辺の演算と効率よく最適化されるようになることがあります。ただし、インライン展開された関数は共有できないので、RTL をインプリメントするのに必要なエリアが増加する可能性があります。

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

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

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

構文

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

#pragma HLS inline <region | recursive | off>

説明:

region
指定した領域内の (または関数の本体に含まれる) すべての関数をインライン展開するよう指定し、領域スコープに適用します。
recursive
デフォルトでは、関数のインライン展開は 1 つの階層レベルでのみ実行され、指定の関数内の関数はインライン展開されません。recursive オプションを使用すると、指定の関数または領域内のすべての関数が再帰的にインライン展開されます。
off
関数のインライン展開をオフにし、指定の関数がインライン展開されないようにします。たとえば、関数に recursive オプションが指定されている場合、ほかの関数はインライン展開されても、特定の呼び出された関数がインライン展開されないようにできます。
ヒント: Vivado HLS ツールでは小型の関数が自動的にインライン展開されるので、INLINE プラグマに off オプションを使用すると、この自動インライン展開が実行されないようにできます。

例 1

次の例では、指定した領域内 (foo_top の本体) のすべての関数をインライン展開しています。この関数内の下位関数はインライン展開されません。

void foo_top { a, b, c, d} {
  #pragma HLS inline region
  ...

例 2

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

foo_sub (p, q) {
#pragma HLS inline off
int q1 = q + 10;
foo(p1,q);// foo_3
...
}
void foo_top { a, b, c, d} {
  #pragma HLS inline region recursive 
  ...
  foo(a,b);//foo_1
  foo(a,c);//foo_2
  foo_sub(a,d);
  ...
}
注記: この例では、INLINE は関数 foo_top の内容に下向きに適用されますが、foo_sub を呼び出すコードには上向きに適用されます。

例 3

次の例では、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];
    }