本連載はHisa Ando氏による連載「コンピュータアーキテクチャ」の初掲載(2005年9月20日掲載)から第72回(2007年3月31日掲載)までの原稿を再掲載したものとなります。第73回以降、最新のものにつきましては、コチラにて、ご確認ください。

ここでALUの設計に戻って、次は、ALUの中の一番の大物であるADDERの設計に取り掛かろう。

  • 1ビット フルアダー回路

    1ビット フルアダー回路

この図に示すように、フルアダーは、1個のXORでAとB入力の加算を行い、もう1個のXORでA、Bの和とキャリー入力C-inの和を求めSumを生成する。そして、その下の3個の2NANDと1個の3NANDは、桁上がりのキャリーC-outを計算する。3個の2NANDは、それぞれC-inとA、C-inとB、AとBの両方が"1"となると"0"を出力し、4番目の3NANDにより、C-outを"1とする。つまり、A、B、C-inのうちのいずれか2個以上が"1"であるとC-outが"1"となる。ということで、フルアダーはA、B、C-inの3つの1ビット入力を加算した結果と桁上がり信号を生成することができる。

このフルアダーで1ビットの加算が出来るようになったので、次は4ビットのアダーである。多ビットの加算を行う高速アダーについてはいずれ稿を改めて説明しようと思うが、4004の設計では高々4ビットの加算であるので、最も単純なリップルキャリー方式のアダーを用いる。この4ビットアダーの回路を次の図に示す。

  • 4ビット リップルキャリーアダー

    4ビット リップルキャリーアダー

最下位ビットのA0とB0とCinをフルアダーで加算し、そのキャリーを次のA1、B1のフルアダーに入力するというように、キャリーを次々と伝搬させていく。ADDERは、加算だけでなく、減算も行う必要があるので、ここで、一寸、数値の表現法の話と減算のやり方について述べておこう。

正の数値は単純な2進数で表わすとして、負の数値の表現法には1の補数表現と2の補数表現、あるいは、1ビットを符号に用いる方法などが考えられる。最上位ビットをサイン(符号)ビットとし、+3は0011、-3は1011とする表現法は整数の加減算に適しないので、通常、整数の表現としては用いられない。しかし、浮動小数点数の場合は単純な加減算ができないので、この表現方法が用いられている。

1の補数表現は、例えば3のバイナリ表現の0011に対して-3は、各ビットを否定して1100と表現する。しかし、この表現法で表わした+3と-3の加算は、0011と1100の加算であり、1111となる。つまり、0000と1111の両方がゼロを表わすことになり、面倒である。

これに対して、2の補数表現の負数は1の補数表現に1を加えたものであり、-3は1101となる。2の補数表現での+3と-3の加算は、0011と1101の加算であり、10000となる。ここで最上位ビットからのキャリーを無視すると結果は0000となり、上手くゼロとなる。また、+3と-2の加算の場合は、0011と1110の加算となり10001となるので、これもキャリーを無視すると0001となりOKである。そして、結果が負になる+3と-4の加算は、0011と1100の加算であり、1111 = -1となり、これもOKである。というように、2の補数表現を使うと正、負の数の足し算が上手く行くので、現在の計算機は整数に関してはこの表現法を用いている。ということで、ここでの設計は2の補数表現を用いることにする。

2の補数表現でA-Bを行う場合は、Bの2の補数を求め、それをAに加えてやれば良い。しかし、2の補数表現はビットごとに否定を行いそれに1を加えた数であるので、そのままでは+1が必要になる。しかし、A-Bを求める場合には、ADDERにAと、Bの否定を入力し、さらにキャリーC-inを"1"にして加算を行えばBの2の補数表現を加算したことになる。この関係は任意のビット長に当てはまるので、12ビットの引き算を4ビットずつ実行する場合は、B-high、B-mid、B-lowと4ビット毎に区切って、それぞれの否定を取り*B-high、*B-mid、*B-lowとし、先ず、A-low+*B-low+1を求め、キャリーをYに保存しておき、次にA-mid+*B-mid+Yを計算し、また、キャリーをYに格納し、最後にA-high+*B-high+Yを計算すれば良い。

また、4004のSUB命令はボローを含めて減算を行う命令であるので、ボローが無い場合は、上記の減算を行い、ボローがある場合は、2の補数表現にするための+1とボローの-1が相殺するので、C-inをゼロとして加算をおこなってやれば良い。つまり、ボロー付きの減算の場合は、Yを反転してC-inとすれば良い。

加算と減算動作を行う4ビット加減算器の回路を次の図に示す。

  • 4ビット加減算回路

    4ビット加減算回路。減算のためのインバータとマルチプレクサを含む

前の図に示した4ビットリップルキャリーアダーのB入力側に、否定をとるためのインバータと、Bか*Bか、およびC-inかその否定かを選択するマルチプレクサを付加している。そして、Add / Sub信号により、加算の場合はB側を、減算の場合は*B側を選択する。この部分は、インバータとマルチプレクサの替わりにXORゲートを用いても良い。

そして、ALUで最後に残ったのが、CC Genサブユニットである。このサブユニットは、JCN命令において次のような条件が成立しているか不成立であるかを判定する。

  • C2=1:アキュムレータの内容が"0"の場合にはジャンプ
  • C3=1:キャリーが"1"の場合にはジャンプ
  • C4=1:テスト信号が"0"の場合にはジャンプ
  • C1=1:上記のジャンプ条件を反転

これを実現する回路は次の図のようになる。

  • CC Gen生成サブユニット

    CC Gen生成サブユニット

アキュムレータの内容が"0"となっていることの検出は、ACC0~3の4ビットの信号を2個の2NORと1個の2NANDで4入力OR回路を作ってAll-0を検出し、これをインバータで反転しているが、4NORを使っても良い。そして、この条件が検査されるのはC2=1の場合であるので、次の2NANDでC2とANDを取る。キャリーフラグは、Yレジスタの出力をそのままC3とANDすれば良い。そして、TESTは"0"の時に条件成立なので、インバータで反転してC4とANDを取る。これらを3NANDで纏めると、条件が成立した場合には"1"になる信号が出来る。C1が"1"の場合には条件を反転するためにXORゲートを使い、条件の成立、不成立を保持するためにCCフラグFFに格納する。条件成立/不成立の格納はJCN命令の最初のX3サイクルに行う必要があるので、X3とCJN、1stByte信号をANDしてFFのエネーブルに入力している。