pragma HLS array_reshape - 2023.2 日本語

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

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

説明

重要: Array_Partition および Array_Reshape プラグマおよび指示子は、最上位関数の M_AXI インターフェイスではサポートされません。代わりに、ベクター データ型 で説明するように、hls::vector データ型を使用できます。

ARRAY_RESHAPE プラグマは、配列の垂直リマップと、ビット幅を増やして配列の要素を連結する機能を改良したものです。これにより、使用されるブロック RAM の数を削減すると共に、データへの並列アクセスを実現できます。このプラグマでは元の配列よりも要素数が少なくビット幅の広い配列が作成され、1 クロック サイクルでアクセスできるデータ量が増加します。

次のようなコードがあるとします。

void foo (...) {
int array1[N];
int array2[N];
int array3[N];
#pragma HLS ARRAY_RESHAPE variable=array1 type=block factor=2 dim=1
#pragma HLS ARRAY_RESHAPE variable=array2 type=cyclic factor=2 dim=1
#pragma HLS ARRAY_RESHAPE variable=array3 type=complete dim=1
...
}

ARRAY_RESHAPE プラグマを使用すると、配列が次の図に示すように変換されます。

図 1. ARRAY_RESHAPE プラグマ

構文

C ソースの配列変数が定義されている関数の領域内に配置します。

#pragma HLS array_reshape variable=<name> type=<type>  factor=<int>  dim=<int> off=true

説明:

variable=<name>
必須の引数で、再形成する配列変数を指定します。
type=<type>
分割タイプを指定します (オプション)。デフォルトは complete です。次のタイプがサポートされます。
cyclic
元の配列の要素をインターリーブすることにより小型配列が作成されます。たとえば、factor=3 の場合、要素 0 は新しく作成される 1 番目の配列に割り当てられ、要素 1 は 2 番目、要素 2 は 3 番目、要素 3 は 1 番目の配列に割り当てられます。最終的な配列は、新しい配列を 1 つの配列に垂直連結 (ワードを連結してワード数が大きいものを作成) したものになります。
block
ブロック タイプの再形成では、元の配列の連続したブロックから小型配列が作成されます。これにより、配列が <N> 個 (<N>factor= オプションで定義されている数) のブロックに分割され、その <N> 個のブロックが word-width*N で 1 つの配列にまとめられます。
complete
配列を一時的に個々の要素に分割してから、ワード数の大きい 1 つの配列にまとめます。1 次元配列の場合、これはワード数が非常に大きいレジスタを 1 つ作成するのと同じです (元の配列が N 個の M ビット要素を含む場合、N*M ビットのレジスタとなる)。これが配列再形成のデフォルト タイプです。
factor=<int>
現在の配列を分割する量 (一時的に作成する配列数) を指定します。2 に設定すると、配列が 2 分割され、ビット幅は倍になります。3 に設定すると、配列が 3 分割され、ビット幅は 3 倍になります。
重要: 完全分割では指定しません。ブロック分割およびサイクリック分割では、factor= は必須です。
dim=<int>
多次元配列のどの次元を分割するかを指定します。配列が <N> 次元の場合、0 ~ <N> の整数を指定します。
  • 0 を指定すると、多次元配列のすべての次元が指定したタイプおよび係数オプションで分割されます。
  • 0 以外の値を指定すると、指定した次元のみが分割されます。たとえば、1 を指定した場合、最初の次元のみが分割されます。
object
コンテナー配列のみに関連します。このキーワードを指定すると、ARRAY_RESHAPE プラグマがコンテナー内のオブジェクトに適用され、コンテナー内のオブジェクトのすべての次元が再形成されますが、コンテナー自体のすべての次元は保持されます。このキーワードを指定しない場合、プラグマはコンテナー配列に適用され、オブジェクトには適用されません。
off=true
指定された変数の ARRAY_RESHAPE 機能をディスエーブルにします。

例 1

17 個の要素を含む 8 ビット配列 AB[17] を、ブロック マップを使用して 5 つの要素を含む新しい 32 ビット配列に再形成します。

#pragma HLS array_reshape variable=AB type=block factor=4
ヒント: factor=4 に指定すると、配列は 4 つに分割されます。つまり、17 個の要素がビット幅が 4 倍の 5 つの要素を含む配列に再形成されます。この場合、最後の要素 AB[17] は、5 番目の要素の下位 8 ビットにマップされ、5 番目の要素の残りは空になります。

例 2

次の例では、2 次元配列 AB[6][4] を次元 [6][2] の配列 1 つに再形成しています。この次元 2 のビット幅は 2 倍です。

#pragma HLS array_reshape variable=AB type=block factor=2 dim=2

例 3

次の例では、関数 func の 3 次元の 8 ビット配列 AB[4][2][2] を 128 ビット幅は (4×2×2×8) の 1 要素配列 (1 つのレジスタ) に再形成しています。

#pragma HLS array_reshape variable=AB type=complete dim=0
ヒント: dim=0 は、配列のすべての次元を再形成することを指定します。

例 4

次のコード例に示すように、パーティション分割された配列は、新しい構造の配列でアドレス指定できます。

struct SS
{
  int x[N];
  int y[N];
};
  
int top(SS *a, int b[4][6], SS &c) {
#pragma HLS array_reshape type=complete dim=0 variable=b
#pragma HLS interface mode=ap_memory port=b[0]