toyintelligence’s diary

コンピュータの基礎を遊んで学ぶ趣味ブログ

フリップフロップ自作

お次はフリップフロップ。これは数を記憶する機械。フリップフロップにも色々あるようだが、一番簡単そうなRS型をチョイス。RとSが入力で、Q(とその反転)が出力。一度Sに1を入力するとQが1になり、Sを0にもどしてもその状態が維持される。Rに1を入力するとQが0になり、Rを0にもどしても維持される。回路図上で手計算したら確かにそうなったが、なんか騙された気がする…

作った回路はこんな感じ。緑LEDがQ、赤LEDがQの反転。緑ケーブルがS、赤ケーブルがR。例によってケーブルを奥につなぐと1、手前につなぐと0。

f:id:toyintelligence:20200413235400p:plain
初期状態。Q=0

f:id:toyintelligence:20200413235437p:plain
Sに1を入れるとQが1になる

f:id:toyintelligence:20200413235506p:plain
すると、Sを0に戻してもQは1のまま

f:id:toyintelligence:20200413235532p:plain
Rに1をいれるとQが0にリセットされる

f:id:toyintelligence:20200413235557p:plain
Rを0に戻してもQは0のまま

フリップフロップは揮発性で電源を落とすと内容が失われると聞いていたが、この回路は電源を落としても内容が保持されたり、電源を抜いてる間にケーブルを抜き差しすると電源を入れたときにその結果が反映されたりして、なんだこれはとなったが、どうもコンデンサに貯められた電気のせいだったようだ。このコンデンサかなりしぶといんですね。

全加算器自作

前回作った半加算器を二個組み合わせて全加算器を作る。全加算器はA、B、Cinの計3つの1bit入力を足し合わせて2bitの値を得て、C、Sの計2つの1bitとして出力する機械。2つの数を足し算するときに、その2進数版のある桁に着目し、その桁の数字A、Bを下の桁からの繰り上がりCin、上の桁への繰り上がりCを勘定に入れて計算するのに使える。文章だとわかりにくいが、筆算のイメージを使うと

f:id:toyintelligence:20200413233749p:plain
足し算における全加算器の役割

な感じ。なので、全加算器を大量に用意してCとCinを繋げば任意の大きさの数の足し算ができるようになる。

作った回路はこんな感じ。緑LEDがS、赤LEDがC。青ケーブルがA、B、黄色ケーブルがCin。ケーブルを最奥につなぐと1、奥のブレッドボードの手前につなぐと0。

f:id:toyintelligence:20200413231749p:plain
0+0+0=00

f:id:toyintelligence:20200413233326p:plain
1+0+0=01

f:id:toyintelligence:20200413233348p:plain
1+0+1=10

f:id:toyintelligence:20200413233410p:plain
1+1+1=11

OK!

ダイオードの極性を間違えてだいぶ詰まってしまった。まだまだ修行が足りない。とにかく、これで足し算が計算できるようになった。

半加算器自作

もうちょっと計算っぽいことをやりたいので、半加算器を作る。半加算器とは1bitの数2つを足し合わせて2bitの出力を得る計算機。例の本に載ってる回路例はAND、OR、NOTゲートを組み合わせたもの(こんなの)だが、うちの文明は万能なるNANDゲートを手にしているので、NANDだけで組みたい。というわけで、自前で設計してNANDゲート7個の半加算器を作った。ちなみに頭の良い人が設計すればNANDゲート5個でできるらしい。

例によってワイヤを手前につなぐと0、奥につなぐと1。赤LEDがsum、緑LEDがcarry。つまり両方消灯で0、赤のみ点灯で1、緑のみ点灯で10。

f:id:toyintelligence:20200407004402j:plain
0+0=0

f:id:toyintelligence:20200407004418j:plain
0+1=1

f:id:toyintelligence:20200407004432j:plain
1+0=1

f:id:toyintelligence:20200407004459j:plain
1+1=10

自分で設計して実装したのがきちんと動いたので大変満足。

次回は全加算器を作る。

NAND回路自作と74HC00

