Nand2tetris –Project 1

以nand为基础构建其他简单逻辑门

//Elementary logic gates

CHIP And {
    IN a, b;
    OUT out;

    PARTS:
    Nand(a=a, b=b, out=out1);
    Not(in=out1, out=out);

}

CHIP Not {
    IN in;
    OUT out;

    PARTS:
    Nand(a=in, b=in, out=out);

}

CHIP Or {
    IN a, b;
    OUT out;

    PARTS:
    Not(in=a, out=out1);
    Not(in=b, out=out2);
    Nand(a=out1, b=out2, out=out);

}

CHIP Xor {
    IN a, b;
    OUT out;

    PARTS:
    Nand(a=a, b=b, out=out1);
    Or(a=a, b=b, out=out2);
    And(a=out1, b=out2, out=out);

}

CHIP Mux {
    IN a, b, sel;
    OUT out;

    PARTS:
    Not(in=sel, out=nsel);
    And(a=nsel, b=a, out=and1);
    And(a=sel, b=b, out=and2);
    Or(a=and1, b=and2, out=out);

}

CHIP DMux {
    IN in, sel;
    OUT a, b;

    PARTS:
    Not(in=sel, out=nsel);
    And(a=in, b=nsel, out=a);
    And(a=in, b=sel, out=b);
}
    


//16-bit variants

CHIP Not16 {
    IN in[16];
    OUT out[16];

    PARTS:
    Not(in=in[0], out=out[0]);
    Not(in=in[1], out=out[1]);
    Not(in=in[2], out=out[2]);
    Not(in=in[3], out=out[3]);
    Not(in=in[4], out=out[4]);
    Not(in=in[5], out=out[5]);
    Not(in=in[6], out=out[6]);
    Not(in=in[7], out=out[7]);
    Not(in=in[8], out=out[8]);
    Not(in=in[9], out=out[9]);
    Not(in=in[10], out=out[10]);
    Not(in=in[11], out=out[11]);
    Not(in=in[12], out=out[12]);
    Not(in=in[13], out=out[13]);
    Not(in=in[14], out=out[14]);
    Not(in=in[15], out=out[15]);

}

CHIP And16 {
    IN a[16], b[16];
    OUT out[16];

    PARTS:
    And(a=a[0], b=b[0], out=out[0]);
    And(a=a[1], b=b[1], out=out[1]);
    And(a=a[2], b=b[2], out=out[2]);
    And(a=a[3], b=b[3], out=out[3]);
    And(a=a[4], b=b[4], out=out[4]);
    And(a=a[5], b=b[5], out=out[5]);
    And(a=a[6], b=b[6], out=out[6]);
    And(a=a[7], b=b[7], out=out[7]);
    And(a=a[8], b=b[8], out=out[8]);
    And(a=a[9], b=b[9], out=out[9]);
    And(a=a[10], b=b[10], out=out[10]);
    And(a=a[11], b=b[11], out=out[11]);
    And(a=a[12], b=b[12], out=out[12]);
    And(a=a[13], b=b[13], out=out[13]);
    And(a=a[14], b=b[14], out=out[14]);
    And(a=a[15], b=b[15], out=out[15]);

}

CHIP Or16 {
    IN a[16], b[16];
    OUT out[16];

    PARTS:
    Not16(in=a, out=outa);
    Not16(in=b, out=outb);
    And16(a=outa, b=outb, out=out1);
    Not16(in=out1, out=out);

}

CHIP Mux16 {
    IN a[16], b[16], sel;
    OUT out[16];

    PARTS:
    Mux(a=a[0], b=b[0], sel=sel, out=out[0]);
    Mux(a=a[1],b=b[1],sel=sel,out=out[1]);
	Mux(a=a[2],b=b[2],sel=sel,out=out[2]);
	Mux(a=a[3],b=b[3],sel=sel,out=out[3]);
	Mux(a=a[4],b=b[4],sel=sel,out=out[4]);
	Mux(a=a[5],b=b[5],sel=sel,out=out[5]);
	Mux(a=a[6],b=b[6],sel=sel,out=out[6]);
	Mux(a=a[7],b=b[7],sel=sel,out=out[7]);
	Mux(a=a[8],b=b[8],sel=sel,out=out[8]);
	Mux(a=a[9],b=b[9],sel=sel,out=out[9]);
	Mux(a=a[10],b=b[10],sel=sel,out=out[10]);
	Mux(a=a[11],b=b[11],sel=sel,out=out[11]);
	Mux(a=a[12],b=b[12],sel=sel,out=out[12]);
	Mux(a=a[13],b=b[13],sel=sel,out=out[13]);
	Mux(a=a[14],b=b[14],sel=sel,out=out[14]);
	Mux(a=a[15],b=b[15],sel=sel,out=out[15]);

}

//Multi-way variants

CHIP Mux4Way16 {
    IN a[16], b[16], c[16], d[16], sel[2];
    OUT out[16];

    PARTS:
    Mux16(a=a, b=b, sel=sel[0], out=o1);
    Mux16(a=c, b=d, sel=sel[0], out=o2);
    Mux16(a=o1, b=o2, sel=sel[1], out=out);

}

CHIP Mux8Way16 {
    IN a[16], b[16], c[16], d[16],
       e[16], f[16], g[16], h[16],
       sel[3];
    OUT out[16];

    PARTS:
    Mux4Way16(a=a, b=b, c=c, d=d, sel=sel[0..1], out=out1);
    Mux4Way16(a=e, b=f, c=g, d=h, sel=sel[0..1], out=out2);
    Mux16(a=out1, b=out2, sel=sel[2], out=out);

}

CHIP Or8Way {
    IN in[8];
    OUT out;

    PARTS:
    Or(a=in[0], b=in[1], out=out1);
    Or(a=in[2], b=in[3], out=out2);
    Or(a=in[4], b=in[5], out=out3);
    Or(a=in[6], b=in[7], out=out4);
    Or(a=out1, b=out2, out=out5);
    Or(a=out3, b=out4, out=out6);
    Or(a=out5, b=out6, out=out);

}

CHIP DMux4Way {
    IN in, sel[2];
    OUT a, b, c, d;

    PARTS:
    Not(in=sel[0], out=ns0);
    And(a=in, b=sel[0], out=outbd);
    And(a=in, b=ns0, out=outac);
    DMux(in=outbd, sel=sel[1], a=b, b=d);
    DMux(in=outac, sel=sel[1], a=a, b=c);

}

CHIP DMux8Way {
    IN in, sel[3];
    OUT a, b, c, d, e, f, g, h;

    PARTS:
    Not(in=sel[0], out=ns0);
    And(a=in, b=sel[0], out=bdfh);
    And(a=in, b=sel[0], out=aceg);

    DMux4Way(in=bdfh, sel=sel[1..2], a=b, b=d, c=f, d=h);
    DMux4Way(in=aceg, sel=sel[1..2], a=a, b=c, c=e, d=g);

}