第4回: 減算回路・ALU

1の補数と2の補数

2進数で負の数をあらわすときには、「2の補数」というものを 使うのでした。 「2の補数」は、「1の補数(全ビットのNOTをとったもの)」+1で、 次の表のように、たしかに足してゼロになる(最上位の桁上がりは無視する) ので、負の数をあらわしていることがわかります。
数(1) 1の補数 2の補数(2) (1)+(2)
000 111 (1)000 (1)000
001 110 111 (1)000
010 101 110 (1)000
011 100 101 (1)000
100 011 100 (1)000
101 010 011 (1)000
110 001 010 (1)000
111 000 001 (1)000

減算器(p.54)

加算器を使った減算器


この2の補数を使うと、減算を行う減算器を作ることができます。 つまりこのようにN桁の加算器で、最下位の桁上がり入力Cinを 使うと、S = A + B + Cin ということですが、 たとえばBのところに/B(つまりBの全ビットの反転をとったもの)を 入力し、Cin=1とすれば、S = A + (/B + 1) となりますが、 「/B+1」は、Bの2の補数そのものですから、結果としてS = A - B を 求めたのと同じことになります。

ちなみにBのところは、上のような回路(EXORゲートそのもの)の出力B'を Bの代わりに入れておけば、 M=0のときはBが、M=1のときは/Bが、B'として加算器に与えられることになりますから、 Mの値に応じて加算(M=0)と減算(M=1)を切り替えるためには 次のような回路とすればよいでしょう。

論理演算ユニット

この構成を拡張すると、Nビット加算器のBの部分に与える値B'を すべて0, B, /B, すべて1と切り替えることで、 Cinに与える値とあわせて、 次の8通りの演算ができることがわかります。 (S1, S0は、B'に与える値を切り替える2ビットの選択(select)信号)
S1S0B Cin S = A + B + Cin 内容
00すべて0 0 A そのまま
00すべて0 1 A+1 increment
01B 0 A+B 加算
01B 1 A+B+1
10/B 0 A+/B
10/B 1 A+/B+1 = A-B 減算
11すべて1 0 A -1 decrement
11すべて1 1 A
つまりBから、選択信号(S1, S0)によって、すべて0, B, /B, すべて1、の いずれかをつくり、それとCin、AをNビット加算器に加えれば、 これらのすべての算術演算を行うことができるわけです。

このような種々の算術演算(加算・減算など。乗算・除算は除く)に加えて、 論理演算、すなわちビットごとの論理積(AND)・論理和(OR)・否定(NOT) ・排他的論理和(EXOR)を、機能を切り替えて演算できる回路を 作ることができます。 このような回路を、算術論理演算ユニット(Arithmetic Logic Unit; ALU)と 呼びます。

シフト演算

論理演算の一種に「シフト演算」があります。 これは、C言語で「>>」や「<<」という演算子であらわす演算で、 2進数としての変数の値を、全体に右あるいは左にシフトするものです。 (シフトしてあいたビットに入れる値によって、論理シフトと算術シフトの 2種類がある) このシフト演算は、例えば2n倍の乗算に使えたりと、 いろいろと使える場面が多いので、専用の演算回路として持っている プロセッサ(特にDSP)も多いようです。

シフト演算回路(シフタ)の構成にもいくつかありますが、 最も効率のよい回路として「バレルシフタ」と呼ばれるものが 知られています。

この図は、4ビットの2進数[a3:a0]を、右に[s1:s0]ビット分(2進数表現) シフトした結果[x3:x0]を求めるためのバレルシフタの回路です。 □ブロックはセレクタを表します。

バレルシフタでは、このように1ビット, 2ビット, 4ビット, ・・・という 2nのシフトを行うか行わないかを、 1段ごとのセレクタで選択し、実際の「シフト」は、2nビット分 シフトした先に配線がつながっていることで行われていることになります。 左シフトや算術シフトも同様に構成することができます。


戻る