diff options
Diffstat (limited to 'ee4363')
-rw-r--r-- | ee4363/mp2/mipspipe_mp2.v | 81 |
1 files changed, 55 insertions, 26 deletions
diff --git a/ee4363/mp2/mipspipe_mp2.v b/ee4363/mp2/mipspipe_mp2.v index 2e8b98b..303522a 100644 --- a/ee4363/mp2/mipspipe_mp2.v +++ b/ee4363/mp2/mipspipe_mp2.v @@ -10,12 +10,12 @@ module mipspipe_mp2 (clock); IFIDIR, IDEXA, IDEXB, IDEXIR, EXMEMIR, EXMEMB, // pipeline latches EXMEMALUOut, MEMWBValue, MEMWBIR; - wire [4:0] IDEXrs, IDEXrt, EXMEMrd, MEMWBrd, MEMWBrt; // hold register fields - wire [5:0] EXMEMop, MEMWBop, IDEXop; // hold opcodes + wire [4:0] IDEXrs, IDEXrt, EXMEMrd, MEMWBrd, MEMWBrt, IFIDrt, IFIDrs; // hold register fields + wire [5:0] EXMEMop, MEMWBop, IDEXop, IFIDop; // hold opcodes wire [31:0] Ain, Bin; // ALU inputs // declare the bypass signals - wire bypassAfromMEM, bypassAfromALUinWB, bypassBfromMEM, bypassBfromALUinWB, bypassAfromLWinWB, bypassBfromLWinWB; + wire bypassAfromMEM, bypassAfromALUinWB, bypassBfromMEM, bypassBfromALUinWB, bypassAfromLWinWB, bypassBfromLWinWB, bypassIDEXAfromWB, bypassIDEXBfromWB, STALL; // Define fields of pipeline latches assign IDEXrs = IDEXIR[25:21]; // rs field @@ -26,6 +26,9 @@ module mipspipe_mp2 (clock); assign EXMEMop = EXMEMIR[31:26]; // opcode assign MEMWBop = MEMWBIR[31:26]; // opcode assign IDEXop = IDEXIR[31:26]; // opcode + assign IFIDrs = IFIDIR[25:21]; + assign IFIDrt = IFIDIR[20:16]; + assign IFIDop = IFIDIR[31:26]; // The bypass to input A from the MEM stage for an ALU operation @@ -40,18 +43,30 @@ module mipspipe_mp2 (clock); assign bypassAfromLWinWB = (IDEXrs == MEMWBIR[20:16]) & (IDEXrs!=0) & (MEMWBop==LW); // The bypass to input B from the WB stage for an LW operation assign bypassBfromLWinWB = 0; - + //Stall in case of WB + assign bypassIDEXAfromWB = ((MEMWBIR != nop) & (IFIDIR != nop) & (IFIDrs == MEMWBrt) & (MEMWBop == LW)) | + ((MEMWBop == ALUop) & (MEMWBrd == IFIDrs)); + assign bypassIDEXBfromWB = ((MEMWBIR != nop) & (IFIDIR != nop) & (IFIDrt == MEMWBrt) & (MEMWBop == LW)) | + ((MEMWBop == ALUop) & (MEMWBrd == IFIDrt)); // The A input to the ALU is bypassed from MEM if there is a bypass there, // Otherwise from WB if there is a bypass there, and otherwise comes from the IDEX register assign Ain = bypassAfromMEM? EXMEMALUOut : (bypassAfromALUinWB | bypassAfromLWinWB)? MEMWBValue : IDEXA; // The B input to the ALU is bypassed from MEM if there is a bypass there, // Otherwise from WB if there is a bypass there, and otherwise comes from the IDEX register - assign Bin = IDEXB; + // Ripped off of above just replacing "A" with "B" + assign Bin = bypassBfromMEM? EXMEMALUOut : (bypassBfromALUinWB | bypassBfromLWinWB)? MEMWBValue : IDEXB; reg [5:0] i; // used to initialize latches reg [10:0] j,k; // used to initialize memories + + // Make the Big Stall + assign STALL = (IDEXop == LW) && + //All of this is anded with the above (Lisp would be proud) + (((IFIDop == LW) && (IFIDrs == IDEXrt)) | + ((IFIDop == ALUop) && ((IFIDrs == IDEXrt) | (IFIDrt == IDEXrt))) | + ((IFIDop == SW) && ((IFIDrs == IDEXrt) | (IFIDrt == IDEXrt)))); initial begin PC = 0; @@ -62,16 +77,16 @@ module mipspipe_mp2 (clock); for (i = 0;i<=31;i = i+1) Regs[i] = i; // initialize latches - IMemory[0] = 32'h00412820; - IMemory[1] = 32'h8ca30004; - IMemory[2] = 32'haca70005; - IMemory[3] = 32'h00602020; - IMemory[4] = 32'h01093020; - IMemory[5] = 32'hac06000c; - IMemory[6] = 32'h00c05020; - IMemory[7] = 32'h8c0b0010; - IMemory[8] = 32'h00000020; - IMemory[9] = 32'h002b6020; + IMemory[0] = 32'h00412820; // ADD $5, $2, $1 + IMemory[1] = 32'h8ca30004; // LW $3, 4($5) + IMemory[2] = 32'haca70005; // SW $7, 5($5) + IMemory[3] = 32'h00602020; // ADD $4, $3, $0 + IMemory[4] = 32'h01093020; // ADD $6, $8, $9 + IMemory[5] = 32'hac06000c; // SW $6, $12($0) + IMemory[6] = 32'h00c05020; // ADD $10, $6, $0 + IMemory[7] = 32'h8c0b0010; // LW $11, 32($0) + IMemory[8] = 32'h00000020; // ADD $0, $0, $0 + IMemory[9] = 32'h002b6020; // ADD $12, $1, $11 for (j=10; j<=1023; j=j+1) IMemory[j] = nop; DMemory[0] = 32'h00000000; @@ -82,17 +97,31 @@ module mipspipe_mp2 (clock); for (k=5; k<=1023; k=k+1) DMemory[k] = 0; end - always @ (posedge clock) - begin - - // FETCH: Fetch instruction & update PC - IFIDIR <= IMemory[PC>>2]; - PC <= PC + 4; - - // DECODE: Read registers - IDEXA <= Regs[IFIDIR[25:21]]; - IDEXB <= Regs[IFIDIR[20:16]]; - IDEXIR <= IFIDIR; + always @ (posedge clock) begin + if (~STALL) begin + // FETCH: Fetch instruction & update PC + IFIDIR <= IMemory[PC>>2]; + PC <= PC + 4; + + // DECODE: Read registers + if (~bypassIDEXAfromWB) begin + IDEXA <= Regs[IFIDIR[25:21]]; + end + else begin + IDEXA <= MEMWBValue; + end + + if (~bypassIDEXBfromWB) begin + IDEXB <= Regs[IFIDIR[20:16]]; + end + else begin + IDEXB <= MEMWBValue; + end + IDEXIR <= IFIDIR; + end + else begin //IF (STALL) + IDEXIR <= nop; + end // EX: Address calculation or ALU operation if ((IDEXop==LW) |(IDEXop==SW)) // address calculation & copy B |