NAND回路ができた。昨日の不具合は電流が足りなくてLEDが光らなかった様子。抵抗を小さくしたらちゃんと動いた。ついでに赤を計算結果表示用、緑を導通確認用にしたら見やすくなった。カタログスペックは同じはずなんだが…なお電圧チェック中にショートさせてしまいLEDが一つお亡くなりになった。今回の工作で初の殉職者。南無。

f:id:toyintelligence:20200405234033j:plain
 \lnot ( 0 \land 0)=1
f:id:toyintelligence:20200405234630j:plain
 \lnot ( 0 \land 1)=1
f:id:toyintelligence:20200405234657j:plain
 \lnot ( 1 \land 1)=0
これでチューリング完全に手が届いた!

というわけでNAND回路を自作できることを確認したので、出来合いのロジックICの使用を解禁。本にあったLEDを光らせる回路を作って動作確認。赤が計算結果表示用。

f:id:toyintelligence:20200405235114j:plain
 \lnot ( 0 \land 0)=1
f:id:toyintelligence:20200405235124j:plain
 \lnot ( 0 \land 1)=1
f:id:toyintelligence:20200405235136j:plain
 \lnot ( 1 \land 1)=0
あれだけ苦労した回路がこんな簡単にできてしまった…と言いたいところだが、キャパシタやGNDを取るための回路のせいでそんなにシンプルではない。キャパシタのおかげで電源を切ったあとにLEDがゆっくり消えていくのがおもしろい。

AND回路とNOT回路の自作

初歩的なパーツが揃ったので本格的に遊びだす。 f:id:toyintelligence:20200404235811j:plain CPUを作るのにパソコンを使うのもおかしいので、紙とペン、そして計算尺(!)を使っていく。まあ計算尺の出番はないと思うけど、雰囲気は大事。パソコンは情報収集と発信にのみ使う。

いきなり74HCとかのブラックボックスなロジックICを使いだすまえに、論理回路を基本的なパーツから自作できることを確認しよう。ダイオードとかトランジスタとかの半導体は中身が見えなくてちょっと気持ち悪いが、使って良いものとする。

まずはダイオードを使ったAND回路から。ワイヤを最奥列につなぐと1、手前につなぐと0。緑LEDが計算結果表示用で、赤LEDは導通確認用。

f:id:toyintelligence:20200405000009j:plain
 0 \land 0 = 0
f:id:toyintelligence:20200405000051j:plain
 0 \land 1 = 0
f:id:toyintelligence:20200405000110j:plain
 1 \land 1 = 1
ちゃんと動いた!各部の電圧も理論通り。

次はトランジスタを使ったNOT回路。エミッタ、コレクタ、ベースは頭ではわかっているつもりだが、基板に配置する段になるととてもややこしい。慣れるまで時間がかかりそうだ。

f:id:toyintelligence:20200405002211j:plain
 \lnot 0=1
f:id:toyintelligence:20200405002242j:plain
 \lnot 1=0
できた!

この2つを組み合わせればNAND回路になるはずなんだが何かがおかしい。無駄に並列になっているはずの箇所を単純化させると動作しなくなる。また明日考えよう。

電位とはポテンシャルである、というのが肌にしみて理解できた。完全に理解したってやつですねw

千里の道も一歩から

材料が届いたのでLEDを光らせてみた。電圧が理論通りの値になってて一安心。最初は抵抗の値が合わなくて「なにこれ壊れてるじゃん」という考えが一瞬頭をよぎってしまったが、自分がテスタのゼロ合わせを忘れてただけだったwあの本に書いてあった「初心者のうちは何かがおかしいときは自分を疑え」というのは金言。

f:id:toyintelligence:20200401225645j:plain

Brainf*ck;

github.com

大昔(何年前か数えてみたら戦慄したので書かない^^;)に作ったPython製のBrainf*ckインタプリタ。通常のBrainf*ckに加えて、メモリ内容を整数として標準出力に吐く命令:と標準入力を整数として読み取る命令;を実装してあるので、数字の入出力がかんたん。

フィボナッチ数列を延々と吐き続けるコード:

python brainfck.py "
>++++[-<+++++++++++>]<>
+:<.>>+:<<.>>
[<[->>>+<<<]>[->+>+<<]>>:
<<<<.>>>>
[-<<+>>]<[-<<+>>]<]
"

その出力:

1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025...