The following tables were compiled from data included in the MIPS Green Sheet and the Opcodes chart courtesy of OpenCores.
Register File Definition
| Name | Number | Use |
|---|---|---|
| $zero | 0 | The Constant Value 0 |
| $at | at | Assembler Temporary |
| $v0-$v1 | 2-3 | Values for Function Results and Expression Evaluation |
| $a0-$a3 | 4-7 | Arguments |
| $t0-$t7 | 8-15 | Temporaries |
| $s0-$s7 | 16-23 | Saved Temporaries |
| $t8-$t9 | 24-25 | Temporaries |
| $k0-$k1 | 26-27 | Reserved for OS Kernel |
| $gp | 28 | Global Pointer |
| $sp | 29 | Stack Pointer |
| $fp | 30 | Frame Pointer |
| $ra | 31 | Return Address |
Core Instruction Set Definition
| Instruction | Name | Format | Verilog Operation | Opcode bitfields | |||||
|---|---|---|---|---|---|---|---|---|---|
| Arithmetic Logic Unit | |||||||||
| ADD rd, rs, rt | Add | R | R[rd] = R[rs] + R[rt]; Ov = (R[rs](31)==R[rt](31))&~(R[rt](31)==R[rd](31)) |
000000 | rs | rt | rd | 00000 | 100000 |
| ADDI rt, rs, imm | Add Immediate | I | R[rt] = R[rs] + SignExtImm; Ov = (R[rs](31)==R[rt](31))&~(R[rt](31)==R[rd](31)) |
001000 | rs | rt | imm | ||
| ADDIU rt, rs, imm | Add Immediate Unsigned | I | R[rt] = R[rs] + SignExtImm | 001001 | rs | rt | imm | ||
| ADDU rd, rs, rt | Add Unsiged | R | R[rd] = R[rs] + R[rt] | 000000 | rs | rt | rd | 00000 | 100001 |
| AND rd, rs, rt | And | R | R[rd] = R[rs] & R[rt] | 000000 | rs | rt | rd | 00000 | 100100 |
| ANDI rt, rs, imm | And Immediate | I | R[rt] = R[rs] & ZeroExtImm | 001100 | rs | rt | imm | ||
| LUI rt, imm | Load Upper Immediate | I | R[rt] = {imm,16’b0} | 001111 | rs | rt | imm | ||
| NOR rd, rs, rt | Nor | R | R[rd] = ~(R[rs] | R[rt]) | 000000 | rs | rt | rd | 00000 | 100111 |
| OR rd, rs, rt | Or | R | R[rd] = R[rs] | R[rt] | 000000 | rs | rt | rd | 00000 | 100101 |
| ORI rt, rs, imm | Or Immediate | I | R[rt] = R[rs] | ZeroExtImm | 001101 | rs | rt | imm | ||
| SLT rd, rs, rt | Set Less Than | R | R[rd] = $signed (R[rs] < R[rt])?1:0 | 000000 | rs | rt | rd | 00000 | 101010 |
| SLTI rt, rs, imm | Set Less Than Immediate | I | R[rt] = $signed(R[rs] < SignExtImm)?1:0 | 001010 | rs | rt | imm | ||
| SLTIU rt, rs, imm | Set Less Than Immediate Unsigned | I | R[rt] = (R[rs] < SignExtImm)?1:0 | 001011 | rs | rt | imm | ||
| SLTU rd, rs, rt | Set Less Than Unsigned | R | R[rd] = (R[rs] < R[rt])?1:0 | 000000 | rs | rt | rd | 00000 | 101011 |
| SUB rd, rs, rt | Subtract | R | R[rd] = $signed(R[rs] - R[rt]); Ov = ~(R[rs](31)==R[rt](31))&(R[rt](31)==R[rd](31)) |
000000 | rs | rt | rd | 00000 | 100010 |
| SUBU rd, rs, rt | Subtract Unsigned | R | R[rd] = R[rs] - R[rt] | 000000 | rs | rt | rd | 00000 | 100011 |
| XOR rd, rs, rt | Exclusive Or | R | R[rd] = R[rs] ^ R[rt] | 000000 | rs | rt | rd | 00000 | 100110 |
| XORI rd, rs, imm | Exclusive Or Immediate | I | R[rt] = R[rs] ^ ZeroExtImm | 001110 | rs | rt | imm | ||
| Shifter | |||||||||
| SLL rd, rt, sa | Shift Left Logical | R | R[rd] = R[rt] << sa | 000000 | rs | rt | rd | sa | 000000 |
| SLLV rd, rt, rs | Shift Left Logical Variable | R | R[rd] = R[rt] << R[rs] | 000000 | rs | rt | rd | 00000 | 000100 |
| SRA rd, rt, a | Shift Right Arithmetic | R | R[rd] = R[rt] <<< sa | 000000 | 00000 | rt | rd | sa | 000011 |
| SRAV rd, rt, rs | Shift Right Arithmetic Variable | R | R[rd] = R[rt] <<< R[rs] | 000000 | rs | rt | rd | 00000 | 000111 |
| SRL rd, rt, sa | Shift Right Logical | R | R[rd] = R[rt] >> sa | 000000 | rs | rt | rd | sa | 000010 |
| SRLV rd, rt, rs | Shift Right Logical Variable | R | R[rd] = R[rt] >> R[rs] | 000000 | rs | rt | rd | 00000 | 000110 |
| Multiply | |||||||||
| DIV rs, rt | Divide | R | HI = $signed(rs) % $signed(rt); LO = $signed(rs) / $signed(rt) | 000000 | rs | rt | 0000000000 | 011010 | |
| DIVU rs, rt | Divide Unsigned | R | HI = rs % rt; LO = rs / rt | 000000 | rs | rt | 0000000000 | 011011 | |
| MFHI rd | Move From HI | R | R[rd] = HI | 000000 | 0000000000 | rd | 00000 | 010000 | |
| MFLO rd | Move From LO | R | R[rd] = LO | 000000 | 0000000000 | rd | 00000 | 010010 | |
| MULT rs, rt | Multiply | R | {HI,LO} = $signed({ {32{R[rs](31)}},R[rs]} * { {32{ R[rt](31) }},R[rt]}); |
000000 | rs | rt | 0000000000 | 011000 | |
| MULTU rs, rt | Multiply Unsigned | R | {HI,LO} = R[rs] * R[rt] | 000000 | rs | rt | 0000000000 | 011001 | |
| Branch | |||||||||
| BEQ rs, rt, offset | Branch On Equal | I | if(R[rs] == R[rt]) pc += (offset << 2) + 4 | 000100 | rs | rt | offset | ||
| BGEZ rs, offset | Branch On >= 0 | I | if(R[rs] >= 0) pc += (offset << 2) + 4 | 000001 | rs | 00001 | offset | ||
| BGEZAL rs, offset | Branch On >= 0 And Link | I | R[$ra] = pc; if(R[rs] >= 0) pc += (offset << 2) + 4 | 000001 | rs | 10001 | offset | ||
| BGTZ rs, offset | Branch On > 0 | I | if(R[rs] > 0) pc += (offset << 2) + 4 | 000111 | rs | 00000 | offset | ||
| BLEZ rs, offset | Branch On <= 0 | I | if(R[rs] <= 0) pc += (offset << 2) + 4 | 000110 | rs | 00000 | offset | ||
| BLTZ rs, offset | Branch On < 0 | I | if(R[rs] < 0 ) pc += (offset << 2) + 4 | 000001 | rs | 00000 | offset | ||
| BLTZAL rs, offset | Branch On < 0 And Link | I | R[$ra] = pc; if(R[rs] < 0) pc += (offset << 2) + 4 | 000001 | rs | 10000 | offset | ||
| BNE rs, rt, offset | Branch On Not Equal | I | if(R[rs] != R[rt]) pc += (offset << 2) + 4 | 000101 | rs | rt | offset | ||
| Jump | |||||||||
| J target | Jump | J | pc = pc_upper | (target << 2) | 000010 | target | ||||
| JAL target | Jump and Link | J | R[$ra] = pc; pc = (target <<2) | 000011 | target | ||||
| JALR | Jump and Link Register | J | R[rd] = pc; pc = R[rs] | 000000 | rs | 00000 | rd | 00000 | 001001 |
| JR | Jump Register | J | pc = R[rs] | 000000 | rs | 000000000000000 | 001000 | ||
| Memory Access | |||||||||
| LB rt, offset(rs) | Load Byte | I | R[rt] = SignExt(M[R[rs]+SignExtImm](7:0)) | 100000 | rs | rt | offset/imm | ||
| LBU rt, offset(rs) | Load Byte Unsigned | I | R[rt] = {24’b0, M[R[rs]+SignExtImm](7:0)} | 100100 | rs | rt | offset/imm | ||
| LH rt, offset(rs) | Load Halfword | I | R[rt] = SignExt(M[R[rs]+SignExtImm](15:0)) | 100001 | rs | rt | offset/imm | ||
| LHU rt, offset(rs) | Load Halfword Unsiged | I | R[rt] = {16’b0, M[R[rs]+SignExtImm](15:0)} | 100101 | rs | rt | offset/imm | ||
| LW rt, offset(rs) | Load Word | I | R[rt] = M[R[rs]+SignExtImm] | 100011 | rs | rt | offset/imm | ||
| SB rt, offset(rs) | Store Byte | I | M[R[rs]+SignExtImm](7:0) = R[rt](7:0) | 101000 | rs | rt | offset/imm | ||
| SH rt,offset(rs) | Store Halfword | I | M[R[rs]+SignExtImm](15:0) = R[rt](15:0) | 101001 | rs | rt | offset/imm | ||
| SW rt,offset(rs) | Store Word | I | M[R[rs]+SignExtImm] = R[rt] | 101011 | rs | rt | offset/imm | ||
| SignExtImm = {16{imm[15],imm} ZeroExtImm = {16{1’b0},imm} pc_upper = pc[31:28] Ov = Overflow Flag, Active High |
|||||||||
Other References
The following resources supported our overall implementation.
- Omran, Safaa S. and Hadeel S. Mahmood. Hardware Modeling of a 32-bit, Single Cycle RISC Processor Using VHDL. ICIT 2013 The 6th International Conference on Information Technology. May 2013. The block diagram titled "The complete datapath control scheme of MIPS" was a helpful resource in mapping out additional operations in our CPU.
- Arithmetic. Duke University. 2011. This was an introductory lecture to floating-point arithmetic.