Struggling with Program Counter (PC)

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

Struggling with Program Counter (PC)

MultiplexorMan
I'm struggling hard with the PC. It solution seems just out of reach.

    Mux16(a=in, b=false, sel=reset, out=q);
    Or(a=reset, b=load, out=q2);
    Register(in=q, load=q2, out=q3);
    Mux16(a=q3, b=q6, sel=inc, out=q4);
    Register(in=q4, load=true, out=q5, out=out);
    Inc16(in=q5, out=q6);

This setup obviously fails because when inc=1 the load command is by passed. I feel like these posts hold the key I just haven't been able to put the puzzle pieces together.

Start Here:
http://nand2tetris-questions-and-answers-forum.32033.n3.nabble.com/PC-struggle-td4028870.html
Hint: If you connect a Register's load to true it turns the Register into a 16-bit DFF.

Then you can make PC like you made bit Bit, except that the feedback wire is replaced with a circuit that computes the next value for the PC.

Also, in hardware it is often easier to generate all the options you might need and select the one that's required by the current control values.  Think about handling the f bit in the ALU, but in this case there are more options.
 
Then This:
http://nand2tetris-questions-and-answers-forum.32033.n3.nabble.com/PC-Counter-td687060.html
note that the order of the if statements and the order of your circuitry are related
Chapter 3 has the remedy to your question. You can use one of the other chips in the chapter to control and recall different states of the counter. Hopefully this helps.
 
Interesting:
http://nand2tetris-questions-and-answers-forum.32033.n3.nabble.com/PC-Counter-td4030223.html
Just an update/FYI I actually did figure this out after reading another comment of yours! My logic was flawed in the assumption that we only wanted the register's load bit to be 1 when we load from "in". I hope this isn't too much of a hint to others looking to solve this the "simple way" but we actually want the register's load bit to be true any time there is an operation requiring a state change in the register. From there it was a simple matter of combinational logic to construct what constitutes a state change - and voila!
Reply | Threaded
Open this post in threaded view
|

Re: Struggling with Program Counter (PC)

WBahn
Administrator
You've got two Register parts in your design, but a program counter only stores a single value, hence it only needs one Register.

Think of the PC as a circuit that has different behaviors depending on the three inputs and first make circuits that just have each of the designed behaviors: increment, load, reset, and hold. What are the differences between these circuits? Can you use Mux16 parts (or other parts) to be able to change between the different behaviors? Now all you need to do is figure out how to use the three input signals to control the multiplexer select inputs.
Reply | Threaded
Open this post in threaded view
|

Re: Struggling with Program Counter (PC)

MultiplexorMan
It was getting pretty late when wrote and posted that code. Here are the building blocks I've been trying to work with. The previously posted code shows my frustration in wiring the circuit leading to two registers. I basically just tried to mash the puzzle pieces together.

Reset:
Mux16(a=?, b=false, sel=reset, out=?);

Load:
Idea 1: Register(in=in, load=load, out=out);
Idea 2: Mux16(a=?, b=in, sel=load, out=toReg);
        Register(in=toReg, load=load, out=out);

Inc:
Mux16(a=?, b=fromInc, sel=inc, out=toReg);
Register(in=toReg, load=true, out=toInc, out=?);
Inc16(in=toInc, out=fromInc);

Selection Logic Idea:
Mux4Way16(a=?, b=?, c=?, d=?, sel[1]=inc, sel[0]=reset, out=out);
Reply | Threaded
Open this post in threaded view
|

Re: Struggling with Program Counter (PC)

WBahn
Administrator
The thing you need to note is that the only difference between the various behaviors is what gets applied to the input port of the Register part.

Using a Mux4Way16 is a perfectly reasonable way to go and makes things pretty simple in the end.

But you have two select inputs but three control signals. So you need a little circuit to take the three control signals and map them to the two select signals of the mux. The simplest way to do that is to make a truth table showing all eight possible combinations of the three control signals and have a column for the desired behavior (of which there are four). Then you can assign one of the four possible select signal combinations to each of the behaviors (conceptually it doesn't matter, but certain choices make the resulting logic a bit simpler, but not enough to spend too much time fretting over it -- pick one and push one). Then you just need to apply the signal that needs to make it to the Register input port to the appropriate mux input.
Reply | Threaded
Open this post in threaded view
|

Re: Struggling with Program Counter (PC)

MultiplexorMan
Success! The thing I love about this course is that moment when the hardware simulator returns a success!

Thank you for your feedbacK! I ended up scratching the idea of using the Mux4Way16 and decided to work backwards from the output to the inputs. Whiteboarding this method resulted in three Mux16's, one Register, and one Inc16.

I can't believe the struggle to write 5 lines of code. LOL
What a thrilling experience!
Reply | Threaded
Open this post in threaded view
|

Re: Struggling with Program Counter (PC)

WBahn
Administrator
Glad to hear it -- and I can definitely relate to the feeling of accomplishment when it finally comes together.

Using separate muxes is also the way I did it. It seems more obvious to my way of thinking, but it's a bit harder to describe the idea underlying it.