読者です 読者をやめる 読者になる 読者になる

kivantium活動日記

プログラムを使っていろいろやります

バレルシフタ

この記事はkivantium Advent Calendarの14日目です。

昨日浮動小数点数の乗算をやりました。
今日は浮動小数点数の加減算をするのに必要な部品であるバレルシフタを紹介します。

シフトの使い道

シフト演算は高速なのでビット演算テクニックとしてよく使われますが、ハードウェア実装は意外と難しいです。

1bitのシフトならシフトレジスタを用意して隣に移動すればよいのですが、任意のbit数シフトするにはバレルシフタと呼ばれる回路が必要になります。

浮動小数点数の加減算を行う際にもシフトが必要です。浮動小数点数仮数部は最上位が1になるように格納されているため、指数部が異なる場合は小数点の位置を合わせる必要があります。
1.01 \times 2^01.11\times 2^{-3}を足し算するためには

1.01
0.00111
--------
1.011111

のようにずらさないといけません。

そこでバレルシフタの実装を見ていきます。

バレルシフタの作り方

バレルシフタは、入力がシフトされる数字Aと何bitシフトするかを表すS、出力がシフトした数字Bという形の回路です。
中身はマルチプレクサをたくさん集めて作られています。

Aが8bitの場合、Sは0~7なので3bitとなります。
このとき、

tmp1 = A         if S[2] == 0
     = A << 4    if S[2] == 1
tmp2 = tmp1      if S[1] == 0
     = tmp1 << 2 if S[1] == 1
B    = tmp2      if S[0] == 0
     = tmp2 << 1 if S[0] == 1

となるようにマルチプレクサをつなげば2進数に対応した分だけシフトされるので目的の回路が作れます。

実際にはVerilogのシフト演算子を使えば任意のシフトができるのでおそらく内部でバレルシフタを合成しているのだと思いますが、本当かどうかは分かりません。