Open6
コンピュータシステムの理論と実装の読書メモ
ピン留めされたアイテム
はじめに
2021/4からゆっくりと読み進めていく中で感想などを書きます。
基本的にシュミレータ上で動かすため理想的な環境で動いている。実際のPCで起こるクロック周期や遅延などの問題は考えない
参考
Home | nand2tetris
y-meguro/nand2tetris: 「コンピュータシステムの理論と実装」の演習用
「コンピュータシステムの理論と実装」をやりきりました - Qiita
1章 ブール論理
プール式
ブール演算 And、Or、Not の3つが基本。
どのようなブール関数であれ、3 つのブール演算 And、Or、Not を用いて表現できる。
ゲート
- Nand (ナンド)
- Nandからすべてのゲートを作成する
- Xor (エックスオア、排他的論理和)
- 入力が互いに異なる場合に 1 を返し、それ以外は 0
- Mux (マルチプレクサ)
- 選択ビットによって入力された2データビットのうちどちらかを出力
- 多ビットを一度に扱う場合はMux16
- 多入力ビットを使って出力値を分けたい場合はMux4Way16、Mux8Way16
- DMux (デマルチプレクサ)
- ひとつの入力を選択ビットに従い2つの可能な出力のどちらかに振り分ける
- 多選択ビットを使って多出力にしたい場合はDMux4Way、DMux8Way
HDLの実装のコツ
ピン
- 定数を入力するときは「true」か「false」(それぞれ 1 と 0 に対応する)
- 入力ピンの入力数は 1 であるため、ひとつのソースだけから信号を送信される
- 多ビットパスの一部のピンに対応する場合、例えば入力ピンのin[0]からin[7]にvを代入するときは
in[0..7]=v
と記載する- 入力ピン、出力ピンともに定義可能
- 例えば
Foo(in[2..4]=v, in[6..7]=true, out[0..3]=x, out[2..6]=y)
- 出力ピンで内部ピンと回路の出力ピン両方出力することが可能
- 例えば
out=a, out=out
と記載すると内部ピンaと回路の出力ピンout両方出力できる
- 例えば
2章 ブール算術
- 1章の論理ゲートからArithmetic Logical Unit、ALU(算術論理演算器)を作る
- 2進数の加算でコンピュータの多くの命令は実現できる
- 引算は2の補数を使えば加算になる
- 書籍のALUは、Hack と呼ばれる特定のコンピュータプラットフォームだけで使われる専用の回路
- 作るALUは、必要な18種の算術論理演算。「乗算」「除算」「浮動小数点演算」の機能はOS レベルで実装される
3章 順序回路
- 組み合わせ回路
- 時間という概念はモデル化されていない
- 入力値が変われば、その出力値は時間に関係なく直ちに変わる
- 順序回路(sequential circuit)
- 時間が経過してもデータを記憶することのできる記憶素子
- フリップフロップ(flip-flop)
- コンピュータで使われる記憶装置すべてが実装される。
- D 型フリップフロップ(data flip-flop、DFF)
- 「時間に基づく振る舞い」が可能
- ひとつ前の入力値を出力する、つまり out(t) = in(t − 1)
- DFF は「時間遅延」という性質を内在するからである。つまり、DFFによって、時刻 t の出力ではなく、時刻 t − 1 の出力がその回路自身に影響を与える
- レジスタ
- データを“格納”したり、“呼び出し”たりすることができる記憶装置。
- レジスタに新しい値を保持させたいならば、その新しい値を入力 in に入れ、「読み込みビット」である load に 1 を設定すればよい。また、もし内部の値をレジスタに保持させたいならば、load ビットを 0 にすればよい
- メモリ
- レジスタをたくさん積み重ねることで、RAM(RandomAccess Memory)ユニットを構築することができる。
- RAM
- メモリ中のすべてのワード(多ビットのレジスタの持つ値)は物理的に存在する場所に関係なく同じ時間で直接アクセスできなければならない
- 他とは重複しないユニークな番号(0 から n − 1までの間の整数)をアドレス(物理的な意味でのアドレスではない)として割り当て、アドレス値によってレジスタを個別に選択することができる論理ゲートを構築する。
4章
- アセンブリ(assembly)
- バイナリコードで書く代わりに、記号によるコマンドを用いたプログラム
- アセンブラ(assembler)
- アセンブリ(assembly)から機械語であるバイナリへと変換するプログラム
Hack言語仕様
メモリアドレス空間
- 命令メモリ
- CPU は命令メモリに存在するプログラムだけを実行することができる。リードオンリー
- データメモリ
レジスタ - D: データ値だけを保持する
- A: データレジスタとアドレスレジスタの二役を担う。A の中身はデータ値と解釈されたり、データメモリ(または命令メモリ)のアドレスとして解釈されたりする。
- M: Aレジスタのアドレスが参照している値(内部でAレジスタが示すアドレスの値を取得するルール)Memory[A] (メモリ中のアドレスがAの場所) たとえば、「D = Memory[516] - 1」のような操作を行いたい場合、まず Aレジスタに 516 を設定する命令「@516」を実行し、続いて「D=M-1」を行う命令を実行する。つまり、RAMロケーション(M)を含むコマンドを実行する前に、Aレジスタを希望のRAMアドレス(@address)に設定する必要がある
コマンド
- @value
- 特定の値を A レジスタに格納するためのコマンド。value は数値もしくは数値を表すシンボルのどちらかである。たとえば、sum が 17 という値が格納されたメモリ位置を参照しているとすると、@17 と@sum はともに「A ←17」を行う。
https://morimori-kochan.hatenablog.com/entry/2019/01/14/002915 がわかりやすくまとまっていた。