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

📄 alu.v

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

module ALU (/*AUTOARG*/
   // Outputs
   IALU2MEM, ALUResult, ALUResultRegAddr, ALUResultUnlatched, 
   ALUResultRegAddrUnlatched, ALURtDataOut, 
   // Inputs
   Clk, ClkEN, IRF2ALU, IRF2ALUUnlatched, RsData, RtData, 
   LinkPCRFOut, LinkPCAddrRFOut
   );

   output [31:0] IALU2MEM;
   
   output [31:0] ALUResult;
   output [4:0]  ALUResultRegAddr;
   output [31:0] ALUResultUnlatched;
   output [4:0]  ALUResultRegAddrUnlatched;

   output [31:0] ALURtDataOut;	// used for memory store
   
   input Clk;
   input ClkEN;
   
   input [31:0] IRF2ALU;
   input [31:0] IRF2ALUUnlatched;

   input [31:0] RsData;
   input [31:0] RtData;

   input 	LinkPCRFOut;
   input [4:0]	LinkPCAddrRFOut;

   reg [31:0] 	IALU2MEM;
   
   reg [31:0] ALUResult;
   reg [4:0]  ALUResultRegAddr;
   reg [31:0] newALUResult;
   reg [4:0]  newALUResultRegAddr;

   reg [31:0] ALURtDataOut;
   
   wire       iIsLW;
   wire       iIsSW;
   
   wire       iIsADD;
   wire       iIsADDI;
   wire       iIsADDIU;
   wire       iIsADDU;

   wire       iIsAND;
   wire       iIsANDI;
   wire       iIsNOR;
   wire       iIsOR;
   wire       iIsORI;

   wire       iIsLUI;		       
   
   wire       iIsSLL;
   wire       iIsSLLV;

   wire       iIsSLT;
   wire       iIsSLTI;
   wire       iIsSLTIU;
   wire       iIsSLTU;

   wire       iIsSRA;
   wire       iIsSRAV;
   wire       iIsSRL;
   wire       iIsSRLV;

   wire       iIsSUB;
   wire       iIsSUBU;

   wire       iIsXOR;
   wire       iIsXORI;

   wire [15:0] imm;
   wire [31:0] signExtendedImm;
   
   wire [31:0] rsPrt;
   wire [31:0] rsMrt;
   wire [31:0] rsPimm;
   reg [31:0]  addResult;
   wire        iIsSomeAdd;

   reg [31:0]  logResult;
   wire        iIsSomeLog;

   wire [4:0]  leftShiftAmount;
   wire [31:0] leftShiftResult;
   wire [4:0]  rightShiftAmount;
   wire [31:0] rightShiftLogResult;
   wire [31:0] rightShiftArithResult;
   reg [31:0]  shiftResult;
   wire        iIsSomeShift;

   wire [32:0] seSetRs;
   wire [32:0] seSetRt;
   wire [32:0] seSetImm;
   wire [32:0] subSetRes;
   reg [31:0]  setResult;
   wire        iIsSomeSet;

   wire [31:0] i;
   wire [5:0]  op;
   wire [4:0]  rsAddr;
   wire [4:0]  rtAddr;
   wire [4:0]  rdAddr;
   wire [4:0]  sa;
   wire [5:0]  funct;

