I haven't done the 6th of the course yet, but I have finished the 5th one (everything works fine) and still don't really understand a few things that might not be addressed later, so I thought I might as well ask now.
1, How exactly do the clock cycles work in the hack computer? Is it enough if we really just have one clock that controls all the registers in the CPU and the Memory chip with the same period? Is this what's happening in the HACK computer? I can see that this should work, but I have the following issue, as I will state in the following question.
2, How do commands like A=A+1;JMP work? Suppose this command "happens" at time 10, and at this time the output of A is 30. The PC follows after the ARegister in the CPU, so at time 10, the input signal of PC is still only 30, not A+1 = 31, and so at time 11, the PC output will be 30.
And yet, the code A=A+1;JMP is supposed to make the program address jump to 31 (I think). I can see various ways of fixing this. First, we can limit ourselves to the situation of being in C-instruction, since an A-instruction can't do any sort of jumping. Further, we can restrict ourselves to the situation where the destination of the C-instruction is A, since otherwise a jump will change the value of PC to the proper, most up-to-date value of A. So suppose we're in a C-instruction with destination that contains A. If we simply "link" the output of the ALU directly to the input of the PC, all problems should be fixed.
More precisely, since PC already has the input coming from register A, we would have to do this by say linking the ALU output and ARegister output to a mux that would go into the PC input, and choose to use the ALU input only if we're in C-instruction and A is a destination of the ALU.
The following questions are perhaps a bit too hardware-focused. If these problems/concepts are non-trivial, I don't need an answer - just a reference to what type of books I should consider to learn this topic would be appreciated. The questions are also very vague, because I'm confused about the topic and can't really describe it myself what it is that I don't understand. So please feel free to skip the question if these things don't have clear answers or are the questions are too vague/confusing, or poorly written.
3, What options for clock cycles are there? What about say... changing the cycle to twice as fast/twice as slow in various substructures of the computer? It seems intuitive that the PC is crucial and dictates some sort of "basic" speed, but if for example I had two registers linked up one after the other in the CPU (for some reason), maybe it could sometimes make sense to make their clock speed twice as fast, so that during each PC cycle the input of the first propagates to the second one. Of course, the first register might then display "wrong" values, since we might get into a feedback loop, and so this might just be useless design.
How is any sort of "intersection" avoided between the various clock cycle phases? Obviously we want to void a feedback loop, so we need to make sure that during a short amount of time when we "update" the output of a register (the time when output is "assigned" the value of the input), we need to block any sort of signal that could change the value of this register. I know this is done by a clock, but how exactly do we do this to avoid any possible issues?
I can see that if we have a clock that outputs signal S, we could perhaps somehow achieve the following:
Output of register can only be changed if signal S > 0.7, value of register can only be changed if S<0.3. Together with a periodic signal this should work. In other words, we keep some sort of safety margin for when the signal is on/off, by making the transistor switch more/less sensitive to the signal.
The best way to understand how the clock interacts with the circuit is to keep in mind that ALL of the registers in the entire machine (including the A, the D, the PC, and every last RAM cell) load whatever is present on their inputs into the register on the rising edge of the clock provided the 'load' signal is asserted. Otherwise they just hold the value that was already there.
So, except for that brief instant during the rising edge of the clock, all of the registers are simply outputting the value that was stored in them on the last rising clock edge.
All of the logic in the various chips are thus using the values in the registers that was stored on the last rising clock edge. Some of these signals go to the data inputs and/or the control inputs of some of the registers, but those values just sit there and can't get acted upon until the next rising clock edge.
When that rising edge comes, whatever values are on the inputs at that moment get loaded into those registers that are selected. While this also results in the outputs of the registers changing and, eventually, the inputs of some of the registers changing yet again, this process takes time. In a well-design register, by the time the new value is available at the output of the register the input is already no longer sensitive to it -- too much time has past since the rising edge of the clock.
So in your example of
If A has the value 30 in it, then the CPU will calculate the value 31 and that value will be present on the input of the A register, as will the load signal for the A register. But the A register itself still has 30 stored in it. The JMP part of the instruction will assert the load signal for the PC, and the data value at the PC is the current contents of the A-register, which is 30.
On the rising edge of the clock, 30 will get loaded into the PC and 31 will get loaded into the A-register.
No, the command A=A+1;JMP is NOT supposed to make the program jump to address 31. It is the responsibility of the programmer to store the target address into the A register BEFORE executing an instruction that has a jump part.
In reply to this post by pk1234
The issues you are talking about here fall under the general heading of "computer architecture" and it is a very large and diverse field. Modern architectures are insanely complicated and play all kinds of games in order to squeeze performance out of a chip while minimizing power consumption. They have portions of the chip which are completely powered down except when they are needed and portions of the chip that use asynchronous logic (and all of the demons that come along with it) in order to accomplish this. They have different clock speeds in different parts of the chip in order to manage bottlenecks. Each of these tasks involves a lot of very nontrivial design work to ensure that it works reliably.
At the other end of the spectrum you have chips that are not much more complicated than the Hack where the emphasis isn't on performance, but rather some combination of simplicity, minimal cost, and minimum power consumption at the expense of computational capability.
In reply to this post by WBahn
Thank you very much for the replies, they make complete sense.
I was only worried that maybe keeping the rising clock edge signal short enough could be problematic - so I thought that maybe you have to use two registers A and B that form a cycle, and periodically block the connection from A to B, then from B to A, etc. This would basically mean that when you allow the input of the register A to be loaded, then at this time you can also block its output, to avoid any feedback loop. But I see that if the time you allow the input to be loaded is short enough, and you use proper design, then you don't have to worry about a feedback loop from the output of the register.
In reply to this post by pk1234
About clock cycle , i have a questions also ?
For example ; (I chose all values randomly by the way )
PC times Asm Codes
1- D = A
3- A = A + 1
First Question ,
in this example :
at time 1 ;
1- the input of the DRegister is "32"
2-the value of the Dregister is "0"
3-the output of Dregister is also consequently "0"
4-Most importan maybe LOAD of the DDegister is "1" ??
When i push the button "Single Step" in CPU emulator
Actually, the transition from time 1 to time 2
1-The Clock is on the rising edge
2-Also LOAD of the DDegister is "1"
So the input is loading in the DRegister , and before the time 2 (actually when the code is "@5" ) the loading process is already finished .
So is this explanation true ??
The seceond Question is ;
I realized that the output of the DRegister is going to be "32" after the time 3.
İs this because at the end of the time 1 (first c-instraction in my code ) clock is "TICK"
and at the end of the time 3 (second c-instraction in my code ) clock is "TOCK" ??
Can i think like that ??
|Free forum by Nabble||Edit this page|