もし、コンピュータの無い時代に飛ばされたら、われわれソフトウェア開発者に何ができるだろうか。
Ryan North の『ゼロからつくる科学文明』は、タイムマシンが壊れて紀元前 25,000 年に取り残された読者に向けて書かれている。農業から蒸気機関を経て、コンピュータの作り方まで載っている。人気マンガ『Dr. STONE』は逆に現代の文明が滅びたあとの話で、磁気コアメモリでコンピュータまで作ってしまう。
考えるぶんには楽しい。科学文明を自分の手で進めるだなんて、わくわくする。ただ、コンピュータとなると、そこで思考が止まってしまう。果たして、自分はゼロからコンピュータを作れるだろうか。
時間も労働力も無限にあると仮定して、タイムスリップ先でコンピュータを作れるかを考えてみよう。大学の実験では、論理回路を組んで Verilog を書いて FPGA に焼くところまでやった覚えがある。しかし、トランジスタから論理回路を組むところはどうもふわっとしている。電気電子工学系の学科では取り扱うのだろうか?いずれにしても、自分の所属していた情報工学系の学生実験では扱わなかった。そうなると、いつタイムスリップしても安心できるように、予行演習をするに越したことはない。
そこで、トランジスタからコンピュータを組んでみようと思う1。コンピュータの回路と言えばマイクロプロセッサだが、いきなり丸々組むのは骨だろう。まずは小さく始めたい。ということで、今回はマイクロプロセッサが値を覚えるのに使っている回路、Flip-Flop を作ってみることにした。
Flip-Flop の論理回路を設計する
論理回路の講義を復習しながら進めよう。 Flip-Flop について調べてみると、忘れていることが結構あった。
Flip-Flop は、1 ビットを記憶する論理回路だ。入力が変わっても、覚えろと言われるまで以前に記憶した値を出力し続ける。この「覚えろ」をクロック (CLK) と呼ぶ。
Flip-Flop を必要なビット数だけ並べれば、レジスタを作ることができる2。
どの Flip-Flop を作るか?
代表的な Flip-Flop には、SR、JK、T、D の 4 種類がある。それぞれ、以下の入出力を持つ回路だ。
SR Flip-Flop は、S (Set) に 1 を入力すると出力が 1 になり、R (Reset) に 1 を入力すると 0 になる。ただし、両方の入力を同時に 1 にすることは禁止されている。
JK Flip-Flop は SR Flip-Flop の「禁止」を解消したもので、両方 1 にすると出力が反転する。
T Flip-Flop は入力が 1 本しかなく、1 を入力するたびに出力を反転させる。
D Flip-Flop も入力が 1 本で、覚えさせたい値をそのまま受け取って出力する。
今回作る Flip-Flop はレジスタなので、入力された値を単に記憶させたい。
SR Flip-Flop と JK Flip-Flop は、0 と 1 を別々の入力としている。 Flip-Flop に入力する前に、覚えさせたい値を 2 本へ振り分ける回路が要る。
T Flip-Flop は入力が 1 本で済むが、言えるのは「反転しろ」だけだ。狙った値にするには、現在の値を知っていないといけない。
D Flip-Flop だけが、覚えさせたい値をそのまま 1 本で渡せる。実際に、マイクロプロセッサの Flip-Flop には D が使われている。
しかも残りの 3 つは、D Flip-Flop があれば作れる。 T Flip-Flop は D Flip-Flop の手前に XOR を 1 つ置くだけでいい。 JK Flip-Flop は、そこに足すゲートが 4 つに増える。 SR Flip-Flop に至っては、Latch の形で D Flip-Flop の中に入っている。
そうなると、実装の目標は D Flip-Flop で良いだろう。
D Flip-Flop は、D Latch 2 つと NOT からなる
D Flip-Flop の中には、D Latch と呼ばれる回路が 2 つ入っている。前を Primary、後ろを Secondary と呼ぶ3。加えて、NOT ゲートを 1 つ使用する。
実のところ、この Latch も Flip-Flop 同様、1 ビットを覚える回路だ。違うのは、いつ値を覚えるかだ。
Flip-Flop はクロックが立ち上がる瞬間の入力を取り込む。 Latch は、Enable という入力が 1 の間ずっと取り込み続け、入力が動けば出力も一緒に動く。 Enable が 0 に戻った瞬間の値が、そのまま維持されるようになる。
D Latch はほぼ D Flip-Flop の要件を満たしているようにも見えるが、なぜ D Latch が 2 つ要るのだろうか。論理回路図では、2 つを直列にして、片方の Enable にクロックの反転を入れている。すると、Primary が通しているときに Secondary は通さない。どちらも入力を受け入れる時間が無くなり、値が受け入れられるのはクロックが切り替わる一瞬だけになる。
これをエッジトリガと呼ぶ。そのために NOT ゲートが要る。クロックをそのまま Secondary へ、反転させて Primary へ入れる。
これで D Flip-Flop の構造はわかった。では、D Latch は何でできているのか。
D Latch はラップしてカプセル化した SR Latch だ
D Latch を開けると、次は SR Latch と呼ばれる回路が出てくる。その名の通り、SR Flip-Flop の Latch バージョンだ。 SR Latch も SR Flip-Flop 同様、S に 1 を入れれば出力が 1 に、R に 1 を入れれば 0 になる。両方を同時に 1 にしてはいけないところも同じだ。
D Latch は、この 2 本を外から触らせない。 D と Enable の 2 本を受け取って、中で S と R を作る。
S は AND(D, Enable)、R は AND(NOT(D), Enable) だ。使うゲートは、D を反転させる NOT が 1 つと、AND が 2 つ。
D とその反転が同時に 1 になることはないので、S と R も同時に 1 にならない。禁止だった組み合わせが、作れない組み合わせになった。すなわち、SR Latch をラップしてカプセル化したものが D Latch だ。
では、SR Latch は何でできているのか。
SR Latch は記憶を担当する最小の要素
SR Latch を開けると NOR ゲートが 2 個ある。片方の出力を、もう片方の入力へ繋ぐ。それを互いにやる。それだけだ。
NOR ゲートは、入力が両方とも 0 のときだけ 1 を出す。繋いだ瞬間に状態を持てるのは、この性質のせいだ。
S に 1 を入れると、その NOR ゲートの出力は 0 になる。 0 になった出力は、もう片方の入力へ渡る。相手は R も 0 なので、入力が両方 0 になって 1 を出す。これが、S に 1 を入れたときに 1 になるほうの出力だ。
その 1 が、最初の NOR ゲートの入力へ戻ってくる。ここで S を 0 に戻しても、戻ってきた 1 が入ったままなので、出力は 0 で動かない。自分が出した値が、一周して自分を維持させている。
入力だけで出力が決まっていた回路が、前の状態によっても出力が決まる回路になった。これが記憶の最小の形だ。
さあ、これで D Flip-Flop の分解が完了した。全体を見渡すと、いまの論理回路図に出てくるのは AND ゲート、NOT ゲート、そして NOR ゲートだ。これをどのようにしてトランジスタに落とし込むかを考えるのが次のステップだ。
各論理ゲートをトランジスタに落としこむ
小学生のころ、地域の発明クラブでラジオを作ったことがある。配られたのは手順書と回路図で、既製品の基板に部品の足を入れ、順番にはんだ付けしていく、それだけの作業だ。それでも十分楽しかったけれど、頭の中は疑問でいっぱいだった。どうしてこれで音が出るのだろう?そもそも足が 3 本もある部品に、どのように電流が流れるのだろう?疑問は尽きなかったが、追究するほどの知識は持っていなかった。
トランジスタと言えば、いまでもあの黒い半円が頭に浮かぶ。片面が平らで、そこに型番が刻んである。足は 3 本、下へまっすぐ伸びている。
当時は意識していなかったが、3 本の足にはそれぞれ名前がある。 Emitter (E)、Collector (C)、Base (B) だ。 B に少しだけ電流を流すと、C から E へ、その何百倍かの電流が流れるというものだ。
今回はラジオを作ったときと同じ、この素朴なトランジスタで論理ゲートを組む。 20 年越しの答え合わせだ。
トランジスタ 2 個で NOR ゲートを作る
現代のコンピュータでもっぱら使われる論理ゲートは NAND だ。 NAND があれば何でもできる。入力の 2 本を同じ線に繋げば NOT になり、その NOT を出口に足せば AND、入口の 2 本に足せば OR になる。 1 種類だけで全部のゲートを作れるものを万能ゲートと呼ぶ。
今回は、NAND ではなく、NOR で組もうと思う。 NOR も万能ゲートなので、この 1 種類で足りる。 NAND をトランジスタで組むと、出力と GND の間にトランジスタを直列に並べることになり、並べるほど ON にするのに要る電圧が上がっていく。 NOR なら並列に並べるだけで済み、1960 年代に活躍したアポロ誘導コンピュータも 3 入力 NOR 1 種類で組まれていた。消費電力が NAND より高いのが難点だが、今回の規模なら問題にならないだろう。
ここから 0 と 1 は電圧になる。電源に近い高い電圧が 1 で、GND に近い低い電圧が 0 だ。電源側へ繋ぐのを吊る、GND 側へ繋ぐのを落とすと言う。
組み方はこうなる。電源から 1 kΩ で出力を吊る。トランジスタ 2 個の Collector を出力に並べて繋ぎ、Emitter は両方とも GND へ落とす。それぞれの Base に 10 kΩ を入れて、その手前が入力の A と B になる。
A も B も 0 なら、トランジスタは 2 個とも OFF のままで、出力は 1 kΩ で電源に吊られて 1 になる。どちらか一方でも 1 になれば、そのトランジスタが ON になって出力を GND へ引き落とす。 NOR の真理値表をそのまま出すことができた。
トランジスタ 1 個の NOT
前述の NOR ゲートの入力を 1 本にすると、そのまま NOT になる。トランジスタ 1 個と抵抗 2 本だ。
NOR の真理値表から、B の列を消しただけとも言える。
NOR ゲートと NOT ゲートのみで D Latch を組む
今回、トランジスタで作るのは NOR ゲートと NOT ゲートだけなので、論理回路図のほうを NOR に寄せる必要がある。 AND はド・モルガンの法則を使って、2 つの入力をそれぞれ反転させて NOR に入れれば作れる。
これで D Latch の入口を書き換えると、ゲートが 1 つ増える。 AND で描いていたときは、NOT 1 つと AND 2 つで計 3 個だった。書き換えると Enable を反転させる NOT も必要になり、計 4 個になる。
これで、全部のゲートをトランジスタに落とし込めるようになった。
各モジュールに必要なトランジスタと抵抗の数は以下の通り。
| ゲート数 | トランジスタ数 | 抵抗数 | |
|---|---|---|---|
| NOT | - | 1 | 2 |
| NOR | - | 2 | 3 |
| SR Latch | NOR 2 | 4 | 6 |
| D Latch | SR Latch + NOT 2 + NOR 2 | 10 | 16 |
| D Flip-Flop | D Latch 2 + NOT 1 | 21 | 34 |
1 ビットを覚えるのに、トランジスタ 21 個と抵抗 34 本。
買い物リストができた。
アキバに買い出しに行く
シルバーウィークの開始に合わせて、秋月電子の秋葉原店に行った。店内は老若男女でごった返していた。
さて、以下を調達した。まずは回路部品。
| 品目 | 数量 | 金額 |
|---|---|---|
| NPN トランジスタ 2SC1815L-GR-T92 | 100 個 | 500 円 |
| カーボン抵抗 1/4 W 10 kΩ | 100 本 | 100 円 |
| カーボン抵抗 1/4 W 1 kΩ | 100 本 | 100 円 |
| カーボン抵抗 1/4 W 330 Ω | 100 本 | 200 円 |
| 3 mm 砲弾型赤 LED | 10 個 | 100 円 |
| タクトスイッチ 4P (赤・青) | 2 個 | 30 円 |
| 電池ボックス 単 3 × 3 本 | 1 個 | 160 円 |
| 単 3 アルカリ乾電池 | 4 本 | 160 円 |
合わせて 1,350 円。トランジスタは 1 個 5 円である。この値段の部品を 21 個並べて、1 ビットを覚えさせることになる。
写真には細ピンヘッダや積層セラミックコンデンサなど、上記に挙げなかった部品もいくつか写っている。セラコンは電源のパスコンに要るかもしれないと思い、一応買っておいた。ボタンを押す速さで動く回路に、パスコンの出番は無い。
出力を光らせる LED は赤しか買っていない。緑は元から持っていたものを使った。
高かったのは工具と消耗品のほうだ。
| 品目 | 数量 | 金額 |
|---|---|---|
| ブレッドボード 830 穴 + ジャンパワイヤセット | 2 枚 | 2,560 円 |
| 耐熱ビニル電線 0.65 mm 単線 10 色 × 2 m | 1 組 | 750 円 |
| ワイヤーストリッパー ENGINEER PA-07 | 1 本 | 2,950 円 |
| デジタルマルチメータ DER EE DE-200A | 1 台 | 3,280 円 |
こちらで 9,540 円。部品代の 7 倍以上を、部品を挿す道具と測る道具に払ったことになる。まあ長期の趣味と考えれば妥当だろう。
締めて 10,890 円也。
ブレッドボードに挿していく
D Flip-Flop を組むに当たって、電子回路図の上では 21 個のトランジスタと 34 本の抵抗を並べるだけの簡単な作業のはずだった。だけれども、論理回路と電子回路を頭の中で行き来し続けるのは思いの外思考の負荷が高かった。
ただ、配置を考えるのは楽しかった。ブレッドボードは縦 5 穴が 1 本に繋がっているので、その並びに合わせてゲートを寝かせると行を詰められる。どう置けば余りが出ないかを探すのは、パズルに近い。
できあがったのがこれだ。
想定外の難所を 3 つ紹介する。
難所その 1: D Latch 1 つで、830 穴のブレッドボードが 1 枚埋まった
論理回路図上では、D Latch はシンプルに見える。 NOT ゲート 2 つと、NOR ゲート 4 つだけだ。
実物は違った。 D Latch 1 つで 830 穴が埋まる。 D Flip-Flop には D Latch が 2 つ要るので、予備のつもりで買った 2 枚目まで使うことになった。
けれど、これこそが味わいたかった感覚だ。集積回路の登場がいかにエポックメイキングだったかを、肌で感じられる。
難所その 2: 配線をリファクタするたびに動かなくなる
手で回路図を書いてから挿しても、並べ方を考えないとジャンパがどんどん交差していく。見かねて配線をリファクタしたら、動かなくなった。
どこかで挿し間違えたのだろうが、物理なので当然 Undo は効かない。キャンバスに絵を描く絵師の気持ちがよくわかる。
小 1 時間かけて見つけたバグの原因は、1 枚目と 2 枚目をつなぐ電源の線を、4.5 V と GND で逆に挿していたというものだった。コーディングにも共通するが、こういったときの犯人は大抵しょうもないものだ。
それ以来、区切りごとにブレッドボードの写真を撮るようにした。差分を見る手段は写真しかない。
難所その 3: 電子回路図上のトランジスタ記号と実物の足の順番が違うのはなんなの?
もしかすると電子回路あるあるなのかもしれないが、これが一番まいった。
電子回路図のトランジスタの記号は、真ん中の縦棒が Base で、そこから 2 本が出ている。実物は印字面を手前にして足を下に向けると、左から E、C、B の順に並ぶ。真ん中に来るのは Collector だ。
図を見ながら挿すたびに読み替えることになり、21 個も挿すと嫌になる。途中から、手元の回路図に E、C、B と書き込むようにした。それでも毎回読み替える手間はかかったが、次第に慣れてきた。
ようやく完成した D Flip-Flop が、こちら!
電源を入れて、D を押して、CLK を押す。操作はこれだけだ。
2 枚の板にはそれぞれ緑と赤の LED が付いていて、緑が点けば 1、赤が点けば 0 を表す。 D Flip-Flop の出力として見るのは、下の板 (Secondary) のほうだ。
D を押すと、Primary の緑だけが点く。 Secondary は赤のまま動かない。
D を押したまま CLK を押すと、その瞬間に Secondary の緑が点く。 D を押したまま CLK を離しても、どちらも動かない。 D を離すと、Primary だけが赤へ戻り、Secondary の緑は残る。
OK、Flip-Flop が 1 ビットを覚えている。
D を離したまま、もう一度 CLK を押す。今度は Secondary が赤に戻る。
OK、正しく動作していそうだ。
まとめ
今回、1 ビットを覚えるのにトランジスタを 21 個必要とした。もしこれが 1 バイトを覚えさせるなら、同じものを 8 つ並べることになる。 21 × 8 で 168 個。ブレッドボードも 2 × 8 で 16 枚になり、その間をジャンパワイヤが交錯することになる。
次回は加算器を実装したいと考えている。ただ、これも同じ 3 本足のトランジスタで組むとなると、ブレッドボード何枚の作業になるだろうか。ちょっと考えたくない。
最初期のマイクロプロセッサ Intel 4004 は約 2,300 個のトランジスタでできているという。マイクロプロセッサのトランジスタ数の果てしなさを身をもって体感したところで、トランジスタで作るのはここまでにしよう。その先はロジック IC を使ってみようと思う。
74HC02 と 74HC74 は 74 シリーズと呼ばれるロジック IC で、型番の下 2 桁が中身を指すらしい。 02 なら 2 入力の NOR が 4 個、74 なら D Flip-Flop が 2 個、どちらも 14 本足のチップ 1 つに収まって 100 円しない。
では、真ん中の HC は何か。 High-speed CMOS の略で、ゲートの組み方を表しているそうだ。組み方には世代がある。今回のように抵抗とトランジスタだけで組むやり方を RTL と呼び、これが一番古い側にあたる。
| 方式 | 何で組むか | 止まっているときの電流 |
|---|---|---|
| RTL | 抵抗とトランジスタ | 0 を出しているゲート 1 個あたり 4.5 mA |
| TTL | トランジスタ (入力段もトランジスタ) | RTL より少ないが、流れ続ける |
| CMOS | N と P のトランジスタの対 | ほとんど流れない |
RTL は、電源から 1 kΩ と石を通って GND まで、道がつながったままになる。出力が 0 のゲートは、その間ずっと電流を捨てている。ボタンに触らず置いているだけで、電池は減っていく。
CMOS は N と P のどちらかが必ず閉じていて、その道ができない。流れるのは切り替わる一瞬だけで、止まっていれば食わないそうだ。ミリアンペアで捨てていたものが、マイクロアンペアの桁になるらしい。
紀元前 25,000 年に飛ばされたとして、1 ビットまでの道は通った。トランジスタで NOR を作り、NOR を 2 個、互いの入力へ繋ぐと記憶になる。ふわっとしていたのは、ちょうどこの区間だった。
今回、学生実験の延長のようなことを久しぶりにやって楽しかった。有意義な長期連休の使い方ができたと思う。次回の加算器はロジック IC を使えるのでだいぶ楽になるはずだ。近いうちに取り組もうと思う。
Footnotes
-
トランジスタそのものを作る難しさは考えないものとする。秋月電子が紀元前 25,000 年にあることにして話を進める。 ↩
-
マイクロプロセッサの記憶部分の中でも、汎用レジスタは Flip-Flop ではなく、古くは DRAM、今は SRAM を使って作られている。 Flip-Flop が使われるのは、状態機械や命令レジスタ、プリフェッチキュー、ALU のフラグのほうだ。ダイを顕微鏡で読み解いている Ken Shirriff の数え上げによれば、Intel 8086 には 237 個入っている。 ↩
-
一般には Master / Slave と呼ぶ。 IEEE が規格でこの語を避けるよう方針を出しており、
gitのデフォルトブランチがmasterからmainに変わったのも同じ流れにある。ただし Flip-Flop ではまだ人口に膾炙しておらず、IEEE Access にも 2024 年に「master-slave flip-flop」を題に含む論文が載っている。 ↩
