通常、ネイティブの C/C++ 整数型で実行可能な有効な演算は、ap_[u]fixed
型で演算子のオーバーロードを使用するとサポートされます。オーバーロードされた演算子に加え、ビット レベルの演算を実行しやすくする演算子およびメソッドが含まれています。
2 進数の算術演算子
加算
ap_[u]fixed::RType ap_[u]fixed::operator + (ap_[u]fixed op)
任意精度の固定小数点と指定したオペランド op
を加算します。
オペランドには、次のいずれかの整数型を使用できます。
- ap_[u]fixed
- ap_[u]int
- C/C++
結果のデータ型 ap_[u]fixed::RType
は、2 つのオペランドのデータ型によります。
ap_fixed<76, 63> Result;
ap_fixed<5, 2> Val1 = 1.125;
ap_fixed<75, 62> Val2 = 6721.35595703125;
Result = Val1 + Val2; //Yields 6722.480957
Val2
の方が整数部および小数部のビット幅が広いため、結果値をすべて格納できるようにするため、結果のデータ型の幅はこのビット幅に 1 を足したものになります。
データの幅を指定すると、次に示すように、べき関数を使用してリソースが制御されます。同様に、AMDでは、固定小数点演算の幅を指定する代わりに、格納された結果の幅を指定することをお勧めします。
ap_ufixed<16,6> x=5;
ap_ufixed<16,7>y=hl::rsqrt<16,6>(x+x);
減算
ap_[u]fixed::RType ap_[u]fixed::operator - (ap_[u]fixed op)
任意精度の固定小数点値から指定したオペランド op
を減算します。
結果のデータ型 ap_[u]fixed::RType
は、2 つのオペランドのデータ型によります。
ap_fixed<76, 63> Result;
ap_fixed<5, 2> Val1 = 1625.153;
ap_fixed<75, 62> Val2 = 6721.355992351;
Result = Val2 - Val1; // Yields 6720.23057
Val2
の方が整数部および小数部のビット幅が広いため、結果値をすべて格納できるようにするため、結果のデータ型の幅はこのビット幅に 1 を足したものになります。
乗算
ap_[u]fixed::RType ap_[u]fixed::operator * (ap_[u]fixed op)
任意精度の固定小数点値を指定したオペランド op
と乗算します。
ap_fixed<80, 64> Result;
ap_fixed<5, 2> Val1 = 1625.153;
ap_fixed<75, 62> Val2 = 6721.355992351;
Result = Val1 * Val2; // Yields 7561.525452
この例では、Val1
と Val2
を乗算しています。この結果のデータ型は、整数部のビット幅と小数部のビット幅の和になります。
除算
ap_[u]fixed::RType ap_[u]fixed::operator / (ap_[u]fixed op)
任意精度の固定小数点値を指定したオペランド op
で除算します。
ap_fixed<84, 66> Result;
ap_fixed<5, 2> Val1 = 1625.153;
ap_fixed<75, 62> Val2 = 6721.355992351;
Val2 / Val1; // Yields 5974.538628
この例では、Val2
で Val1
を除算しています。十分な精度を保持するため、次のようになります。
- 結果のデータ型の整数ビット幅は、
Val2
の整数ビット幅と、Val1
の小数ビット幅の和になります。 - 結果のデータ型の小数ビット幅は、
Val2
の小数ビット幅と等しくなります。
ビット単位の論理演算子
ビット単位 OR
ap_[u]fixed::RType ap_[u]fixed::operator | (ap_[u]fixed op)
任意精度の固定小数点と任意のオペランド op
にビット単位演算を適用します。
ap_fixed<75, 62> Result;
ap_fixed<5, 2> Val1 = 1625.153;
ap_fixed<75, 62> Val2 = 6721.355992351;
Result = Val1 | Val2; // Yields 6271.480957
ビット単位 AND
ap_[u]fixed::RType ap_[u]fixed::operator & (ap_[u]fixed op)
任意精度の固定小数点と任意のオペランド op
にビット単位演算を適用します。
ap_fixed<75, 62> Result;
ap_fixed<5, 2> Val1 = 1625.153;
ap_fixed<75, 62> Val2 = 6721.355992351;
Result = Val1 & Val2; // Yields 1.00000
ビット単位 XOR
ap_[u]fixed::RType ap_[u]fixed::operator ^ (ap_[u]fixed op)
任意精度の固定小数点と任意のオペランド op
に xor
ビット単位演算を適用します。
ap_fixed<75, 62> Result;
ap_fixed<5, 2> Val1 = 1625.153;
ap_fixed<75, 62> Val2 = 6721.355992351;
Result = Val1 ^ Val2; // Yields 6720.480957
インクリメントおよびデクリメント演算子
前置インクリメント
ap_[u]fixed ap_[u]fixed::operator ++ ()
任意精度の固定小数点変数を 1
インクリメントします。
ap_fixed<25, 8> Result;
ap_fixed<8, 5> Val1 = 5.125;
Result = ++Val1; // Yields 6.125000
後置インクリメント
ap_[u]fixed ap_[u]fixed::operator ++ (int)
この演算関数は、次を実行します。
- 任意精度の固定小数点変数を
1
インクリメント。 - この任意精度の固定小数点の元の値を返す。
ap_fixed<25, 8> Result; ap_fixed<8, 5> Val1 = 5.125; Result = Val1++; // Yields 5.125000
前置デクリメント
ap_[u]fixed ap_[u]fixed::operator -- ()
任意精度の固定小数点変数を 1
デクリメントします。
ap_fixed<25, 8> Result;
ap_fixed<8, 5> Val1 = 5.125;
Result = --Val1; // Yields 4.125000
後置デクリメント
ap_[u]fixed ap_[u]fixed::operator -- (int)
この演算関数は、次を実行します。
- 任意精度の固定小数点変数を
1
デクリメント。 - この任意精度の固定小数点の元の値を返す。
ap_fixed<25, 8> Result; ap_fixed<8, 5> Val1 = 5.125; Result = Val1--; // Yields 5.125000
単項演算子
加算
ap_[u]fixed ap_[u]fixed::operator + ()
任意精度の固定小数点変数のセルフ コピーを返します。
ap_fixed<25, 8> Result;
ap_fixed<8, 5> Val1 = 5.125;
Result = +Val1; // Yields 5.125000
減算
ap_[u]fixed::RType ap_[u]fixed::operator - ()
任意精度の固定小数点変数の負の値を返します。
ap_fixed<25, 8> Result;
ap_fixed<8, 5> Val1 = 5.125;
Result = -Val1; // Yields -5.125000
0 との等価比較
bool ap_[u]fixed::operator ! ()
この演算関数は、次を実行します。
- 任意精度の固定小数点変数を
0
と比較。 - 結果を返す。
bool Result; ap_fixed<8, 5> Val1 = 5.125; Result = !Val1; // Yields false
ビット単位の反転
ap_[u]fixed::RType ap_[u]fixed::operator ~ ()
任意精度の固定小数点変数のビット単位の補数を返します。
ap_fixed<25, 15> Result;
ap_fixed<8, 5> Val1 = 5.125;
Result = ~Val1; // Yields -5.25
シフト演算子
符号なし左シフト
ap_[u]fixed ap_[u]fixed::operator << (ap_uint<_W2> op)
この演算関数は、次を実行します。
- 指定した整数オペランド分左にシフト。
- 結果を返す。
オペランドには次の C/C++ の整数型を使用できます。
-
char
-
short
-
int
-
long
左シフト演算で返されるデータ型は、シフトされたデータ型と同じ幅になります。
ap_fixed<25, 15> Result;
ap_fixed<8, 5> Val = 5.375;
ap_uint<4> sh = 2;
Result = Val << sh; // Yields -10.5
結果のビット幅は (W = 25
、I
= 15
) です。左シフト演算の結果のデータ型は Val
と同じであるため、次のようになります。
-
Val
の上位 2 ビットがシフト アウトされます。 - 結果は -10.5 になります。
結果が 21.5 になるようにするには、ap_ufixed<10, 7>(Val)
のように、まず Val
を ap_fixed<10, 7>
にキャストする必要があります。
符号付き左シフト
ap_[u]fixed ap_[u]fixed::operator << (ap_int<_W2> op)
この演算子は、次を実行します。
- 指定した整数オペランド分左にシフト。
- 結果を返す。
オペランドが正か負かによって、シフトの方向が変わります。
- オペランドが正の場合は右シフトが実行されます。
- オペランドが負の場合は左シフト (逆方向) が実行されます。
オペランドには次の C/C++ の整数型を使用できます。
-
char
-
short
-
int
-
long
右シフト演算で返されるデータ型は、シフトされたデータ型と同じ幅になります。
ap_fixed<25, 15, false> Result;
ap_uint<8, 5> Val = 5.375;
ap_int<4> Sh = 2;
Result = Val << sh; // Shift left, yields -10.25
Sh = -2;
Result = Val << sh; // Shift right, yields 1.25
符号なし右シフト
ap_[u]fixed ap_[u]fixed::operator >> (ap_uint<_W2> op)
この演算関数は、次を実行します。
- 指定した整数オペランド分右にシフト。
- 結果を返す。
オペランドには次の C/C++ の整数型を使用できます。
-
char
-
short
-
int
-
long
右シフト演算で返されるデータ型は、シフトされたデータ型と同じ幅になります。
ap_fixed<25, 15> Result;
ap_fixed<8, 5> Val = 5.375;
ap_uint<4> sh = 2;
Result = Val >> sh; // Yields 1.25
すべての上位ビットを保持する必要がある場合は、ap_fixed<10,
5>(Val)
のように、まず Val
の小数部のビット幅を拡張します。
符号付き右シフト
ap_[u]fixed ap_[u]fixed::operator >> (ap_int<_W2> op)
この演算子は、次を実行します。
- 指定した整数オペランド分右にシフト。
- 結果を返す。
オペランドが正か負かによって、シフトの方向が変わります。
- オペランドが正の場合は右シフトが実行されます。
- オペランドが負の場合は左シフト (逆方向) が実行されます。
オペランドには C/C++ の整数型 (char
、short
、int
、または long
) を使用できます。
右シフト演算で返されるデータ型は、シフトされるデータ型と同じ幅になります。次に例を示します。
ap_fixed<25, 15, false> Result;
ap_uint<8, 5> Val = 5.375;
ap_int<4> Sh = 2;
Result = Val >> sh; // Shift right, yields 1.25
Sh = -2;
Result = Val >> sh; // Shift left, yields -10.5
1.25
比較演算子
等価比較
bool ap_[u]fixed::operator == (ap_[u]fixed op)
任意精度の固定小数点変数と指定したオペランドを比較します。
等しい場合は true
、等しくない場合は false
を返します。
オペランド op
のデータ型には、ap_[u]fixed
、ap_int
または C/C++ の整数型を使用できます。次に例を示します。
bool Result;
ap_ufixed<8, 5> Val1 = 1.25;
ap_fixed<9, 4> Val2 = 17.25;
ap_fixed<10, 5> Val3 = 3.25;
Result = Val1 == Val2; // Yields true
Result = Val1 == Val3; // Yields false
不等価比較
bool ap_[u]fixed::operator != (ap_[u]fixed op)
任意精度の固定小数点変数を指定したオペランドと比較します。
等しくない場合は true
、等しい場合は false
を返します。
オペランド op
のデータ型には、次を使用できます。
- ap_[u]fixed
- ap_int
- C または C++ の整数型
次に例を示します。
bool Result;
ap_ufixed<8, 5> Val1 = 1.25;
ap_fixed<9, 4> Val2 = 17.25;
ap_fixed<10, 5> Val3 = 3.25;
Result = Val1 != Val2; // Yields false
Result = Val1 != Val3; // Yields true
以上
bool ap_[u]fixed::operator >= (ap_[u]fixed op)
変数を指定のオペランドと比較します。
変数がオペランド以上の場合は true
、そうでない場合は false
を返します。
オペランド op
のデータ型には、ap_[u]fixed
、ap_int
または C/C++ の整数型を使用できます。
次に例を示します。
bool Result;
ap_ufixed<8, 5> Val1 = 1.25;
ap_fixed<9, 4> Val2 = 17.25;
ap_fixed<10, 5> Val3 = 3.25;
Result = Val1 >= Val2; // Yields true
Result = Val1 >= Val3; // Yields false
以下
bool ap_[u]fixed::operator <= (ap_[u]fixed op)
変数と指定のオペランドを比較し、変数がオペランド以下の場合は true
、そうでない場合は false
を返します。
オペランド op のデータ型には、ap_[u]fixed
、ap_int
または C/C++ の整数型を使用できます。
次に例を示します。
bool Result;
ap_ufixed<8, 5> Val1 = 1.25;
ap_fixed<9, 4> Val2 = 17.25;
ap_fixed<10, 5> Val3 = 3.25;
Result = Val1 <= Val2; // Yields true
Result = Val1 <= Val3; // Yields true
大なり (>)
bool ap_[u]fixed::operator > (ap_[u]fixed op)
変数を指定のオペランドと比較し、変数がオペランドより大きい場合は true
、そうでない場合は false
を返します。
オペランド op
のデータ型には、ap_[u]fixed
、ap_int
または C/C++ の整数型を使用できます。
次に例を示します。
bool Result;
ap_ufixed<8, 5> Val1 = 1.25;
ap_fixed<9, 4> Val2 = 17.25;
ap_fixed<10, 5> Val3 = 3.25;
Result = Val1 > Val2; // Yields false
Result = Val1 > Val3; // Yields false
小なり (<)
bool ap_[u]fixed::operator < (ap_[u]fixed op)
変数と指定のオペランドを比較し、変数がオペランド未満の場合は true
、そうでない場合は false
を返します。
オペランド op のデータ型には、ap_[u]fixed
、ap_int
または C/C++ の整数型を使用できます。次に例を示します。
bool Result;
ap_ufixed<8, 5> Val1 = 1.25;
ap_fixed<9, 4> Val2 = 17.25;
ap_fixed<10, 5> Val3 = 3.25;
Result = Val1 < Val2; // Yields false
Result = Val1 < Val3; // Yields true
ビット演算子
ビットの選択と設定
af_bit_ref ap_[u]fixed::operator [] (int bit)
任意精度の固定小数点値から 1 ビット選択し、それを返します。
戻り値は、ap_[u]fixed
変数の対応するビットをセットまたはクリアできる参照値です。ビット引数は整数値である必要があり、選択するビットの指数を指定します。最下位ビットの指数は 0
です。最大指数はこの ap_[u]fixed
変数のビット幅から 1 を引いた値になります。
結果のデータ型は af_bit_ref
で、値は 0
または 1
です。次に例を示します。
ap_int<8, 5> Value = 1.375;
Value[3]; // Yields 1
Value[4]; // Yields 0
Value[2] = 1; // Yields 1.875
Value[3] = 0; // Yields 0.875
ビット範囲
af_range_ref af_(u)fixed::range (unsigned Hi, unsigned Lo)
af_range_ref af_(u)fixed::operator [] (unsigned Hi, unsigned Lo)
この演算は、ビット セレクト演算子 [] に似ていますが、1 ビットではなくビットの範囲を指定し、
任意精度の固定小数点変数からビットのグループを選択します。引数 Hi
は範囲の上限のビットを指定し、引数 Lo
は下限のビットを指定します。Lo
が Hi
よりも大きい場合は、選択されたビットが逆順で返されます。
戻り値のデータ型 af_range_ref
は、Hi
および Lo
で指定される ap_[u]fixed
変数の範囲の参照です。次に例を示します。
ap_uint<4> Result = 0;
ap_ufixed<4, 2> Value = 1.25;
ap_uint<8> Repl = 0xAA;
Result = Value.range(3, 0); // Yields: 0x5
Value(3, 0) = Repl(3, 0); // Yields: -1.5
// when Lo > Hi, return the reverse bits string
Result = Value.range(0, 3); // Yields: 0xA
範囲選択
af_range_ref af_(u)fixed::range ()
af_range_ref af_(u)fixed::operator []
これは、範囲選択演算子 []
の特殊ケースで、任意精度の固定小数点値からすべてのビットを標準の順序で選択します。
戻り値のデータ型 af_range_ref
は、Hi = W - 1 および Lo = 0 で指定される範囲の参照です。次に例を示します。
ap_uint<4> Result = 0;
ap_ufixed<4, 2> Value = 1.25;
ap_uint<8> Repl = 0xAA;
Result = Value.range(); // Yields: 0x5
Value() = Repl(3, 0); // Yields: -1.5
長さ
int ap_[u]fixed::length ()
ビット数を表す整数値を任意精度の整数値で返します。データ型または値に使用できます。次に例を示します。
ap_ufixed<128, 64> My128APFixed;
int bitwidth = My128APFixed.length(); // Yields 128
明示的な変換メソッド
固定小数点から double 型
double ap_[u]fixed::to_double ()
このメンバー関数は、固定小数点値を IEEE の倍精度フォーマットに変換します。次に例を示します。
ap_ufixed<256, 77> MyAPFixed = 333.789;
double Result;
Result = MyAPFixed.to_double(); // Yields 333.789
固定小数点から浮動小数点
float ap_[u]fixed::to_float()
このメンバー関数は、固定小数点値を IEEE の浮動精度フォーマットに変換します。次に例を示します。
ap_ufixed<256, 77> MyAPFixed = 333.789;
float Result;
Result = MyAPFixed.to_float(); // Yields 333.789
固定小数点から半精度浮動小数点
half ap_[u]fixed::to_half()
このメンバー関数は、固定小数点値を HLS の半精度 (16 ビット) 浮動精度フォーマットに変換します。次に例を示します。
ap_ufixed<256, 77> MyAPFixed = 333.789;
half Result;
Result = MyAPFixed.to_half(); // Yields 333.789
固定小数点から ap_int 型
ap_int ap_[u]fixed::to_ap_int ()
このメンバー関数は、この固定小数点値を、小数ビットを切り捨てた整数ビットのみを含む ap_int
型に変換します。次に例を示します。
ap_ufixed<256, 77> MyAPFixed = 333.789;
ap_uint<77> Result;
Result = MyAPFixed.to_ap_int(); //Yields 333
固定小数点から整数型
int ap_[u]fixed::to_int ()
unsigned ap_[u]fixed::to_uint ()
ap_slong ap_[u]fixed::to_int64 ()
ap_ulong ap_[u]fixed::to_uint64 ()
このメンバー関数は、固定小数点値を C のビルトイン整数型に変換します。次に例を示します。
ap_ufixed<256, 77> MyAPFixed = 333.789;
unsigned int Result;
Result = MyAPFixed.to_uint(); //Yields 333
unsigned long long Result;
Result = MyAPFixed.to_uint64(); //Yields 333
ap_[u]fixed
をほかのデータ型に変換するには、AMDでは C 形式のキャストを使用する代わりに、メンバー関数を明示的に呼び出すことをお勧めします。コンパイル時のデータ型属性へのアクセス
ap_[u]fixed<>
型には、データ型のサイズと設定がコンパイル時に決定されるようにする複数のスタティック メンバーがあります。このデータ型には、static const
メンバーである width
、iwidth
、qmode
、および omode
があります。
static const int width = _AP_W;
static const int iwidth = _AP_I;
static const ap_q_mode qmode = _AP_Q;
static const ap_o_mode omode = _AP_O;
これらのデータ メンバーは、既存の ap_[u]fixed<>
型から次の情報を抽出するために使用できます。
-
width
- データ型の幅。
-
iwidth
- データ型の整数部分の幅。
-
qmode
- データ型の量子化モード。
-
omode
- データ型のオーバーフロー モード。
これらのデータ メンバーを使用すると、たとえば既存の ap_[u]fixed<>
型のデータ幅を抽出して、コンパイル時に別の ap_[u]fixed<>
型を作成できます。
次の例は、変数 Res
のサイズを、変数 Val1
および Val2
よりも 1 ビット大きくし、同じ量子化モードで定義します。
// Definition of basic data type
#define INPUT_DATA_WIDTH 12
#define IN_INTG_WIDTH 6
#define IN_QMODE AP_RND_ZERO
#define IN_OMODE AP_WRAP
typedef ap_fixed<INPUT_DATA_WIDTH, IN_INTG_WIDTH, IN_QMODE, IN_OMODE> data_t;
// Definition of variables
data_t Val1, Val2;
// Res is automatically sized at run-time to be 1-bit greater than INPUT_DATA_WIDTH
// The bit growth in Res will be in the integer bits
ap_int<data_t::width+1, data_t::iwidth+1, data_t::qmode, data_t::omode> Res = Val1 +
Val2;
これにより、INPUT_DATA_WIDTH、IN_INTG_WIDTH、または data_t
の量子化モードの値をアップデートした場合でも、Vitis HLS で加算によるビット増加が正しくモデリングされるようになります。