Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
001
Matthew McTaggart
Project Abstract:
This project demonstrates the implementation of the 32bit MIPS processor architecture. The general
data path flow is shown in the following figure.
The dataflow is controlled by a clock which controls the program counter (PC) increment and the
pipeline registers given as IF/ID, ID/EX, EX/MEM, and MEM/WB. The five stages in this processor
architecture are the instruction fetch (IF), instruction decode (ID), execution (EX), data memory (MEM),
and write back (WB). In the case for the project, the instruction fetch is controlled by a slider switch
where the user enters the instructions into the pipeline on the positive edge, this is noted as the clock to
the system, and is called userinput. As per specification, the only output of the system is when the first
instruction has passed through the entire pipeline; this is denoted by the signal Status.
Introduction:
The MIPS instruction fetch implementation is based from the following schematic. The PCSrc signal and
the EX/MEM values are passed from the EX/MEM latch register. These control the program counter if a
branch on equal instruction occurs. The program counter is used to pass the instruction from the
instruction memory and the program counter increment is used to continually increment the program
counter such that instructions can be passed into the pipeline sequentially from the instruction memory
file.
Once the instruction has been fetched, it is passed to the instruction decode where the controls bits are
determined, and the registers to be read and written to. The WB, M, EX signals are passed through the
pipeline as control bits for the corresponding stages. The register is written to once instructed to from
the RegWrite signal from the WB stage. The register to be written to, and the value to be written for
that register, are determined from the WB stages multiplexor (mux).
In the execution stage, the branch address, if a branch on equal occurs, is determined from adding the
program counter increment and the sign extension of the 16bit address field characteristic of the MIPS Iformat. The jump signal, or the PCSrc is dependent on the ALUResult being zero, asserting the Zero
signal, and the M branch control signal being asserted.
The RegDst source is controlled from the EX control bit, and passes the correct destination register to for
write back depending on whether the instruction is MIPS R-format or MIPS I-format. The first five bits of
the instruction is the function bits, and this controls the ALU function through the ALU Control module.
Finally the second ALU data source is controlled by the ALUScr control signal. This controls whether
Read Data 2 passes to the ALU, for MIPS R-format, or the sign extension of the immediate, for MIPS I
format.
The Branch AND gate controls the PcScr in the instruction fetch stage, and the MemWrite and MemRead
signals are controlled by the control signals passed from the execution stage. The destination of the
write back mux is determined from the control signal MemToReg passed from the execution stage.
Output Waveform:
Testbench Code:
ID/EX Register Latch Output
Testbench Code:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Peter Rancourt & Matthew McTaggart
// Engineer: CMPEN331.001
//////////////////////////////////////////////////////////////////////////////////
module testbench();
//IF
reg clock;
wire [31:0] InstMem;
wire [31:0] PcIncr;
//IFID Latch
wire [31:0] InstMem1;
wire [31:0] PcIncr1;
//ID
wire [1:0] WB;
wire [2:0] M;
wire [3:0] EX;
wire [31:0] IDIFPcIncr;
wire [31:0] Data1;
wire [31:0] Data2;
wire [31:0] SE;
wire [4:0] Rt;
wire [4:0] Rd;
//IDEX Latch
wire [1:0] WB1;
wire [2:0] M1;
wire [3:0] EX1;
wire [31:0] IDIFPcIncr1;
wire [31:0] Data11;
wire [31:0] Data21;
wire [31:0] SE1;
wire [4:0] Rt1;
wire [4:0] Rd1;
//EX
wire [1:0] WB2;
wire [2:0] M2;
wire [31:0] AdderOut2;
wire AluZero2;
wire [31:0] AluOut2;
wire [31:0] Data22;
wire [4:0] MuxOutReg2;
wire [2:0] AluCont;
//EXMEM Latch
wire [1:0] WB3;
wire [2:0] M3;
wire [31:0] AdderOut3;
wire AluZero3;
wire [31:0] AluOut3;
wire [31:0] Data23;
wire [4:0] MuxOutReg3;
//MEM
wire [1:0] WB4;
wire [31:0] ReadData4;
wire [31:0] AluResult4;
wire [4:0] MuxOutReg4;
wire BranchPcMux;
//MEMWB Latch
wire [1:0] WB5;
wire [31:0] ReadData5;
wire [31:0] AluResult5;
wire [4:0] MuxOutReg5;
//WB Stage
wire [31:0] WBMuxOut;
wire Status;
//MODULE INSTANTIATIONS
//IF
IFSTAGE
ifTest(clock,BranchPcMux,AdderOut3,InstMem,PcIncr);
IFIDLATCH
ifLatchTest(clock,InstMem,PcIncr,InstMem1,PcIncr1);
//ID
IDSTAGE
idTest(InstMem1,PcIncr1,WB5[1],MuxOutReg5,WBMuxOut,WB,M,EX,IDIFPcIncr,Data1,Data2,SE,Rt,Rd);
IDEXLATCH
idLatchTest(clock,WB,M,EX,IDIFPcIncr,Data1,Data2,SE,Rt,Rd,WB1,M1,EX1,IDIFPcIncr1,Data11,Data21,SE
1,Rt1,Rd1);
//EX
EXSTAGE
exTest(WB1,M1,EX1,IDIFPcIncr1,Data11,Data21,SE1,Rt1,Rd1,WB2,M2,AdderOut2,AluZero2,AluOut2,Data22,
MuxOutReg2,AluCont);
EXMEMLATCH
exLatchTest(clock,WB2,M2,AdderOut2,AluZero2,AluOut2,Data22,MuxOutReg2,WB3,M3,AdderOut3,AluZero3,A
luOut3,Data23,MuxOutReg3);
//MEM
MEMSTAGE
memTest(WB3,M3,AdderOut3,AluZero3,AluOut3,Data23,MuxOutReg3,WB4,ReadData4,AluResult4,MuxOutReg4,B
ranchPcMux);
MEMWBLATCH
memLatchTest(clock,WB4,ReadData4,AluResult4,MuxOutReg4,WB5,ReadData5,AluResult5,MuxOutReg5);
//WB
WBSTAGE
wbTest(WB5,ReadData5,AluResult5,WBMuxOut);
initial begin
//InstMem = 32'h00000000;
clock = 0; //Cycle 0
#10 clock = 1;
//InstMem = 32'h002300AA;
#5 clock = 0; //Cycle 2
#5 clock = 1;
//InstMem = 32'h10654321;
#5 clock = 0; //Cycle 3
#5 clock = 1;
// InstMem = 32'h00100022;
#5 clock = 0; //Cycle 4
#5 clock = 1;
//InstMem = 32'h8C123456;
#5 clock = 0; //Cycle 5
#5 clock = 1;
//InstMem = 32'h8F123456;
#5 clock = 0; //Cycle 6
#5 clock = 1;
//InstMem = 32'hAD654321;
#5 clock = 0; //Cycle 7
#5 clock = 1;
//InstMem = 32'h13012345;
#5 clock = 0; //Cycle 8
#5 clock = 1;
//InstMem = 32'hAC654321;
#5 clock = 0; //Cycle 9
#5 clock = 1;
//InstMem = 32'h12012345;
#5 clock = 0; //Cycle 10
#5 clock = 1;
//InstMem = 32'h00000000;
#5 clock = 0; //Cycle 11
#5 clock = 1;
//InstMem = 32'h00000000;
#5 clock = 0; //Cycle 12
#5 clock = 1;
//InstMem = 32'h00000000;
#5 clock = 0; //Cycle 13
#5 clock = 1;
//InstMem = 32'h00000000;
#5 clock = 0; //Cycle 14
#5 clock = 1;
//InstMem = 32'h00000000;
#5 clock = 0; //Cycle 15
#5 clock = 1;
//InstMem = 32'h00000000;
#5 clock = 0; //Cycle 16
#5 clock = 1;
//InstMem = 32'h00000000;
end
always @(posedge clock)
begin
#1
$display("T = %d WB(IDEX) = %b M(IDEX) = %b EX(IDEX) = %b PCPass(IDEX) = %d Data1(IDEX) =
%d Data2(IDEX) = %d SExt(IDEX) = %d Rs(IDEX) = %d Rd(IDEX) = %d T = %d WB(EXMEM) = %b M(EXMEM) =
%b Adder(EXMEM) = %d AluZero(EXMEM) = %d AluOut(EXMEM) = %d WriteData(EXMEM) = %d RegMux(EXMEM) =
%d T = %d WB(MEMWB)= %b ReadData(MEMWB) = %d AluResult(MEMWB) = %d WBRegister(MEMWB) =
%d",$time,WB1,M1,EX1,IDIFPcIncr1,Data11,Data21,SE1,Rt1,Rd1,$time,WB3,M3,AdderOut3,AluZero3,AluOut
3,Data23,MuxOutReg3,$time,WB5,ReadData5,AluResult5,MuxOutReg5); end
endmodule
Design Schematic
Overview:
The input is the user control of the instruction fetch, and the output is an LED indication when a branch
instruction occurs.
The status knows information about the first instruction and indicates that the light should assert once
the condition is met.
Routed Design:
Result Image:
The LED did in fact light up when expected, at T 60ns on the waveform simulation.
module MIPSprocessor(userinput,Status);
input userinput;
//Slide Input by user to control the instruction fetching. (User
Defined Clock, so to speak). The slider will be indicated in the
output Status;
//On the board, a light will indicate when a branch instruction occurs. We
know that at the second instruction, we'll get an LED lit. It will be defined in the constraints
file.
//IF
wire [31:0] InstMem;
wire [31:0] PcIncr;
//IFID Latch
wire [31:0] InstMem1;
wire [31:0] PcIncr1;
//ID
wire [1:0] WB;
wire [2:0] M;
wire [3:0] EX;
wire [31:0] IDIFPcIncr;
wire [31:0] Data1;
wire [31:0] Data2;
wire [31:0] SE;
wire [4:0] Rt;
wire [4:0] Rd;
//IDEX Latch
wire [1:0] WB1;
wire [2:0] M1;
wire [3:0] EX1;
wire [31:0] IDIFPcIncr1;
wire [31:0] Data11;
wire [31:0] Data21;
wire [31:0] SE1;
//EX
wire [1:0] WB2;
wire [2:0] M2;
wire [31:0] AdderOut2;
wire AluZero2;
wire [31:0] AluOut2;
wire [31:0] Data22;
wire [4:0] MuxOutReg2;
wire [2:0] AluCont;
//EXMEM Latch
wire [1:0] WB3;
wire [2:0] M3;
wire [31:0] AdderOut3;
wire AluZero3;
wire [31:0] AluOut3;
wire [31:0] Data23;
wire [4:0] MuxOutReg3;
//MEM
wire [1:0] WB4;
wire [31:0] ReadData4;
wire [31:0] AluResult4;
wire [4:0] MuxOutReg4;
wire BranchPcMux;
//MEMWB Latch
wire [1:0] WB5;
wire [31:0] ReadData5;
wire [31:0] AluResult5;
wire [4:0] MuxOutReg5;
//WB Stage
wire [31:0] WBMuxOut;
wire Status;
//testing
//assign branch = M3[2]&AluZero3;
//wire branch;
//MODULE INSTANTIATIONS
//IF
IFSTAGE
ifTest(userinput,BranchPcMux,AdderOut3,InstMem,PcIncr);
IFIDLATCH
ifLatchTest(userinput,InstMem,PcIncr,InstMem1,PcIncr1);
//ID
IDSTAGE
idTest(InstMem1,PcIncr1,WB5[1],MuxOutReg5,WBMuxOut,WB,M,EX,IDIFPcIncr,Data1,Data2,SE,Rt,Rd);
IDEXLATCH
idLatchTest(userinput,WB,M,EX,IDIFPcIncr,Data1,Data2,SE,Rt,Rd,WB1,M1,EX1,IDIFPcIncr1,Data11,Data2
1,SE1,Rt1,Rd1);
//EX
EXSTAGE
exTest(WB1,M1,EX1,IDIFPcIncr1,Data11,Data21,SE1,Rt1,Rd1,WB2,M2,AdderOut2,AluZero2,AluOut2,Data22,
MuxOutReg2,AluCont);
EXMEMLATCH
exLatchTest(userinput,WB2,M2,AdderOut2,AluZero2,AluOut2,Data22,MuxOutReg2,WB3,M3,AdderOut3,AluZer
o3,AluOut3,Data23,MuxOutReg3);
//MEM
MEMSTAGE
memTest(WB3,M3,AdderOut3,AluZero3,AluOut3,Data23,MuxOutReg3,WB4,ReadData4,AluResult4,MuxOutReg4,B
ranchPcMux);
MEMWBLATCH
memLatchTest(userinput,WB4,ReadData4,AluResult4,MuxOutReg4,WB5,ReadData5,AluResult5,MuxOutReg5);
//WB
WBSTAGE
wbTest(WB5,ReadData5,AluResult5,WBMuxOut);
endmodule
Bonus:
Output Waveform:
We can see in fact we get 12 being written back to register 1 indicated by the last two waveforms.
Results:
The outputs of R1, R2, R3 from the register file: