コンピュータ
動作原理

コンピュータの動作原理(5)順序回路

六本木順序回路ごめんなさいもうしません

セレクタ

コンピュータの動作原理を考える上で大事な回路にセレクタがあります。マルチプレクサとも言います。複数の信号のうち1つを選択する回路です。例によって真理値表から。

S A B Y
0 0 0 0
0 0 1 0
0 1 0 1
0 1 1 1
1 0 0 0
1 0 1 1
1 1 0 0
1 1 1 1

Sが選択信号です。
S=0の時はAが、S=1の時はBが出力Yに出てきます。(選択される側の)信号の数が増えたら、選択信号も増やします。4つから1つ選ぶなら選択信号は2本ですね。

複数本の信号から1本を選択して出力する方法としては、この他に tristate buffer というモノを使う方法もあります。これにはこのシリーズ(2)でちらっと出てきたCMOSを使います。選択した信号以外は、電源側のMOSFETもGND側のもOFFにするというやり方です。選択した信号以外は電気的にどこにもつながっていない状態にします。そうすると、選択した信号の0か1かだけが、その先の回路に伝わっていきます。
詳しくはぐぐってみてください。

ALUは常に結果を全部出してると(1)で触れました。全部出てるけど、結果は1つだけしか必要ない場合が殆どなので、セレクタなどでそのうち1つを採用します。この選択信号は、やはりどこかの回路から出力されています。(1)の図にある制御信号のうちの1つがこれです。

加算

加算についてもやっておきます。といっても、加算器についてはちょっと探せば解説がたくさん出てきますからそっちにまかせて、ここでは「コンピュータは減算」と言った流れで加算をどう解釈するかについてだけ解説します。

加算は減算回路があれば A+B → A-(0-B) にすればいい事は前回解説しました。もう1つ、加算は繰り上がりがあるので、繰り上がりが発生したら1を上の桁に伝えるようにします。
減算回路は下の桁への貸し=0の時はそのぶん1を引いていました。加算の場合はこの入力が0なら、減算の時引いていた1を引かないように変えます。減算回路は黙ってても1を引いちゃいますから、引かないという事は1を足すという事ですね。これで貸し=1と加算の時の繰り上がり=1の違いにも対応できます。結果、A+B → A-(0-B)+1 変形して A-(0-B-1) ですね。まだ減算回路しかやってないですし。
あとは減算か加算かを選択するセレクタのSのような信号を増やして、Bと(0-B-1)とを切り替えれば、加算と減算とどっちにもなる回路が出来ます。

まず0-Bの真理値表です。

B r Y
0 1 0
1 0 1

上の桁から借りた1と、引かれる数0は省略してあります。rとYは合わせて2桁です。

ここから更に1を引きます。入力は上の表の出力ですから2通りしかありません。また、上の表と同じ桁ですから、上の桁からの借りはさっき借りた分でまかないます。

r Y (r:Y)-1
1 0 1
0 1 0

この-1は下の桁への貸しが0(貸しっぱなし)という意味にもなります。貸しが0の前提ですから、更に上の桁も、つまりどの桁も下からは返ってこない前提です。という事はわざわざ上に0を渡す必要は無いので真理値表では省略します。0からBと1を引くのですから、どっちみち上には返せませんし。
結果を見ると NOT B ですね。という事で下が加算と減算の切り替えを追加した回路です。BとNOT Bをセレクタで切り替えるようにしてあります。OPが減算か加算かを選択する信号、uが下への貸し又は加算の場合下からの繰り上がりです。

 ※前回から今回ここまでの回路は SUB_ADD.circ に入っています。

「加算しか出来ない」の謎

1つのプロセッサコア(ダイ)に10数億個のトランジスタの乗る現在では、工夫をして加算と減算を1つの回路で実現する意味はあまりありません。符号ビット+絶対値でもいいわけです。けど、昔のトランジスタ数の節約が必要だった頃のプロセッサ(例えば1974年発表のi8080は、6μmのNMOSでトランジスタ数5000個と言われています)では、ちょっとした工夫でトランジスタが節約できる方法は必要だったはずです。1ビットの加算回路に30個以上のトランジスタが使われているわけですからね。
その事が、加算器を利用して減算も行う→コンピュータは加算しか出来ない、と間違って伝わったのではないかと思います。

