Since the control unit takes one input which is opCode, Jr and other R type instructions passes to 000000 to control unit. But for Jr, RegWrite must be 0. How does the control unit differentiate between Jr and the other R-type instructions if they have the same opCode? Do I need to pass funct code to control unit?
I'm working on a Mips Datapath simulator. I have implemented the control unit using a logic design I found in a Computer Architecture lecture notes from a university. You can ignore the AluOp for now.
this.outputs[0].changeValue(opCode == "000000"); // regdest
this.outputs[1].changeValue(opCode == "000010" || opCode == "000011"); //jump
this.outputs[2].changeValue(opCode == "000100"); //branch
this.outputs[3].changeValue(opCode == "100011"); //memread
this.outputs[4].changeValue(opCode == "100011"); // memtoreg
this.outputs[5].changeValue(
["000000"].includes(opCode)
? "10"
: ["100011", "101011"].includes(opCode)
? "00"
: opCode == "000100"
? "01"
: "11" //X
); //aluop
this.outputs[6].changeValue(opCode == "101011"); //memwrite
this.outputs[7].changeValue(opCode != "000000" && opCode != "000100"); //alusrc
this.outputs[8].changeValue(
!["101011", "000010", "000100"].includes(opCode)
); //regwrite
Here is the current version of the simulator: https://saliherdemk.github.io/Mips-Datapath-Simulator/
I searched for a more complex, geniune logic for control unit but I didn't find. Standard datapath needs to modification for JR instruction but I didn't find anything about inside of the control unit.
Jr datapath looks like this. But since opCode is same it jumps to address in the rd register for all R type instructions. Do we need to pass func code to the control unit?
The jr
instruction does not use the rd
field.
Thus, for that instruction the rd
field should have 0
, so even if RegWrite
were true, it would be the "zero register" that is written. I believe that is the case for all the R-type instructions, including multiplication/division, mfhi, mthi, etc.. — that the rd
field will be 0, when the instruction does not write a register.
Since you have to be able to handle (i.e. ignore) writes to the zero register, as in add $0, $1, $1
, for example, you might simply handle the jr
the same way knowing the rd
field is zero.
You may rely on that or choose not to, ask your coursework.
From https://www.cs.cmu.edu/afs/cs/academic/class/15740-f97/public/doc/mips-isa.pdf, A 4.2 Instruction encoding Picture:
The instruction word encoding is shown in pictorial form at the top of the instruction description. This picture shows the values of all constant fields and the opcode names for opcode fields in upper-case. It labels all variable fields with lower-case names that are used in the instruction description. Fields that contain zeroes but are not named are unused fields that are required to be zero. A summary of the instruction formats and a definition of the terms used to describe the contents can be found in CPU Instruction Formats on page A-174.
In response to the diagram that has been edited to support jr
:
That's quite the diagram! It is missing the traditional circuitry for j
and jal
, and seems to have taken over the Jump
mux for jr
. The following diagram shows the more traditionally used MIPS datapath, which includes j
and jal
but not jr
.
IMHO, they should have started with the j
/jal
circuitry as per my reference, and then added yet another mux for jr
— but either way, that last mux needs to choose between jr
and everything else, so, yes, it will need additional treatment to work properly — your diagram is effectively broken as is.
Yes, it could be that the Control
takes the extra bits (i.e. funct
).
Or — and I would probably choose this — it could be treated like ALU control
, which already takes those funct
bits along with ALUOp
from Control
(which has an indication of R-Type instructions.)
The ALUOp
has a way to tell ALU control
to use the funct
bits (when ALUOP
=2, then it consults the funct
bits), which is what is needed to check for jr
vs. any other R-Type.
In fact, there's really no reason to duplicate ALU control
, what I would do is simply change the JumpReg
control signal to come from the ALU control
rather than directly from Control
, which as you are pointing out doesn't have enough information to properly work that end mux. However, ALU control
has all the information it needs to understand jr
vs. all else, so I say that's where JumpReg
should come from.
Jr datapath looks like this. But since opCode is same it jumps to address in the rd register for all R type instructions. Do we need to pass func code to the control unit?
It is broken and needs something, and so I'd change JumpReg
to originate from ALU control
instead of Control
. As for the internals of ALU control
, this would then require adding new logic to the ALUOp
table, namely a row and a column. The new row for matching jr
by ALUOp
=2 and funct
=jr
, and the new column for the JumpReg
mux control signal value, e.g. output of zero unless jr
, then 1. I also probably rename ALU control
to Secondary Control
or something else more general.