=============================
= Lec-4-HW-2-LC3-instructionFetch
=============================

You have seen the three states of the instruction-fetch
phase of instruction execution. The three controller states
accomplish the following: 

(state-18)
    increment the PC and copy the content of the
    PC to the MAR, simultaneously; 
(state-33)
    copy the memory's output to the MDR, repeating 
    until the signal R=1 indicates the memory 
    unit finished the read operation;
(state-35) 
    copy the MDR content to the IR.

(See LC3-PPappendC.pdf and LC3-ControlStates.txt
in docs/.)

The global clock signal, "sys_clk", triggers a 
register to accept the data on its input and 
propagate it to its output. This is called a 
register write, and it overwrites the data that 
was in the register before the clock pulse arrived. 
Of course, the register's write-enable signal must be 
1'b1 for this to occur.

Your job in this assignment is to trace instruction fetch
operations. If you haven't already, get an up-to-date copy
of the library files from projects/LC3-trunk/lib/, and put
them in your branch's lib/. You will also be using the
verilog file, "top_rtl_testInstr.v", which you will generate 
yourself from test.jelib:top_rtl_testInstr{sch}.

Using Electric, open the "top" cell in the "system.jelib" 
library. (My notation is "system.jelib:top{sch}".)
Investigate the wire and bus connections on which signals
will propate during instruction-fetch. You will identify
each bus/wire connection path involved. Then you will 
add verilog code to test.jelib:top_rtl_testInstr{sch} and 
generate a new simulation/top_rtl_testInstr.v file.

The code you will add will be of the form shown in this
example,

    always @( top.PCout ) begin
        $write("=====(t=%0d)===", $time );
        $display("===PCout=%b===", top.PCout);
    end

That bus, "PCout", happens to be the bus connected
to the output of the PC in system:top. This will display
the signal value on that bus at any time it changes.
(Note that for signals you do not give a name to, Electric
gives a default name, such as "net@375". When Electric
generates verilog code, that will be changed to "net_375"
to avoid verilog syntax problems.)

That example will allow you to see the last part
of the PC <== PC+1 operation in state 18, just after
the clock signal causes a write to the PC. You are to
add other such statements until you can trace out
the entire signal propagation path for that register-
transfer operation, including the input and output of
devices along the path such as the "plus1" device.

In similar fashion, add verilog code so you can trace
out the other register-transfer operations that occur
in the other states of instruction-fetch phase.

The LC3's controller, aka its "micro-sequencer", has 
instance name "uSeq", and is an instance of the cell 
uControl.jelib:uSeq{sch}.
All control signals come from uSeq. You should also
have output statements for the required control signals
along your register-transfer path. You will see that
all control signals, wires or busses, are named the same as
uSeq's output ports. E.g., LD_PC is the name of the wire
attached to the PC's write-enable input. Verilog code to
display that signal would be,

   always @( LD_PC ) begin
        $write("--(t=%0d)---", $time );
        $display("-LD_PC=%b---", top.LD_PC);
   end
  
You will get docs/LC3-uArch-ControlStates.txt. 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.
Fill in for each relevant state the values of all control 
signals along your register-transfer paths. If you prefer, you
can print a copy of docs/LC3-PP-Append-C.pdf and annotate the
controller's state diagram instead.

WHAT TO TURN IN:
Turn in a cover sheet. In your comments section, explain 
generally how you went about the task assigned. Attach
your verilog code output, annotated with comments explaining
each step of each register-transfer operation. Explain each
signal change and why it is occuring at that time. Also
attach your version of docs/LC3-uArch-ControlStates.txt with
control signal values filled in for states 18, 33, and 35.

--------------------------------------------
NOTES
--------------------------------------------

--- Heirarchical naming
"top.PCout" names a signal in the instance "top". 
There is an instance of 
    system.jelib:top{sch} 
in the cell 
    test.jelib:top_rtl_testInstr{sch}
That instance has the name "top". You can look at 
the name of an object using Edit.ObjectProperties after 
selecting the object. To refer to an object lower down in 
the hierarchy, use dot notation:
    "instance_name.object_name"

Do not be confused by identical names:
the instance has the name "top", and it is an
instance of type "top". The type "top" is defined 
in system.jelib:top{sch}. In verilog, the instance
"top" will be an instance of type "module system__top".

--- Identical names
Busses and wires may also have the same name as
the export they are connected to. For instance, we
could name "PCout" to be "out", which is also the
name of the PC's output export.

--- Naming busses/wires
You will have to name buses/wires yourself in many cases. 
For instance, "net@375" is hard to remember. Seeing it 
mentioned in your trace output will make it difficult to 
identify what is going on. You can set the name of any object 
via Edit.ObjectProperties.

--- NAMING A BUS
A bus's name MUST indicate the number of wires in
the bus. So, a proper name for the bus attached to
PC's out export would be "PCout[15:0]". Note that
Electric does not bother with that when it creates
its own names, but you need to.

