定数のビット幅を求める
定数のビット幅を求めるには次のようにbitw< >というテンプレートを定義すればよい。
/* ビット幅を求めるテンプレート */ template<int N> struct bitw {enum {val=bitw<N/2>::val+1};}; template<> struct bitw<0> {enum {val=0};}; /* 要素数N個の配列のインデックスビット幅 */ static const int WN = bitw<N-1>::val; |
この定義によれば
bitw<0>::val = 0
bitw<1>::val = bitw<1/2>::val+1 = bitw<0>::val+1 = 0
bitw<2>::val = bitw<2/2>::val+1 = bitw<1>::val+1 = 1
bitw<3>::val = bitw<3/2>::val+1 = bitw<1>::val+1 = 1
bitw<4>::val = bitw<4/2>::val+1 = bitw<2>::val+1 = 2
...
とbitw<N>::valはNのビット幅になっている。
なおVitisHLSでは、関数の再帰呼び出しは合成できないが、テンプレートの再帰呼び出しは合成できるので大丈夫である。
◇
このbitw< >はVerilogの$clog2( )に似ているが
$clog2(3) = 2、bitw<3>::val = 2
$clog2(4) = 2、bitw<4>::val = 3
$clog2(5) = 3、bitw<5>::val = 3
と2のべき乗のときに異なる。
すなわち、要素数N個の配列のインデックスビット幅 $clog2(N) はbitw<N>ではなくbitw<N-1>であることに注意。