がんばるぞ

がんばります

コンピュータシステムの理論と実装 Chap3

www.amazon.co.jp

これの三章です。

三章の概要

この章では順序回路について学び、フリップフロップレジスタ、メモリなどを実装する。

順序回路

順序回路とは時間に依存した回路のこと。
1章、2章で実装した回路は時間に依存しておらず、組み合わせ回路と呼ばれる。

クロック

時間の経過をモデル化したやつ
こいつが各回路に信号(タイムユニット)を送り続けることによって、時間に依存した回路を実装することができる。

フリップフロップ

順序回路の中で最も基本的な回路。
いくつかある種類のうち、本書では D型フリップフロップ(DFF) を採用している。
こいつのおかげで回路の同期的な計算が可能となる

DFF は 1bit の入力とクロック入力という2つの入力と1bitの出力があり、振る舞いとしては一つ前のタイムユニットの入力を出力するだけの回路である
この回路を元にさまざまな記憶素子を実装していく

レジスタ

データを格納したり読み出したりすることができる記憶装置
多ビットを記憶できるレジスタが持つ値はワードと呼ばれる。

メモリ(RAM)

任意の長さのワードを記憶できる装置。
物理的な記憶位置に関係なく、同じ時間で直接値にアクセスできる

カウンタ

タイムユニットが進むごとに任意の整数が加算されていく回路。
任意の整数は 1 が用いられることが多い。

順序回路の実装

2章までに実装した回路と予め用意されているフリップフロップ回路を用いて、レジスタ・メモリ・カウンタなどの順路回路を実装する。

以降は僕が実装したコードが出てくるので、ネタバレされたくない人は読まない方がよいです

1bitレジスタ

in と 制御ビットの load の2つを入力として受け取り、 load が1の場合に保存された値を読み込み、 load が 0 の場合に in の値を書き込めばOK

Mux(a=loop, b=in, sel=load, out=mux);
DFF(in=mux, out=out, out=loop);

16bitレジスタ

1bitレジスタの16bit版。
なので、1bitレジスタを16個並べるだけで良さそうだったのでそうした

Bit(in=in[0], out=out[0], load=load);
...
Bit(in=in[15], out=out[15], load=load);

RAM(8|64|512|4K|16K)

inload に加えて address の3つの入力を受け取り、 address の値によって読み書きするレジスタを選択出来ればOK。

各16bitレジスタの出力を Multiplexor で振り分ければいけそうだったのでそうした。 また、指定されたレジスタ以外に書き込みが発生するとまずいので、 入力の loadDemultiplexor で振り分けてる

以下のコードは RAM8 だけど、それ以外のRAMも同じようなロジックでいける。

DMux8Way(in=load, sel=address, a=load1, b=load2, c=load3, d=load4, e=load5, f=load6, g=load7, h=load8);
Register(in=in, out=out1, load=load1);
Register(in=in, out=out2, load=load2);
Register(in=in, out=out3, load=load3);
Register(in=in, out=out4, load=load4);
Register(in=in, out=out5, load=load5);
Register(in=in, out=out6, load=load6);
Register(in=in, out=out7, load=load7);
Register(in=in, out=out8, load=load8);
Mux8Way16(a=out1, b=out2, c=out3, d=out4, e=out5, f=out6, g=out7, h=out8, sel=address, out=out);

カウンタ

in と制御ビットである inc , load , reset の4つの入力を受け取り、 制御ビットに合わせて動作を変えればOK
inc が 1 の場合は格納されている値をインクリメントし、 load が 1 の場合は格納されている値を in で上書きし、 reset が 1 の場合は格納している値を 0 にする。
値の格納にはレジスタを使う

ALU と同じような実装で良さそうだったのでそうした。

// inc
Inc16(in=loop, out=incremented);
Mux16(a=loop, b=incremented, sel=inc, out=in1);

// load
Mux16(a=in1, b=in, sel=load, out=in2);

// reset
Mux16(a=in2, b[0..15]=false, sel=reset, out=in3);

Register(in=in3, load=true, out=out, out=loop);

感想

うお〜メモリを実装したぞ〜〜