Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug]: In Project 5: CPU, the order of the chips matters. #360

Closed
1 of 2 tasks
Arcadonauts opened this issue Jun 10, 2024 · 7 comments · Fixed by #389
Closed
1 of 2 tasks

[bug]: In Project 5: CPU, the order of the chips matters. #360

Arcadonauts opened this issue Jun 10, 2024 · 7 comments · Fixed by #389
Assignees
Labels
bug Something isn't working

Comments

@Arcadonauts
Copy link

Tool

Hardware Simulator

Interface

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

Contact Details

No response

What happened?

If I put the registers above the ALU, I fail the test at time 19. If I put the ALU above the registers, I pass the test.

Additional Comments

This one might actually be an issue with my understanding, not with the Web IDE. If this is desired behavior, and I don't understand how HDL works, then please accept my apologies.

Do you want to try to fix this bug?

  • I want to try to add this feature!

Code of Conduct

  • I agree to follow this project's Code of Conduct
@Arcadonauts Arcadonauts added the bug Something isn't working label Jun 10, 2024
@DavidSouther
Copy link
Collaborator

This looks like a duplicate of #337. Please re-verify with the most recent version (which you should get by refreshing the page), and if it is not fixed, please re-open this issue and include your code that is failing.

@Arcadonauts
Copy link
Author

I refreshed, but maybe there's some sort of cache issue? (Firefox)

If the registers at Point A are moved down to Point C, it passes every test, but as it is here, it fails only at time=19.

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:

         


        PC(
            in = regAOut, reset = reset,
            load = jump, inc = true, out[0..14] = pc
        );  

        // Point A

        Register(
            in = muxAOut, load = loadA, 
            out = regAOut, out[0..14] = addressM
        );

        Register(
            in = aluOut, load = loadD, 
            out = regDOut, out = xValue
        );

        // Point B

        ALU(
            y = yValue, 
            x = xValue,
            zx = instruction[11], // zero the x input?
            nx = instruction[10], // negate the x input?
            zy = instruction[9], // zero the y input?
            ny = instruction[8], // negate the y input?
            f = instruction[7],  // compute (out = x + y) or (out = x & y)?
            no = instruction[6], // negate the out output?
            out = aluOut, // 16-bit output
            out = outM,
            zr = eq,      // if (out == 0) equals 1, else 0
            ng = neg      // if (out < 0)  equals 1, else 0
        );

        // Point C
        


        And(a = canJump, b = isCInstruction, out = jump);
        
        Or8Way(
            in[0] = jumpPos, in[1] = jumpZero, 
            in[2] = jumpNeg, out = canJump
        );

        And(a = instruction[0], b = pos, out = jumpPos);
        And(a = instruction[1], b = eq, out = jumpZero);
        And(a = instruction[2], b = neg, out = jumpNeg);

        And(a = nonNeg, b = nonZero, out = pos);
        Not(in = eq, out = nonZero);
        Not(in = neg, out = nonNeg);

        And(
            a = instruction[3], b = instruction[15], 
            out = writeM
        );

        Mux16(
            a = regAOut, b = inM, 
            sel = instruction[12], out = yValue
        );



        Mux16(
            a = aluOut, b = instruction,
            sel = isAInstruction, out = muxAOut
        );

        And(
            a = isCInstruction, b = instruction[5],
            out = storeA
        );

        Or(
            a = isAInstruction, b = storeA,
            out = loadA,
        );

        And(
            a = isCInstruction, b = instruction[4],
            out = loadD
        );

        Not(in = instruction[15], out = isAInstruction);
        Not(in = isAInstruction, out = isCInstruction);

}```


@netalondon
Copy link
Collaborator

This is indeed not fixed yet, reopening.

@netalondon
Copy link
Collaborator

@DavidSouther maybe I'm missing something but I just don't think that the insertion sort approach is equivalent to a proper topological sort here.

Changing to a topological sort fixes this issue.
(I added that in #381 without pulling in an entire graph class, just using this.insToPart and this.partsToOut if that's any better).

Again, I could be missing something, let me know what you think.

@DavidSouther
Copy link
Collaborator

It seems that I'm the one who's missing something - empirically, your topological sort works and the insertion sort isn't sufficient.

I'll take a closer look at #381- if I can find the difference, I'll be pleased, but we'll go with what you've got that is working.

@DavidSouther
Copy link
Collaborator

It sounds like in #376 we're not sure whether it's the sort or the clock order based on the internal CPU implementation?

@netalondon
Copy link
Collaborator

It sounds like in #376 we're not sure whether it's the sort or the clock order based on the internal CPU implementation?

Looks like a sorting issue after all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
3 participants