このセクションでは、前に説明した GCC コンパイラの動作を考慮して、Vitis HLS でどのように aligned
および packed
属性を使用して効率的なハードウェアを作成するかについて説明します。まず、Vitis HLS の Aggregate (集約) および Disaggregate (分割) について理解しておく必要があります。内部変数およびグローバル変数などの構造体またはクラス オブジェクトは、デフォルトで分割されます。分割とは、構造体/クラスが、構造体/クラス メンバーごとに 1 つずつ、別々のオブジェクトに分けられることを意味します。作成される要素の数とタイプは、その構造体の内容によって決まります。構造体の配列は、複数の配列 (構造体の各メンバーに別々の配列) としてインプリメントされます。
ただし、最上位関数の引数として使用される構造体は、デフォルトで集約されたままになります。集約とは、構造体のすべての要素が単一の幅の広いベクターに収集されることを意味します。これにより、構造体のすべてのメンバーを同時に読み出しおよび書き込みできます。構造体のメンバー要素は C/C++ コードに記述されている順序でベクターに配置されます (構造体の最初の要素がベクターの LSB に、最後の要素がベクターの MSB に配置される)。構造体の配列は個別の配列要素に分割され、下位から上位の順のベクターに配置されます。
AGGREGATE プラグマを使用しない場合の動作
|
AGGREGATE プラグマを使用した場合の動作 (compact=auto または指定なし)
|
|||
---|---|---|---|---|
インターフェイス引数 | 内部変数 | インターフェイス引数 | 内部変数 | |
AXI プロトコル インターフェイス ( |
aggregate compact=none | なし | compact=none | なし |
hls::stream オブジェクトを含む構造体/クラス |
構造体/クラスを自動的に分割 | 構造体/クラスを自動的に分割 | なし | なし |
その他のインーフェイス プロトコル | aggregate compact=bit | 自動的に分割 | compact=bit | compact=bit |
Vitis HLS のデフォルトの集約動作の目的は、最上位のハードウェア インターフェイスで x86_64-gnu-linux メモリ レイアウトを使用し、内部ハードウェアを最適化して結果の品質 (QoR) を向上させることです。上の表は、Vitis HLS のデフォルト動作を示しています。表には、ユーザーが AGGREGATE
プラグマを指定しないデフォルト モードと、ユーザーが AGGREGATE
プラグマを指定した場合の 2 つのモードが示されています。
AXI4 インターフェイス (m_axi
/s_axilite
/axis
) の場合、構造体は、データ構造パディング で説明されるように、構造体の要素の順序に従ってデフォルトでパディングされます。これにより、構造が最も近い 2 のべき乗のサイズに集約されるため、この場合はパディングが適用される可能性があります。これにより、AGGREGATE プラグマに compact=none
オプションが推論されます。
ほかのインターフェイス プロトコルの場合、構造体はビット レベルでパックされるため、集約されたベクターはその構造体のさまざまな要素のサイズにすぎません。これにより、AGGREGATE プラグマに compact=bit
オプションが推論されます。
上記の規則の唯一の例外は、インターフェイスでを間接的に hls::stream
を使用する場合です (つまり、hls::stream
オブジェクトは、構造体/クラス内で指定され、インターフェイス ポートのタイプとして使用されます)。hls::stream
オブジェクトを含む構造体は、常に個々のメンバー要素に分割されます。