⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if.v

📁 麻省理工的一个实验室实现的MIPS IP CORE
💻 V
字号:
/* 
Daniel L. Rosenband
10/4/99
*/

module IF (/*AUTOARG*/
   // Outputs
   IAddr, IIF2RF, IIF2RFUnlatched, LinkPC, PCP8, LinkPCAddr, 
   // Inputs
   MClk, IFClkEN, NewProg, IIn, AEqB, AEq0, ALt0, RaData
   );

   output [31:0] IAddr;		// address to instruction memory -- must be valid by falling edge
   output [31:0] IIF2RF;	// instruction latched at IF and passed to RF
   output [31:0] IIF2RFUnlatched;// unlatched version of IIF2RF

   output 	 LinkPC;	// link instruction (pc should be stored...)
   output [31:0] PCP8;		// pc + 8 (for link instruction)
   output [4:0]  LinkPCAddr;
   
   input 	 MClk;
   input 	 IFClkEN;
   input 	 NewProg;

   input [31:0]  IIn;

   input 	 AEqB;
   input 	 AEq0;
   input 	 ALt0;
   input [31:0]  RaData;

   reg 		 LinkPC;
   reg [31:0] 	 PCP8;
   reg [4:0] 	 LinkPCAddr;
   
   wire [5:0] 	 op;		// opcode
   wire [4:0] 	 rtAddr;	// source
   wire [4:0] 	 rdAddr;
   wire [5:0] 	 funct;		// opcode function

   wire 	 iIsBEQ;
   wire 	 iIsBGEZ;
   wire 	 iIsBGEZAL;
   wire 	 iIsBGTZ;
   wire 	 iIsBLEZ;
   wire 	 iIsBLTZ;
   wire 	 iIsBLTZAL;
   wire 	 iIsBNE;
   wire 	 iIsJ;
   wire 	 iIsJAL;
   wire 	 iIsJALR;
   wire 	 iIsJR;

   wire 	 iIsLW;
   wire 	 loadBubble;

   wire [31:0] 	 rsData;
   
   reg [31:0] 	 pc;		// program counter
   wire [31:0] 	 pcP4;		// pc + 4
   wire [31:0] 	 pcPOffset;	// pc + offset
   wire [31:0] 	 pcTarget;	// target field for pc
   wire [31:0] 	 pcReg;
   wire 	 usePCPOffset;	// pcPOffset should be next PC
   wire 	 usePCTarget;	// pcTarget should be next PC
   wire 	 usePCReg;	// pcReg should be next PC
   
   wire [15:0] 	 offset;
   wire [31:0] 	 signExtendedOffset;
   wire [25:0] 	 target;
   reg [31:0] 	 i;
   reg [31:0] 	 newI;

   wire 	 sEqT;		// s = t
   wire 	 sGEZ;		// s >= 0
   wire 	 sGTZ;		// s > 0
   wire 	 sLEZ;		// s <= 0
   wire 	 sLTZ;		// s < 0
   wire 	 sNET;		// s != t

// signal renaming
   assign IAddr = pc;
   assign IIF2RF = i;
   assign IIF2RFUnlatched = newI;
   assign rsData = RaData;

   always @ (posedge MClk)
     i <= newI;

   assign loadBubble = (iIsLW && ((IIn[25:21] == rdAddr) || (IIn[20:16] == rdAddr)));
   
   always @ (/*AUTOSENSE*/IFClkEN or IIn or i or loadBubble)
     begin
	if (IFClkEN)
	  newI = loadBubble ? 32'b0 : IIn;
	else			// 
	  newI = i;
     end // always @ (...
   
   assign op = i[31:26];
   assign rtAddr = i[20:16];
   assign rdAddr = i[15:11];
   assign funct = i[5:0];

   assign offset = i[15:0];
   assign signExtendedOffset = {{14{offset[15]}}, offset[15:0], 2'b00};
   assign target = i[25:0];

   assign pcP4 = pc + 3'h4;
   assign pcPOffset = pc + signExtendedOffset;
   assign pcTarget = {pc[31:28], target, 2'b00};
   assign pcReg = rsData;

   assign sEqT = AEqB;
   assign sGEZ = AEq0 || (!ALt0);
   assign sGTZ = !(ALt0 || AEq0);
   assign sLEZ = ALt0 || AEq0;
   assign sLTZ = ALt0;
   assign sNET = !AEqB;
   
   assign iIsBEQ     = (op == 6'b000100);
   assign iIsBGEZ    = (op == 6'b000001) && (rtAddr == 5'b00001);
   assign iIsBGEZAL  = (op == 6'b000001) && (rtAddr == 5'b10001);
   assign iIsBGTZ    = (op == 6'b000111) && (rtAddr == 5'b00000);
   assign iIsBLEZ    = (op == 6'b000110) && (rtAddr == 5'b00000);
   assign iIsBLTZ    = (op == 6'b000001) && (rtAddr == 5'b00000);
   assign iIsBLTZAL  = (op == 6'b000001) && (rtAddr == 5'b10000);
   assign iIsBNE     = (op == 6'b000101);
   assign iIsJ       = (op == 6'b000010);
   assign iIsJAL     = (op == 6'b000011);
   assign iIsJALR    = (op == 6'b000000) && (funct == 6'b001001);  // TBD -- other 0 fields ?
   assign iIsJR      = (op == 6'b000000) && (funct == 6'b001000);

   assign iIsLW      = (op == 6'b100011);
 
   assign usePCPOffset = 
	  (iIsBEQ  && sEqT) ||
	  ((iIsBGEZ || iIsBGEZAL) && sGEZ) ||
	  (iIsBGTZ && sGTZ) ||
	  (iIsBLEZ && sLEZ) ||
	  ((iIsBLTZ || iIsBLTZAL) && sLTZ) ||
	  (iIsBNE && sNET);

   assign usePCTarget = iIsJ || iIsJAL;

   assign usePCReg = iIsJALR || iIsJR;

   always @ (posedge MClk)
     begin
	if (NewProg)
	  pc <= 32'b0;
	else
	if (IFClkEN)
	  casex ({loadBubble, usePCPOffset, usePCTarget, usePCReg}) /* $s full_case parallel_case */
	    4'b0000 : pc <= pcP4;
	    4'b1xxx : pc <= pc;
	    4'b01xx : pc <= pcPOffset;
	    4'b0x1x : pc <= pcTarget;
	    4'b0xx1 : pc <= pcReg;
	  endcase // casex({usePCOffset, usePCTarget, usePCReg})
     end // always @ (posedge MClk)

   always @ (/*AUTOSENSE*/iIsBGEZAL or iIsBLTZAL or iIsJAL or iIsJALR)
       LinkPC <= iIsBGEZAL || iIsBLTZAL || iIsJAL || iIsJALR;

   always @ (posedge MClk)
     if (IFClkEN)
       LinkPCAddr <= iIsJALR ? rdAddr : 5'b11111;

   always @ (posedge MClk)
     if (IFClkEN)
       PCP8 <= pc + 4'h8;

endmodule // IF

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -