任意精度データ型
通常のCコードでは数ビットで足りる変数でもint型で書くが、高位合成ではint型は常に32ビット分の回路が作られて不都合なので、ビット幅を明示的に書く「任意精度データ型のクラス」が用意されている。ヘッダはap_int.hをincludeするだけで使える。(ap_fixed.hもあるがap_int.hと同じものである)
◇
(1) 任意精度データ型
ap_int<W> 符号付き整数型 ap_uint<W> 符号なし整数型 ap_fixed<W,I> 符号付き固定小数点型 ap_ufixed<W,I> 符号なし固定小数点型 W: 全ビット幅(max 1024) I: 整数部のビット幅 |
・代入時の量子化モードは切り捨て(デフォルト)
・ビットの選択は a[5]
・ビット範囲の選択は a.range(7,4) または a(7,4)
・連接(Verilogの{a,b}に相当)は (a,b)
・int型への変換は a.to_int()
・double型への変換は a.to_double()
・左シフト時の注意:
シフト結果はシフト前と同じビット幅しか保持されないので、キャストしてからシフトする必要がある。
例) ap_int<8> a8, ap_int<4> a4=0xfのとき
// 00001100 = 1111 << 2
a8 = a4 << 2;
// 00111100 = 00001111 << 2
a8 = (ap_int<8>) a4 << 2;
(2) bool型
1ビットの変数にap_uint<1>を使うとregでなくreg[0:0]にマッピングされる。間違いではないが気持ち悪いので、bool型を使う方がよい。
◇◇
任意精度型どうしの計算は自動的に符号拡張・桁合わせしてくれる。
例) ap_int<8> k=1, ap_fixed<8,4> a=1.5のとき
ap_fixed<8,4> b = a + kは2.5
またRTL記述のようにビット列としても扱えるが、わかりにくくなるので避けた方がよい。
例) ap_fixed<8,4> a=1.5(ビット列0001.1000)のとき
a << 2 は6.0 (ビット列0110.0000)
~a は-1.5625 (ビット列1110.0111)
◇◇◇
任意精度型はそのままprintできないのでC流にint,double型に直すか、またはC++流にcoutを使う。
ap_uint<8> k; ap_fixed<8,4> a; // C流の書き方 printf("a[%0d]=%f\n",k.to_int(),a.to_double()); // C++流の書き方 coutは標準出力,endlは改行 std::cout << "a[" << k << "]=" << a << std::endl; |