4bit CPU の製作

概要


CPUのアーキテクチャを勉強する中で、4bitCPUを汎用ICで自作するといったステキな書籍に出会い、実際に作ってみましたので紹介します。

書籍紹介


タイトル:CPUの創りかた
著者:渡波 郁(となみ かおる)

初版は2003年で結構古いですが、今でもちょくちょく制作している人を見かけます。コンデンサやダイオードの役割やテスターの使い方から説明されているので、電気回路にそこまで詳しくない方でも設計できるような内容になっています。イラスト付きで優しく楽しげに説明されていて読みやすいです。

4bit CPUの概要


作ってから気付きましたが、ちゃんとコンピュータの五大要素で構成されています。(レジスタは演算装置かも)
スライドスイッチで構成されるROMに機械語として8bitで定義された命令を設定し、クロックに同期して処理が実行されます。命令は後述しますが、ADD・MOV・JMP等の簡単なものです。※ALUはただの加算器

なお本書では、この4bit CPUのことを「とりあえず動作するだけの4bitCPU」として「TD4」と呼んでいました。

動作の流れ

  1. 電源投入
  2. クロック発振、リセット解除
  3. プログラムカウンタがカウントアップ
  4. プログラムカウンタが示すROMの命令を読み込む
  5. 命令をデコードし処理を実行
  6. 3.に戻る

命令・デコーダの設計


本書ではプログラム(定義した命令の組み合わせ)で「3分タイマー」を実行例として挙げていますが、時間はプログラムで指定します。どうせなら「3分タイマー」ではなく「可変タイマー」として入力装置から時間を入力できないかと思い、命令およびデコーダを自分で設計してみました。オリジナルな部分入れたいですし。

条件分岐に入力装置の値を使用するために、「ADD A, IN」「ADD B, IN」 を追加します。(参考P.153)
ALUの入力セレクタ回路を変更し、レジスタA/Bに入力装置の値(IN)を加算できるようにします。
(2022/10/26追記:結局、追加した命令は使っていませんでした…)

変更箇所①(ALU入力セレクタ)
74HC153(Quad 2-ch MUX)x2 → 74HC157(Dual 4-ch MUX)x3



変更箇所②(命令)
命令は以下のように定義しました。デコーダの回路が簡単になるようにオペコードを決めます。

命令 デコーダ入力 デコーダ出力
オペコード フラグ データセレクタ レジスタ
OP3 OP2 OP1 OP0 C Flag SEL Reg SEL 0 SEL I LOAD0 LOAD1 LOAD2 LOAD3
ADD A, Im 0 0 0 1 X 0 0 1 0 1 1 1
ADD A, IN 0 0 0 0 X 0 0 0 0 1 1 1
MOV A, B 1 0 1 1 X 1 0 1 0 1 1 1
MOV A, Im 0 1 0 1 X X 1 1 0 1 1 1
IN A 0 1 0 0 X X 1 0 0 1 1 1
ADD B, Im 0 0 1 1 X 1 0 1 1 0 1 1
ADD B, IN 0 0 1 0 X 1 0 0 1 0 1 1
MOV B, A 1 0 0 1 X 0 0 1 1 0 1 1
MOV B, Im 0 1 1 1 X X 1 1 1 0 1 1
IN B 0 1 1 0 X X 1 0 1 0 1 1
OUT B 1 0 1 0 X 1 0 1 1 1 0 1
OUT Im 1 1 0 0 X X 1 1 1 1 0 1
JNC(C=0) 1 1 1 0 0 X 1 1 1 1 1 0
JNC(C=1) 1 1 1 0 1 X 1 1 1 1 1 1
JMP 1 1 1 1 X X 1 1 1 1 1 0

変更箇所③(デコーダ)
オペコードが決まったら、カルノー図を使って論理回路を設計します。
LOAD0はこんな感じ。

LOAD0 = !OP3&OP1 | OP1&!OP0 | OP3&OP2 | OP3&!OP1
LOAD1 = !OP3&!OP1 | OP3&OP2 | OP3&OP1
LOAD2 = !OP3 | OP2&OP1 | !OP2&OP0
LOAD3 = !OP3 | !OP2 | !OP1 | !OP0&C-Flag

