环境
- Time 2023-07-07
前言
说明
参考:https://www.nand2tetris.org/
参考:《编码:隐匿在计算机背后的语言》
目标
接上一节,实现 Bit、Register、RAM8、RAM64、RAM512、RAM4K、RAM16K、PC。
Bit
/*** 1-bit register:* If load[t] == 1 then out[t+1] = in[t]*                 else out does not change (out[t+1] = out[t])*/CHIP Bit {IN in, load;OUT out;PARTS:// Put your code here:Mux(a = d, b = in, sel = load, out = o);DFF(in = o, out = out, out = d);
}
Register
/*** 16-bit register:* If load[t] == 1 then out[t+1] = in[t]* else out does not change*/CHIP Register {IN in[16], load;OUT out[16];PARTS:// Put your code here:Bit(in = in[0], load = load, out = out[0]);Bit(in = in[1], load = load, out = out[1]);Bit(in = in[2], load = load, out = out[2]);Bit(in = in[3], load = load, out = out[3]);Bit(in = in[4], load = load, out = out[4]);Bit(in = in[5], load = load, out = out[5]);Bit(in = in[6], load = load, out = out[6]);Bit(in = in[7], load = load, out = out[7]);Bit(in = in[8], load = load, out = out[8]);Bit(in = in[9], load = load, out = out[9]);Bit(in = in[10], load = load, out = out[10]);Bit(in = in[11], load = load, out = out[11]);Bit(in = in[12], load = load, out = out[12]);Bit(in = in[13], load = load, out = out[13]);Bit(in = in[14], load = load, out = out[14]);Bit(in = in[15], load = load, out = out[15]);
}
RAM8
/*** Memory of 8 registers, each 16 bit-wide. Out holds the value* stored at the memory location specified by address. If load==1, then* the in value is loaded into the memory location specified by address* (the loaded value will be emitted to out from the next time step onward).*/CHIP RAM8 {IN in[16], load, address[3];OUT out[16];PARTS:// Put your code here:DMux8Way(in = load, sel = address, a = la, b = lb, c = lc, d = ld,e = le, f = lf, g = lg, h = lh);Register(in = in, load = la, out = oa);Register(in = in, load = lb, out = ob);Register(in = in, load = lc, out = oc);Register(in = in, load = ld, out = od);Register(in = in, load = le, out = oe);Register(in = in, load = lf, out = of);Register(in = in, load = lg, out = og);Register(in = in, load = lh, out = oh);Mux8Way16(a = oa, b = ob, c = oc, d = od, e = oe, f = of, g = og,h = oh, sel = address, out = out);
}
RAM64
/*** Memory of 64 registers, each 16 bit-wide. Out holds the value* stored at the memory location specified by address. If load==1, then* the in value is loaded into the memory location specified by address* (the loaded value will be emitted to out from the next time step onward).*/CHIP RAM64 {IN in[16], load, address[6];OUT out[16];PARTS:// Put your code here:DMux8Way(in = load, sel = address[0..2], a = ra, b = rb, c = rc,d = rd, e = re, f = rf, g = rg, h = rh);RAM8(in = in, load = ra, address = address[3..5], out = oa);RAM8(in = in, load = rb, address = address[3..5], out = ob);RAM8(in = in, load = rc, address = address[3..5], out = oc);RAM8(in = in, load = rd, address = address[3..5], out = od);RAM8(in = in, load = re, address = address[3..5], out = oe);RAM8(in = in, load = rf, address = address[3..5], out = of);RAM8(in = in, load = rg, address = address[3..5], out = og);RAM8(in = in, load = rh, address = address[3..5], out = oh);Mux8Way16(a = oa, b = ob, c = oc, d = od, e = oe, f = of, g = og,h = oh, sel = address[0..2], out = out);
}
RAM512
/*** Memory of 512 registers, each 16 bit-wide. Out holds the value* stored at the memory location specified by address. If load==1, then* the in value is loaded into the memory location specified by address* (the loaded value will be emitted to out from the next time step onward).*/CHIP RAM512 {IN in[16], load, address[9];OUT out[16];PARTS:// Put your code here:DMux8Way(in = load, sel = address[0..2], a = ra, b = rb, c = rc,d = rd, e = re, f = rf, g = rg, h = rh);RAM64(in = in, load = ra, address = address[3..8], out = oa);RAM64(in = in, load = rb, address = address[3..8], out = ob);RAM64(in = in, load = rc, address = address[3..8], out = oc);RAM64(in = in, load = rd, address = address[3..8], out = od);RAM64(in = in, load = re, address = address[3..8], out = oe);RAM64(in = in, load = rf, address = address[3..8], out = of);RAM64(in = in, load = rg, address = address[3..8], out = og);RAM64(in = in, load = rh, address = address[3..8], out = oh);Mux8Way16(a = oa, b = ob, c = oc, d = od, e = oe, f = of, g = og,h = oh, sel = address[0..2], out = out);
}
RAM4K
/*** Memory of 4K registers, each 16 bit-wide. Out holds the value* stored at the memory location specified by address. If load==1, then* the in value is loaded into the memory location specified by address* (the loaded value will be emitted to out from the next time step onward).*/CHIP RAM4K {IN in[16], load, address[12];OUT out[16];PARTS:// Put your code here:DMux8Way(in = load, sel = address[0..2], a = ra, b = rb, c = rc,d = rd, e = re, f = rf, g = rg, h = rh);RAM512(in = in, load = ra, address = address[3..11], out = oa);RAM512(in = in, load = rb, address = address[3..11], out = ob);RAM512(in = in, load = rc, address = address[3..11], out = oc);RAM512(in = in, load = rd, address = address[3..11], out = od);RAM512(in = in, load = re, address = address[3..11], out = oe);RAM512(in = in, load = rf, address = address[3..11], out = of);RAM512(in = in, load = rg, address = address[3..11], out = og);RAM512(in = in, load = rh, address = address[3..11], out = oh);Mux8Way16(a = oa, b = ob, c = oc, d = od, e = oe, f = of, g = og,h = oh, sel = address[0..2], out = out);
}
RAM16K
/*** Memory of 16K registers, each 16 bit-wide. Out holds the value* stored at the memory location specified by address. If load==1, then* the in value is loaded into the memory location specified by address* (the loaded value will be emitted to out from the next time step onward).*/CHIP RAM16K {IN in[16], load, address[14];OUT out[16];PARTS:// Put your code here:DMux4Way(in = load, sel = address[0..1], a = ra, b = rb, c = rc, d = rd);RAM4K(in = in, load = ra, address = address[2..13], out = oa);RAM4K(in = in, load = rb, address = address[2..13], out = ob);RAM4K(in = in, load = rc, address = address[2..13], out = oc);RAM4K(in = in, load = rd, address = address[2..13], out = od);Mux4Way16(a = oa, b = ob, c = oc, d = od, sel = address[0..1], out = out);
}
PC
/*** A 16-bit counter with load and reset control bits.* if      (reset[t] == 1) out[t+1] = 0* else if (load[t] == 1)  out[t+1] = in[t]* else if (inc[t] == 1)   out[t+1] = out[t] + 1  (integer addition)* else                    out[t+1] = out[t]*/CHIP PC {IN in[16],load,inc,reset;OUT out[16];PARTS:// Put your code here:/** 如果inc为1,将之前输出的值加1 */Inc16(in = ao, out = o);Mux16(a = ao, b = o, sel = inc, out = o1);/** 如果load为1,从输入读取地址 */Mux16(a = o1, b = in, sel = load, out = o2);/** 如果reset为1,从直接为0 */Mux16(a = o2, b = false, sel = reset, out = o3);/** 使用寄存器保存之前的值 */Register(in = o3, load = true, out = out, out = ao);
}
总结
通过之前建立起来的逻辑门,实现了算术逻辑单元 ALU。