📄 cpu_part1.v
字号:
//Implementation of Dual Issue 5 Stage Pipeline architecture that takes care of dependenciesmodule CPU (clock); // Instruction opcodes parameter LW = 6'b100011, SW = 6'b101011, BEQ = 6'b000100, NOP = 32'b0, ALUop = 6'b0,BNE=6'b000101; input clock; reg[31:0] PC, Regs[0:31], IMemory[0:1023],DMemory[0:1023],// separate memories IFIDIR, IDEXIR, EXMEMIR, MEMWBIR, //Pipeline registers IDEXA, IDEXB, // Register File Outputs 32 bit data EXMEMB, // Read B data for address EXMEMALUOut, MEMWBValue, // pipeline registers IFIDIR2, IDEXIR2, EXMEMIR2, MEMWBIR2, //Pipeline registers IDEXA2, IDEXB2, // Register File Outputs 32 bit data EXMEMB2, // Read B data for address EXMEMALUOut2, MEMWBValue2; // pipeline registers reg[1:0]SRegs[0:31]; reg [1:0] BFlag ,BFlag2,BTFlag,BTFlag2,HFlag,HFlag2,SwapFlag; // for handling branch instructions //BTflags if set imply that the Branch is taken //SwapFlag tells : First instrunction is a branch and that swap has taken place //HFlags indicate that RAW hazard present issue corr no of NOPs set as indicated by their value //BFlag incdicate the presence if branch instruction and that it is being evaluated // These wires will serve as wire [4:0] IDEXrs, IDEXrt, MEMWBrd, MEMWBrt; // Access register fields wire [5:0] IFIDop,EXMEMop, MEMWBop, IDEXop; // Access opcodes wire [31:0] Ain, Bin; // the ALU inputs wire [4:0] IFIDrs,IFIDrt,IFIDrd; //access rs and rt wire [4:0] IDEXrs2, IDEXrt2, MEMWBrd2, MEMWBrt2; // Access 2register fields wire [5:0] IFIDop2,EXMEMop2, MEMWBop2, IDEXop2; // Access 2 opcodes wire [31:0] Ain2, Bin2; // the ALU 2 inputs wire [4:0] IFIDrs2,IFIDrt2,IFIDrd2; //access Rs and Rt // These assignments define fields from the pipeline registers assign IFIDrs =IFIDIR[25:21]; assign IFIDrt =IFIDIR[20:16]; assign IFIDrd =IFIDIR[15:11]; assign IFIDrs2 =IFIDIR2[25:21]; assign IFIDrt2 =IFIDIR2[20:16]; assign IFIDrd2 =IFIDIR2[15:11]; assign IDEXrs = IDEXIR[25:21]; // rs field - R/I type assign MEMWBrd = MEMWBIR[15:11]; //rd field assign MEMWBrt = MEMWBIR[20:16]; //rt field--used for loads assign IFIDop=IFIDIR[31:26];// the opcodes assign EXMEMop = EXMEMIR[31:26]; // the opcodes assign MEMWBop = MEMWBIR[31:26]; // the opcodes assign IDEXop = IDEXIR[31:26] ; // the opcodes assign IDEXrs2 = IDEXIR2[25:21]; // rs field - R/I type assign MEMWBrd2 = MEMWBIR2[15:11]; //rd field assign MEMWBrt2 = MEMWBIR2[20:16]; //rt field--used for loads assign IFIDop2=IFIDIR2[31:26];// the opcodes assign EXMEMop2 = EXMEMIR2[31:26]; // the opcodes assign MEMWBop2 = MEMWBIR2[31:26]; // the opcodes assign IDEXop2 = IDEXIR2[31:26] ; // the opcodes // Inputs to the ALU come directly from the ID/EX pipeline registers assign Ain = IDEXA; assign Bin = IDEXB; assign Ain2 = IDEXA2; assign Bin2 = IDEXB2; reg [5:0] i; //used to initialize registers initial begin PC = 0; //note PC is the index used to access the Instr Mem and does NOT show the actual contents of PC IFIDIR = NOP; IDEXIR = NOP; EXMEMIR = NOP; MEMWBIR = NOP; // put no-ops in pipeline registers IFIDIR2 = NOP; IDEXIR2 = NOP; EXMEMIR2 = NOP; MEMWBIR2 = NOP; BFlag=0;BFlag2=0;HFlag=0;HFlag2=0;BTFlag=0;BTFlag2=0;SwapFlag=0; for (i=0;i<=31;i=i+1) Regs[i] = i; //initialize registers--just so they aren?t cares for (i=0;i<=31;i=i+1) SRegs[i] = 0; //initialize registers--just so they aren?t cares // ===================================================================== // Initialize Instruction Memory // =================================================================== IMemory[0] = 32'b00000000000000000000000000000000; //NOP //IMemory[1] = 32'b10001101010010110000000000000000; //lw r11<-M[r10+0] IMemory[1] = 32'b00000000110001110010100000000000; //ADD r5=r6+r7 IMemory[2] = 32'b00000000011001000001000000000000;//add r2=r3+r4 IMemory[3] = 32'b00010000010001100000000000000100;//BNE // ===================================================================== // Initialize Data Memory // ===================================================================== for (i=0;i<=31;i=i+1) DMemory[i] = i; end // initial always @ (posedge clock) begin // Remember that ALL these actions happen every pipe stage and with the use of <= they happen in parallel! // ========================================================================= // Stage 1 - Instruction Fetch Stage // ------------------------------------------------------------------------- if(HFlag==0 && HFlag2==0)begin if(BFlag2==0 && BFlag==0) begin //No branches if(BTFlag2==0&& BTFlag==0)begin //normal condition IFIDIR <= IMemory[PC>>2]; IFIDIR2 <= IMemory[(PC+4)>>2]; PC<=PC+8; end else begin //implies branch is taken if(BTFlag==1) begin //implies 1st instr was the branch IFIDIR<=IMemory[(PC+(MEMWBIR2[15:0]>>2))]; //PC is already incremented in prev cycle IFIDIR2<= IMemory[(PC+(MEMWBIR2[15:0]>>2)+4)]; PC<=PC+8; BTFlag<=0; end if(BTFlag2==1) begin //implies 2 nd instruction was a branch IFIDIR<=IMemory[(PC+(MEMWBIR2[15:0]>>2))]; //PC is already incremented in prev cycle IFIDIR2<=IMemory[(PC+(MEMWBIR2[15:0]>2)+4)]; PC<=PC+8; BTFlag2<=0; end end //end of Branch taken check end else begin //branch being evaluated if(BFlag ==2 ||BFlag==3)begin IFIDIR<=NOP; IFIDIR2<=NOP; BFlag<=BFlag-1; end if(BFlag==1)begin IFIDIR<=NOP; IFIDIR2<=NOP; BFlag<=BFlag-1; PC<=PC-4; end if(BFlag2!=0) begin IFIDIR<=NOP; IFIDIR2<=NOP; BFlag2<=BFlag2-1; end end //end of branch evaluation check end else begin //presence of RAW hazards if(HFlag==3 ||HFlag==2) begin IFIDIR<=NOP; IFIDIR2<=NOP; HFlag<=HFlag-1; end if(HFlag==1) begin IFIDIR<=NOP; IFIDIR2<=NOP; HFlag<=HFlag-1; PC<=PC-4; end if(HFlag2!=0) begin IFIDIR<=NOP; IFIDIR2<=NOP; HFlag2<=HFlag2-1; end end //end // Fetch & increment PC // ========================================================================= // Stage 2 - Decode Stage // ------------------------------------------------------------------------- if(IFIDIR!=NOP) begin if(IFIDop==ALUop)begin if((SRegs[IFIDIR[25:21]]!=1) && (SRegs[IFIDIR[20:16]]!=1))begin //rs and rt not equal to rd SRegs[IFIDIR[15:11]]<=1; //set rd IDEXA <= Regs[IFIDIR[25:21]]; IDEXB <= Regs[IFIDIR[20:16]]; IDEXIR <= IFIDIR; if(IFIDIR2!=NOP) begin if(IFIDop2==ALUop)begin //I2 an ALU op if((SRegs[IFIDIR2[25:21]]!=1) && (SRegs[IFIDIR2[20:16]]!=1))begin SRegs[IFIDIR2[15:11]] <=1; //set rd IDEXA2 <= Regs[IFIDIR2[25:21]]; IDEXB2 <= Regs[IFIDIR2[20:16]]; IDEXIR2<=IFIDIR2; if(IFIDIR[15:11]==IFIDIR[15:11]) //WAW check IDEXIR<=NOP; end else begin IDEXIR2<= NOP; HFlag2<=3; end end else if(IFIDop2==BEQ || IFIDop2==BNE)begin if((SRegs[IFIDIR2[25:21]]!=1 )&& (SRegs[IFIDIR2[20:16]]!=1))begin BFlag2<=3; //introduce 3 NOPs IDEXA2 <= Regs[IFIDIR2[25:21]]; IDEXB2 <= Regs[IFIDIR2[20:16]]; IDEXIR2<= IFIDIR2; end else begin IDEXIR2<= NOP; HFlag2<=3; end end else if(IFIDop2==LW) begin SRegs[IFIDIR2[20:16]]<=1; //set dest to 1 IDEXA2 <= Regs[IFIDIR2[25:21]]; IDEXB2 <= Regs[IFIDIR2[20:16]]; IDEXIR2 <= IFIDIR2; if(IFIDIR[20:15]==IFIDIR2[15:11])//WAW ALU-LW check IFIDIR<=NOP; end else begin IDEXA2 <= Regs[IFIDIR2[25:21]]; IDEXB2 <= Regs[IFIDIR2[20:16]]; IDEXIR2 <= IFIDIR2; end end else begin //I2 is a NOP IDEXA2 <= Regs[IFIDIR2[25:21]]; IDEXB2 <= Regs[IFIDIR2[20:16]]; IDEXIR2 <= IFIDIR2; end end else begin //I1 fails RAW test IDEXIR<=NOP; IDEXIR2<=NOP; HFlag<=3; end end else if(IFIDop==BNE ||IFIDop ==BEQ) begin if((SRegs[IFIDIR[25:21]]!=1) && (SRegs[IFIDIR[20:16]]!=1))begin BFlag<=3; //introduce 3 more NOPs ..implies 1st instruction a branch IDEXA2 <= Regs[IFIDIR[25:21]]; IDEXB2 <= Regs[IFIDIR[20:16]]; // get registers IDEXIR2<=IFIDIR; //pass along IR--can happen anywhere, since this affects next stage only! IDEXIR <= NOP; SwapFlag<=1; //swap instructions and send 1st to ALU 2 end else begin HFlag<=3; //RAW hazarad detected. Introduce 3 NOPs IDEXIR<=NOP; IDEXIR2<=NOP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -