シリーズ「コンピュータの CPU のしくみ」 第4回

回路が「飛ぶ」とは?

1 つずつしか、進めない

ここまでの 3 回を、短く振り返っておこう。

手順を 0 と 1 のパターンにして、メモリに並べた。1 つぶんの手順が命令で、上 4 桁が「何をするか」、下 4 桁が「どの番地か」だ(第1回)。 上 4 桁をデコーダに通すと、16 本の線のうち 1 本だけが 1 になり、その先の入口が開く(第2回)。 そして、クロックを「読む拍」と「こなす拍」に分けて交互に回すと、番地のカウンタが 1 つずつ数える番地の命令が、上から順に実行された(第3回)。

前回の終わりに、こう書いた。

番地のカウンタは、1 つずつ進むことしかできない。だから、手順は、いつもメモリの上から下へ、1 列に流れていく。

どうして 1 つずつなのか。 番地のカウンタの入口には、いつも「いまの番地に 1 を足した数」がつながっているからだ。 出口を 1 増やして、入口に戻す。クロックが来るたびに、それを受け取る。回路には、それ以外の入口がない。

番地のカウンタのまわりだけを、取り出してみよう。

番地のカウンタ0000 = 0入口+10001 = 1出口クロック0
番地のカウンタは 0。入口に届いているのは、いつも 1 を足した 1。

出口から出た数は、下の +1 の箱で 1 増えて、左を回って入口に戻る。 クロックを何度入れても、入口に届くのは、いまの番地の次の数だけだ。

けれど、番地のカウンタが覚えているのも、ただの 4 桁の数だった。 別の数を入れてやれば、次に読む番地は、そこになる。

カウンタに、書き込む

入口は 1 つしかない。そこは、もう「1 を足した数」でふさがっている。

似た話を、このシリーズの中で、もう見ている。 第2回の、A の箱の入口だ。

A の箱は、持ってくるではメモリからの数を、足すでは加算器の答えを、受け取りたかった。 けれど、A の箱の入口も 1 つしかない。 そこで、入口の手前に「通すか、0 にするか」を 2 つ置き、デコーダの線で、どちらか一方だけを通した。

番地のカウンタでも、同じことをすればいい。 番地のカウンタの入口の手前に、選ぶ箱を置く。

  • 1 を足した数を通す AND を 4 つ
  • 命令の下 4 桁を通す AND を 4 つ
  • 2 つを合流させる OR を 4 つ

通すか、0 にするかの AND を 2 組と、合流の OR。 A の箱の入口とも、第3回でメモリの番地の入口に置いた選ぶ箱とも、同じ形だ。 『記憶のしくみ』を読んだ人は、第6回の「取り替えることは、まだできない」と、その答えになった第8回の「入口を、選ぶ」を思い出してほしい。カウンタの入口は加算器でふさがっていて、選ぶ仕組みは後の回に回していた。それが、番地のカウンタにも付く。

あとは、いつ下 4 桁のほうを通すかを決めればいい。

命令に、新しい上 4 桁を 1 つ割り当てる。0101、飛ぶだ。 飛ぶには、番地のカウンタを、命令の下 4 桁に書き換える、という意味を持たせる。 「足す 15 番地」の 15 は、数を取りにいく番地だった。「飛ぶ 0 番地」の 0 は、次に読む番地そのものになる。

デコーダの 0101 の線は、これまで、どこにもつながっていなかった。ここに入口をつなぐ。

  • 線 0101 が 1 で、
  • いまがこなす拍のとき、

選ぶ箱は、命令の下 4 桁を通す。それ以外は、これまでどおり、1 を足した数を通す。

選ぶ箱だけを取り出したのが、下の図だ。 1 を足した数は 0011(3)、命令の下 4 桁は 0000(0)にしてある。あとで動かす「飛ぶ 0 番地」の場面と同じ数だ。 左の 2 つのスイッチを押して、下 4 桁が通るのはどんなときかを確かめてほしい。

+1 した数0011 = 3命令の下 4 桁0000 = 0次の番地を選ぶ+1+1下 4 桁番地のカウンタの入口へ0011 = 3線 01010こなす拍0
どちらも 0。選ぶ箱は +1 した数(3)を通す。2 つのスイッチを押してみてほしい。

2 つとも 1 にしたときだけ、選ぶ箱の文字が「下 4 桁」に変わり、番地のカウンタの入口に 0 が届く。

そして、番地のカウンタが受け取る合図は、2 つになる。

  • 読む拍のクロック(これまでどおり)
  • 飛ぶ拍のクロック … こなす拍のクロック AND 線 0101

2 つを OR で合流させる。

ANDOR飛ぶ拍のクロック番地のカウンタへ読む拍のクロック0こなす拍のクロック0線 01010受け取る合図
クロックが来ていない。スイッチを押してみてほしい。

読む拍のクロックが来れば、これまでどおり受け取る。こなす拍のクロックは、線 0101 が 1 のときだけ、AND を通り抜けて届く。 受け取る瞬間に入口に届いているのは、読む拍なら 1 を足した数、飛ぶをこなす拍なら命令の下 4 桁だ。

「こなす拍のとき」という条件は、省けない。 飛ぶをこなした次の拍は、読む拍だ。そのとき命令の置き場には、まだ飛ぶが残っている。線 0101 だけで選ぶと、読む拍でも下 4 桁が通ってしまい、番地のカウンタは 1 進まない。飛び先の命令を、2 回こなしてしまうのだ。 下の表は、あとで動かすプログラムを、本物の回路で 10 拍ずつ回した記録だ。ボタンで、条件を外した回路に切り替えられる。

表の数は、どれもその拍が終わったあとの値

拍段階命令の置き場番地のカウンタA の箱
1読む0010 111010
2こなす0010 111015
3読む0011 110125
4こなす0011 110125
5読む0101 000035
6こなす0101 000005
7読む0010 111015
8こなす0010 1110110
9読む0011 1101210
10こなす0011 1101210
6 拍目に飛んで、7 拍目は 0 番地を読み、番地のカウンタは 1 に進む。8 拍目の足すで、A の箱は 10。

条件を外すと、7 拍目に番地のカウンタが 0 のまま進まない。0 番地の足すを 2 回こなして、A の箱は 15 になってしまう。

押して、確かめる

3 つの命令を並べて、飛ばしてみよう。

番地中身読み方
00010 1110足す 14 番地
10011 1101書き込む 13 番地
20101 0000飛ぶ 0 番地
31111 0000止まる
130000 0000合計を置く場所
140000 0101数 5

14 番地の 5 を A の箱に足して、13 番地に書き込み、0 番地に飛ぶ。 3 番地に止まる命令はあるけれど、2 番地の飛ぶが 0 番地へ戻してしまうので、そこには届かない。

飛ぶ シミュレータ

「飛ぶ」の拍で、番地のカウンタに何が入るかを見てください

拍の状態読む拍クロックの門開次の番地を選ぶ+1+1番地のカウンタ0000 = 0命令の置き場0000 0000デコーダ00110001001011110101番地を選ぶ0000 = 0メモリ(16 語)0010 1110メモリ → A の箱閉加算器 → A の箱閉A の箱0000 = 0加算器1110 = 14ランプ C0クロック0

太い線は束(番地と数は 4 本、語は 8 本)。「次の番地を選ぶ」の大きな文字が、いま通しているほう。クロックの門は、止まると「閉」になる

はじめは読む拍。番地のカウンタは 0。次の番地を選ぶ箱は、いつもは「+1」を通している。クロックを入れると、0 番地の語が命令の置き場に届く。

読んだ番地の順:まだ読んでいない

拍ごとの記録

拍段階番地起きたこと
まだクロックを入れていない
番地中身読み方(人間のメモ)
0000(0)足す 14 番地
0001(1)書き込む 13 番地
0010(2)飛ぶ 0 番地
0011(3)止まる
0100(4)0000 0000
0101(5)0000 0000
0110(6)0000 0000
0111(7)0000 0000
1000(8)0000 0000
1001(9)0000 0000
1010(10)0000 0000
1011(11)0000 0000
1100(12)0000 0000
1101(13)0000 0000数 0(合計を置く場所)
1110(14)0000数 5
1111(15)0000 0000

青い行は、読む拍で使う番地(番地のカウンタ)。琥珀色の行は、こなす拍で使う番地(命令の下 4 桁)。0〜3 番地は上 4 桁も、14 番地は下 4 桁を、押して替えられる(替えると、はじめからやり直す)

第3回の図に、新しい箱が 1 つ増えた。左の列のいちばん上、次の番地を選ぶだ。 「番地のカウンタ」の出口からは、1 を足した数がこの箱に上がっていく。選ばれた数は、真下の番地のカウンタの入口に下りてくる。出力を入口に戻す輪が、この 2 つの箱のあいだにできている。 箱の中の大きな文字が、いま通しているほうだ。ふだんは「+1」。

「クロックを入れる」を押していこう。

はじめの 5 拍は、これまでと同じだ。 1 拍目で 0 番地を読み、2 拍目で A の箱が 5 になる。3 拍目で 1 番地を読み、4 拍目で 13 番地に 5 が書き込まれる。5 拍目で 2 番地の 0101 0000 を読み、番地のカウンタは 3 に進む。

6 拍目が、新しい。

デコーダの 0101 の線が 1 になり、選ぶ箱の文字が「下 4 桁」に変わる。 命令の置き場の下 4 桁 0000 が、番地のカウンタの入口に届き、クロックが落ちる瞬間に、番地のカウンタが 3 から 0 に変わる。

7 拍目に読むのは、0 番地だ。手順が、戻った。

拍段階番地番地のカウンタ(あと)A の箱何が起きたか
1読む0100 番地の命令を読む
2こなす141514 番地の 5 を A の箱へ
3読む1251 番地の命令を読む
4こなす1325A の箱の 5 を 13 番地へ
5読む2352 番地の命令を読む
6こなす005番地のカウンタ ← 0
7読む0150 番地の命令を読む
8こなす141105 + 5 を A の箱へ

6 拍で 1 周。1 周するたびに、A の箱と 13 番地が 5 ずつ増えていく。 『記憶のしくみ』を読んだ人は、第6回の、足す数を 5 にしたアキュムレータを思い出してほしい。クロックが来るたびに 5 ずつ増える、あの動きだ。あのときは、人間がクロックを押していた。今回は、手順が自分で、足す→書く→戻る、を繰り返している。

この箱の中では、ゲートが 1892 個働いている。第3回より 16 個増えた。

番地も、数

何が起きたのか、整理しておこう。

番地のカウンタが覚えているのは、次に読む番地だった。 その番地は、4 桁の数にすぎない。足し算の答えと同じ、ただのパターンだ。 だから、命令の下 4 桁にある数を入れれば、次に読む番地は、そこになる。

回路がしたことは、入口の手前に、選ぶ箱を 1 つ置いただけだ。 「飛ぶ」という動きは、どこにも配線されていない。配線されているのは、「飛ぶの線が 1 のとき、番地のカウンタは別の数を受け取る」という選び方だけだ。

次に読む番地も、ただの数だ。番地のカウンタに別の数を書き込めば、手順は好きなところへ飛べる。

では、飛び先を替えてみよう。 表の 2 番地の下 4 桁は、押して替えられる。0000 を 0011(3)にして、クロックを入れてみてほしい。 6 拍目で、番地のカウンタは 3 になり、7 拍目に読むのは 3 番地の止まる命令だ。8 拍目で、クロックの門が閉じる。13 番地には 5 が入ったまま、8 拍で止まった。 替えたのは、メモリの中の 4 桁だけだ。回路は、1 本も変えていない。

飛び先は、前にも後ろにも、好きなところへ置ける。 ここでは、いつも同じ番地へ飛んだ。もっと工夫した飛び方もあるけれど、それはこのシリーズでは扱わない。

止まらない

最初のプログラムに戻そう(「メモリを元に戻す」を押す)。 「自動で進める」を押して、しばらく眺めてほしい。

読んだ番地の順は、0、1、2、0、1、2……と繰り返す。3 番地には、永久に届かない。 止まる命令は、あるのに、たどりつけない。

A の箱の数も、増えていく。5、10、15、そして次は 20 のはずだが、4 桁に入るのは 15 まで。 15 + 5 = 20 は、5 桁目にあふれて 4 になり、ランプ C が点く。 『計算のしくみ』を読んだ人は、第5回の桁あふれを思い出してほしい。 13 番地は、5、10、15、4、9、14、3、8、13、2、7、12、1、6、11、0 と回り、16 周(96 拍)で元の 0 に戻る。 どこまで待っても、止まらない。

では、止まるようにしてみよう。 2 番地の飛ぶを、0000 0000(何もしない)に替えればいい。 飛ばなくなったので、番地のカウンタは 3 へ進み、止まる命令に届く。8 拍で止まり、13 番地は 5 だ。 前の節で飛び先を 3 にしたのも、止まる命令に届かせる、という点では同じだった。

(前回考えた「止まる命令が無かったら」も、そのうえで 3 番地を 0000 0000 にすれば試せる。)

止めたいところで

いつも飛ぶ命令は、止まらないことと引き換えに、好きなだけ繰り返せることを手に入れた。 けれど、繰り返すたびに 5 を足すだけでは、役に立たない。 たとえば、足した数が、ある大きさになったら止めたい。 それ以外のときだけ、戻って足したい。

いま持っている飛ぶは、そうは動いてくれない。 飛ぶ命令は、そこに着いた瞬間に、飛ぶ。足し算の答えが何であっても、飛ぶ。

さっき、ランプ C が点くのを見た。 15 + 5 のときだけ点いて、あとは消えている。ランプ C は、「計算の結果」を覚えている。

計算の結果を見て、飛ぶか飛ばないかを決められないか。

次回は、飛ぶ命令に条件を付けて、結果によって手順が分かれるようにしてみる。

参考文献