How do I set output flags for ALU in "Nand to Tetris" course?
For anyone else interested, the solution the emulator supports is to use multiple outputs Something like:
Mux16( a=preout, b=notpreout, sel=no, out=out,out=preout2,out[15]=ng);
This is how I did the ALU:
CHIP ALU {
IN // 16-bit inputs:
x[16], y[16],
// Control bits:
zx, // Zero the x input
nx, // Negate the x input
zy, // Zero the y input
ny, // Negate the y input
f, // Function code: 1 for add, 0 for and
no; // Negate the out output
OUT // 16-bit output
out[16],
// ALU output flags
zr, // 1 if out=0, 0 otherwise
ng; // 1 if out<0, 0 otherwise
PARTS:
Mux16(a=x, b=false, sel=zx, out=M16x);
Not16(in=M16x, out=Nx);
Mux16(a=M16x, b=Nx, sel=nx, out=M16M16x);
Mux16(a=y, b=false, sel=zy, out=M16y);
Not16(in=M16y, out=Ny);
Mux16(a=M16y, b=Ny, sel=ny, out=M16M16y);
And16(a=M16M16x, b=M16M16y, out=And16);
Add16(a=M16M16x, b=M16M16y, out=Add16);
Mux16(a=And16, b=Add16, sel=f, out=F16);
Not16(in=F16, out=NF16);
Mux16(a=F16, b=NF16, sel=no, out=out, out[15]=ng, out[0..7]=zout1, out[8..15]=zout2);
Or8Way(in=zout1, out=zr1);
Or8Way(in=zout2, out=zr2);
Or(a=zr1, b=zr2, out=zr3);
Not(in=zr3, out=zr);
}
The solution as Pax suggested was to use an intermediate variable as input to another chip, such as Or16Way. Here is the code after I fixed the problem and debugged:
CHIP ALU {
IN // 16-bit inputs:
x[16], y[16],
// Control bits:
zx, // Zero the x input
nx, // Negate the x input
zy, // Zero the y input
ny, // Negate the y input
f, // Function code: 1 for add, 0 for and
no; // Negate the out output
OUT // 16-bit output
out[16],
// ALU output flags
zr, // 1 if out=0, 0 otherwise
ng; // 1 if out<0, 0 otherwise
PARTS:
// Zero the x input
Mux16( a=x, b=false, sel=zx, out=x2 );
// Zero the y input
Mux16( a=y, b=false, sel=zy, out=y2 );
// Negate the x input
Not16( in=x2, out=notx );
Mux16( a=x2, b=notx, sel=nx, out=x3 );
// Negate the y input
Not16( in=y2, out=noty );
Mux16( a=y2, b=noty, sel=ny, out=y3 );
// Perform f
Add16( a=x3, b=y3, out=addout );
And16( a=x3, b=y3, out=andout );
Mux16( a=andout, b=addout, sel=f, out=preout );
// Negate the output
Not16( in=preout, out=notpreout );
Mux16( a=preout, b=notpreout, sel=no, out=preout2 );
// zr flag
Or16Way( in=preout2, out=notzr );
Not( in=notzr, out=zr );
// ng flag
And16( a=preout2, b=true, out[15]=ng );
// Get final output
And16( a=preout2, b=preout2, out=out );
}