Question regarding PC and ARegister

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Question regarding PC and ARegister

Justin
I have a question regarding the sequence in which the PC loads from the A Register.

Say I have the following program:

@1
A=A+1;JMP

I would expect to jump to instruction 1 since A would not output '2' until the beginning of the next cycle. Basically I assume the PC would use the same value in the A register that was sent to the ALU not the calculated one from the ALU. It seems like it would take another cycle for '2' to reach the PC.

Let me know if my question is unclear.

Thank you
Reply | Threaded
Open this post in threaded view
|

Re: Question regarding PC and ARegister

culchie
Your question is very clear and I am (almost 100%) certain that what you are saying is correct.
Reply | Threaded
Open this post in threaded view
|

Re: Question regarding PC and ARegister

Justin
Thanks for the reply. The problem is that if I load the following lines into the CPU emulator the instruction pointer will jump to '2' instead of '1' after evaluating the second instruction.

I have the following test program:

0 - @1
1 - D=A+1
2 - A=A+1;JGT

When I run the above program in the CPU emulator I get the following instruction order

0,1,2,2,3

but I expect

0,1,2,1,2,3

Is that correct as well?

Thanks
Reply | Threaded
Open this post in threaded view
|

Re: Question regarding PC and ARegister

culchie

I tried a similar program to the one you have shown (I put in a label) to see if that behaved as I thought it should but it didn't.

(Loop)
D=A+1
@Loop
A=A+1;JGT

This loops continuously between the last 2 statements, ie ignoring the D=A+1 statement.
Looks like I was wrong, sorry.
I'd like someone to explain this as well

Reply | Threaded
Open this post in threaded view
|

Re: Question regarding PC and ARegister

cadet1620
Administrator
In reply to this post by Justin
Justin wrote
I have a question regarding the sequence in which the PC loads from the A Register.

Say I have the following program:

@1
A=A+1;JMP
I would expect to jump to instruction 1 since A would not output '2' until the beginning of the next cycle. Basically I assume the PC would use the same value in the A register that was sent to the ALU not the calculated one from the ALU. It seems like it would take another cycle for '2' to reach the PC.

Let me know if my question is unclear.

Thank you

What you expect is correct, and in fact is what happens using the Hardware Simulator with a Computer.hdl built as directed in the book. Here's the output from the Hardware Simulator using the above test program:
|time|  pc   |   instruction    | a-reg | d-reg |alu-out|
| 0  |     0 | 0000000000000001 |     0 |     0 |     0 | @1
| 1  |     1 | 1110110111100111 |     1 |     0 |     2 | A=A+1;JMP
| 2  |     1 | 1110110111100111 |     2 |     0 |     3 | A=A+1;JMP
| 3  |     2 | 0000000000000000 |     3 |     0 |     0 | @0
| 4  |     3 | 0000000000000000 |     0 |     0 |     0 | @0
Exactly as you expected, one can see at time 1 that A is 1, the ALU output is 2 and the PC is loaded with 1 and A is updated for the NEXT instruction to use. (Which is does, jumping to address 2.)

This appears to be a bug in the CPU Emulator. (Turn on data flow animation and you can watch it grab the new PC from the output of the ALU!)

--Mark

Reply | Threaded
Open this post in threaded view
|

Re: Question regarding PC and ARegister

culchie
Thanks for your explanation.
This thread showed me how shaky my understanding of the sequential stuff is.
Reply | Threaded
Open this post in threaded view
|

Re: Question regarding PC and ARegister

cadet1620
Administrator
In reply to this post by Justin
I've been hacking around with Hack, and one of the things I was trying to do was a jump through a pointer in memory. The code for this would be:
    @pointer
    A=M;JMP
where pointer is a RAM variable that contains a code address I want to jump to.

As per the discussion in this topic, this works in the CPU simulator but not in the HW simulator with my CPU. I thought about it a bit, and came up with this fix that makes it work as expected (and as implemented in the CPU simulator).

What we want to happen is to jump to the new value of A if it's being updated, otherwise jump to the stored value of A. This can be done by adding a single mux:

    ARegister(load=a-ld, in=a-in, out=a-reg);
    Mux16(sel=a-ld, a=a-reg, b=a-in, out=jmp-addr);
    PC(in=jmp-addr, reset=reset, inc=true, load=pc-ld, out=pc);  // was in=a-reg
I haven't tried this with my modified CPU yet, but you should be able to test for a null pointer and jump if it's OK in a single instruction.
    @pointer
    A=M;JNZ
    // continue here if pointer is null
Happy Hack hacking! --Mark