3章 順序回路 (コンピュータシステムの理論と実装)

# はじめに

これは、「コンピュータシステムの理論と実装」(以下「Nand2Tetris」という)の第3章 順序回路のプロジェクトに対するレポートである。

Qiitaでは、画像の利用に制約があるため、論理ゲート図など掲載することは省いている。


# プロジェクトに対するレポート

## 目標
* 1章と2章で作成した論理ゲート等を使い、レジスタを作成すること。

## 材料
* Nand2Tetrisで定義しているHDL言語
* ハードウェアエミュレータ

## 実装

### 1ビットレジスタ
1ビットレジスタは、Nand2Tetrisに記載された図3−1のとおりに作成することである。順序回路の設計で重要なクロックの概念は内包されているDFFを使うことで簡略化されている。

```hdl:Bit.hdl
    // Put your code here:
    Mux(a=w2, b=in, sel=load, out=w1);
    DFF(in=w1, out=w2, out=out);
```

ハードウェアエミュレータを使い、Bit.Tstスクリプトを動作させると、Comparison ended successfullyと表示された。

### レジスタ
1ビットレジスタを16個並べる。

```hdl:Register.hdl
    // Put your code here:
    Bit(in=in[0], load=load, out=out[0]);
    Bit(in=in[1], load=load, out=out[1]);
    Bit(in=in[2], load=load, out=out[2]);
    Bit(in=in[3], load=load, out=out[3]);
    Bit(in=in[4], load=load, out=out[4]);
    Bit(in=in[5], load=load, out=out[5]);
    Bit(in=in[6], load=load, out=out[6]);
    Bit(in=in[7], load=load, out=out[7]);
    Bit(in=in[8], load=load, out=out[8]);
    Bit(in=in[9], load=load, out=out[9]);
    Bit(in=in[10], load=load, out=out[10]);
    Bit(in=in[11], load=load, out=out[11]);
    Bit(in=in[12], load=load, out=out[12]);
    Bit(in=in[13], load=load, out=out[13]);
    Bit(in=in[14], load=load, out=out[14]);
    Bit(in=in[15], load=load, out=out[15]);
```

ハードウェアエミュレータを使い、Register.Tstスクリプトを動作させると、Comparison ended successfullyと表示された。

### レジスタメモリ
レジスタを8個並べる回路である。レジスタの選択にデマルチプレクサを利用する。一般的な汎用レジスタである。

```hdl:RAM8.hdl
    // Put your code here:
    DMux8Way(in=load, sel=address, a=w1, b=w2, c=w3, d=w4, e=w5, f=w6, g=w7, h=w8);
    Register(in=in, load=w1, out=w9);
    Register(in=in, load=w2, out=w10);
    Register(in=in, load=w3, out=w11);
    Register(in=in, load=w4, out=w12);
    Register(in=in, load=w5, out=w13);
    Register(in=in, load=w6, out=w14);
    Register(in=in, load=w7, out=w15);
    Register(in=in, load=w8, out=w16);
    Mux8Way16(a=w9, b=w10, c=w11, d=w12, e=w13, f=w14, g=w15, h=w16, sel=address, out=out);
```

ハードウェアエミュレータを使い、RAM8.Tstスクリプトを動作させると、Comparison ended successfullyと表示された。

```hdl:RAM64.hdl
    // Put your code here:
    DMux8Way(in=load, sel=address[3..5], a=w1, b=w2, c=w3, d=w4, e=w5, f=w6, g=w7, h=w8);
    RAM8(in=in, load=w1, address=address[0..2], out=w9);
    RAM8(in=in, load=w2, address=address[0..2], out=w10);
    RAM8(in=in, load=w3, address=address[0..2], out=w11);
    RAM8(in=in, load=w4, address=address[0..2], out=w12);
    RAM8(in=in, load=w5, address=address[0..2], out=w13);
    RAM8(in=in, load=w6, address=address[0..2], out=w14);
    RAM8(in=in, load=w7, address=address[0..2], out=w15);
    RAM8(in=in, load=w8, address=address[0..2], out=w16);
    Mux8Way16(a=w9, b=w10, c=w11, d=w12, e=w13, f=w14, g=w15, h=w16, sel=address[3..5], out=out);
```

ハードウェアエミュレータを使い、RAM64.Tstスクリプトを動作させると、Comparison ended successfullyと表示された。

### カウンタ
プログラムカウンタもレジスタの一つとして設計する。

```hdl:PC.hdl
    // Put your code here:
    Mux16(a=w4, b=w5, sel=inc, out=w1);  
    Mux16(a=w1, b=in, sel=load, out=w2);
    Mux16(a=w2, b=false, sel=reset, out=w3); 
    Register(in=w3, load=true, out=w4, out=out);
    Inc16(in=w4, out=w5);
```

ハードウェアエミュレータを使い、PC.Tstスクリプトを動作させると、Comparison ended successfullyと表示された。


## 考察
各順序回路をBitから段階的に実装した。NandゲートとDFFの利用個数を以下の表にまとめる。

| 順序回路 | Nandゲート個数 | DFF個数 | 説明 |
|:-:|:-:|:-:|:-:|
| Bit | 4 | 1 |   |
| Register | 64 | 16 | Bit 16個 |
| RAM8 | 575 | 128 | Register 8個　DMux8way(35) Mux9way16(28) |
| RAM64 | 4663 | 1024 | RAM8 8個  DMux8way(35) Mux9way16(28) |
| PC | 528 | 16 | Mux16 3個 Register Inc16 |