// renaming
   assign      ALUResultUnlatched = newALUResult;
   assign      ALUResultRegAddrUnlatched = newALUResultRegAddr;

   always @ (posedge Clk)
     if (ClkEN)
       IALU2MEM <= IRF2ALU;
   
   assign i = IRF2ALU;
   assign op = i[31:26];
   assign rsAddr = i[25:21];
   assign rtAddr = i[20:16];
   assign rdAddr = i[15:11];
   assign imm = i[15:0];
   assign sa = i[10:6];
   assign funct = i[5:0];

   assign iIsLW     = (op == 6'b100011);
   assign iIsSW     = (op == 6'b101011);
   
   assign iIsADD    = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b100000);
   assign iIsADDI   = (op == 6'b001000);
   assign iIsADDIU  = (op == 6'b001001);
   assign iIsADDU   = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b100001);

   assign iIsAND    = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b100100);
   assign iIsANDI   = (op == 6'b001100);
   assign iIsNOR    = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b100111);
   assign iIsOR     = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b100101);
   assign iIsORI    = (op == 6'b001101);

   assign iIsLUI    = (op == 6'b001111) && (rsAddr == 5'b00000);
   
   assign iIsSLL    = (op == 6'b000000) && (rsAddr == 5'b00000) && (funct == 6'b000000);
   assign iIsSLLV   = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b000100);

   assign iIsSLT    = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b101010);
   assign iIsSLTI   = (op == 6'b001010);
   assign iIsSLTIU  = (op == 6'b001011);
   assign iIsSLTU   = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b101011);

   assign iIsSRA    = (op == 6'b000000) && (rsAddr == 5'b00000) && (funct == 6'b000011);
   assign iIsSRAV   = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b000111);
   assign iIsSRL    = (op == 6'b000000) && (rsAddr == 5'b00000) && (funct == 6'b000010);
   assign iIsSRLV   = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b000110);

   assign iIsSUB    = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b100010);
   assign iIsSUBU   = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b100011);

   assign iIsXOR    = (op == 6'b000000) && (sa == 5'b00000) && (funct == 6'b100110);
   assign iIsXORI   = (op == 6'b001110);

   assign      signExtendedImm = {{16{imm[15]}}, imm[15:0]};
   assign      rsPrt = RsData + RtData;
   assign      rsMrt = RsData - RtData;
   assign      rsPimm = RsData + signExtendedImm;
   
   always @ (/*AUTOSENSE*/iIsADD or iIsADDI or iIsADDIU or iIsADDU
	     or iIsSUB or iIsSUBU or rsMrt or rsPimm or rsPrt)
     begin
	casex ({iIsADD, iIsADDI, iIsADDIU, iIsADDU, iIsSUB, iIsSUBU}) /* $s full_case parallel_case */
	  6'b000000 : addResult = 32'bx;
	  6'b1xxxxx : addResult = rsPrt;
	  6'bx1xxxx : addResult = rsPimm;
	  6'bxx1xxx : addResult = rsPimm;
	  6'bxxx1xx : addResult = rsPrt;
	  6'bxxxx1x : addResult = rsMrt;
	  6'bxxxxx1 : addResult = rsMrt;
	endcase // casex({iIsADD, iIsADDI, iIsADDIU, iIsADDU, iIsSUB, iIsSUBU})
     end // always @ (...

   assign iIsSomeAdd = iIsADD || iIsADDI || iIsADDIU || iIsADDU || iIsSUB || iIsSUBU;

   always @ (/*AUTOSENSE*/RsData or RtData or iIsAND or iIsANDI
	     or iIsNOR or iIsOR or iIsORI or iIsXOR or iIsXORI or imm)
     begin
	casex ({iIsAND, iIsANDI, iIsNOR, iIsOR, iIsORI, iIsXOR, iIsXORI}) /* $s full_case parallel_case */
	  7'b0000000 : logResult = 32'bx;
	  7'b1xxxxxx : logResult = RsData & RtData;
	  7'bx1xxxxx : logResult = {16'b0, imm & RsData[15:0]};
	  7'bxx1xxxx : logResult = ~(RsData | RtData);
	  7'bxxx1xxx : logResult = RsData | RtData;
	  7'bxxxx1xx : logResult = {RsData[31:16], (imm | RsData[15:0])};
	  7'bxxxxx1x : logResult = RsData ^ RtData;
	  7'bxxxxxx1 : logResult = {RsData[31:16], (imm ^ RsData[15:0])};
	endcase // casex({iIsAND, iIsANDI, iIsNOR, iIsOR, iIsORI, iIsXOR, iIsXORI})
     end // always @ (...

   assign iIsSomeLog = iIsAND || iIsANDI || iIsNOR || iIsOR || iIsORI || iIsXOR || iIsXORI;
   
   assign leftShiftAmount = iIsSLL ? sa : RsData[4:0];
   assign leftShiftResult = RtData << leftShiftAmount;

   assign rightShiftAmount = (iIsSRA || iIsSRL) ? sa : RsData[4:0];
   assign rightShiftLogResult = RtData << rightShiftAmount;
   assign rightShiftArithResult = {{32{RtData[31]}}, rightShiftLogResult[31:0] >> rightShiftAmount};
   
   always @ (/*AUTOSENSE*/iIsSLL or iIsSLLV or iIsSRA or iIsSRAV
	     or iIsSRL or iIsSRLV or leftShiftResult
	     or rightShiftArithResult or rightShiftLogResult)
     begin
	casex ({iIsSLL, iIsSLLV, iIsSRA, iIsSRAV, iIsSRL, iIsSRLV}) /* $s full_case parallel_case */
	  6'b000000 : shiftResult = 32'bx;
	  6'b1xxxxx : shiftResult = leftShiftResult;
	  6'bx1xxxx : shiftResult = leftShiftResult;
	  6'bxx1xxx : shiftResult = rightShiftArithResult;
	  6'bxxx1xx : shiftResult = rightShiftArithResult;
	  6'bxxxx1x : shiftResult = rightShiftLogResult;
	  6'bxxxxx1 : shiftResult = rightShiftLogResult;
	endcase // casex({iIsSLL, iIsSLLV, iIsSRA, iIsSRAV, iIsSRL, iIsSRLV})
     end // always @ (...

   assign iIsSomeShift = iIsSLL || iIsSLLV || iIsSRA || iIsSRAV || iIsSRL || iIsSRLV;

   assign seSetRs = (iIsSLT || iIsSLTI) ? {RsData[31], RsData[31:0]} : {1'b0, RsData[31:0]};
   assign seSetRt = iIsSLT ? {RtData[31], RtData[31:0]} : {1'b0, RtData[31:0]};
   assign seSetImm = iIsSLTI ? {{17{imm[15]}}, imm[15:0]} : {1'b0, {16{imm[15]}}, imm[15:0]};
   assign subSetRes = (iIsSLT || iIsSLTU) ? (seSetRs - seSetRt) : (seSetRs - seSetImm);

   always @ (/*AUTOSENSE*/iIsSLT or iIsSLTI or iIsSLTIU or iIsSLTU
	     or subSetRes)
     begin
	casex ({iIsSLT, iIsSLTI, iIsSLTIU, iIsSLTU}) /* $s full_case parallel_case */
	  4'b0000 : setResult = 32'bx;
	  4'b1000 : setResult = subSetRes[32] ? {31'b0, 1'b1} : 32'b0;
	  4'b0100 : setResult = subSetRes[32] ? {31'b0, 1'b1} : 32'b0;
	  4'b0010 : setResult = subSetRes[32] ? {31'b0, 1'b1} : 32'b0;
	  4'b0001 : setResult = subSetRes[32] ? {31'b0, 1'b1} : 32'b0;
	endcase // casex({iIsSLT, iIsSLTI, iIsSLTIU, iIsSLTU})
     end // always @ (...

   assign iIsSomeSet = iIsSLT || iIsSLTI || iIsSLTIU || iIsSLTU;

   always @ (posedge Clk)
     if (ClkEN)
       ALUResult <= newALUResult;

   always @ (/*AUTOSENSE*/LinkPCRFOut or RtData or addResult or iIsLUI
	     or iIsLW or iIsSW or iIsSomeAdd or iIsSomeLog
	     or iIsSomeSet or iIsSomeShift or imm or logResult
	     or rsPimm or setResult or shiftResult)
     begin
	casex ({iIsSomeAdd, iIsSomeLog, iIsSomeShift, iIsSomeSet, iIsLUI, LinkPCRFOut, iIsLW || iIsSW}) /* $s full_case parallel_case */
	  7'b0000000 : newALUResult <= 32'bx;// TBD
	  7'b1000000 : newALUResult <= addResult;
	  7'b0100000 : newALUResult <= logResult;
	  7'b0010000 : newALUResult <= shiftResult;
	  7'b0001000 : newALUResult <= setResult;
	  7'b0000100 : newALUResult <= {imm[15:0], 16'b0};
	  7'b0000010 : newALUResult <= RtData[31:0];
	  7'b0000001 : newALUResult <= rsPimm;
	endcase // casex({iIsSomeAdd, iIsSomeLog, iIsSomeShift, iIsSomeSet, iIsLUI})
     end // if (ClkEN)

   always @ (posedge Clk)
     if (ClkEN)
       ALUResultRegAddr <= newALUResultRegAddr;

   always @ (/*AUTOSENSE*/LinkPCAddrRFOut or LinkPCRFOut or iIsADDI
	     or iIsADDIU or iIsANDI or iIsLUI or iIsLW or iIsORI
	     or iIsSLTI or iIsSLTIU or iIsXORI or rdAddr or rtAddr)
     begin
	if (iIsADDI || iIsADDIU || iIsANDI || iIsORI || iIsLUI || iIsSLTI || iIsSLTIU || iIsXORI || iIsLW)
	  newALUResultRegAddr = rtAddr;
	else
	  if (LinkPCRFOut)
	    newALUResultRegAddr = LinkPCAddrRFOut;
	  else
	    newALUResultRegAddr = rdAddr;
     end

   always @ (posedge Clk)
     if (ClkEN)
       ALURtDataOut <= RtData;
   
endmodule // ALU

	    

⌨️ 快捷键说明

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