CPUよもやま話(論理ゲートを使って加算器を作ってみよう)
前回はトランジスタを利用した基本的な論理ゲートであるAND、OR、NOTの作り方を紹介しました。今回は、その論理ゲートをさらに組み合わせて加算器なるものを作ってみましょう。専門家の方には初歩的過ぎるかもしれませんが、そのあたりはご容赦下さい。
その前に、加算器ってなーに?って言う人もいるかもしれないので簡単に説明しておきます。
加算器とは、二進数と二進数を足し算(算術的加算)して、二進数で計算結果を出力するための回路です。例えば、0101と0101を入力として与えたなら、1010を出力します。(10進数での、5+5=10と同義)
よく混同されがちなのが、論理演算です。論理演算は入力に対して真(1)か偽(0)を出力するだけなので算術的意味はありません。具体的に論理和と算術的加算の違いを見てみましょう。
まずは、論理和から
次に、算術的加算
このように、結果は違います。
しかし両者はまったく1ミリも無関係なのではなく、算術的演算は、論理演算を応用してテクニカルに実装されているのです。
?(゜ρ゜)?
安心して下さい、その辺を順を追って説明してみようと思います。
半加算器とは?
まずは桁上がりをどう実装するか?を考えなくてはいけません。
そこで考案されたのが、この半加算器です。(AとBは同じ桁の入力、Sはその桁の合計値出力、Cは桁上がり出力です)
真理値表
AとBが1ならばこの桁は0になり、桁上がりが発生するというものです。論理回路をシミュレートできる「Logisim」を使って真理値表どおりに動作させてみたので、見比べてみて下さい。
繰り返しになりますが、 AとBの両方が1であった場合Sが0、Cが1になるようになっています。つまりその桁の算術的加算をこのようなAND、OR、NOTの組み合わせで実現することができます。(XORを使う場合もあり)
全加算器とは?
さて、半加算器では、上位桁への桁上がり出力はできるものの、下位桁からの桁上がりを受け付ける回路がありません。そこで考案されたのが、半加算器2つとORを組み合わせて作られた全加算器です。(AとBは同じ桁の入力、Xは下位桁からの桁上がり入力、Sはその桁の合計値出力、Cは桁上がり出力です)
真理値表
Logisimのアニメーションと真理値表を見比べてみて下さい。
このように下位桁からの桁上がりを含めた算術的加算を、半加算器2個とORで実現しています。
4ビットの加算器を作ってみる
勘のいい人なら半加算器と全加算器を組み合わせて、任意ビット(桁)の加算器を作れることに気付いたかもしれません。
最下位ビットには下位ビットからの桁上がり入力がない半加算器を置き、上位ビットには残り必要な個数の全加算器を置きます。半加算器の桁上がり出力(C)を次のビットの全加算器の桁上がり入力(X)に接続し、さらにその全加算器の桁上がり出力(C)を次のビットの全加算器の桁上がり入力(X)に接続し・・・・・・というふうに半加算器1個+全加算器3個を組み合わせれば4ビットの加算器になります。回路図中のHA(Half adder)は半加算器、FA(Full adder)は全加算器を表します。どちらも先ほどLogisimで作った半加算器と全加算器を部品化してLogisimで再利用したものです。(Logisimは一枚絵で回路を作るだけでなく、別途作成した回路を部品化して別の回路で再利用することができます。さらに再利用したものを含む回路をも部品化して別の回路で再利用できる・・・・・・プログラミングで言えばクラスとクラスの継承のような使い方ができるので便利です!)
入力Bを0101で固定し、入力Aを0000→0001→0011→0111→1111というふうに変化させたときの出力Sは次のようになります。
最後のケースは4ビット目が桁上がりしていますが、桁上がりを入力する5ビット目がないのでオーバーフローしています。
任意ビットの加算器を作るのなら、このように半加算器1個+全加算器n個で実現することができます。
さて、今回紹介した加算器は最も原始的な構造のものと言えるでしょう。この他に加算器を応用した減算器、加算器の動作を高速化するためのキャリー先読み・キャリー予測・・・・・・etc.これらの仕組みはCPUの中のALU(演算装置)の基本となるものです。この辺も機会があれば、記事にしてみようと思います。
既に紹介済みですが、論理回路作成と動作確認はフリーソフトの「Logisim」を使用しました。感電や半田ごてによる火傷の心配がないので手軽に遊ぶことができます。