豊原備忘録

意味わからん学生が書き物します

Nand2Tetris完走の感想 ハードウェア編

はじめに

コンピュータアーキテクチャ,および低レイヤー分野の名著『コンピュータシステムの理論と実装』──通称 Nand2Tetrisを一から読んでいって,一章ずつ感想とやったことを記述していく記事である.基本的に,サンプルコードとかを全部丁寧に実装していくつもりだ.完走するのだから.とりあえずハードウェアの部分だけを書く.

www.oreilly.co.jp

実装の感想

github.com
私がどのようにハードウェアコードを実装したかはこのリポジトリの中身を見てほしい.

第一章

ブール代数の話.K専でやった内容と全く一緒だった.抽象化をやりましょうねと強く宣言している.
NANDはプリミティブ...原始的な,基礎的な論理素子で「NAND」EもできるためあらゆるものはNANDで実装できる.
とりあえず基本的な論理回路をNANDで実装してみようという感じだった.
著者オリジナルのHDLと開発環境は最初はなれなかったが,写経していくうちに感覚を肌で覚えた.
ここでめちゃくちゃGitいじりに苦戦する.後々多ビットのものになるとごり押しで解決しないといけなかった.

第二章

ALU──算術論理演算装置の実装をしようという話だった.NAND2TetrisのALUの評価についてはつよつよの低レイヤerの人たちが絶賛していた.

そのALUのアーキテクチャは,最小限の内部パーツだけから構成されてはいるが,それにもかかわらず,非常に多くの機能を持つ.それゆえ,その論理設計は「効率さ」と「簡潔さ」を示す良い手本になるだろう.

著者も自画自賛している.実際,制御ビット6bitのみで基本的な算術論理演算をすべて行えるのは大きい.しかも入力のゼロ化・反転や出力反転,AND演算しかないのに64通りの演算ができてしまうあたりはキショイぐらいには綺麗だった.


ここの実装で詰まったこととして,sub bus of an internal node maybe ...みたいなエラーがALU実装中に発生した.これは多ビット内部ピンでは[0..15]といった表記,つまりbit分割を行うことはできず,論理チップのHDL内で最初に定義された入出力ピンのみで行えるようだ.
参照
github.com

f==1のときにadd演算であることに気づかず設計していた

第三章

順序回路の話.DFFからインクリメンタとかレジスタ,メモリの実装を進めていく.
inとかoutをイタリックで書かないでほしい...
レジスタを実装するのに,inとoutを直接つなげるのは間違った設計だと一喝する文章があって笑いそうになった.ほかにも,ALUがレジスタからの入力を待っている間は「ゴミを出力し続けている」と書いている.言い過ぎだろう.
しかしこれは逆に,回路全体をクロック同期させることができるということ.幾らゴミを出していても,アキュムレータに保存するならその間に正しい入力がALUになされて「製品」がやってくるだろう.
多ビットバスを示すにはバスに斜線を入れるという知見を手に入れた.
メモリの実装の仕方で,レジスタ群をいくつか用意して,アドレスの上位ビットを群選択に,下位ビットを群中の個々のレジスタを選択するのに使うという発想がまず神がかっていた.DMuxとか3-8decoderとかを使えば機能を簡略化できる発想.

PCの実装で,インクリメント機能に多ビットFullAdderを使えばいいことに気づくまで割と時間がかかった.

第四章

一番理解に苦戦した部分.Hackのアセンブリ言語に慣れようという話.アドレッシング法とかもK専でやった.
DレジスタとAレジスタがあって,前者はデータのみ,後者はデータとアドレスをつっこんで,メモリの参照をしたい場合はAレジスタ経由らしい.シンボルラベルを活用しようという感じでもあった.

第五章

実際にHackCPUの実装をする.四章の機械語の仕様と,アーキテクチャ図を見ながら頑張ってコードを書いてく.ビット拡張とか縮小のための回路も実装した.
一回ループがあるというエラーが出たので全部書き直したりもした.

nand2tetris-questions-and-answers-forum.52.s1.nabble.com

nand2tetris-questions-and-answers-forum.52.s1.nabble.com

nand2tetris-questions-and-answers-forum.52.s1.nabble.com

こういうサイトでエラーの原因を調べたりしたので知見を共有.
キーボード入力が反応しないときはScreenモードで,キーボードアイコンを押してみよう.
ビルトイン回路の仕様を良く勧められる.ビルトインというのは,抽象化・ボックス化された回路のこと.つまり,入出力ピンと回路の簡単な仕組みさえ知っていればいいような状態のことを言う.わざわざNANDとかほかの論理素子で実装しなくていいようになっているということである.

ハードウェア実装を通した感想

本を購入してから5章分の実装までかなり時間をかけてしまったが,HDLコードを書いて回路を実装しているときはパズルを解いている感じで楽しかった.そのうえ接続ミスなどバグがなければ正しく動いてくれるのだから,その時の喜びは計り知れない.
NAND2Tetrisは後半からブーストをかけていくが,前半できちっと基礎をやっておくことで後半の高レイヤー部分でも常にハードウェアのことを意識するためだろう,という予想がついた.
丁寧に一個ずつ話を進めていくから手を動かしやすかったし,理解にさほど時間もかからなかった.著者のアーキテクチャの設計があまりにも神過ぎることも肌で感じたようだった.

後半のアセンブラとかVMコンパイラ実装をする話もそのうち書いていく.はず.