=============================
= Lec-3-HW-3-LC3-PC
=============================

You have seen the three states of the fetch phase
of instruction execution. The three controller states
accomplish the following: (F1) increment the PC and copy
the content of the PC to the MAR (in parallel); (F2)
copy the memory's output to the MDR, repeating until
the memory signal R=1 indicates the memory unit finished
the read operation; and (F3) copy the MDR content to
the IR. In LC3 documentation those three states are
given the labels state-18, state-33, and state-35,
respectively.  See docs/LC3-PPappendC and
docs/LC3-ControlStates.txt.

As we will see later, the clock signal, "sys_clk",
triggers the registers to accept the data on their
inputs. This is called a register write, and it
overwrites the data that was in the register before
the clock pulse arrived. For state-18 (F1), the
PC's value is sent to the MAR and an incrementer,
and from the incrementer to the PC's inputs. So,
if the PC=1234 before, the MAR=1234 and the PC=1235
after the clock pulses.

Your job in this assignment is to get the PC
increment working. If you haven't already, copy the
Electric .jelib library files from projects/LC3-trunk/lib
to your branch's lib directory. Using Electric, open
the "top" cell in the "system.jelib" library. (My notation
in future will be "system.jelib:top".) Investigate the
bus connections and verify whether or not the required
connections exist between the PC's output and the incrementer 
and back to the PC's input. Repair as needed.

That is one-third of the job. You will notice in
docs/LC3-PPappendC that the incrementer (labeled "+1")
sends its output to a MUX, and from the MUX the signal
goes to the PC's input. There is a MUX select control signal.
The LC3's controller, aka the micro-sequencer, has instance 
name "uSeq", and is an instance of uControl.jelib:uSeq.
All control signals come from uSeq. This includes the MUX's
select signal PCMUX[1:0]. In order for the signal from the
"+1" unit to be sent to the PC's inputs, the PCMUX signal must
be set correctly for state-18. Also, the PC will not accept
the input, i.e., there won't be a register write, unless the
PC's write-enable signal, LD_PC, is also set correctly for 
state-18.

Aside from making the necessary bus and wire connections so
that signals can get from source to destination, the needed
control signals must be set. uSeq contains a memory in which
all control signal values are stored. That memory is addressed
by the current state of uSeq. When uSeq is in state-18, the
memory word at address 18 is fetched, and the various bits
of that word are connected to the control signal wires and
busses at uSeq's outputs. The content of that memory is specified
in uStore.jelib:uStore. Conveniently, each control signal has
its own table there. So, rather than worry about an entire,
50-bit control word, you can focus on each control signal
separately. All the signals already have verilog code to
initialize them to 0. Your job is to fix these signals as
needed. For instance, in uStore, you will find verilog code
for LD_PC. Since in state-18 you want the PC to do a register
write, you must have LD_PC=1 for that state. The syntax for
that is, "LD_PC[18]=1'b1;". Note that all the various control
signals are concatenated into a single bus, which is the
uSeq's memory word output.

The PCMUX signal also needs to be set similarly. That signal
depends on which of the MUX's inputs you connected the "+1"
output to. The MUX's inputs are labeled "00", "01", "10", and
"11". If you connected to the "01" input, then for state 18
you will want PCMUX[18]=2'b01, for example. Notice that for
those states in which the PC is not being written, it doesn't
matter which input PCMUX selects since LD_PC=0 in that case
(unless you mistakenly set it to 1).

You will find docs/LC3-uArch-ConstrolStates.txt is a handy
tool for you to use. It has, in text, a representation of the
complete controller state diagram from PP's appendix C. Each
state shows register-transfer language (RTL) for what
needs to be done in that state. You will find it useful to
fill in for each state whatever non-zero control signals
should be set. Then use that to guide you as you edit uStore.

TESTING:
Create a new cell in test.jelib. Place an instance of
system.jelib:top. Name the instance "top". Add a verilog code
box. Since uSeq has a system clock that runs and sends pulses
throughout the LC3, you do not need to stimulate any signals.
What you do need to do is output signals so you can see what
is happening. As I recall, the clock pulses every 20 simulation
time ticks. Each state lasts for one clock cycle, and changes
occur at the next clock pulse. Also, registers have a delay
in propagating their input to their output when they are written.
This delay is something like two ticks, if I recall. You will
want to see what happens when.

First, write an "initial" statement to $display() a hello 
message, wait 100 ticks, and $finish. Next, drop in another
verilog code box. Write an "always @(top.sys_clk)" statement and
display the simulation time using $time. This will tell
you when the clock changed its output. Also $display() the
sys_clk's value,
    $display( " (t=%0d) sys_clock = %b ", $time, top.sys_clk );
After that, put in a delay to allow the register outputs to
change and any signals to propagate. Something like #5 will
probably do. Then add code to $display whatever signals you
need to see to determine whether the PC gets properly incremented.
You will probably have to name a wire or bus so you can refer
to it in your $display code. E.g., name a bus connected to
the PC's output as "PC_out".

Note that the "clock pulse" is considered to occur when
sys_clk changes from 0 to 1. Remember to check Electic's message
window when you do Tools.Simulation(Verilog).WriteVerilogDeck.
It will have warning messages telling you if it found problems
with your design. You can ignore the warning about sys_clk
that says it is both an input and an output. You can also
ignore any warnings about files not being opened for reading.

WARININGS

1. Name your system.jelib:top instance: The instance icon shows
the module name "top", but this is not the instance's name.
Select the instance icon, and do,
     Edit.Object.ObjectProperties
to change its instance name.

2. Name your signals by their bus size: The output from the PC
is 16 bits. Suppose you gave the bus attached to it the name
"PC_out". That will disconnect bus wires in the resulting
verilog code. Use "PC_out[15:0]". 


WHAT TO TURN IN:
Turn in a cover sheet. In your comments section, explain how
you went about altering your copy of the LC3 design. That is,
detail what connections were made and what control signals were
set to what values. Test your implementation, and describe
the results of your tests and any problems you detected.
Of course, check in your modifications to your branch. Do not
wait to check in until you have everything working: Make some
changes, check in, test, make more changes, check in, test ...
Also check in the output from your tests. Recall that you can
send a process's stdout output to a file instead of the screen:
    %> vvp a.out > test-1.out
for example, sends whatever output "vvp a.out" produces to the
file "test-1.out".