Nand2tetris - CPU 是机器语言的解释器
本文是 nand2tetris 课程的读书笔记,不会列举过多细节,仅精炼出有意思的概念,供日后查阅。
CPU 的目的是解释机器语言。
解释意味着逻辑的 分支。
输入A => 产生行为X
输入B => 产生行为Y
ALU 实现了对基础算术逻辑运算的分支,除此之外,CPU 还需要读写内存和寄存器。
这部分逻辑构成了围绕着 ALU 的外部电路。
既然 CPU 的核心功能是“分支”(更广义的概念,不单指 JMP 这种分支)
那么它的复杂度就是分支的复杂度。
通过硬件的层次化设计,将复杂度拆散到各个中间层。例如:寄存器,ALU
从而化繁为简,从机械进化成思维。
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:
// ALU 计算逻辑
Not(in=instruction[15], out=isAIns);
Mux16(a=instruction, b=aluOut, sel=instruction[15], out=newA);
Or(a=instruction[5], b=isAIns, out=needNewA);
ARegister(in=newA, load=needNewA, out=aValue);
And(a=instruction[4], b=instruction[15], out=needNewD);
DRegister(in=aluOut, load=needNewD, out=dValue);
Mux16(a=aValue, b=inM, sel=instruction[12], out=aluInMA);
ALU(x=dValue, y=aluInMA, zx=instruction[11], nx=instruction[10], zy=instruction[9], ny=instruction[8],
f=instruction[7], no=instruction[6], out=aluOut, zr=aluZr, ng=aluNg);
// 结果更新逻辑
And16(a=aluOut, b=true, out=outM);
And(a=instruction[3], b=instruction[15], out=writeM);
And16(a=aValue, b=true, out[0..14]=addressM);
// 程序计数器(PC)更新逻辑
Not(in=aluZr, out=nonZero);
Not(in=aluNg, out=notNeg);
And(a=nonZero, b=notNeg, out=greater);
And(a=greater, b=instruction[0], out=needJump1);
And(a=aluNg, b=instruction[2], out=needJump2);
And(a=aluZr, b=instruction[1], out=needJump3);
Or(a=needJump1, b=needJump2, out=foo2);
Or(a=foo2, b=needJump3, out=foo3);
And(a=instruction[15], b=foo3, out=needNewPc);
Not(in=needNewPc, out=needIncPc);
PC(in=aValue, load=needNewPc, inc=needIncPc, reset=reset, out[0..14]=pc);
}
CPU 与 Memory 和外围设备连接,就是基本的计算机。