aboutsummaryrefslogtreecommitdiffstats
path: root/ee4363/mp2
diff options
context:
space:
mode:
Diffstat (limited to 'ee4363/mp2')
-rw-r--r--ee4363/mp2/mipspipe_mp2.v125
-rw-r--r--ee4363/mp2/test_mipspipe_mp2.v53
2 files changed, 178 insertions, 0 deletions
diff --git a/ee4363/mp2/mipspipe_mp2.v b/ee4363/mp2/mipspipe_mp2.v
new file mode 100644
index 0000000..2e8b98b
--- /dev/null
+++ b/ee4363/mp2/mipspipe_mp2.v
@@ -0,0 +1,125 @@
+// Incomplete behavioral model of MIPS pipeline
+
+module mipspipe_mp2 (clock);
+ // in_out
+ input clock;
+
+ // Instruction opcodes
+ parameter LW = 6'b100011, SW = 6'b101011, BEQ = 6'b000100, nop = 32'b00000_100000, ALUop = 6'b0;
+ reg [31:0] PC, Regs[0:31], IMemory[0:1023], DMemory[0:1023], // instruction and data memories
+ 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 [31:0] Ain, Bin; // ALU inputs
+
+ // declare the bypass signals
+ wire bypassAfromMEM, bypassAfromALUinWB, bypassBfromMEM, bypassBfromALUinWB, bypassAfromLWinWB, bypassBfromLWinWB;
+
+ // Define fields of pipeline latches
+ assign IDEXrs = IDEXIR[25:21]; // rs field
+ assign IDEXrt = IDEXIR[20:16]; // rt field
+ assign EXMEMrd = EXMEMIR[15:11]; // rd field
+ assign MEMWBrd = MEMWBIR[15:11]; // rd field
+ assign MEMWBrt = MEMWBIR[20:16]; // rt field -- for loads
+ assign EXMEMop = EXMEMIR[31:26]; // opcode
+ assign MEMWBop = MEMWBIR[31:26]; // opcode
+ assign IDEXop = IDEXIR[31:26]; // opcode
+
+
+ // The bypass to input A from the MEM stage for an ALU operation
+ assign bypassAfromMEM = (IDEXrs == EXMEMrd) & (IDEXrs!=0) & (EXMEMop==ALUop);
+ // The bypass to input B from the MEM stage for an ALU operation
+ assign bypassBfromMEM = 0;
+ // The bypass to input A from the WB stage for an ALU operation
+ assign bypassAfromALUinWB = 0;
+ // The bypass to input B from the WB stage for an ALU operation
+ assign bypassBfromALUinWB = 0;
+ // The bypass to input A from the WB stage for an LW operation
+ 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;
+
+ // 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;
+
+
+ reg [5:0] i; // used to initialize latches
+ reg [10:0] j,k; // used to initialize memories
+
+ initial begin
+ PC = 0;
+ IFIDIR = nop;
+ IDEXIR = nop;
+ EXMEMIR = nop;
+ MEMWBIR = nop; // no-ops in pipeline latches
+
+ 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;
+ for (j=10; j<=1023; j=j+1) IMemory[j] = nop;
+
+ DMemory[0] = 32'h00000000;
+ DMemory[1] = 32'hffffffff;
+ DMemory[2] = 32'h00000000;
+ DMemory[3] = 32'h00000000;
+ DMemory[4] = 32'hfffffffe;
+ 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;
+
+ // EX: Address calculation or ALU operation
+ if ((IDEXop==LW) |(IDEXop==SW)) // address calculation & copy B
+ EXMEMALUOut <= Ain +{{16{IDEXIR[15]}}, IDEXIR[15:0]};
+ else if (IDEXop==ALUop) begin
+ case (IDEXIR[5:0]) // R-type instruction
+ 32: EXMEMALUOut <= Ain + Bin; // add operation
+ default: ; // other R-type operations: subtract, SLT, etc.
+ endcase
+ end
+
+ EXMEMIR <= IDEXIR;
+ EXMEMB <= Bin; // pass along the IR & B register
+
+ // MEM
+ if (EXMEMop==ALUop) MEMWBValue <= EXMEMALUOut; // pass along ALU result
+ else if (EXMEMop == LW) MEMWBValue <= DMemory[EXMEMALUOut>>2];
+ else if (EXMEMop == SW) DMemory[EXMEMALUOut>>2] <=EXMEMB; // store
+
+ MEMWBIR <= EXMEMIR; // pass along IR
+
+ // WB
+ if ((MEMWBop==ALUop) & (MEMWBrd != 0)) // update latches if ALU operation and destination not 0
+ Regs[MEMWBrd] <= MEMWBValue; // ALU operation
+ else if ((MEMWBop == LW)& (MEMWBrt != 0)) // Update latches if load and destination not 0
+ Regs[MEMWBrt] <= MEMWBValue;
+ end
+
+endmodule
+
diff --git a/ee4363/mp2/test_mipspipe_mp2.v b/ee4363/mp2/test_mipspipe_mp2.v
new file mode 100644
index 0000000..f184011
--- /dev/null
+++ b/ee4363/mp2/test_mipspipe_mp2.v
@@ -0,0 +1,53 @@
+//
+// Test bench for the mipspipe
+// Boram Lee
+//
+
+`include "mipspipe_mp2.v"
+
+module test_mipspipe;
+
+ reg clock;
+ reg [3:0] clock_cycle;
+
+// instantiate pipeline module
+ mipspipe_mp2 u_mipspipe_mp2(clock);
+
+// initialize clock and cycle counter
+ initial begin
+ clock = 0;
+ clock_cycle=4'h0;
+ #160 $finish;
+ end
+
+// 10 unit clock cycle
+ always
+ #5 clock = ~clock;
+
+ always @(posedge clock)
+ begin
+ clock_cycle=clock_cycle+1;
+ end
+
+
+// display contents of pipeline latches at the end of each clock cycle
+ always @(negedge clock)
+ begin
+ $display("\n\nclock cycle = %d",clock_cycle," (time = %1.0t)",$time);
+ $display("IF/ID registers\n\t IF/ID.PC+4 = %h, IF/ID.IR = %h \n", u_mipspipe_mp2.PC, u_mipspipe_mp2.IFIDIR);
+ $display("ID/EX registers\n\t ID/EX.rs = %d, ID/EX.rt = %d",u_mipspipe_mp2.IDEXrs,u_mipspipe_mp2.IDEXrt,"\n\t ID/EX.A = %h, ID/EX.B = %h",u_mipspipe_mp2.IDEXA,u_mipspipe_mp2.IDEXB);
+ $display("\t ID/EX.op = %h\n",u_mipspipe_mp2.IDEXop);
+ $display("EX/MEM registers\n\t EX/MEM.rs = %d, EX/MEM.rt = %d",u_mipspipe_mp2.IDEXrs,u_mipspipe_mp2.IDEXrt,"\n\t EX/MEM.ALUOut = %h, EX/MEM.ALUout = %h",u_mipspipe_mp2.EXMEMALUOut,u_mipspipe_mp2.EXMEMB);
+ $display("\t EX/MEM.op = %h\n",u_mipspipe_mp2.EXMEMop);
+ $display("MEM/WB registers\n\t MEM/WB.rd = %d, MEM/WB.rt = %d",u_mipspipe_mp2.MEMWBrd,u_mipspipe_mp2.MEMWBrt,"\n\t MEM/WB.value = %h",u_mipspipe_mp2.MEMWBValue);
+ $display("\t EX/MEM.op = %h\n",u_mipspipe_mp2.MEMWBop);
+ end
+
+// log to a vcd (variable change dump) file
+ initial
+ begin
+ $dumpfile("test_mipspipe.vcd");
+ $dumpvars;
+ end
+
+endmodule