Assignment 2: MIPS Multicycle Processor
Assignment Outline
Assignment 2 accounts for 15% of your overall mark in the EEE339 module. This assignment is to test your understanding of the behavioural specification of the MIPS-Lite multi-cycle processor design presented in the lectures.
A sample Verilog code is available at Appendix A.
You will need to add an instruction memory to the design and initialise it with your assembly code. The procedure is given in the Appendix B. Currently the memory initialization file of the instruction memory ROM is empty. You can write the machine code of your MIPS instructions into the memory locations of the initialisation file.
To ensure that it is your own work that is being assessed, Appendix C indicates the specific tasks for each student.
The assignment is to be undertaken in a series of steps which you should complete in order.
1. Sketch the ASM chart of the state machine. [10 Marks]
2. Write a programme to: [20 Marks in total and 4 Marks each]
a. Load the data stored in locations X and Y of the data memory into registers P and Q.
b. Add register P with constant 6 and store the result in the register R.
c. If the result in registers Q and R is equal to each other, then branch to instruction a.
d. Store the result in the register R into the memory location 24.
e. Jump to instruction a.
3. Simulate your program. To test instructions d and e, you need to change the data in the data memory at some stage. [30 Marks]
4. Add code to support R-type instructions such as AND, OR, sub, slt, and NOR, and simulate the instruction specified for each student in the attached table. [20 Marks]
5. Add some extensions to cope with the exceptions when an opcode not supported by this MIPS-lite processor is detected or PC goes into an address for data memory. [20 Marks]
Reports
Your report should include the following contents:
1. The ASM chart for the state machine.
2. The MIPS code and the corresponding machine code.
3. Simulation waveforms for the opcode, state, PC, IR, ALUOut and relevant registers (P, Q, R) must be demonstrated and annotated. You should clearly indicate why the simulations show that the operation is correct or incorrect.
4. Description of the modifications made to implement the additional instruction or extensions. Highlight the changes made in the code.
5. Lab demonstration for your work is not required.
6. The submission deadline is at 2 pm on Friday 12th December 2020 (Week 13). A hard copy should be submitted to the box in front of my office EE518 and a pdf file should be submitted to the ICE at the same time.
Appendix A
// The behavioural specification of a MIPS multicycle processor originaly developed for simulation by Patterson and Hennesy
// Modified by Dr. M. Xu in June 2010
module CPU (clock, reset, opcode, state, PC, IR, ALUOut, MDR, A, B, P, Q, R);
parameter R_Type = 6’b000000, LW = 6’b100011, SW = 6’b101011, BEQ=6’b000100, J=6’000010;
input clock, reset; //external inputs
output [31:0] PC, IR, ALUOut, MDR, A, B, P, Q, R;
output [2:0] state;
output [5:0] opcode;
// The architecturally visible registers and scratch registers for implementation
reg [31:0] PC, Regs[0:31], Memory [0:31], IR, ALUOut, MDR, A, B;
reg [2:0] state; // processor state
wire [5:0] opcode; //use to get opcode easily
wire [31:0] SignExtend,PCOffset; //used to get sign extended offset field
assign opcode = IR[31:26]; //opcode is upper 6 bits
assign SignExtend = {{16{IR[15]}},IR[15:0]}; //sign extension of lower 16-bits of instruction
assign PCOffset = SignExtend << 2; //PC offset is shifted
assign P = Regs[1]; // you must change registers according to your tasks !
assign Q = Regs[2];
assign R = Regs[3];
// set the PC to 0 and start the control in state 1
initial begin PC = 0; state = 1; end
//The state machine--triggered on a rising clock
always @(posedge clock or posedge reset) begin
Regs[0] = 0; // to make sure R0 is always 0
if (reset) begin
PC = 0;
state = 1;
Memory[16]=32'h00000005; // words 16-31 used for data memory
Memory[17]=32'h0000000B;
Memory[18]=32'h00000055;
Memory[19]=32'h000000BB;
Memory[20]=32'h00005555;
Memory[21]=32'h0000BBBB;
Memory[22]=32'h55555555;
Memory[23]=32'hBBBBBBBB;
// words 0-15 used for instruction memory
// add the machine code of your instructions here
end
else begin
case (state) //action depends on the state
1: begin // first step: fetch the instruction, increment PC, go to next state
IR <= Memory[PC>>2];
PC <= PC + 4;
state=2; //next state
end
2: begin // second step: Instruction decode, register fetch, also compute branch address
A <= Regs[IR[25:21]];
B <= Regs[IR[20:16]];
state= 3;
ALUOut <= PC + PCOffset; // compute PC-relative branch target
end
3: begin // third step: Load/store execution, ALU execution, Branch completion
state =4; // default next state
if ((opcode==LW) |(opcode==SW)) ALUOut <= A + SignExtend; //compute effective address
else if (opcode == R_Type) case (IR[5:0]) //case for the various R-type instructions
32: ALUOut= A + B; //add operation
default: ALUOut= A; //other R-type operations: subtract, SLT, etc.
endcase
else if (opcode == BEQ) begin
if (A==B) PC <= ALUOut; // branch taken--update PC
state = 1;
end
else if (opcode == J) begin
PC = {PC[31:28], IR[25:0],2'b00}; // the jump target PC
state = 1;
end //Jumps
else ; // other opcodes or exception for undefined instruction would go here
end
4: begin
if (opcode == R_Type) begin //ALU Operation
Regs[IR[15:11]] <= ALUOut; // write the result
state =1;
end //R-type finishes
else if (opcode == LW) begin // load instruction
MDR <= Memory[ALUOut>>2]; // read the memory
state =5; // next state
end
else if (opcode == SW) begin
Memory[ALUOut>>2] <= B; // write the memory
state = 1; // return to state 1
end //store finishes
else ; // other instructions go here
end
5: begin // LW is the only instruction still in execution
Regs[IR[20:16]] = MDR; // write the MDR to the register
state = 1;
end //complete a LW instruction
default: state = 1;
endcase
end
end
endmodule
Appdendix B
Inserting LPM ROM
Select MegaWizard Plug-In Manager from the tools menu and click on the Next button.
Select the ROM: 1-PORT and give a name to the output file. This name should be the same as the one which has been used for Instruction memory instantiation in your Verilog code.
Select the width and depth of the memory.
Deselect the input and output registers.
Give a name to the memory initialisation file, e.g. Instruction.mif. You can use your name as the file name. In this case you should edit the Verilog module name in the provided code.
Deselect the creation of the optional files and click on Finish button.
Click on the New icon and select the Memory Initialization File.
Input 32 for the Number of words and 32 for the Word size.
Now you can insert your machine code into the Instruction memory locations. You should be noted that this memory is not byte oriented and addresses are incremented by one not by 4.
Appendix C
ID
English Name
Memory locations (X,Y)
Registers
(P,Q,R)
Simulation
22,23
1,2,3
AND
PAGE
PAGE 10