# Week 5：CPUを作る部品

## 今週のゴール

- 2進数で整数を表し、簡単な加算ができる。
- ALU、マルチプレクサ、レジスタ、PC、RAMの役割を区別できる。
- 組合せ回路と状態保持回路がCPU内でどう協力するか説明できる。
- Nand2Tetrisで加算器とALUの信号を観察する。

## 1. 2進数

各桁が0または1で、右から `2⁰, 2¹, 2²...` の重みを持ちます。

```text
1101₂ = 1×8 + 1×4 + 0×2 + 1×1 = 13₁₀
```

4ビットの符号なし整数なら0～15を表せます。nビットなら `0` から `2ⁿ-1` です。

### 2の補数

多くのCPUは負数を2の補数で表します。4ビットで `-3` を作るには、`3 = 0011` のビットを反転して1を加えます。

```text
0011 → 1100 → 1101
```

4ビット2の補数の範囲は-8～7です。加算回路を正負で共用しやすい利点があります。

## 2. 加算器

半加算器は2ビットを加えます。

```text
Sum   = A XOR B
Carry = A AND B
```

全加算器は前の桁からのCarry-inも加えます。全加算器を並べると多ビット加算器になります。単純なリップルキャリー方式では桁ごとにキャリーが伝わるため、ビット数が増えると遅延が増えます。

## 3. ALU

ALU（Arithmetic Logic Unit）は、制御信号に応じて入力へ演算を行います。

代表的な操作：

- 加算・減算
- AND、OR、XOR、NOT
- 左右シフト
- ゼロか、負かなどの状態判定

ALUは「計算内容を自分で決める」のではありません。命令を解読した制御回路が、どの演算を行うか指示します。

## 4. マルチプレクサ

複数の入力から一つを選ぶ回路です。2入力MUXなら次のように動作します。

| select | output |
|---:|---|
| 0 | A |
| 1 | B |

CPU内では、ALUへ渡す値、次のPC、レジスタへ書き戻す値などを選択します。データの「交差点」に相当します。

## 5. フリップフロップとレジスタ

組合せ回路には過去を覚える能力がありません。フリップフロップはクロックの特定タイミングで入力を取り込み、次の更新まで保持します。

複数ビット分を並べたものがレジスタです。CPUのレジスタは、演算対象、アドレス、途中結果などを保持します。

## 6. プログラムカウンター

PC（Program Counter）は、次に取得する命令のアドレスを保持するレジスタです。

通常は次の命令へ進むため増加します。分岐や関数呼び出しでは、別の値が書き込まれます。

```text
通常：PC ← PC + 命令長
分岐：PC ← 分岐先アドレス
```

## 7. RAM

RAMはアドレスを指定してデータを読み書きする記憶装置です。概念的にはレジスタを大量に並べ、アドレスデコーダーで対象を選びます。

CPU内のレジスタと外部の主記憶は、容量、速度、コストが大きく異なります。第8週で階層として扱います。

## 部品のつながり

```text
命令メモリ ─→ 命令レジスタ ─→ 制御回路
                                  │ 制御信号
レジスタ群 ─→ MUX ─→ ALU ─→ MUX ─→ レジスタ群
                    │
                 データメモリ

PC ─→ 次命令アドレス
```

## 実習

Nand2Tetrisで以下を観察・作成します。

1. Project 2のHalfAdderとFullAdder。
2. Add16へ `000...0011` と `000...0101` を入力する。
3. ALUの制御ビットを変え、加算・AND・ゼロ出力を確認する。
4. Project 3のRegisterで、loadが0のとき値が保持されることを確認する。
5. PCでincrement、load、resetの優先関係を確認する。

## 説明課題

「ALUだけではCPUにならない」理由を、レジスタ、PC、制御回路という語を使って説明してください。

## 小テスト

1. `10110₂`を10進数へ変換せよ。
2. ALUが演算内容を選ぶために受け取るものは何か。
3. MUXの役割を一文で答えよ。
4. PCは何を保持するか。
5. load信号が無効なレジスタは、クロック後に値をどうするか。

[解答](../answers.md#week-5)

