算術論理回路(arithmetic logic unit)またはALUはもっとも設計の難しい回路である。 まず,キャリーのある加算ができなければならない。 補数も作られなければならない。 ビットごとのANDやORといったビット演算もできるとありがたい。 数値の比較もできるとよい。 ということで,単なる加算器の集合よりも,高機能の演算ができる回路を考えよう。
しかし,いきなり高機能の回路と言われても考えづらいと思われるので, まずキャリーに着目して,加算器の改良から取り掛かろう。 加算器の問題は何桁にも及ぶキャリーの伝播時間が馬鹿にならないことである。 同期式回路の場合,すべての論理処理が終了するまで, 次のクロックパルスを送れないから, 実はこのキャリー伝播時間がコンピュータ全体の速度を決めてしまうのである。
比較的簡単な回路で,かつ,比較的速い動作をするキャリーの計算法として
マンチェスタキャリーチェーン(Manchester carry chain)という方式が提案されている。
これは,図 4.4に示した全加算器の真理値表を見てみると,
ほとんどの欄で
と
が等しいという事実を利用した方式である。
この結果,多くの場合,各桁ではキャリー
を改めて計算することなく,
をそのまま後段に伝播すればよいことになる。
式できちんと確認しておこう。
まず,下からのキャリーのない場合には次式が成立する。
| (9.1) | |||
| (9.2) |
| (9.3) | |||
| (9.4) | |||
| (9.5) |
であるとキャリーはそのまま上に伝えてよいことになるので,
を作り出す機能は伝達子(propagator)Pと呼ばれる。
伝達がない場合には,
に基づき新たなキャリーを発生することになるが,
この機能を生成子(generator)Gと呼ぶ。
さらに,この否定を消滅子(killer)Kと呼ぶ。
消滅子はプリチャージ論理の際,使われる。
は
と
のEORであるが,この論理を行う部分をRと記載しよう。
図 9.5に1bit分のALUの概念図を示すが, ここでK,P,Rを固定の論理を扱うブロックとはしないで, 図 5.12に示した任意の論理関数を実現できる回路に置き換えると, 極めてたくさんの演算を行うことができるようになるのである。
は
でのプリチャージ論理により決定される。
になって初めて,Kによりその電位を下げるかどうかが決まる。
これに対応して,KとPの機能ブロックの出力には
とのANDゲートを置くことにより,
このプリチャージ論理との整合性をとっている。
これらの機能ブロックに送る信号
,
,
を
いろいろ変化させたときに実現できる機能の例を,図 9.6に示す。
先に第8章プログラムの図 8.3で示した
機械語の命令セットの演算命令と比較し,やや多めの機能が示されている。
例えば,
をALU全体に対するキャリーインとして,
,
などの加減算は,データ幅以上の加減算の際,必要な命令である。
ALUは全体として,その動作結果に応じたフラグ(flag)を出す。
これらフラグは,オーバフロー,ALU全体の
(キャリーアウト),
シフトの際の
(シフト溢れ),減算の結果の正負などであるが,
図 9.7に示すフラグレジスタ(flag register)と呼ばれる
16bitの一時メモリーへ蓄積され,
Aバスを経由して,他のレジスタやALUなどで利用することができる。
これらのうち,4から6bit目は
や
の作業の結果,決定される。
フラグレジスタのMSBには,
フラグビット(flag bit)と呼ばれる特別の役割が与えられている。
この特定のビットは,上記0から7bit目までに記載されたフラグのうち,
いずれかが選ばれ,そのコピーが記録される。
どのビットが選ばれるかは,制御部から与えられる当該演算の指令の中に記載される。
このフラグビットは,条件分岐の際利用されたり,
これから述べるALUの条件付演算命令に利用される。
図 9.6中,
ALU全体へのキャリーイン
の欄に書かれた
とは,
このフラグビットを意味する。
フラグレジスタの0bit目には,1回前のフラグビットも蓄積されるため,
これをうまく利用すれば,かなり前のALUの状態を利用することも可能である。
次に条件付演算命令について述べよう。 乗除算は,複数のステップによって達成されるが, ステップによっては,MSBなどの値によって,実行する計算が異なる。 これを,通常のプログラムの条件分岐命令によって実行すると, かなりの時間がかかる。 そのため,前命令でフラグレジスタのフラグビットにMSBなどの値を記憶し, 次命令でその値により実行する機能を変えるという手法を使うことにより, 高速化が果たせる。 もちろん,すべての条件分岐をこのようにするのは, 限りなく機能が増えるので得策ではないが, 乗除算のように比較的よく使われ,かつ次命令が定まったものに適用するのは, 極めて有効である。 こういう形で拡張されたALUの機能の一例を図 9.8に示す。
ここまでの説明でシフタとALUはかなり深い関係にあることを予想できたかもしれない。
実際,シフタの主なる活躍場所は乗除算である。
シフタも入力側または出力側のいずれかにレジスタが必要であるが,
ここではシフタの出力側に置き,かつ関連の深いALUの入力レジスタと兼用している。
シフタの出力が必要な場合も,それを直接シフタからは出さないで,
ALUを素通りさせて利用するようになっている。
この際,ALUの動作は
になされるから,時間ロスは発生しない。
,
,