CPUの創りかた
CPU設計の超入門書として良書とという評判だったので、読んでみました。
表紙の絵は、書店で買うにはちょっと恥ずかしい感じですが、内容は至って真面目です。
説明の順序が良くて文章も平易で非常に読みやすかったので3時間程度での読了でした。すんなり内容が入ってきたのは、本書の読みやすさももちろんですが、先にパタヘネ本を読んでCPUの概要を把握していたのも大きかったです。
文章がどれくらい読み易いかは、以下のサンプルページを見てもらうと一目瞭然です。
専門的な内容にも関わらず、いわゆる教科書っぽい堅苦しさは一切有りません。
この本を読む上での前提知識は、2進数、論理式(AND,OR等)が分かるレベルがあれば十分です。回路やプログラムの知識、CPUの仕組みについては、本文中で丁寧に説明してくれているので不要です。
本書の購入理由は、CPU自体を基板上で創りたいというのは目的ではなく、”論理回路の組み合わせでCPUが実装できるか?”の実例が見たかったので、その疑問に答えてくれる丁度良い本でした。この本のおかげで、自分の中での論理回路->CPUのミッシングリンクが幾分解消した気がします。
CPU内部の仕組みについては、パタヘネ本でもある程度踏み込んだ内容が書かれているのですが、この本を追加で読んでおく事で具体的な回路構成がイメージ出来る様になります。ここでいう”具体的な”は、論理回路の組み合わせや、周辺のアナログ回路とのI/Fの等を指しています。
パタヘネ本では省略されていた(そもそもCPU外の話なので、パタヘネ本の対象外なのですが)、外部入力のプルアップやリセット回路なども、仕組みを含めて詳細に説明されています。
余談ですが、書籍の中で作成したCPUであるTD4は非常にシンプルなアーキテクチャなので、アセンブラやシミュレータも簡単に作れそうです。PICのシミュレータ作りがひと段落したら、こっちも作ってみたいところです(というか、PICのシミュレータを中断してこちらを先に作ったほうが速いかも…)。構成のシンプルさのおかげで、ひょっとしたら論理回路レベルのエミュレーションまで作れるかもしれません。
とりあえずメモっておきたかった事を羅列しておきます。
全部読んでからのメモなので、本文の説明順では有りません。
TD4のスペック
4bitマイコン 命令長 : 8bit プログラムメモリ : 16word レジスタ : Aレジスタ、Bレジスタ(共に4bit)の2つ OUT命令だけ、命令に対してレジスタが直交して無い ステータスレジスタ: キャリーフラグ1bitのみ (条件付ジャンプでのみ使用) I/O : 入力,出力ともに1ポート(共に4bit) トランジスタ数 : 推定1500個程度らしい |
CPU構成要素の実装方法
クロックジェネレータ RC発信とシュミットトリガIC(74HC14)で生成 レジスタ 4bitカウンタ(74HC161)のカウンタ機能を殺して、4bitのFFとして使用 ソースレジスタの決定回路 2ビットのセレクタ(74HC163)を使用して、決定している (74HC163は4ビットのセレクタが2個あるので、ICが2つ必要) デスティネーションレジスタの決定回路 レジスタに使った7HC161のLOADピンをAssertにすることで決定している プログラムカウンタ 4bitカウンタ(74HC161)のカウンタ機能を使用 I/O レジスタを1つ殺してI/Oを作る Input は、ALU->レジスタの出力を、外部ピンに変更する。 Outputは、レジスタ->ALUの入力を、外部ピンに変更する。 プログラムメモリ ディップスイッチで代用!! (ROMだとライタが必要になるのを回避するため) プログラムレジスタのアドレス指定 74HC154のデコーダで,制御ユニットの4bit入力から読み出す番地を決定している ALU 4ビットの加算器(74HC283)を使用 ステータスレジスタ(C) ALUで使用している加算器のキャリーピンをFF(74HC74)に保持 命令のデコーダ これが、このCPUで一番複雑なところ 真理値表を書いて、ロジックICでがんばる opcodeを工夫しているので、ORが4個とNANDが3個で実装できる 74HC32,74HC10が各1個 |
命令のフォーマット
全命令共に、上位4bitがオペコードで、下位4bitがデータとなる。対象レジスタを指定するビットは無い(命令毎に対象レジスタが固定になっている)
命令一覧
opcodeをどうやって決めたかは、本文中に説明無し。命令 処理 opcode ---------- -------------------- ------- ADD A, Im A += Im 0000 ADD B, Im B += Im 0101 MOV A, Im A = Im 0011 MOV B, Im B = Im 0111 MOV A, B A = B 0001 MOV B, A B = A 0100 JMP Im pc = Im 1111 JNC Im if(C==0) { pc = Im } 1110 IN A A = InPort 0010 IN B B = InPort 0110 OUT B OutPort = B 1001 OUT Im OutPort = Im 1011 |
CPUのステージ分け(Fetch/Decode/Execute/WriteBack)
ステージ分けはせず、非同期で処理している。レジスタへの書き込みが終わるまでの遅延に対して、クロックが十分低い(1Hz or 10Hz)ので問題が起きないようになっている。
パイプライン処理は、当然行われていない。
その他メモ
CPUにとっては、MOV命令とADD命令は同じもの
ALUがどんな演算をしたかが違うだけ、と捕らえれば分かりやすい。
MOV命令はALUが何もせずに、デスティネーションレジスタに値を格納している。 ADD命令はALUが加算をして、デスティネーションレジスタに値を格納している。 |
前者の”ALUが何もせずに”を”ALUが0を加算して”に読み返ると同じというイメージがさらに伝わりやすいかもしれない。
エッジトリガの作り方
“セレクタとNOT回路*2″を2セット用意して直列につなげば良い。
仮に、直列につないだ2つを前段、後段と呼ぶ事にする。
以下の仕組みで、立ち上がりエッジの情報を保持する事が可能となる
(クロック信号を元にセレクタを切り替える)
クロックがOFFの時: 前段側は、入力データを常に受け取れるようにする、 後段側は、記憶回路の構成にして出力を安定させる。 クロックがONの時: 前段側は、記憶回路の構成にして出力を安定させる。 後段側は、入力データを常に受け取れるようにする。 |
これでクロックがONになった瞬間の入力値を、出力側は安定して出す事が出来る。
今まで、”論理回路の話”と、”クロック信号のエッジトリガによる同期処理”がつながってなかったのでこの説明は有りがたかった。
(書籍では、ちゃんと回路図も明示してもっと分かりやすく説明してくれてます)
というわけで、CPU周りの実装に興味がある人には、絶対にお勧めな一冊です。

CPUの創りかた
コメントを残す