===============================
= Lec-4-HW-3-LC3-ifetch
===============================

The prior two exercises got the LC3's first state of
the instruction-fetch phase working. The remaining
two states of this phase are state-33 and state-35,
in which the MDR and IR are loaded with the next instruction
to be executed. This exercise is to complete the instruction
fetch phase. At this point you should be able to write your
own test bench code to observe specific signals in the LC3.
You will be introduced to a test bench that provides information
after each state change of the controller. This information
includes the simulation time, the controller's state, and the
contents of all registers, including the PC, MAR, MDR, IR, and
PSR (and the CC bits of the IR).

As before, refer to docs for state information, and refer
to Lec-4 lecture notes for operations and wire paths, as
well as state information and control signals.

The first step is to verify that there are connected paths
between the bus interface (MDR and MAR) and the memory unit 
on the Memory-IO bus, and between the MDR and the IR. The
Memory-IO bus consists of three parts: (1) the address bus, 
(2) the data bus, and (3) the control bus. 

The output of the MAR must be connected to the address input 
of the memory unit for the memory to know which cell to access. 
This is done via the address bus. 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, and consists of three bits of information: 

  one bit indicates that the address on the address bus is 
  within the range of addresses handled by the memory unit;

  one bit lets the memory unit know that the controller is 
  interested in doing a Memory-IO operation;

  and one bit indicates whether it is a read or a write.

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
except have a wire/bus path from the address bus to its address
inputs. 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 a signal

 isMemoryAddress = 1

and otherwise that signal will be 0.


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
this by setting the control signal, 

  MIO_EN = 1. 

The controller also indicates the type of operation by setting

  R_W (0 for read, 1 for write)

So, 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) go between the BusLogic unit and the 
controller, uSeq. For clarity, BusLogic translates the combination 
into two separate control bus signals,

  MIO_R (1 for MIO = 1 and R_W = 0, 0 otherwise)
  MIO_W (1 for MIO = 1 and R_W = 1, 0 otherwise)

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 sends back its own "ready" signal.
These signals are combined into one control bus signal "MIO_READY",
and passed back to the controller via BusLogic as the "R" signal.

When the correct data becomes available at the data output of the 
memory unit, the memory unit's data output must be connected to the
MDR. It is easier to connect them continously until the operation
completes successfully and continuously clock 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.

Now that the instruction (the 16-bits of the cell referenced by the
MAR) is in the MDR, those bits need to be sent to the IR. The MDR
must be connected to sys_bus, its tri-state activated, and the IR
have its LD_IR write-enable signal activated for state-35.

The instruction will then be in the IR when the controller is in
state-32 "instruction decode" where it can decide what to do next
depending on the instruction's opcode bits.

TESTING

Use your own testbench code to display the values of any signals 
you need to see. Use names on wires for this. CAVEAT: if you name
a bus, be sure to indicate its size, e.g., MDR_in[15:0]; otherwise
your bus signals will be disconnected.

You can also use test.jelib:top_rtl_testInstr. It has display code 
for all registers. It will be somewhat useless to use this code 
unless there is some instruction in the LC3's memory that is not 
all zeroes, as the LC3's hardware sets all registers (except the 
PC and PSR) to all zero bits at system startup, including the memory
content. You won't be able to tell whether a memory read operation 
sent the correct bits to the MDR if the bits are all zero both before 
and after the operation. (Of course, you can see that something went
completely wrong if you get "x" or "z" for bit values.)

The verilog code in top_rtl_testInstr includes code to
initialize memory:

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

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

  16'h0200 == 16'b0000001000000000

are two ways of specifying the same values of 16 bits.

WHAT TO TURN IN

Check in your changes to your lib/ files and any other files
you created in the course of your work (excepting obviously
temporary files such as "a.out" " files). Turn in a 
paper coversheet explaining your progress, difficulties, steps 
you took, the state of things, joys, angst, hopes, fears, ....