てきとうなさいと べぇたばん

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

CPUができた瞬間 ノート上で苦しんでるようス 機械語の仕様をみて苦しんでるようす

CPUを作る

機械語から命令を読み取り、CPUの中にあるALUに計算させたり、計算結果をレジスタに保存させたり、プログラムカウンタへ次の命令のアドレスを指定させる役割を果たす。

長く苦しい道のりだった

CPUというハードウェアは、機械語の内容を読み取れないとうまくいかない。最初はアセンブリ言語を読んで、4章の機械語の仕様と比較したり、2章のALUの仕様を読んで機械語と比較したり…

一番苦悩した場所

一番躓いたのはアドレスの指定部分。プログラムカウンタに対してどのタイミングでアドレスを読みこませるかという部分が最初意味がわからなかった。ALUで出力されたoutMは関係ないし…あれ?となる。

この仕様は、前のA命令を元に指定されたアドレスをAレジスタに保存して、現状のC命令を元にALUの出力が0か、マイナス値かを判断してアドレスをインクリメントさせるか、Aレジスタにある値をアドレスとしてloadするかを選択する。

ALUの出力に、ngとzrがあった意味がわかったよ。ここで使うんだね…

Twitterでのぼくのくるしんでるようすをごらんください

HDL

またしてもまさかりが飛んできそうなHDLだな。

CHIP CPU {

    IN  inM[16],         // M value input  (M = contents of RAM[A])
        instruction[16], // Instruction for execution
        reset;           // Signals whether to re-start the current
                         // program (reset==1) or continue executing
                         // the current program (reset==0).

    OUT outM[16],        // M value output
        writeM,          // Write to M? 
        addressM[15],    // Address in data memory (of M)
        pc[15];          // address of next instruction

    PARTS:
    Mux16(a = instruction, b = aluo, sel = instruction[15], out = dff);
    Not(in = instruction[15], out = aprog);
    And(a = instruction[15], b = instruction[5], out = d1);
    Or(a = aprog, b = d1, out = loada);
    Register(in = dff, load = loada, out = a, out[0..14] = addressM, out[15] = tmp);
    Mux16(a = a, b = inM, sel = instruction[12], out = aandm);
    ALU(x = d, y = aandm, zx = instruction[11], nx = instruction[10], zy = instruction[9], ny = instruction[8], f = instruction[7], no = instruction[6], out = aluo, out = outM, zr = aluzr, ng = alung);

    And(a = instruction[15], b = instruction[4], out = dload);
    Register(in = aluo, load = dload, out = d);

    Not(in = alung, out = tmpnalung);
    Not(in = aluzr, out = naluzr);
    And(a = tmpnalung, b = naluzr, out = nalung);

    And(a = nalung, b = instruction[0], out = plusjmp);
    And(a = aluzr, b = instruction[1], out = zerojmp);
    And(a = alung, b = instruction[2], out = minujmp);
    Or(a = minujmp, b = zerojmp, out = j1);
    Or(a = j1, b = plusjmp, out = jump);

    And(a = instruction[15], b = instruction[3], out = writeM);
    And(a = instruction[15], b = jump, out = pcload);

    PC(in = a, inc = true, load = pcload, reset = reset, out[0..14] = pc, out[15] = pctmp);
}