順序回路

今まで解説したものは、入力が変わるとそれにあわせて出力もすぐに変わる回路でした。こういう回路を「組み合わせ回路」と言います。
ストアードプログラム方式のプロセッサはどうしても一時的な記憶が必要です。例えば、これから実行しようとしているマシンコードを指すための、プログラムカウンタとかインストラクションポインタとか言うアレですね。
一時的に状態を記憶する回路というとラッチやフリップフロップ(Flip-Flop(FF))と呼ばれるものがあります。探すと色々出てきます。そういったものを利用した回路を「順序回路」と呼びます。
順序回路はRSラッチというやつから入るのが正しい順番の様ですが、それはこのシリーズの目的から外れるので、プロセッサに必要なD-Flip-Flopについて解説します。

D-Flip-Flop

心がふわっと天に届くみたいな話ではありません。入力と制御信号を受け入れる回路で、0か1かを一時的に取って置く事ができます。制御信号によってコントロールします。たとえば下がDFFの例でCLKが制御信号です。

これは、CLKが1の時はINがそのままOUTに出ます、CLKを1から0にすると、その瞬間のINがOUTに出たままになりそして、CLKが0の間はOUTが変化しません。メモリー(のうちSRAMと呼ばれているもの)は基本的にこの回路です。この回路は0と1の真理値表は書けません。動作を表す時は0か1かを書くかわりにCLKが0→1に変化した時やその逆の時の記号を使います。

この回路はCLKが1の時にINがOUTにダダ漏れになるので、この回路のOUTがいくつか組み合わせ回路を経由して、ぐるっと回ってこの回路のINにつながっていたら、回路全体が忙しくなります。
そこでこの回路を二段にします。それぞれにCLKの反転と(さらに反転して)CLKを入れてやります。マスタースレーブ方式と言います。


CLK→反転→マスターへ→さらに反転→スレーブになってます。
マスターはCLKが0の時(マスターに入力するCLKが1の時)にINがそのままマスター→スレーブの継ぎ目に出るのですが、スレーブにさらに反転したCLK(マスターへのCLKが1なら、スレーブに来るCLKは0)を入れているので、INが変わってもOUTは変化しません。CLKが1になると、今度はマスターが変化しないのでスレーブ側が入力をそのまま出しても問題ありません。安定ですね。

少し工夫するとGATEを6個に減らせるので(どういう理屈かは私はわかりませんが)ここからはそれを採用して解説します。

コレに「非同期リセット」を付けます。何が非同期かというと、CLKが0か1か,INが0か1かに関わらずResetを0にするとすぐにOUTが0になります。そしてResetが0の間はOUTは変わりません。このReset信号は、コンピュータのリセットスイッチを押したときや電源が入った直後などに内部状態を文字通りリセットするのに使います。つまり、非同期言いたかっただけです。

こんな感じです。

もうひとつ追加します。Enable信号です。

Enable信号が0の時はCLKを遮断するようにDFFを入れてあります。こっちはEnableが1の時にCLKがそのまま出て、Enableが0の時はCLKが変わってもそれが出ないようにしてあります。先のDFFとはCLKの位置が違いますね、確認してください。
これでEnable信号が0の時はこのFFは入力を記憶しない、それより前にEnable=1だった時の値を維持します。
アセンブリ言語の命令で「引き算するけど結果は捨てる」というのは、結果を残す引き算だったらメモリやレジスタに書き込むけれど、結果は捨てる=Enable信号を0にして書き込まないようにする、というやり方です。
もちろん、このEnable信号も、制御信号のうちの1つです。

CLKが0→1になって出力が変わったら、その先に組み合わせ回路がつながっていれば、そっちの出力もそのタイミングで変化します。それを順序回路の入力にフィードバックして、という構成にすると、CLKに同期して全体が先に進んで行きます。この時のCLKが一般にクロックと呼ばれているもので、プロセッサの動作の基本です。

プロセッサを構成する重要な要素について基本を一通り解説しました。次回からはもうすこし具体的にプロセッサの動作について解説していきます。


 ※以上の回路は FLIPFLOP.circ に入っています。 Logisim用のドキュメントです。xmlですから右クリで。