「CPUの創りかた」の4bitCPUをブレッドボードで作りました

[CPUの創りかた | 渡波 郁](https://amzn.to/31iMqeQ) を読んで、中で紹介されている 4bitCPU をブレッドボードで作ってみました。けっこう時間がかかったのですが、面白かったのでメモを残しておきます。
※ 間違いのないように記載したつもりですが、どこかに間違いがあるかもしれません。作る際は、自己責任で確認しながら作っていただければと思います。

# 本の紹介

[CPUの創りかた | 渡波 郁](https://amzn.to/31iMqeQ) はタイトルの通り、CPU の自作がテーマとなっている本です。「TD4（とりあえず動作するだけの 4bitCPU）」の作成を通じて、基本的な CPU の動作原理がわかりやすく紹介されています。実際にこの TD4 を作られている読者の方も多く、検索するとたくさんの方の記事が見つかります。
手を動かしながら学びたいという方にはおすすめの一冊です。

<img width="300" alt="IMG_0719.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402795/8eff0418-7efd-b396-a586-a5c158d9ee8a.jpeg">

# 作り終わって

進め方を載せる前に、作ったものや、読む前からの変化を記載します。

## 作ったもの

ブレッドボードで 4bitCPU を作ることができました。
そして結構ごちゃごちゃになってしまいました。でも思った通りに動かすことができて、また作りきることができて良かったです。（PC = プログラムカウンタです）
<img width="600" alt="cpu.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402795/8569acc1-f511-a7b2-418a-ccb9d77bdb6a.jpeg">
<img width="600" alt="cpu2.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402795/c3d06d4e-7192-aed3-5a75-96515cc2ed5b.png">

また ROM の部分は Arduino Uno で代替しましたが、使用したコードは以下のフォルダにアップしています。
[Arduino/td4_rom at master · y-meguro/Arduino](https://github.com/y-meguro/Arduino/tree/master/td4_rom)

## 使用した部品（購入した部品）

LED や IC などは壊す可能性もあるので、不安な方は多めに買っておいてもいいかもしれません。
※ ROM の部分は Arduino Uno で代用しているため、本と異なります（74HC154 などは使っていません）
※ 電源も結局 Arduino Uno から取ったため不要でしたが、一応記載しています

| 名前                                                                                       | 個数 | メモ                                   |
|--------------------------------------------------------------------------------------------|------|----------------------------------------|
| [74HC74(Dフリップフロップ)](http://akizukidenshi.com/catalog/g/gI-08597/)                   | 1    | 回路数: 1                              |
| [74HC161(レジスタ)](https://www.kashinoki.shop/?pid=122479142)                             | 4    | 回路数: 4                              |
| [74HC153(4chマルチプレクサ)](http://akizukidenshi.com/catalog/g/gI-10924/)                  | 2    | 回路数: 2                              |
| [74HC32(2入力OR)](http://akizukidenshi.com/catalog/g/gI-12877/)                            | 1    | 回路数: 4                              |
| [74HC10(3入力NAND)](https://www.kashinoki.shop/?pid=122479082)                             | 1    | 回路数: 3                              |
| [74HC14(シュミットトリガ)](http://akizukidenshi.com/catalog/g/gI-10923/)                    | 1    | 回路数: 5                              |
| [74HC283(4ビット全加算器)](https://www.kashinoki.shop/?pid=122479187)                       | 1    | 回路数: 1                              |
| [0.1μF(セラミックコンデンサ)](http://akizukidenshi.com/catalog/g/gP-11154/)                | 11   |                                        |
| [10μF(無極性電解コンデンサ)](http://akizukidenshi.com/catalog/g/gP-04624/)                 | 1    |                                        |
| [10μF(有極性電解コンデンサ)](http://akizukidenshi.com/catalog/g/gP-10590/)                 | 2    |                                        |
| [100μF(有極性電解コンデンサ)](http://akizukidenshi.com/catalog/g/gP-05002/)                | 1    |                                        |
| [DIPスイッチ4P](http://akizukidenshi.com/catalog/g/gP-00586/)                              | 1    |                                        |
| [100Ω](http://akizukidenshi.com/catalog/g/gR-25101/)                                       | 1    | 100本単位で購入                        |
| [1KΩ](http://akizukidenshi.com/catalog/g/gR-25102/)                                        | 1    | 100本単位で購入                        |
| [3.3KΩ](http://akizukidenshi.com/catalog/g/gR-25332/)                                      | 1    | 100本単位で購入                        |
| [10KΩ](http://akizukidenshi.com/catalog/g/gR-25103/)                                       | 1    | 100本単位で購入                        |
| [33KΩ](http://akizukidenshi.com/catalog/g/gR-25333/)                                       | 1    | 100本単位で購入                        |
| [100KΩ](http://akizukidenshi.com/catalog/g/gR-25104/)                                      | 1    | 100本単位で購入                        |
| [LED赤](http://akizukidenshi.com/catalog/g/gI-11577/)                                      | 8    | 壊す可能性やテストで使用する可能性あり |
| [LED青](http://akizukidenshi.com/catalog/g/gI-11578/)                                      | 4    | 壊す可能性やテストで使用する可能性あり |
| [LED黄緑](http://akizukidenshi.com/catalog/g/gI-11637/)                                    | 1    | 壊す可能性やテストで使用する可能性あり |
| [タクトスイッチ](http://akizukidenshi.com/catalog/g/gP-03652/)                             | 2    |                                        |
| [トグルスイッチ](http://akizukidenshi.com/catalog/g/gP-02399/)                             | 1    |                                        |
| [電源](http://akizukidenshi.com/catalog/g/gM-00029/)                                       | 1    | Arduino から電源とったので不要だった   |
| [ブレッドボード用ＤＣジャックＤＩＰ化キット](http://akizukidenshi.com/catalog/g/gK-05148/) | 1    | Arduino から電源とったので不要だった   |
| [電池ボックス](http://akizukidenshi.com/catalog/g/gP-00327/)                               | 1    | テスト時に使用                         |
| [ブレッドボード用ジャンパーワイヤ](http://akizukidenshi.com/catalog/g/gC-05159/)           | 2    | 長いもの                               |
| [ブレッドボード用ジャンパーワイヤ](https://amzn.to/324BId3)                                | 2    | 短いもの                               |
| [Arduino Uno](https://amzn.to/341wW0A)                                                     | 1    |                                        |
| [ブレッドボード短](http://akizukidenshi.com/catalog/g/gP-05294/)                           | 4    |                                        |
| [ブレッドボード長](https://amzn.to/2VSzT0q)                                                | 1    | 3個入りを1つ購入                       |
| [ペンチ](https://amzn.to/2q2he6t)                                                          | 1    |                                        |
| [ニッパー](https://amzn.to/31c97B7)                                                        | 1    |                                        |
| [ワイヤーストリッパー](https://amzn.to/2oz9ubT)                                            | 1    | アースコードを剥くために使用           |
| [ESDマット](https://amzn.to/33nCL8c)                                                       | 1    |                                        |
| [アースコード](https://amzn.to/35ozmYy)                                                    | 1    |                                        |
| [アースターミナル付変換アダプタ](https://amzn.to/31boidY)                                  | 1    |                                        |
| [アース線](https://amzn.to/2B6OsUJ)                                                        | 1    |                                        |
| [ピン揃え](https://amzn.to/2M926wJ)                                                        | 1    |                                        |
| [ＤＩＰ－ＩＣ引き抜き工具](http://akizukidenshi.com/catalog/g/gT-13303/)                   | 1    |            


## 方針

- 見ての通り、はんだ付けはせず、ブレッドボードで作っています
- また ROM の部分は [Arduino Uno](https://amzn.to/341wW0A) で代替しています
- 本当ははんだ付けもやりたかったし、ROM も作りたかったのですが、時間の関係で断念しちゃいました

## 本を読む前からの変化

- この本に取り組む前に [コンピュータシステムの理論と実装](https://amzn.to/2B73AS5) をやって、HDL で CPU を実装していたが、物理的にも作成してみることで、より一層イメージを掴むことができた
    - 「コンピュータシステムの理論と実装」については [「コンピュータシステムの理論と実装」をやりきりました - Qiita](https://qiita.com/y-meguro/items/dc11c31cc2667aa20b3c) の記事を書きました
- LED の使い方、IC の使い方、電圧の H と L がどのように 0 と 1 に変換されるか、といったことを理解できた
- 各部品（レジスタ・ALU・ROM など）をどのように組み合わせて、CPU として動作させているか、イメージが明確になった
- 電子工作は未経験だったが、部品の買い方にはじまり、ブレッドボードの仕組み、Arduino Uno の仕組みといった、電子工作の基本中の基本も理解することができた
- 作成中、うまくいかないこともたくさんあったので、その中でどのように原因を特定していくか、またどのようなミスを犯しやすいか、理解することができた
- 細かい読書メモは以下にあげています
    - [CPUの創りかた - y-meguro's reading record](https://y-meguro.gitbook.io/reading-record/how_to_create_cpu)

# 進め方

ここから少し長くなってしまいますが、本を読み終わった後、どのように作成を進めていったか書いてみようと思います。
最初はんだ付けする気満々だったので、無駄が多いですし、知らないことが多すぎて遠回りしながら進めていったのですが、もし同じように苦しみながら進めていく方の参考になれば幸いです。

## Day 1: 理解の浅いまま、まず注文
- 過去にトライされている方のブログを参考に必要な道具を注文
  - [いまさらCPUを創る(1)：パーツリスト - fumiLab](https://fumimaker.hatenablog.com/entry/2019/05/21/232344) を参考にさせていただきました
- そもそもはんだ付けの知識も道具もないことに気づいて、そちらもあわせて注文
  - [電子工作歴15年が推す工具 - fumiLab](https://fumimaker.hatenablog.com/entry/2019/05/30/213134) を参考にさせていただきました
- 基本的に [秋月電子通商](http://akizukidenshi.com/catalog/top.aspx) で注文
- はんだ付けしなきゃいけないと思いこんでいたが、ブレッドボードという選択肢もあることを知る
  - [TD4ブレッドボード版できた！ - marlesanのブログ](http://marlesan.hatenablog.com/entry/2016/08/08/000047) と [CPU の創りかた(TD4)をブレッドボードで作ってみた話 | saino.me](https://saino.me/2019/08/15/post-1102/) を参考にさせていただきました

## Day 2: 道具が届くも、足りていない部品がたくさん。LED も光らない

- すべての道具が届いたので、開封しつつ作成をはじめる。まずはブレッドボードでトライすることに
    - この時はブレッドボードで作成した後、はんだ付けにトライするつもりでした
- ブレッドボードに電源・LED・抵抗をつなげて、疎通確認をするが、一瞬光ったあと、何も反応しなくなる。LED を変えても音沙汰なし。DC ジャックが悪そうだが確認できない

<img width="300" alt="not_lighting.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402795/ba9ca0d9-b70a-5e1c-261c-9e2967f24a4f.jpeg">

- はんだこての使い方、こて台クリーナーの使い方、デジタルマルチメーターの使い方、ブレッドボードの使い方を学ぶ
- 道具が足りなくてできることがなくなったので、再度注文

## Day 3: Arduino を触りはじめる

- 電池につなげば、LED が光ることを確認

<img width="300" alt="lighting_by_dry_cell.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402795/526b02c0-5e6e-46d1-c542-82963e86b9cd.jpeg">

- [みんなのArduino入門](https://amzn.to/2OTON56) を読みながら、Arduino を触りはじめる
    - Arduino を使って、LED を点滅させられるようになった

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">ArduinoでLEDを点滅させる<a href="https://t.co/jHXdOJUluW">https://t.co/jHXdOJUluW</a></p>&mdash; y-meguro (@yohei_meguro) <a href="https://twitter.com/yohei_meguro/status/1187646083343667205?ref_src=twsrc%5Etfw">October 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## Day 4: Arduino で複数 LED を点滅させられるようになる

- [TD4ブレッドボード版できた！ - marlesanのブログ](http://marlesan.hatenablog.com/entry/2016/08/08/000047) さんの記事の ROM の実装（Arduino）を理解する
    - こちらのコードで Day 9 の挙動確認をさせていただきました。ありがとうございました。
- Arduino を使って、複数 LED を点滅させられるようになった

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">Arduinoで複数LEDを点滅させる<a href="https://t.co/wdewOjd9QP">https://t.co/wdewOjd9QP</a></p>&mdash; y-meguro (@yohei_meguro) <a href="https://twitter.com/yohei_meguro/status/1187646206027034624?ref_src=twsrc%5Etfw">October 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

- はんだ付けの基礎知識を学ぶ
    - [eラーニング　(はんだ付けの基礎知識講習） - NPO 日本はんだ付け協会](https://handa-npo.com/elearning) を購入して、やりました

## Day 5: IC の仕組みを理解し、手動クロック回路を作成する

- 改めて DC ジャックをはんだ付けして、今度は光ることを確認

<img width="300" alt="lighing_by_adapter.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402795/9f31204c-6bbc-df2b-7828-95f839f26c52.jpeg">

- 基本的な IC の仕組みを理解する
    - 1 つの IC に複数の回路が入っていること、Vcc に + を GND に - をつないでおく必要があること
- NOT 回路が入っている IC（74HC04）を正しく動かせることを確認。1A を H にすると、1Y が L（LED が光らない）、1A を L にすると、1Y が H（LED が光る）

<img width="300" alt="not_ic1.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402795/2e67409d-3d04-f967-14ed-7a60889c35a1.jpeg">
<img width="300" alt="not_ic2.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402795/51de879e-d393-13bd-3177-8f4ddb1d7523.jpeg">

- 抵抗の色を見て、どれがどの抵抗かわかるようになる
- ショートさせて、2 つの LED と 1 つの IC を壊してしまう
- 手動クロック回路が正しく動くことを確認する（Push SW を押している間だけ H になる）

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">手動クロック回路<a href="https://t.co/gS64zwIqOH">https://t.co/gS64zwIqOH</a></p>&mdash; y-meguro (@yohei_meguro) <a href="https://twitter.com/yohei_meguro/status/1187646361660837889?ref_src=twsrc%5Etfw">October 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## Day 6: リセット回路とクロック回路を作成する

- クロックジェネレータができる。1Hz バージョンと 10Hz バージョン

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">クロックジェネレータ1Hz<a href="https://t.co/kzXI69vMeq">https://t.co/kzXI69vMeq</a></p>&mdash; y-meguro (@yohei_meguro) <a href="https://twitter.com/yohei_meguro/status/1187646667530502144?ref_src=twsrc%5Etfw">October 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">クロックジェネレータ10Hz<a href="https://t.co/Xz3X4qUWK6">https://t.co/Xz3X4qUWK6</a></p>&mdash; y-meguro (@yohei_meguro) <a href="https://twitter.com/yohei_meguro/status/1187646751630512129?ref_src=twsrc%5Etfw">October 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

- リセット回路とクロック回路をあわせて作成する（リセット回路は Push SW を押している間だけ L になる）

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">リセット回路とクロック回路<a href="https://t.co/TRdvWNiVZl">https://t.co/TRdvWNiVZl</a></p>&mdash; y-meguro (@yohei_meguro) <a href="https://twitter.com/yohei_meguro/status/1187646873596616704?ref_src=twsrc%5Etfw">October 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## Day 7: レジスタ / データセレクタ / ALU / 命令デコーダについて再度理解を深める

- レジスタ / データセレクタ / ALU / 命令デコーダの部分に取り組むに当たり、わからない部分が多いことに気づく
- 改めて本を読み直しながら、理解を深める

## Day 8: プログラムカウンタから ROM を介して、命令デコーダまでの挙動が正しいことを確認する

- プログラムカウンタを作成する

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">プログラムカウンタ<a href="https://t.co/lidIqKuMMD">https://t.co/lidIqKuMMD</a></p>&mdash; y-meguro (@yohei_meguro) <a href="https://twitter.com/yohei_meguro/status/1187646986880610304?ref_src=twsrc%5Etfw">October 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

- プログラムカウンタから、ROMのアドレスを指定して、該当のオペレーションコード取ってくるところまで挙動を確認する

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">オペレーションコードの確認<a href="https://t.co/BwluNEJjin">https://t.co/BwluNEJjin</a></p>&mdash; y-meguro (@yohei_meguro) <a href="https://twitter.com/yohei_meguro/status/1187647064961769472?ref_src=twsrc%5Etfw">October 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

- 命令デコーダの挙動が正しいことを確認する

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">命令デコーダの確認<a href="https://t.co/WEjjEfqJrh">https://t.co/WEjjEfqJrh</a></p>&mdash; y-meguro (@yohei_meguro) <a href="https://twitter.com/yohei_meguro/status/1187647137162510336?ref_src=twsrc%5Etfw">October 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## Day 9: レジスタ / データセレクタ / ALU も作って、一通り完成

- レジスタ / データセレクタ / ALU も作って、一通り完成させる
- A レジスタの点滅を B レジスタが 1 クロック遅れで追いかけていく命令で実行するも、想定通りにいかず苦しむ
    - いきなりこのプログラムで実行せず、本のサンプルプログラム 1 に載っている LED ちかちかを実行すれば良かった
- プログラムカウンタの値が安定せずに悩んだが、クロックの挙動確認用にはさんでいた LED を外したら、安定するようになる
- 無事に思った通りの挙動となることを確認した（左下の赤い LED が A レジスタ、青い LED が B レジスタ）

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">Aレジスタの点滅をBレジスタが追う<a href="https://t.co/RkaYV17wfX">https://t.co/RkaYV17wfX</a></p>&mdash; y-meguro (@yohei_meguro) <a href="https://twitter.com/yohei_meguro/status/1187647226589282304?ref_src=twsrc%5Etfw">October 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## Day 10: 完成！

- 全命令が正しく動くことを以下のコードで確認する
    - [Arduino/check_programs_except_jnc.ino at master · y-meguro/Arduino](https://github.com/y-meguro/Arduino/blob/master/td4_rom/check_programs_except_jnc/check_programs_except_jnc.ino)
    - [Arduino/check_jnc.ino at master · y-meguro/Arduino](https://github.com/y-meguro/Arduino/blob/master/td4_rom/check_jnc/check_jnc.ino)
- 本のサンプルプログラムに書いてあった「LED ちかちか」と「ラーメンタイマー」を ROM に書き込み、正しく挙動することを確認する
    - [Arduino/light_leds.ino at master · y-meguro/Arduino](https://github.com/y-meguro/Arduino/blob/master/td4_rom/light_leds/light_leds.ino)
    - [Arduino/3min_timer.ino at master · y-meguro/Arduino](https://github.com/y-meguro/Arduino/blob/master/td4_rom/3min_timer/3min_timer.ino)

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">LEDちかちか<a href="https://t.co/xEb1PUwemP">https://t.co/xEb1PUwemP</a></p>&mdash; y-meguro (@yohei_meguro) <a href="https://twitter.com/yohei_meguro/status/1187647299742138368?ref_src=twsrc%5Etfw">October 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 終わりに
とても時間がかかってしまいましたが（本を読んでいた時間とあわせると約 100 時間かかりました）、なんとか 4bitCPU を作りきることができました。
これまでに IC や スイッチ、LED を組み合わせて回路を作成した経験はなかったので、最初はどこから手を付けていいかわからず、また失敗も多くて、なかなか大変なチャレンジとなりました。しかし、段々と理解が深まり、徐々に自分で問題を切り分けながら進めていく経験ができたのはとても良かったです。
また、レジスタやデータセレクタ、ALU、ROM がどのように繋がっているか、これまで以上に理解が深まったのもいい経験になりました。興味ある方はぜひどうぞ！

# 参考

## 他に取り組まれている方の記事

- [fumiLab](https://fumimaker.hatenablog.com/) さんの以下の記事
    - [電子工作歴15年が推す工具 - fumiLab](https://fumimaker.hatenablog.com/entry/2019/05/30/213134)
    - [いまさらCPUを創る(1)：パーツリスト - fumiLab](https://fumimaker.hatenablog.com/entry/2019/05/21/232344)
- [TD4ブレッドボード版できた！ - marlesanのブログ](http://marlesan.hatenablog.com/entry/2016/08/08/000047)
- [CPU の創りかた(TD4)をブレッドボードで作ってみた話 | saino.me](https://saino.me/2019/08/15/post-1102/)
- [『CPUの創りかた』のTD4をブレッドボードで作った話。 - ようさいラボのブログ](https://yousay0704.hatenablog.com/entry/2018/08/28/122331)
- https://twitter.com/shootingstar418/status/1170609831482257409

## 部品の購入

- [秋月電子通商](http://akizukidenshi.com/catalog/top.aspx)
- [樫木総業（株）](https://www.kashinoki.shop/)

## 器具の使い方

- [eラーニング　(はんだ付けの基礎知識講習） - NPO 日本はんだ付け協会](https://handa-npo.com/elearning)
- [【初心者向け解説】デジタルマルチメータの使い方[テスター/電圧・抵抗測定] - YouTube](https://www.youtube.com/watch?v=Oiyc06vAxoM)
- [【4分で分かる！】ブレッドボードの説明＆使い方！ - YouTube](https://www.youtube.com/watch?v=GxZoFdHVSXs)
- [サンハヤト　ピンそろった - YouTube](https://www.youtube.com/watch?v=YvhyOXjQnrU)