nand2tetris / web-ide

A web-based IDE for https://nand2tetris.org
https://nand2tetris.github.io/web-ide
Other
38 stars 11 forks source link

[bug]: Order of ARegister and DRegister definitions matter in Project5/CPU #327

Closed Apitheia closed 3 weeks ago

Apitheia commented 1 month ago

Program

Hardware Simulator

Interface

Website (https://nand2tetris.github.io/web-ide)

Contact Details

No response

What happened?

Moving the DRegister to the bottom of the chip causes a timing issue for commands MD=D-1, AMD=D+A. The ALU outputs the wrong value until the following half clock step.

Moving the ARegister to the same location, but not the Mux16 and Or causes AMD=D+A error.

Moving the Or and Mux causes other errors in output that I haven't investigated.

CHIP CPU {

    IN  inM[16],         // M value input  (M = contents of RAM[A])
        instruction[16], // Instruction for execution
        reset;           // Signals whether to re-start the current
                         // program (reset==1) or continue executing
                         // the current program (reset==0).

    OUT outM[16],        // M value output
        writeM,          // Write to M? 
        addressM[15],    // Address in data memory (of M)
        pc[15];          // address of next instruction

    PARTS:

    Not(in=instruction[15], out=Ainstr);
    Or(a=instruction[15], b=false, out=Cinstr);
    Or(a=instruction[12], b=false, out=a);
    Or(a=instruction[11], b=false, out=c1);
    Or(a=instruction[10], b=false, out=c2);
    Or(a=instruction[9], b=false, out=c3);
    Or(a=instruction[8], b=false, out=c4);
    Or(a=instruction[7], b=false, out=c5);
    Or(a=instruction[6], b=false, out=c6);
    Or(a=instruction[5], b=false, out=d1);
    Or(a=instruction[4], b=false, out=d2);
    Or(a=instruction[3], b=false, out=d3);
    Or(a=instruction[2], b=false, out=j1);
    Or(a=instruction[1], b=false, out=j2);
    Or(a=instruction[0], b=false, out=j3);

    And(a=Cinstr, b=d1, out=writeA);
    And(a=Cinstr, b=d2, out=writeD);    
    And(a=Cinstr, b=d3, out=writeM);

    // move these
    Mux16(a=ALUout, b=instruction, sel=Ainstr, out=Ain);
    Or(a=writeA, b=Ainstr, out=loadA);
    ARegister(in=Ain, load=loadA, out=Aout, out[0..14]=addressM);
    DRegister(in=ALUout, load=writeD, out=Dout);
    //

    Mux16(a=Aout, b=inM, sel=a, out=y);
    ALU(x=Dout, y=y,
        zx=c1,
        nx=c2,
        zy=c3,
        ny=c4,
        f=c5,
        no=c6,
        out=ALUout, out=outM,
        zr=zr, ng=ng);

    // (j1 & ng) | (j2 & zr) | (j3 & !(zr | ng))
    And(a=j1, b=ng, out=jlt);
    And(a=j2, b=zr, out=jeq);
    Or(a=jlt, b=jeq, out=jle);

    Or(a=zr, b=ng, out=leq);
    Not(in=leq, out=gt);
    And(a=j3, b=gt, out=jgt);
    Or(a=jle, b=jgt, out=J);

    And(a=Cinstr, b=J, out=loadPC);
    Not(in=loadPC, out=incPC);
    PC(in=Aout, load=loadPC, inc=incPC, reset=reset, out[0..14]=pc);

    //ARegister(in=Ain, load=loadA, out=Aout, out[0..14]=addressM); // AMD=D+A error

    //DRegister(in=ALUout, load=writeD, out=Dout); // MD=D-1, AMD=D+A error

    // move both of these causes other errors
    //Mux16(a=ALUout, b=instruction, sel=Ainstr, out=Ain);
    //Or(a=writeA, b=Ainstr, out=loadA);
}

image

Additional Comments

No response

Do you want to try to fix this bug?

Code of Conduct