共用体 (union) - 2023.2 日本語

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

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

次のコード例では、double および struct を使用して共用体を作成しています。C/C++ コンパイルとは異なり、union のすべてのフィールドに合成で同じメモリ (合成の場合、レジスタ) が使用されるとは限りません。Vitis HLS では、最適なハードウェアを提供するため最適化が実行されます。

#include "types_union.h"

dout_t types_union(din_t N, dinfp_t F)
{
 union {
    struct {int a; int b; } intval;
    double fpval;
 } intfp;
 unsigned long long one, exp;

 // Set a floating-point value in union intfp
 intfp.fpval = F;

 // Slice out lower bits and add to shifted input
 one = intfp.intval.a;
 exp = (N & 0x7FF);

 return ((exp << 52) + one) & (0x7fffffffffffffffLL);
}

Vitis HLS では、次はサポートされません。

  • 最上位関数インターフェイスの共用体。
  • 合成でのポインター再変換。このため、共用体には別のデータ型へのポインターまたは別のデータ型の配列へのポインターは保持できません。
  • 別の変数を介した共用体へのアクセス。同じ共用体を前の例のように使用する場合、次はサポートされません。
    for (int i = 0; i < 6; ++i)
    if (i<3) 
     A[i] = intfp.intval.a + B[i];
     else
     A[i] = intfp.intval.b + B[i];
    }
  • ただし、次のように明示的に記述し直すことができます。
     A[0] = intfp.intval.a + B[0];
     A[1] = intfp.intval.a + B[1];
     A[2] = intfp.intval.a + B[2];
     A[3] = intfp.intval.b + B[3];
     A[4] = intfp.intval.b + B[4];
     A[5] = intfp.intval.b + B[5];

共用体の合成では、ネイティブ C/C++ 型とユーザー定義の型間の型変換はサポートされません。

Vitis HLS デザインでは、生のビットを 1 つのデータ型から別のデータ型に変換するために共用体が使用されることがよくあります。通常、この生ビットの変換は、最上位ポート インターフェイスで浮動小数点値を使用する場合に必要です。次にその例を示します。

typedef float T;
unsigned int value; // the "input"€ of the conversion
T myhalfvalue; // the "output" of the conversion
union
{
  unsigned int as_uint32;
  T as_floatingpoint;
} my_converter;
my_converter.as_uint32 = value;
myhalfvalue = my_converter. as_floatingpoint;

このタイプのコードは浮動小数点 C/C++ データ型では問題なく、変更すれば double 型でも問題ありません。half 型はクラスであり、共用体では使用できないので、typedef および intshort に変更することはできません。その代わりに、次のコードを使用できます。

typedef half T;
short value;
T myhalfvalue = static_cast<T>(value);

同様に、反対方向の変換では、value=static_cast<ap_uint<16> >(myhalfvalue) または static_cast< unsigned short >(myhalfvalue) を使用します。

ap_fixed<16,4> afix = 1.5;
ap_fixed<20,6> bfix = 1.25;
half ahlf = afix.to_half();
half bhlf = bfix.to_half();

また、ヘルパー クラスの fp_struct<half> を使用して、data() または to_int() を使用して変換することもできます。hls/utils/x_hls_utils.h ヘッダー ファイルを使用してください。