0295-Nand-时序逻辑
环境
- 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。

浙公网安备 33010602011771号