1.学习要点
(1)系统
系统=计算设备+程序
前三章只是静态的构建计算设备,第四章描述了程序的最底层表达,即机器语言。最后第五章是对前四章的总结,构建了一个完整的动态的计算机系统工作的模型。
(2)计算机工作的要点就在于:程序存储和程序控制。而程序存储即表明计算机中将程序和数据都存放在存储器中,程序控制即是通过译码将机器指令转换为具体的控制信号进行控制。
(2)Hack硬件平台:
16位冯诺依曼机,包括一个CPU,两个独立的内存模块(指令内存和数据内存)和两个内存映像I/O设备(屏幕和键盘)。
(3)CPU——控制和计算
由ALU,寄存器,控制单元组成。
CPU的结构图参考P94页的结构图,图中缺少控制电路部分需要自己设计,控制电路可以分为:指令译码,指令执行,取指令三部分。
设计控制电路需要理解第四章的机器语言的两种指令(A指令和C指令),Hack指令为16位,从低位到高位可以依次编码为Instruction[0]-Instruction[15],根据第四章的内容可知,
Instruction[15]位为指令类型的识别位,即识别是地址指令A(0)还是计算指令C(1)。
若为地址指令,则剩下15位表示地址。
若为计算指令,则In[0]-In[2]表示jump域,In[3]-In[5]表示dest域,In[6]-In[12]表示computer域,联系到具体电路结构可知In[11]-In[6]对应ALU的zx,nx,zy,f,no控制位,而jump域与zr,ng以及PC有关,dest则与寄存器的load位有关。据此可以来设计控制电路,同时控制电路(取指-译码-执行)也是计算机程序控制的核心。
(4)内存和I/O
内存分为数据内存和指令内存。
I/0映像:创建输入输出设备的二进制仿真,使其对于CPU而言,看上去像普通的内存段。
2.代码实现
(1)CPU
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:
//当指令为A指令时,屏蔽0-5,12控制位
And(a=instruction[15],b=instruction[0],out=I0);
And(a=instruction[15],b=instruction[1],out=I1);
And(a=instruction[15],b=instruction[2],out=I2);
And(a=instruction[15],b=instruction[3],out=I3);
And(a=instruction[15],b=instruction[4],out=I4);
And(a=instruction[15],b=instruction[5],out=I5);
And(a=instruction[15],b=instruction[12],out=I12);
Mux16(a=instruction,b=outALU,sel=instruction[15],out=outMux1);
//写入A寄存器由15和5两个控制位决定,分为00,11两种情况
Xor(a=instruction[15],b=I5,out=loadA1);
Not(in=loadA1,out=loadA);
ARegister(in=outMux1,load=loadA,out=outA);
And16(a=outA,b[0..15]=true,out[0..14]=addressM);
DRegister(in=outALU,load=I4,out=outD);
//地址还是数据A/M
Mux16(a=outA,b=inM,sel=I12,out=outAM);
ALU(x=outD,y=outAM,zx=instruction[11],nx=instruction[10],zy=instruction[9],
ny=instruction[8], f=instruction[7], no=instruction[6],
out=outALU,out=outM,zr=zr,ng=ng);
And(a=I3,b=true,out=writeM);
//j1-j3与PC控制跳转
Not(in=zr,out=notzr);
Not(in=ng,out=notng);
And(a=notzr,b=notng,out=out1);
And(a=I0,b=out1,out=j3);
And(a=I1,b=zr,out=j2);
And(a=I2,b=ng,out=j1);
Or(a=j3,b=j2,out=ep);
Or(a=ep,b=j1,out=loadpc1);
And(a=loadpc1,b=instruction[15],out=loadpc);
PC(in=outAM,load=loadpc,reset=reset,inc=true,out[0..14]=pc);
}
(2)memory
CHIP Memory {
IN in[16], load, address[15];
OUT out[16];
PARTS:
Mux(a=load, b=false, sel=address[14], out=rload); //address[14]=0时,RAM的load有效
Mux(a=false, b=load, sel=address[14], out=sload); //address[14]=0时,Screen的load无效
RAM16K(in=in, load=rload, address=address[0..13], out=rout);
Screen(in=in, load=sload, address=address[0..12], out=sout);
Keyboard(out=kout);
Mux16(a=sout, b=kout, sel=address[13], out=hout);
Mux16(a=rout, b=hout, sel=address[14], out=out);
}
(3)computer
CHIP Computer {
IN reset;
PARTS:
CPU(inM=outM0,instruction=outins,reset=reset,writeM=writeM,outM=outM,addressM=addressM,pc=pc);
Memory(in=outM,load=writeM,address=addressM,out=outM0);
ROM32K(address=pc,out=outins);
}