--- Dissapearing Names in .v files
When creating .v files, Electric reduces the design
by trimming unnecessary wires, busses, and sometimes
objects. E.g., there are several busses attached to
PC's out, with names "net@375" and "net@378" and so
forth. These are all connected together; so, Electric
will eliminate all but one. All connections will use
that remaining signal name. Usually, Electric will not 
eliminate a bus/wire you named. If there
seem to be errors due to non-existent references in
your verilog code, check the verilog output from 
Tools.Simulateion(Verilog).WriteVerilogDeck
to see if the names you refer to in $display() 
statements are still present in the .v file.

--- Register clocking
uSeq has a system clock that runs continuously and sends pulses
throughout the LC3. A clock pulse occurs when sys_clk changes 
from 0 to 1, which happens once every 20 simulation time ticks.
The period from one 0-1 pulse to the next is a clock cycle.
Most registers change state at the next clock rising edge.
Some change at the next falling edge instead. Registers
have a delay in propagating their input to their output when 
they are written. This delay is about two ticks.

--- Verilog, installing instructions in memory
Recall that the testbench, test.jelib:top_rtl_testInstr{sch} has
verilog code to load an instruction into memory. E.g.,

  top.mem.data[ 16'h0200] = 16'b0001010111000101;

This will put 16 bits "0001010111000101" into the memory cell at
address "0200" (a 16-bit address in hex notation). Recall that
the PC initially contains x0200 at startup. You can edit that code
to put any instruction you want into the memory at any cell you want. 
By the way, just to be perfeclty clear,

  16'h0200  and  16'b0000001000000000  and  16'd512

are three ways of specifying the same 16-bit value.

--- Memory-IO bus control signals
The Memory-IO bus consists of three parts: (1) the address bus, 
(2) the data bus, and (3) the control bus. It has tri-state buffers
to control access to the data bus and the MDR input.
The output of the MAR is connected to the address input 
of the memory unit via the address bus so the memory knows which 
cell to access. The memory unit also needs to know that the controller
wants the memory to respond to the address. This is done via the 
control bus and some additional logic attached to the address bus.

There are three bits the memory unit needs: 

  (1) a bit indicating that the address on the address bus is 
  within the range of addresses handled by the memory unit.
  (Other devices may be handling some addresses.)

  (2) a bit that lets the memory unit know that the controller
  is doing a Memory-IO operation.

  (3) a bit indicating whether it is a read or a write.

(1) As the output of the MAR is always affecting the address bus,
the memory unit does not need to do anything to get the address.
But, also attached to the address bus is an "address decoder".
This device detects whether the address is within the range that
the memory unit should respond to. If the value on the address
bus is within that range, it will output the signal,

    isMemoryAddress = 1

and otherwise that signal will be 0.


(2) Just because the address on the address bus is appropriate for
the memory unit does not mean the controller is currently trying
to do a memory or IO (input/output) access. The controller indicates
that by setting the control signal, 

  MIO_EN = 1. 

(3) The controller also indicates the type of operation by setting,

  R_W (0 for read, 1 for write)

For instance, in state-33 the controller is trying
to read and sets MIO_EN = 1 and R_W = 0. The controller then
waits in state-33 until the operation is completed. The memory or IO unit
that is handling the operation will send back to the controller a
signal indicating it finished. This signal is,

  R  (0 for "I am not yet finished", 1 for "All done, ready".) 

The two signals, MIO_EN and R_W, go from uSeq to the BusLogic unit.
For clarity, the BusLogic unit translates the combination into two 
separate control-bus signals, one for a memory or I/O read operation,

  MIO_R ( == 1 if MIO = 1 and R_W = 0)

and another for a memory or I/O write operation,

  MIO_W ( == 1 if MIO = 1 and R_W = 1)

The memory unit has logic to combine the three signals,

  MIO_R, MIO_W, and isMemoryAddress

and produces these signals,

  MEM_R (1 if MIO_R = 1 and isMemoryAddress = 1 )
  MEM_W (1 if MIO_W = 1 and isMemoryAddress = 1 )

and uses them to activate the memory unit via its

  MEM_EN

input. It also uses the R_W signal directly for its own

  R_W

input. It might seem to be a wasted effort to produce the
MEM_R and MEM_W signals, but there are tri-state buffers that
need to be controlled and it is easier to understand their function
if these signals are available.

Each Memory-IO device has its own "ready" signal. These signals are 
combined in BusLogic into one control bus signal, MIO_READY,
and passed back to the controller as the "R" signal.

When the correct data becomes available at the data output of the 
memory unit, the memory unit's output must be connected to the
MDR's input via tri-state buffers. However, it is easier to connect 
it continously until the operation completes successfully, continuously 
clocking the MDR (by setting its LD_MDR write-enable signal to 1 for 
state-33). Only the correct data will be present in the MDR when the 
controller changes to state-35.