🍣

『動かしてわかるCPUの作り方10講』 第7講~第8講(初期CPU完成)

に公開

前回の記事に引き続いて、『動かしてわかるCPUの作り方10講』で学習した内容をまとめていく。

今回の範囲は第7講から第8講までである。第7章では,VHDLでCPUを実装していく.そして第8項では実際にFPGA上でCPUを動かしていく.このパートでは第3講でのCPUエミュレーターの実装と第6講での簡単な回路のVHDLでの実装とFPGA上での実行の双方が生きてくる.

第7講

第3講で作成したCPUエミュレーターをVHDLに移植していく.コード関係は以下にて公開している.

CPUのステージ構成

本講の内容は,ほとんど第3講の内容の移植であるが,少しだけ異なるところがある.計算・読み込み・書き込みの遅延を考える必要がある点である.プログラム上では意識をする必要はないものの,FPGA上では物理的な回路で計算されるため,必然的に遅延を伴う.このことを考慮せずに計算を進めると,バグの温床となってしまう.

この対策として,CPUの動作を「fetch/decode/execute/writeback」とステージ分割していくことになる.クロックの立ち上がりごとにステージを切り替える.そしてステージの切り替えでは,前ステージの計算が終わっていて利用可能なことを保証する.このようにすることで遅延を伴う状況でも問題なく計算を進めていくことができる.

書籍と実装を変更した部分

今回の実装では何点か書籍と実装を変えた部分がある.その意図について記載しておく.

ステージ分割用のクロック

書籍では大本のクロックを4分割することでfetch/decode/execute/writebackの4ステージに分けている.私の実装では,この信号は生かしつつも,fecthやdecodeなどの各モジュールに大本のクロックも入れるようにしている.これは大本のクロックを入れることで,同期性を保つためである.生成AIにレビューをお願いしていたところ,クロックを変化させると遅延や非同期の問題が起こるといわれたため,このように設計しなおした.

register/ram の独立モジュール化

書籍では簡単のためレジスタなどではreg_iという信号をレジスタの数だけ用意している.私の実装では,さすがにポートの記載が煩雑だなと思ったので,独立したモジュールとして切り出している.読み出しや書き出しはアドレスによって行う.生成AIによると,入出力の配線をO(N)からO(log N)に減らす効果もあるらしい.

リセット信号の同期化

今回のCPUではFPGA評価ボード上でのボタンを押すことでリセットできる機能が実装されている.このボタンはクロックの途中にON/OFFが切り替わるため,「メタステーブル」と呼ばれるよからぬ状況が起こるらしい.

これを防ぐため,2段のFFを挿入するモジュールを入れている.これにより1クロック処理が遅延するものの,安全にリセットができるようになっている.

シミュレーション・テストの記載

モジュールごとにシミュレーションを記載し,またassert文にてテストを書くようにした.これによりかなり見通し良く開発を進められたと思っている.

その他

  • 定数をcomponents/conststants.vhdに分離した
  • リセット時にうまくいかないケースがあったため,ステージやレジスタ・RAMについても初期化するようにしている.
  • 7セグメントディスプレイが4つしかないため,16進数表示で妥協している

第8項

前項で作成したCPU回路をFPGA上で実際に動かしていく.ここは第7講でシミュレーションで確認した上だったので,それほど苦はなかった.

動いてとてもうれしい.
1から10までの和を計算しているところ.16進数表示で問題なく55と計算できている.

これからどうするか

書籍ではここから先ではより高度な機能の実装に触れている.

  • RAMをメモリブロック(?)でちゃんと記憶装置として実装する
  • プログラムをfetchコンポーネントにべた書きではないようにする
  • パイプラインの並列実行

自分としては,書籍にはないが,プログラムをUSB経由で送れるようにする改造は気になっている.

とはいうものの,ここまで作ってくると,より壮大なことをやりたい欲も出てきている.自作OS on 自作CPUだったり,自作コンパイラを自作CPUで動かしたりである.この辺りをやろうとすると,今の命令セットでは十分ではなく,RISC-V準拠なども考えるべきかもしれない.また割り込み処理の実装も必要になるはず.そうするとパイプライン化などは時期尚早かもと思っている.

諸々を考えていくと,いったんここで立ち止まって,どこを目指したいのか考えるべきなきがしている.何をしたいのか目標を定め,その上で必要な機能をこの自作CPUに実装していくのがよいと思っている.

上記を踏まえて,一旦はCPUの学習はここで止め,OSやコンパイラの学習に進もうかと思っている.全体像を把握したうえで,目標設定に移るのがよいのではないかと思っている.特にこの記事の更新もいったんストップとしようと思っている.

Discussion