Q: On data hazard detection
Data hazards are possible when
  1a. EX/MEM.RegisterRd == ID/EX.RegisterRs
  1b. EX/MEM.RegisterRD == ID/EX.RegisterRt
  2a. MEM/WB.RegisterRd == ID/EX.RegisterRs
  2b. MEM/WB.RegisterRd == ID/EX.RegisterRt
To resolve the first two data hazards, we can forward value from the EX/MEM pipeline registers. To resolve the latter two hazards,
we can forward value from the MEM/WB pipeline registers. In order to figure out the correct forwarding control logic, we note that
forward will happen:
  1. only if the forwarding instruction will write to a register
   EX/MEM.Regwrite, MEM/WB.Regwrite
  2. AND only if Rd for that instruction is not $zero
   EX/MEM.RegisterRd != 0, MEM/WB.RegisterRd != 0
  3. AND only if forwarding instruction is not a load in MEM stage
   EX/MEM.MemRead == 0
From the above, we could derive the following forwarding conditions:
EX Hazard
if (EX/MEM.RegWrite and (EX/MEM.RegisterRd 』 0)
and (EX/MEM.RegisterRd == ID/EX.RegisterRs))
ForwardA = 10
if (EX/MEM.RegWrite and (EX/MEM.RegisterRd 』 0)
and (EX/MEM.RegisterRd == ID/EX.RegisterRt))
ForwardB = 10
MEM Hazard
if (MEM/WB.RegWrite and (MEM/WB.RegisterRd 』 0)
and (MEM/WB.RegisterRd == ID/EX.RegisterRs))
ForwardA = 01
if (MEM/WB.RegWrite and (MEM/WB.RegisterRd 』 0)
and (MEM/WB.RegisterRd == ID/EX.RegisterRt))
ForwardB = 01
However, if you have a sequence of code that both data hazards happen:
  add $1, $1, $2
  sub $1, $1, $3
  or $1, $1, $4
then you would want to use the most recent result from the sub instruction.
Let's revise the forwarding conditions for MEM hazard to take care of 'double' data hazards
  if (MEM/WB.RegWrite and (MEM/WB.RegisterRd 』 0)
    and not (EX/MEM.RegWrite and (EX/MEM.RegisterRd 』 0)
    and (EX/MEM.RegisterRd == ID/EX.RegisterRs))
    and (MEM/WB.RegisterRd = ID/EX.RegisterRs))
      ForwardA = 01
  if (MEM/WB.RegWrite and (MEM/WB.RegisterRd 』 0)
    and not (EX/MEM.RegWrite and (EX/MEM.RegisterRd 』 0)
    and (EX/MEM.RegisterRd == ID/EX.RegisterRt))
    and (MEM/WB.RegisterRd = ID/EX.RegisterRt))
      ForwardB = 01
Note that the forward condition for MEM hazard in textbook on page 369 is WRONG!
Q: About clock
Your MIPS design should use a rising clock edge to define the boundaries of clock cycles: during the
first half of each processor clock cycle the clock is 1; during the second half of each cycle the clock is 0;
and the end of the cycle is when clock transitions from 0 to 1. By default, most Logisim memory components
(Registers, D Flip-Flops, etc.) are triggered on the rising clock edge, so you can leave them as is. The register
file is the only component that should use a falling clock edge, and can be so configured using the attributes panel.
Q: What does it mean that the Instruction ROM is byte-addressed memory?
The instruction ROM takes an address A as input, advances A bytes
into its memory (remember, 1 byte = 8 bits), and outputs the 32-bit
instruction that starts at the resulting position. 32 bits is 4 bytes,
which is why the PC normally increments by 4 every cycle: it's simply
going to the next instruction.
Q: How do we implement the set-less-than (SLT*) family of instructions?
The current ALU does not provide comparing between two value. As a result,
there are two possible approaches to implement the SLT family of instructions.
You can either put a few comparators in the EX stage, or try to
implement it in terms of other ALU operations.
Q: Should I sign-extend or zero-extend the immediate value in SLTIU and SLTI?
A: The short answer, sign-extend.
The long answer, the MIPS handbook describes the operation of SLTIU as sign-extending the immediate
value first, and then comparing the immediate to Rs both as unsigned integers. As a result, you're limited to
representing the minimum or maximum of the range of representable integers:
0x0000 to 0x7fff turn into 0x00000000 to 0x00007fff: This is 0 to 32767
0x8000 to 0xffff turn into 0xffff8000 to 0xffffffff: This is
maxint-32767 to maxint, where maxint = 2^32 - 1.
For details please refer to MIPS handbook Vol 2, page 204 ~ 205.
Q: What is the best way to design the instruction decoding logic?
A: Logisim has a nice feature that can turn a truth table into logic gates. Search for "Combinational Analysis"
in Logisim Help. You may find it easier than implementing with a ROM.
Q: How to split work between me and my partner?
A: Some of you may decide to have one person work on the IF, ID stage and the
other work on the EX, MEM stage. Before turning your head to work on your own
problem, make sure there is a clear specification on the interface between your module
and your partner's module. A well defined interface will save you a lot of time
when trying to integrate your work together.