📄 alu.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 + -