🌊

『動かしてわかるCPUの作り方10講』 第1講~第3講

に公開

この記事について

CPUについて学びたくなり,『動かしてわかるCPUの作り方10講』を読んでみることにした.最終的にはFPGAをつかってCPUを実装する内容であるらしい.類書としては,

  • FPGAではなく電子工作でCPUを作る(『CPUの創りかた』
  • 表題の本と同様にFPGA上でのCPU実装を扱う(『作ろう! CPU ~基礎から理解するコンピューターのしくみ 』
    の二冊があり,すべて購入した.表題の本を選んだ理由は以下の二つである.
  • 電子工作とCPU理解の難しさが同時に来ると負荷が高い.まずはコードで対応できる範囲に集中し,もしやりたくなったら電子工作でのCPU実装に進むこととした
  • 表題の本はパイプラインの並列化など高度な部分にも触れている

この本で学んだ内容を以下の理由で記事にまとめてみようと思う

  • 自分自身の知識の定着としたり,備忘録にする
  • 今後実装を進める人の参考情報になりうる.とくにFPGAまわりについては,デバイスごとの差も大きく,情報をまとめる価値は大きいと考えている

第1講

第1講では導入と本書全体の内容の外観を書いている.内容としては以下のように大学の講義で学んだことが多かった.

  • 計算機の全体像と,とくにその中でのCPUの役割
  • CPU設計の2つの手法:ボトムアップとトップダウン
    • ボトムアップ手法では,命令セットなどのアーキテクチャを決定したうえで,論理回路のようなハードウェア側から設計を進めていく.従来一般的だったらしい
    • トップダウン手法では逆に,ソフトウェア側からCPUの設計に入っていく,本書でもこちらのアプローチがとられている
  • CPUの基本的な構成やアセンブリ言語のまとめ

第2講~第3講

第2講から第3講では,今後FPGAでCPUを実装するにあたって,高級言語でCPUエミュレーターを実装していく.このため,第2講ではまずシンプルに簡略化されたCPUのアーキテクチャを決定する.そして第3講では実際にこのアーキテクチャに基づくエミュレーターを実装していく.

書籍においてはC言語において実装されていたが,Pythonにて再実装してみた.仕事で慣れているのと,単に本のコードを写経するよりは頭を使い記憶に定着するかと思ったためである.加えて,久しぶりに構文解析器を使ってみたくなったのもある.

実装は以下にて公開しているhttps://github.com/so-nakashima/fpga-cpu-implementation/tree/master/cpu_emulator .いくつか実装意図をまとめておこうと思う.

構文解析の実装

上記レポジトリでは構文解析器も実装している.結局機械語に翻訳してしまうため,書籍では省略されている.理由は上述した通り構文解析を久しぶりに触ってみたかったのが大きい.

構文解析のライブラリとしてはLarkを採用した.かつて数理論理学を学んでいた経験があり,EBNF記法を使える方がやりやすかったためである.

最終的には,READMEに記したような表題の本で採用しているアセンブリ言語を解析できるモジュールが実装できている.

CPUエミュレーター

これが最適だったのかわからないが,クラスを導入して見通し良く実装しようとしていた.各クラスの責任範囲は以下である.

class 責任範囲
CPU_Emulator シミュレーションの制御.MachineStateの更新のループや,hlt()が呼ばれた時の終了など.
MachineState 計算機の状態の管理.計算機の状態は,プログラムカウンター,RAM,条件分岐フラグ,機械語が書かれたROMからなる
StateUpdater MachineStateの更新.特に機械語をデコードし,オペレーションに応じた処理を担当する.

実装しての気づき

  • 算術演算でオーバーフローや2の補数などの厄介ごとに気を遣う必要性.書籍ではshort型を使っているため自動的にできていたが,私の実装ではPythonのint型を使っていたため処理を書く必要があった.これらの処理を書くことで,加減算をする際に計算機(ビット表現)上では何が起きているかよく意識できた.講義では聞いたことがあったものの,手を動かしたことで身をもって知れたと思う.
  • コード上でのROMの独立性とハーバードアーキテクチャの類似性.今回のCPUでは,機械語とデータでbit数が異なり,ハードウェアとしても独立している.このようなアーキテクチャはハーバードアーキテクチャと呼ばれる.一方でPythonでの実装を見ると,ROMは更新されず,MachineStateの代わりにStateUpdaterが機械語を保持していても問題ない.逆にこのような実装のほうがすっきりしていたかもしれない.このROMをMachineStateから分離してしまってよいというのは,ハーバードアーキテクチャのデータと命令の分離と似ているし,そこから来ている現象な気がしている
  • bit演算はあまり触ったことがなく,勉強になった
  • かつて構文解析器を触ったのはOCamlだったのでLarkの勉強にもなった

Discussion