is inM delayed in hack CPU?

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

is inM delayed in hack CPU?

charlesgong
let's say we have a c-instruction ADM=D+A

based on my understanding, in the tick phase the ALU computes D+A from the values emitted by the D and A registers, and then sends it back to D and A and also to M through outM. D and A don't immediately emit the new value (D+A)

then in the tock phase, D and A emit the new value, however inM will be based on the old value of A (the old address, as opposed to address A+D). This is because A didn't immediately emit its new value. Thus the next instruction will have a stale value for M or inM

I believe this will make the CPU not work as intended

Consider this example. We start with mem[1] = 0, mem[2] = 7

@2
D = 1
A = D
AMD = M+D
Here, we expect A, M=mem[1] , D to be all be 1 at the end.

Let's assume the first two lines run as exepcted (so we know at this point that mem[1] = 0, mem[2] = 7, D = 1, A = 2) and let's start at the third line. During tick, the ALU computes D=1 and sends it to A. In this stage, A is emitting addressM=2 to memory. During tock, A emits the new value 1, while memory emits inM=mem[2]=7 because in the tick phase it received the old value addressM=2. Thus, M+D would equal 8, instead of 1.
Reply | Threaded
Open this post in threaded view
|

Re: is inM delayed in hack CPU?

WBahn
Administrator
You don't need to worry about tick and tock phases of the clock.

The values stored in a register (be it D, A, M, or PC) just before the end of an instruction are the values of the expression on the right just after the start of the instruction. Don't make it harder than it is.

Having said that, there is (or perhaps was) a bug in the CPU Emulator that produced incorrect results in a pretty specific case involving a conditional jump in a statement that updates the A register -- a case that is unlikely to be used in practice, but turns out does have at least one oddball use case that I've thought of.

The bug was confirmed in the desktop tools, but I don't know if it was fixed or if it was ever present in the online tools (which have had a few of their own bugs that the desktop tools never had).

So, in your example, you have:

  A   M   D   M[1]   M[2]
  ?   ?   ?     0      7
  2   7   ?     0      7     @2
  2   7   1     0      7     D = 1
  1   7   1     0      7     A = D
  1   1   1     1      7     AMD = M+D

The memory map for each row is what it looks like after the instruction on that row executed. But the instruction uses the values at the end of the prior instruction (i.e., the values from the previous line).

One thing that I think might be causing your confusion is a notion that memory someone continues to remember what the address was even after the address changes.

As soon as the A register's output changes, the address sent to memory changes and memory immediately outputs the data associated with the new address. The memory has no mechanism to act on anything other than the A register's output current output, as that logic is one hundred percent combinational.