Line 1... |
Line 1... |
// $Id: aeMB_xecu.v,v 1.1 2007-11-02 03:25:41 sybreon Exp $
|
// $Id: aeMB_xecu.v,v 1.2 2007-11-02 19:20:58 sybreon Exp $
|
//
|
//
|
// AEMB MAIN EXECUTION ALU
|
// AEMB MAIN EXECUTION ALU
|
//
|
//
|
// Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
|
// Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
|
//
|
//
|
Line 18... |
Line 18... |
// License along with this library; if not, write to the Free Software
|
// License along with this library; if not, write to the Free Software
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
// USA
|
// USA
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.1 2007/11/02 03:25:41 sybreon
|
|
// New EDK 3.2 compatible design with optional barrel-shifter and multiplier.
|
|
// Fixed various minor data hazard bugs.
|
|
// Code compatible with -O0/1/2/3/s generated code.
|
|
//
|
|
|
module aeMB_xecu (/*AUTOARG*/
|
module aeMB_xecu (/*AUTOARG*/
|
// Outputs
|
// Outputs
|
dwb_adr_o, dwb_sel_o, rRESULT, rOPA, rOPB, rDWBSEL, rMSR_IE,
|
dwb_adr_o, dwb_sel_o, rRESULT, rOPA, rOPB, rDWBSEL, rMSR_IE,
|
|
rMSR_BIP,
|
// Inputs
|
// Inputs
|
rREGA, rREGB, rMXSRC, rMXTGT, rRA, rMXALU, rBRA, rDLY, rXCE, rSIMM,
|
rXCE, rREGA, rREGB, rMXSRC, rMXTGT, rRA, rMXALU, rBRA, rDLY, rSIMM,
|
rIMM, rOPC, rRD, rDWBDI, rPC, rRES_MUL, rRES_BSF, gclk, grst, gena
|
rIMM, rOPC, rRD, rDWBDI, rPC, rRES_MUL, rRES_BSF, gclk, grst, gena
|
);
|
);
|
parameter DW=32;
|
parameter DW=32;
|
|
|
// DATA WISHBONE
|
// DATA WISHBONE
|
Line 37... |
Line 43... |
// INTERNAL
|
// INTERNAL
|
output [31:0] rRESULT;
|
output [31:0] rRESULT;
|
output [31:0] rOPA, rOPB;
|
output [31:0] rOPA, rOPB;
|
output [3:0] rDWBSEL;
|
output [3:0] rDWBSEL;
|
output rMSR_IE;
|
output rMSR_IE;
|
|
output rMSR_BIP;
|
|
input [1:0] rXCE;
|
input [31:0] rREGA, rREGB;
|
input [31:0] rREGA, rREGB;
|
input [1:0] rMXSRC, rMXTGT;
|
input [1:0] rMXSRC, rMXTGT;
|
input [4:0] rRA;
|
input [4:0] rRA;
|
input [2:0] rMXALU;
|
input [2:0] rMXALU;
|
input rBRA, rDLY;
|
input rBRA, rDLY;
|
input [1:0] rXCE;
|
//input [1:0] rXCE;
|
input [31:0] rSIMM;
|
input [31:0] rSIMM;
|
input [15:0] rIMM;
|
input [15:0] rIMM;
|
input [5:0] rOPC;
|
input [5:0] rOPC;
|
input [4:0] rRD;
|
input [4:0] rRD;
|
input [31:0] rDWBDI;
|
input [31:0] rDWBDI;
|
Line 57... |
Line 65... |
// SYSTEM
|
// SYSTEM
|
input gclk, grst, gena;
|
input gclk, grst, gena;
|
|
|
reg rMSR_C, xMSR_C;
|
reg rMSR_C, xMSR_C;
|
reg rMSR_IE, xMSR_IE;
|
reg rMSR_IE, xMSR_IE;
|
|
reg rMSR_BE, xMSR_BE;
|
|
reg rMSR_BIP, xMSR_BIP;
|
|
|
|
wire fSKIP = rBRA & !rDLY;
|
|
|
// --- OPERAND SELECT
|
// --- OPERAND SELECT
|
|
|
reg [31:0] rOPA, rOPB;
|
reg [31:0] rOPA, rOPB;
|
always @(/*AUTOSENSE*/rDWBDI or rMXSRC or rPC or rREGA or rRESULT)
|
always @(/*AUTOSENSE*/rDWBDI or rMXSRC or rPC or rREGA or rRESULT)
|
Line 77... |
Line 89... |
2'o1: rOPB <= rRESULT;
|
2'o1: rOPB <= rRESULT;
|
2'o2: rOPB <= rDWBDI;
|
2'o2: rOPB <= rDWBDI;
|
2'o3: rOPB <= rSIMM;
|
2'o3: rOPB <= rSIMM;
|
endcase // case (rMXTGT)
|
endcase // case (rMXTGT)
|
|
|
|
// --- ADD/SUB SELECTOR ----
|
|
// TODO: Refactor
|
|
// TODO: Verify signed compare
|
|
|
|
wire wADDC, wSUBC, wRES_AC, wCMPC, wOPC;
|
|
wire [31:0] wADD, wSUB, wRES_A, wCMP, wOPX;
|
|
|
|
wire wCMPU = (rOPA > rOPB);
|
|
wire wCMPF = (rIMM[1]) ? wCMPU :
|
|
((wCMPU & ~(rOPB[31] ^ rOPA[31])) | (rOPB[31] & ~rOPA[31]));
|
|
|
|
assign {wCMPC,wCMP} = {wSUBC,wCMPF,wSUB[30:0]};
|
|
assign wOPX = (rOPC[0] & !rOPC[5]) ? ~rOPA : rOPA ;
|
|
assign wOPC = ((rMSR_C & rOPC[1]) | (rOPC[0] & !rOPC[1])) & (!rOPC[5] & ~&rOPC[5:4]);
|
|
|
|
assign {wSUBC,wSUB} = {wADDC,wADD};
|
|
assign {wADDC,wADD} = (rOPB + wOPX) + wOPC;
|
|
|
|
reg rRES_ADDC;
|
|
reg [31:0] rRES_ADD;
|
|
always @(rIMM or rOPC or wADD or wADDC or wCMP
|
|
or wCMPC or wSUB or wSUBC)
|
|
case ({rOPC[3],rOPC[0],rIMM[0]})
|
|
4'h2, 4'h6, 4'h7: {rRES_ADDC,rRES_ADD} <= #1 {~wSUBC,wSUB}; // SUB
|
|
4'h3: {rRES_ADDC,rRES_ADD} <= #1 {~wCMPC,wCMP}; // CMP
|
|
default: {rRES_ADDC,rRES_ADD} <= #1 {wADDC,wADD};
|
|
endcase // case ({rOPC[3],rOPC[0],rIMM[0]})
|
|
|
// --- LOGIC SELECTOR ---
|
// --- LOGIC SELECTOR ---
|
|
|
reg [31:0] rRES_LOG;
|
reg [31:0] rRES_LOG;
|
always @(/*AUTOSENSE*/rOPA or rOPB or rOPC)
|
always @(/*AUTOSENSE*/rOPA or rOPB or rOPC)
|
case (rOPC[1:0])
|
case (rOPC[1:0])
|
Line 104... |
Line 144... |
{ {(24){rOPA[7]}}, rOPA[7:0], rMSR_C};
|
{ {(24){rOPA[7]}}, rOPA[7:0], rMSR_C};
|
endcase // case (rIMM[6:5])
|
endcase // case (rIMM[6:5])
|
|
|
// --- MOVE SELECTOR ---
|
// --- MOVE SELECTOR ---
|
|
|
wire [31:0] wMSR = {rMSR_C, 23'h0ED32, 5'b0, rMSR_C, rMSR_IE, 1'b0};
|
wire [31:0] wMSR = {rMSR_C, 3'o0,
|
|
20'h0ED32,
|
|
4'h0, rMSR_BIP, rMSR_C, rMSR_IE, rMSR_BE};
|
wire fMFSR = (rOPC == 6'o45) & !rIMM[14] & rIMM[0];
|
wire fMFSR = (rOPC == 6'o45) & !rIMM[14] & rIMM[0];
|
wire fMFPC = (rOPC == 6'o45) & !rIMM[14] & !rIMM[0];
|
wire fMFPC = (rOPC == 6'o45) & !rIMM[14] & !rIMM[0];
|
reg [31:0] rRES_MOV;
|
reg [31:0] rRES_MOV;
|
always @(/*AUTOSENSE*/fMFPC or fMFSR or rOPA or rOPB or rPC or rRA
|
always @(/*AUTOSENSE*/fMFPC or fMFSR or rOPA or rOPB or rPC or rRA
|
or wMSR)
|
or wMSR)
|
rRES_MOV <= (fMFSR) ? wMSR :
|
rRES_MOV <= (fMFSR) ? wMSR :
|
(fMFPC) ? rPC :
|
(fMFPC) ? rPC :
|
(rRA[3]) ? rOPB :
|
(rRA[3]) ? rOPB :
|
rOPA;
|
rOPA;
|
|
|
// --- ADD/SUB SELECTOR ----
|
|
// TODO: Refactor
|
|
// TODO: Verify signed compare
|
|
|
|
wire wADDC, wSUBC, wRES_AC, wCMPC, wOPC;
|
// --- MSR REGISTER -----------------
|
wire [31:0] wADD, wSUB, wRES_A, wCMP, wOPX;
|
|
|
|
wire wCMPU = (rOPA > rOPB);
|
// C
|
wire wCMPF = (rIMM[1]) ? wCMPU :
|
wire fMTS = (rOPC == 6'o45) & rIMM[14];
|
((wCMPU & ~(rOPB[31] ^ rOPA[31])) | (rOPB[31] & ~rOPA[31]));
|
wire fADDC = ({rOPC[5:4], rOPC[2]} == 3'o0);
|
|
|
assign {wCMPC,wCMP} = {wSUBC,wCMPF,wSUB[30:0]};
|
always @(/*AUTOSENSE*/fADDC or fMTS or fSKIP or rMSR_C or rMXALU
|
assign wOPX = (rOPC[0] & !rOPC[5]) ? ~rOPA : rOPA ;
|
or rOPA or rRES_ADDC or rRES_SFTC or rXCE)
|
assign wOPC = ((rMSR_C & rOPC[1]) | (rOPC[0] & !rOPC[1])) & (!rOPC[5] & ~&rOPC[5:4]);
|
if (fSKIP | |rXCE) begin
|
|
xMSR_C <= rMSR_C;
|
|
end else
|
|
case (rMXALU)
|
|
3'o0: xMSR_C <= (fADDC) ? rRES_ADDC : rMSR_C;
|
|
3'o1: xMSR_C <= rMSR_C; // LOGIC
|
|
3'o2: xMSR_C <= rRES_SFTC; // SHIFT
|
|
3'o3: xMSR_C <= (fMTS) ? rOPA[2] : rMSR_C;
|
|
3'o4: xMSR_C <= rMSR_C;
|
|
3'o5: xMSR_C <= rMSR_C;
|
|
default: xMSR_C <= 1'hX;
|
|
endcase
|
|
|
assign {wSUBC,wSUB} = {wADDC,wADD};
|
// IE/BIP/BE
|
assign {wADDC,wADD} = (rOPB + wOPX) + wOPC;
|
wire fRTID = (rOPC == 6'o55) & rRD[0];
|
|
wire fRTBD = (rOPC == 6'o55) & rRD[1];
|
|
wire fBRK = ((rOPC == 6'o56) | (rOPC == 6'o66)) & (rRA[4:2] == 3'o3);
|
|
|
reg rRES_ADDC;
|
always @(/*AUTOSENSE*/fMTS or fRTID or rMSR_IE or rOPA or rXCE)
|
reg [31:0] rRES_ADD;
|
xMSR_IE <= (rXCE == 2'o2) ? 1'b0 :
|
always @(rIMM or rOPC or wADD or wADDC or wCMP
|
(fRTID) ? 1'b1 :
|
or wCMPC or wSUB or wSUBC)
|
(fMTS) ? rOPA[1] :
|
case ({rOPC[3],rOPC[0],rIMM[0]})
|
rMSR_IE;
|
4'h2, 4'h6, 4'h7: {rRES_ADDC,rRES_ADD} <= #1 {~wSUBC,wSUB}; // SUB
|
|
4'h3: {rRES_ADDC,rRES_ADD} <= #1 {~wCMPC,wCMP}; // CMP
|
always @(/*AUTOSENSE*/fBRK or fMTS or fRTBD or rMSR_BIP or rOPA)
|
default: {rRES_ADDC,rRES_ADD} <= #1 {wADDC,wADD};
|
xMSR_BIP <= (fBRK) ? 1'b1 :
|
endcase // case ({rOPC[3],rOPC[0],rIMM[0]})
|
(fRTBD) ? 1'b0 :
|
|
(fMTS) ? rOPA[3] :
|
|
rMSR_BIP;
|
|
|
|
always @(/*AUTOSENSE*/fMTS or rMSR_BE or rOPA)
|
|
xMSR_BE <= (fMTS) ? rOPA[0] : rMSR_BE;
|
|
|
// --- RESULT SELECTOR
|
// --- RESULT SELECTOR
|
|
|
wire fSKIP = rBRA & !rDLY;
|
|
reg [31:0] rRESULT, xRESULT;
|
reg [31:0] rRESULT, xRESULT;
|
|
|
// RESULT
|
// RESULT
|
always @(/*AUTOSENSE*/fSKIP or rMXALU or rRES_ADD or rRES_BSF
|
always @(/*AUTOSENSE*/fSKIP or rMXALU or rRES_ADD or rRES_BSF
|
or rRES_LOG or rRES_MOV or rRES_MUL or rRES_SFT)
|
or rRES_LOG or rRES_MOV or rRES_MUL or rRES_SFT)
|
Line 168... |
Line 222... |
3'o4: xRESULT <= rRES_MUL;
|
3'o4: xRESULT <= rRES_MUL;
|
3'o5: xRESULT <= rRES_BSF;
|
3'o5: xRESULT <= rRES_BSF;
|
default: xRESULT <= 32'hX;
|
default: xRESULT <= 32'hX;
|
endcase // case (rMXALU)
|
endcase // case (rMXALU)
|
|
|
// C
|
|
wire fMTS = (rOPC == 6'o45) & rIMM[14];
|
|
wire fADDC = ({rOPC[5:4], rOPC[2]} == 3'o0);
|
|
|
|
always @(/*AUTOSENSE*/fADDC or fMTS or fSKIP or rMSR_C or rMXALU
|
|
or rOPA or rRES_ADDC or rRES_SFTC)
|
|
if (fSKIP)
|
|
/*AUTORESET*/
|
|
// Beginning of autoreset for uninitialized flops
|
|
xMSR_C <= 1'h0;
|
|
// End of automatics
|
|
else
|
|
case (rMXALU)
|
|
3'o0: xMSR_C <= (fADDC) ? rRES_ADDC : rMSR_C;
|
|
3'o1: xMSR_C <= rMSR_C; // LOGIC
|
|
3'o2: xMSR_C <= rRES_SFTC; // SHIFT
|
|
3'o3: xMSR_C <= (fMTS) ? rOPA[2] : rMSR_C;
|
|
3'o4: xMSR_C <= rMSR_C;
|
|
3'o5: xMSR_C <= rMSR_C;
|
|
default: xMSR_C <= 1'hX;
|
|
endcase
|
|
|
|
// IE
|
|
wire fRTID = (rOPC == 6'o55) & rRD[0];
|
|
always @(/*AUTOSENSE*/fMTS or fRTID or rMSR_IE or rOPA) begin
|
|
xMSR_IE <= //(rXCE == 2'o1) ? 1'b0 :
|
|
(fRTID) ? 1'b1 :
|
|
(fMTS) ? rOPA[1] :
|
|
rMSR_IE;
|
|
end
|
|
|
|
// --- DATA WISHBONE -----
|
// --- DATA WISHBONE -----
|
|
|
reg [3:0] rDWBSEL, xDWBSEL;
|
reg [3:0] rDWBSEL, xDWBSEL;
|
assign dwb_adr_o = rRESULT[DW-1:2];
|
assign dwb_adr_o = rRESULT[DW-1:2];
|
assign dwb_sel_o = rDWBSEL;
|
assign dwb_sel_o = rDWBSEL;
|
Line 235... |
Line 258... |
|
|
// --- SYNC ---
|
// --- SYNC ---
|
|
|
always @(posedge gclk)
|
always @(posedge gclk)
|
if (grst) begin
|
if (grst) begin
|
rMSR_IE <= 1'b1;
|
//rMSR_IE <= 1'b1;
|
/*AUTORESET*/
|
/*AUTORESET*/
|
// Beginning of autoreset for uninitialized flops
|
// Beginning of autoreset for uninitialized flops
|
rDWBSEL <= 4'h0;
|
rDWBSEL <= 4'h0;
|
|
rMSR_BE <= 1'h0;
|
|
rMSR_BIP <= 1'h0;
|
rMSR_C <= 1'h0;
|
rMSR_C <= 1'h0;
|
|
rMSR_IE <= 1'h0;
|
rRESULT <= 32'h0;
|
rRESULT <= 32'h0;
|
// End of automatics
|
// End of automatics
|
end else if (gena) begin
|
end else if (gena) begin
|
rRESULT <= #1 xRESULT;
|
rRESULT <= #1 xRESULT;
|
rDWBSEL <= #1 xDWBSEL;
|
rDWBSEL <= #1 xDWBSEL;
|
rMSR_C <= #1 xMSR_C;
|
rMSR_C <= #1 xMSR_C;
|
rMSR_IE <= #1 xMSR_IE;
|
rMSR_IE <= #1 xMSR_IE;
|
|
rMSR_BE <= #1 xMSR_BE;
|
|
rMSR_BIP <= #1 xMSR_BIP;
|
end
|
end
|
|
|
// synopsys translate_off
|
|
|
|
// synopsys translate_on
|
|
|
|
endmodule // aeMB_xecu
|
endmodule // aeMB_xecu
|
|
|
No newline at end of file
|
No newline at end of file
|