The files for the Simple MIPS Pipeline model can be downloaded from mips_v1.3.zip
This MIPS model, based on an earlier model of the DLX architecture, was built by David Dolman during tenure of a University of Edinburgh College of Science & Engineering Strachan Scholarship.
Instructions on how to use HASE models can be found at Downloading, Installing and Using HASE.
Figure 1 shows a typical implementation of a simple pipelined MIPS architecture. The Integer Unit is used for both data and address arithmetic, so load/store instructions are processed by the Integer Unit before being sent to the Memory Access Unit and thence to Memory. The Integer Unit also executes the additions required for integer test and relative branch instructions, so the Memory Access Unit also executes branches.
The Integer Unit receives its operands from the Instruction Decode Unit, which is closely coupled to the Registers. These consist of 32 Integer Registers. The results from both arithmetic/logic and load instructions are returned to the Registers by the Write Back Unit.
Figure 1. Typical Simple MIPS Pipeline
The PC and PPC each have two fields: a label and an offset. At the start of the simulation, the Memory entity creates a table of labels and their absolute addresses. When fetching instructions, the Memory entity adds the offset to the label to get the absolute address of the instruction.
For a branch instruction, the use of a label differs from the use of an offset value. When an integer offset is used, the offset value in the instruction is added to the current value of the PC offset field. When a label is used, the label in the instruction is copied into the PC label field and the offset field is set to 0. Similarly, when a jump instruction uses an integer value, the offset field in PC is set equal to this value and the label field is set to 'main'. When a jump instruction uses a label, the label in the instruction is copied into the PC label field and the offset field is set to 0.
The initial value of the label in the PPC and PC is 'main'; this is the starting address of the program (instruction memory address 0).
Note: Despite labels occupying their own line they do not count as instructions and therefore take up no instruction memory. This is an important consideration when using an (absolute) jump or (relative) branch, as line numbers will not reflect instruction addresses. Therefore it is advisable not to use a mixture of labels and offset values in one program.
Instruction | Description | Example | Result |
LB | Load Byte | LB R3 1(R0) | Loads Byte from memory location 1 |
LBU | Load Byte Unsigned | LBU R4 1(R0) | Loads Byte Unsigned from memory location 1 |
SB | Store Byte | SB R1 1(R0) | Stores Byte in R1 into memory location 1 |
LH | Load Halfword | LH R4 2(R0) | Loads Halfword from memory location 2 into R4 |
LHU | Load Halfword Unsigned | LHU R4 2(R0) | Loads Halfword Unsigned from memory location 2 into R4 |
LUI | Load Upper Immediate | LUI R1 124 | Load 124 in the the upper half of regester R1 |
SH | Store Halfword | SH R5 6(R0) | Stores Halfword from R5 into memory loction 6 |
LW | Load Word | LW R4 8(R0) | Loads Word from data memory location word 8 into R4 |
SW | Store Word | SW R3 16(R0) | Stores Word in R3 into location 16 in data memory |
Table 1a. Load/Store Instructions
Instruction | Description | Example | Result |
ADDI | Add Immediate Word | ADDI R1 R2 -4 | Store R2 + -4 in R1 |
ADDIU | Add Immediate Unsigned Word | ADDIU R1 R2 16 | Store R2 + 16 in R1 |
ADD | Add Word | ADD R1 R2 R3 | Store R2 + R3 in R1 |
ADDU | Add Word Unsigned | ADD R1 R2 R3 | Store R2 + R3 in R1 |
SUB | Subtract Word | SUB R1 R2 R3 | Store R2 - R3 in R1 |
SUBU | Subtract Word Unsigned | SUB R1 R2 R3 | Store R2 - R3 in R1 |
SLT | Set on less than | SLT R1 R2 R3 | If R2 is less than R3 set R1 to be 1 else set it to 0 |
SLTI | Set on less than Immediate | SLTI R1 R2 5 | If R2 is less than 5 then set R1 to 1 else set it to 0 |
SLTU | Set on less than Unsigned | SLTU R1 R2 R3 | If the unsigned value of R2 is less than the unsigned value R3 set R1 to 1 else set it to 0 |
SLTIU | Set on less than Immediate Unsigned | SLTIU R1 R2 6 | If the R2 is less than 6 (after sign extension) set R1 to 1 else set it to 0 |
Table 1b. Arithmetic Instructions:
Instruction | Description | Example | Result |
AND | And | AND R1 R2 R3 | Stores result of R2 AND R3 into R1 |
ANDI | And Immediate | ANDI R1 R1 19 | Stores the result of R1 AND 19 back into R1 |
OR | Or | OR R1 R2 R3 | Stores result of R2 OR R3 into R1 |
ORI | Or Immediate | ORI R1 R1 128 | Stores the result of R1 OR 128 back into R1 |
XOR | Exclusive Or | XOR R1 R2 R3 | Stores result of R2 XOR R3 into R1 |
XORI | Exclusive Or Immediate | XORI R1 R1 64 | Stores the result of R1 OR 64 back into R1 |
NOR | Nor | NOR R1 R2 R3 | Stores result of R2 NOR R3 into R1 |
SSL | Shift Word Left Logical | SSL R1 R2 4 | Shift R2 4 bits to the left and store in R1 |
SRL | Shift Word Right Logical | SRL R1 R2 2 | Shift R2 2 bits to the right and store in R1 |
SRA | Shift Word Right Arithmetic | SRA R3 R4 2 | Arithmrticaly shift R4 2 bits right and store in R3 |
SLLV | Shift Word Left Logical Varable | SLLV R1 R2 R3 | Shift R2 left by R3 bits and store in R1 |
SRLV | Shift Word Right Logical Varable | SRLV R1 R2 R3 | Shift R2 right by R3 bits and store in R1 |
SRAV | Shift Word Right Arithmetic Varable | SRAV R1 R2 R3 | Shift R2 right arithemeticaly by R3 bits and store in R1 |
Table 1c. Logical Instructions:
Instruction | Description | Example | Result |
J | Jump | J 8 | Jump to instruction 8 |
JR | Jump Register | J R1 | Jump to the instruction number held in R1 |
Table 1d. Jump Instructions:
Instruction | Description | Example | Result |
BEQ | Branch on equal | BEQ R1 R2 4 | Branch forward 4 instructions if R1 and R2 are equal |
BNE | Branch on not equal | BNE R1 R2 8 | Branch forward 8 instructions if R1 and R2 are not equal |
BLEZ | Branch on less than or equal to zero | BLEZ R2 -2 | Branch back 2 instructions if R2 is less than or equal to zero |
BGTZ | Branch on greater than zero | BGTZ R2 -2 | Branch back 2 instructions if R2 is greater than zero |
BLTZ | Branch on less than zero | BLTZ R2 3 | Branch forward 3 instructions if R2 is less than zero |
BGEZ | Branch on greater than or equal to zero | BGTZ R2 5 | Branch forward 5 instructions if R2 is greater than or equal to zero |
BLTZAL | Branch on less than zero and link | BLTZAL R2 3 | Branch forward 3 instructions if R2 is less than zero |
BGEZAL | Branch on greater than or equal to zero and link | BGTZAL R2 5 | Branch forward 5 instructions if R2 is greater than or equal to zero and link |
Table 1e. Branch Instructions:
Instruction | Description | Example | Result |
BREAK | Breakpoint | BREAK | Halt |
NOP | No Operation | NOP | No operation |
Table 1f. Other Instructions:
![]() |
![]() |
![]() |
Figure 3. Memory, Registers and Data Hazards Displays
The Memory receives instruction requests from the Instruction Fetch Unit and Read/Write requests from the Memory Access Unit and, as appropriate, either returns the contents of the requested memory word to the requesting unit or updates it. It checks for invalid addresses, and sets an error flag in the Scoreboard if either occurs. The size of each array is determined by parameter of the Memory entity, set to 256 as a default.
Data hazards are handled through Use bits. Each register has a Use bit which is set when an instruction that will write to the register is issued and reset when the result is written to the register. In the HASE MIPS model the registers are implemented as C++ structs with two fields: Use bit and value. In the Register Display Window shown in Figure 3, for example, Register 5 has its Use bit set and has a value of 16, while all the others are in the reset state. Before accessing a source or destination register, the Instruction Decode Unit invokes a class in the Registers entity which reads the relevant Use bit. If the Use bit for a Register required as a source operand is set, then there is a RAW hazard, as shown for Register 5 in the Data Hazards Display window. If the Use bit for a Register required as a destination operand is set, then there is a WAW hazard.
At the start of Clock phase 0 each pipeline entity sends an (untraced) packet to the Pipeline Display entity containing a copy of the instruction and status fields from within its own input packet. If the instruction is valid, the Pipeline Display entity 'prints' the instruction to the appropriate place on the screen; if the instruction is not valid it prints 'VOID'.
Instruction | Result/Comment |
ADDI R2 R0 15 | R2 = R0 + 15 (=15) |
ADDI R1 R0 1 | R1 = R0 + 1 (=1) |
loop1: | Label - does not count as an instruction |
ADDI R1 R1 1 | R1 = R1 + 1 (increment R1 by 1) |
ADD R3 R1 R0 | R3 = R1 + R0 (copy R1 to R3) |
loop2: | Label - does not count as an instruction |
ADD R3 R3 R1 | R3 = R3 + R1 (increment R3 by R1) |
SLT R4 R2 R3 | R4 = 1 if R2 < R3 else R4 = 0 |
BNE R4 R0 done | Branch to done if R4 != R0 (R4 != 0) |
SLL R5 R3 2 | R5 = R3 Left shifted 2 places |
J loop2 | Branch to loop2 |
SW R0 0(R5) | Delay slot: Store R0 at memory location R5 |
done: | Label - does not count as an instruction |
BNE R1 R2 loop1 | Branch to loop1 if R1 != R2 |
NOP | Delay slot: No operation |
BREAK | End the simulation |
NOP | No operation |
Return to Computer Architecture Simulation Models
HASE Project