O'REILLY コンピューターシステムの理論と実装【第1章②】

引き続き、Noam Nisan、Shimon Schocken(2015)『コンピューターシステムの理論と実装』O'REILLYの第1章について。


www.oreilly.co.jp


ハードウェア記述言語(HDL: Hardware Description Language)を体験する。環境はMac(OS X)。

ハードウェアシミュレーターは以下よりダウンロード。

www.nand2tetris.org

zipがダウンロードされるので解凍。
解凍したファイル群の構造は以下。

nand2tetris
├── projects
│   ├── 00
│   ├── 01
│   ├── 02
│   ├── 03
│   ├── 04
│   ├── 05
│   ├── 06
│   ├── 07
│   ├── 08
│   ├── 09
│   ├── 10
│   ├── 11
│   ├── 12
│   ├── 13
│   └── demo
└── tools
    ├── Assembler.bat
    ├── Assembler.sh
    ├── CPUEmulator.bat
    ├── CPUEmulator.sh
    ├── HardwareSimulator.bat
    ├── HardwareSimulator.sh
    ├── JackCompiler.bat
    ├── JackCompiler.sh
    ├── OS
    ├── TextComparer.bat
    ├── TextComparer.sh
    ├── VMEmulator.bat
    ├── VMEmulator.sh
    ├── bin
    ├── builtInChips
    └── builtInVMCode


ハードウェアシミュレーターを実行するにはHardwareSimulator.shを実行。

f:id:sota0113:20190113145009p:plain
Hardware Simulator

解凍したファイルの中に、AND,OR,NOT等各回路のHDLが存在する。試しにNAND回路をロードして挙動を確認する。
"File" > "Load Chip"から/.../nand2tetris/builtInChips/Nand.hdlを選択し、"Load Chip"を選択。

f:id:sota0113:20190113145831p:plain

左下のHDLボックスからHDLのコードが確認できる。入力としてa,bの変数、出力としてoutが定義されている。
BUILTIN回路としてNandを実行するように定義されている。BUILTINで定義されている箇所は、builtInChipsディレクトリからJavaのクラス(今回の場合はNand.class)をロードする仕組みになっている。

定義した各変数の入力は"Input pins"ボックスから変更できる。
入力ピンの値を変更後に出力を確認するには、左上">"のアイコンを選択するか、"Run" > "Single Step"を選択する。
(Single Stepとは別に">>"のアイコン又は"Run" > "Run"を実行できる。Single StepはHDLを1度のみ実行するのに対しRunはHDLを繰り返し実行する)


第1章の課題は、Nand回路を最小構成としてAnd,Not,Or,Xor,マルチプレクサを構成する。
HDLファイル作成時、<ファイル名>.hdlのファイル名と、HDLで定義するCHIP名(以下HDL例の中の "CHIP { " )は同値である必要がある。
最小構成のNAND回路を利用するには"PARTS:"を利用する。
記述法等詳細は以下を参照。

https://docs.wixstatic.com/ugd/44046b_bfd91435260748439493a60a8044ade6.pdf


1. And回路の実装

CHIP and-only-nand {
  IN a, b;
  OUT out;
  PARTS:
  Nand(a=a,b=b,out=c);
  Nand(a=c,b=c,out=out);
}

2. Not回路の実装

CHIP not-only-nand {
  IN a, b;
  OUT out;

  PARTS:
  Nand(a=a, b=a, out=out);
}

3. Or回路の実装

CHIP or-only-nand {
  IN a, b;
  OUT out;
  PARTS:
  Nand(a=a, b=a, out=c);
  Nand(a=b, b=b, out=d);
  Nand(a=c, b=d, out=out);
}

4. Xor回路の実装

CHIP xor-only-nand {
  IN a,b;
  OUT out;

  PARTS:
  Nand(a=a,b=a,out=o1); //Not a
  Nand(a=o1,b=b,out=o2); //And not a, b

  Nand(a=b,b=b,out=o3); //Not b
  Nand(a=a,b=o3,out=o4); //And a, not b

  Nand(a=o2,b=o4,out=out); //Shorten Or gate.

}

5. マルチプレクサ回路の実装

CHIP xor-only-nand {
  IN a,b;
  OUT out;

  PARTS:
  Nand(a=a,b=a,out=o1); //Not a
  Nand(a=o1,b=b,out=o2); //And not a, b

  Nand(a=b,b=b,out=o3); //Not b
  Nand(a=a,b=o3,out=o4); //And a, not b

  Nand(a=o2,b=o4,out=out); //Shorten Or gate.

}