コンピュータシステムの理論と実装 CPU
TOP > てきとうにこらむ > ゲーム作りとプログラミング日記 > コンピュータシステムの理論と実装 CPU
CPUを作る
機械語から命令を読み取り、CPUの中にあるALUに計算させたり、計算結果をレジスタに保存させたり、プログラムカウンタへ次の命令のアドレスを指定させる役割を果たす。
長く苦しい道のりだった
CPUというハードウェアは、機械語の内容を読み取れないとうまくいかない。最初はアセンブリ言語を読んで、4章の機械語の仕様と比較したり、2章のALUの仕様を読んで機械語と比較したり…
一番苦悩した場所
一番躓いたのはアドレスの指定部分。プログラムカウンタに対してどのタイミングでアドレスを読みこませるかという部分が最初意味がわからなかった。ALUで出力されたoutMは関係ないし…あれ?となる。
この仕様は、前のA命令を元に指定されたアドレスをAレジスタに保存して、現状のC命令を元にALUの出力が0か、マイナス値かを判断してアドレスをインクリメントさせるか、Aレジスタにある値をアドレスとしてloadするかを選択する。
ALUの出力に、ngとzrがあった意味がわかったよ。ここで使うんだね…
Twitterでのぼくのくるしんでるようすをごらんください
いまCPUつくってるんだけど、機械語を読み直していてつらたん。おっぱいもみたい
— てきめん (@youkidearitai) 2015, 9月 1
ダメダ!機械語とCPUの命令をノートにメモって理解しないとダメだ!!今日はもう終わり!!
— てきめん (@youkidearitai) 2015, 9月 1
昨日のCPUと機械語問題。とりまALUの命令セットとC命令のビット列をみて構築してみる
— てきめん (@youkidearitai) 2015, 9月 2
compニーモニックとALUの命令セットが同じだ。これはありがたい。
— てきめん (@youkidearitai) 2015, 9月 2
ALUのzrとngの使い道がわからなかったが、これはC命令のジャンプで使うのか。
— てきめん (@youkidearitai) 2015, 9月 2
自分で書いたアセンブリをアセンブラで機械語に変換して一行一行読み取る作業をしている。苦しいです。 pic.twitter.com/jzTpg9ase1
— てきめん (@youkidearitai) 2015, 9月 3
CPUのHDLがかけたけど、当たり前のようにこけた
— てきめん (@youkidearitai) 2015, 9月 4
CPUのアドレスジャンプの意味がようやく分かった。jump領域とALUのzrとngを使えばよいのだな
— てきめん (@youkidearitai) September 5, 2015
CPUの進捗は、とりあえずジャンプ命令がひと通り動くようになった。次はAレジスタの操作がうまくいかぬ。
— てきめん (@youkidearitai) September 6, 2015
やった!やったぞ!CPUができた!! #nand2tetris pic.twitter.com/NuBwhtmual
— てきめん (@youkidearitai) 2015, 9月 6
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);
}
一覧
- コンピュータシステムの理論と実装 ブール論理
- コンピュータシステムの理論と実装 ブール論理のつづき
- コンピュータシステムの理論と実装 ALUの実装
- コンピュータシステムの理論と実装 レジスタとメモリとカウンタ
- コンピュータシステムの理論と実装 機械語
- コンピュータシステムの理論と実装 CPU
- コンピュータシステムの理論と実装 コンピュータそのもの
- コンピュータシステムの理論と実装 アセンブラ
- コンピュータシステムの理論と実装 バーチャルマシン#1
- コンピュータシステムの理論と実装 バーチャルマシン#2