// This file is part of www.nand2tetris.org // and the book "The Elements of Computing Systems" // by Nisan and Schocken, MIT Press. // File name: projects/02/ALU.hdl /** * The ALU (Arithmetic Logic Unit). * Computes one of the following functions: * x+y, x-y, y-x, 0, 1, -1, x, y, -x, -y, !x, !y, * x+1, y+1, x-1, y-1, x&y, x|y on two 16-bit inputs, * according to 6 input bits denoted zx,nx,zy,ny,f,no. * In addition, the ALU computes two 1-bit outputs: * if the ALU output == 0, zr is set to 1; otherwise zr is set to 0; * if the ALU output < 0, ng is set to 1; otherwise ng is set to 0. */ // Implementation: the ALU logic manipulates the x and y inputs // and operates on the resulting values, as follows: // if (zx == 1) set x = 0 // 16-bit constant // if (nx == 1) set x = !x // bitwise not // if (zy == 1) set y = 0 // 16-bit constant // if (ny == 1) set y = !y // bitwise not // if (f == 1) set out = x + y // integer 2's complement addition // if (f == 0) set out = x & y // bitwise and // if (no == 1) set out = !out // bitwise not // if (out == 0) set zr = 1 // if (out < 0) set ng = 1 CHIP ALU { IN x[16], y[16], // 16-bit inputs zx, // zero the x input? nx, // negate the x input? zy, // zero the y input? ny, // negate the y input? f, // compute out = x + y (if 1) or x & y (if 0) no; // negate the out output? OUT out[16], // 16-bit output zr, // 1 if (out == 0), 0 otherwise ng; // 1 if (out < 0), 0 otherwise PARTS: // Put you code here: //zxがtrueのとき全部0にする Not(in=zx, out=nzx); //もっと効率いい書き方あるのかな? And16(a[0..15]=x[0..15], b[0]=nzx, b[1]=nzx, b[2]=nzx, b[3]=nzx, b[4]=nzx, b[5]=nzx, b[6]=nzx, b[7]=nzx, b[8]=nzx, b[9]=nzx, b[10]=nzx, b[11]=nzx, b[12]=nzx, b[13]=nzx, b[14]=nzx, b[15]=nzx, out[0..15]=w1x); //nxがtrueのとき全部反転する Xor16(a[0..15]=w1x, b[0]=nx, b[1]=nx, b[2]=nx, b[3]=nx, b[4]=nx, b[5]=nx, b[6]=nx, b[7]=nx, b[8]=nx, b[9]=nx, b[10]=nx, b[11]=nx, b[12]=nx, b[13]=nx, b[14]=nx, b[15]=nx, out[0..15]=w2x); //zyがtrueのとき全部0にする Not(in=zy, out=nzy); And16(a[0..15]=y[0..15], b[0]=nzy, b[1]=nzy, b[2]=nzy, b[3]=nzy, b[4]=nzy, b[5]=nzy, b[6]=nzy, b[7]=nzy, b[8]=nzy, b[9]=nzy, b[10]=nzy, b[11]=nzy, b[12]=nzy, b[13]=nzy, b[14]=nzy, b[15]=nzy, out[0..15]=w1y); //nyがtrueのとき全部反転する Xor16(a[0..15]=w1y, b[0]=ny, b[1]=ny, b[2]=ny, b[3]=ny, b[4]=ny, b[5]=ny, b[6]=ny, b[7]=ny, b[8]=ny, b[9]=ny, b[10]=ny, b[11]=ny, b[12]=ny, b[13]=ny, b[14]=ny, b[15]=ny, out[0..15]=w2y); //加算 Add16(a[0..15]=w2x, b[0..15]=w2y, out[0..15]=wadd); //ANDビット演算 And16(a[0..15]=w2x, b[0..15]=w2y, out[0..15]=wand); //加算かANDか選ぶ Mux16(a[0..15]=wand, b[0..15]=wadd, sel=f, out[0..15]=wcal); //noがtrueのとき全部反転する Xor16(a[0..15]=wcal, b[0]=no, b[1]=no, b[2]=no, b[3]=no, b[4]=no, b[5]=no, b[6]=no, b[7]=no, b[8]=no, b[9]=no, b[10]=no, b[11]=no, b[12]=no, b[13]=no, b[14]=no, b[15]=no, out[0..15]=wres, out[0..15]=out[0..15], out[15]=ng); // Or16to1(a=wres, out=nzr); Not(in=nzr, out=zr); }