あんまり簡単な式にはなりませんでした。
これを回路に落とし込みます。なるべく使用するICが少くなるように考えながら。

LTspiceでシミュレーション


実際に作る前にシミュレーションで動作するか確認しました。74HCシリーズのICを使用する場合は  .libと .asyファイルの追加が必要です。.libはこちらから、.asyはこちらからダウンロードしました。
あと、リセット回路がなぜか異常発振してしまったので、ディレイを設定した電源で代用しました。

ROMに適当なプログラムを入力して実行。 クロックが発振していることと、プログラム通りにレジスタの値が変化していることが確認できました。

回路の実装


いよいよ回路の実装です。実は目指していた姿があって、それがこれです。

電子回路なのに、ちょっとやそっとの衝撃を与えてもびくともしないような、堅牢性ともいうべき機能的な美しさにとても惹かれていました。もともとプリント配線板には美的な要素があると思っていて、例えば高速信号の等長のための引き回しや、ディファレンシャル信号の平行配線などです。
どうせ作るならと、今回は下記のようにいくつかこだわってみました。

  • 配線の強調
    信号の流れがぱっと見でなんとなくわかるように線材を分けました。
    GND:真鍮線、電源:銅線、主要信号:スズメッキ線
  • チップ部品(1608)の使用
    1608部品はユニバーサル基板(2.54mmピッチ)のスルーホール間にちょうどいい大きさ。
  • 電源コネクタにUSB Type-Cを使用
    USB-PD対応(USB-PD端子からも給電可)

最初の作業はダイオード128個の実装。

配置配線は別途検討していたので、地道に作業を進めます。

スズメッキ線の曲げ加工にかなり時間がかかります。。

USB Type-Cコネクタは電源とGNDをとるだけでなく、CCピンも線を出しておきます。5.1 kΩ ± 20%でプルダウンしておけば、PD対応のコネクタからも電源を供給できそうです。(こちらの3.2節を参照)

裏面は0.2mmのポリエステル銅線で配線しました。初めて使いましたが、便利ですね。表面がポリエステル樹脂という絶縁体でコーティングされていて、それが熱で蒸発するのでハンダ付けしたところだけが導通します。予備ハンダはしたほうが作業しやすかったです。ユニバーサル基板無しで実装することもできそう。

すっ飛ばしますが、完成。回路実装の作業時間は50時間ほど。

アクリル板が手元にあったので加工して付けてみました。これも初体験で苦労しました。 ブザーの位置でくり抜きたかったのにずれてる・・・。
アクリル板つければ基板をホコリや衝突から防げますし、透明度高いのでいいですね。

動作確認


全ピンの接続確認を行った後に電源を投入。一部点灯していないLEDがありましたが、無事に動作しました。よかった。

肝心の可変タイマープログラムですが、こんな感じにしました。16個の命令では、可変タイマーとしてきっかり分刻みで動作させることは厳しく、妥協しました。1分は数秒の誤差ですが、時間が増えると誤差も増えていきます。入力値に従いブザーが鳴るまでの時間が変わることを確認できたのでよしとします。

PC命令オペ1オペ2機械語備考
0INA01000000判定用の値として
(16 ー IN)を求め、
レジスタBに保持
1ADDB100110001
2ADDA100010001
3JNC111100001
4MOVAB10110000
5JNP611110110上記の処理が
大体1分になるよう
帳尻合わせ
6ADDA100010001
7JNC511100101
8ADDB100110001
9JNC1111101011経過時間を判定
10OUTIM11001001ブザー鳴らす
LED点灯
11JMP1211111100疑似1分
12JMP1311111101
13ADDA100010001
14JNC1111101011
15JNP811111000

感想


LTspiceでシミュレーションした時点で動作原理についてほぼ理解していましたが、自分の作品として形に残せるので作ってよかったです。映像より実体のほうが影響力は強いと思うので、こういった作品を展示して、CPUや電子工作に興味を持つ人が増えたらいいなあと思いました。
次は面白いものではなく、便利なものを作ろうかな。


コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA