Line 1... |
Line 1... |
// $Id: aeMB_ctrl.v,v 1.5 2007-11-09 20:51:52 sybreon Exp $
|
// $Id: aeMB_ctrl.v,v 1.6 2007-11-10 16:39:38 sybreon Exp $
|
//
|
//
|
// AEMB CONTROL UNIT
|
// AEMB CONTROL UNIT
|
//
|
//
|
// Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
|
// Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
|
//
|
//
|
// This library is free software; you can redistribute it and/or
|
// This file is part of AEMB.
|
// modify it under the terms of the GNU Lesser General Public License
|
//
|
// as published by the Free Software Foundation; either version 2.1 of
|
// AEMB is free software: you can redistribute it and/or modify it
|
// the License, or (at your option) any later version.
|
// under the terms of the GNU Lesser General Public License as
|
//
|
// published by the Free Software Foundation, either version 3 of the
|
// This library is distributed in the hope that it will be useful, but
|
// License, or (at your option) any later version.
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
//
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
// AEMB is distributed in the hope that it will be useful, but WITHOUT
|
// Lesser General Public License for more details.
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
|
// Public License for more details.
|
//
|
//
|
// You should have received a copy of the GNU Lesser General Public
|
// You should have received a copy of the GNU Lesser General Public
|
// License along with this library; if not, write to the Free Software
|
// License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
// USA
|
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.5 2007/11/09 20:51:52 sybreon
|
|
// Added GET/PUT support through a FSL bus.
|
|
//
|
// Revision 1.4 2007/11/08 17:48:14 sybreon
|
// Revision 1.4 2007/11/08 17:48:14 sybreon
|
// Fixed data WISHBONE arbitration problem (reported by J Lee).
|
// Fixed data WISHBONE arbitration problem (reported by J Lee).
|
//
|
//
|
// Revision 1.3 2007/11/08 14:17:47 sybreon
|
// Revision 1.3 2007/11/08 14:17:47 sybreon
|
// Parameterised optional components.
|
// Parameterised optional components.
|
Line 40... |
Line 43... |
// Outputs
|
// Outputs
|
rMXDST, rMXSRC, rMXTGT, rMXALT, rMXALU, rRW, rDWBSTB, rFSLSTB,
|
rMXDST, rMXSRC, rMXTGT, rMXALT, rMXALU, rRW, rDWBSTB, rFSLSTB,
|
dwb_stb_o, dwb_wre_o, fsl_stb_o, fsl_wre_o,
|
dwb_stb_o, dwb_wre_o, fsl_stb_o, fsl_wre_o,
|
// Inputs
|
// Inputs
|
rXCE, rDLY, rIMM, rALT, rOPC, rRD, rRA, rRB, rPC, rBRA, rMSR_IE,
|
rXCE, rDLY, rIMM, rALT, rOPC, rRD, rRA, rRB, rPC, rBRA, rMSR_IE,
|
dwb_ack_i, iwb_ack_i, fsl_ack_i, gclk, grst, gena
|
dwb_ack_i, iwb_ack_i, iwb_dat_i, fsl_ack_i, gclk, grst, gena
|
);
|
);
|
// INTERNAL
|
// INTERNAL
|
//output [31:2] rPCLNK;
|
//output [31:2] rPCLNK;
|
output [1:0] rMXDST;
|
output [1:0] rMXDST;
|
output [1:0] rMXSRC, rMXTGT, rMXALT;
|
output [1:0] rMXSRC, rMXTGT, rMXALT;
|
Line 68... |
Line 71... |
output dwb_wre_o;
|
output dwb_wre_o;
|
input dwb_ack_i;
|
input dwb_ack_i;
|
|
|
// INST WISHBONE
|
// INST WISHBONE
|
input iwb_ack_i;
|
input iwb_ack_i;
|
|
input [31:0] iwb_dat_i;
|
|
|
// FSL WISHBONE
|
// FSL WISHBONE
|
output fsl_stb_o;
|
output fsl_stb_o;
|
output fsl_wre_o;
|
output fsl_wre_o;
|
input fsl_ack_i;
|
input fsl_ack_i;
|
Line 80... |
Line 84... |
input gclk, grst, gena;
|
input gclk, grst, gena;
|
|
|
// --- DECODE INSTRUCTIONS
|
// --- DECODE INSTRUCTIONS
|
// TODO: Simplify
|
// TODO: Simplify
|
|
|
|
wire [5:0] wOPC;
|
|
wire [4:0] wRD, wRA, wRB;
|
|
wire [10:0] wALT;
|
|
|
|
assign {wOPC, wRD, wRA, wRB, wALT} = iwb_dat_i; // FIXME: Endian
|
|
|
wire fSFT = (rOPC == 6'o44);
|
wire fSFT = (rOPC == 6'o44);
|
wire fLOG = ({rOPC[5:4],rOPC[2]} == 3'o4);
|
wire fLOG = ({rOPC[5:4],rOPC[2]} == 3'o4);
|
|
|
wire fMUL = (rOPC == 6'o20) | (rOPC == 6'o30);
|
wire fMUL = (rOPC == 6'o20) | (rOPC == 6'o30);
|
wire fBSF = (rOPC == 6'o21) | (rOPC == 6'o31);
|
wire fBSF = (rOPC == 6'o21) | (rOPC == 6'o31);
|
Line 102... |
Line 112... |
wire fLDST = (&rOPC[5:4]);
|
wire fLDST = (&rOPC[5:4]);
|
|
|
wire fPUT = (rOPC == 6'o33) & rRB[4];
|
wire fPUT = (rOPC == 6'o33) & rRB[4];
|
wire fGET = (rOPC == 6'o33) & !rRB[4];
|
wire fGET = (rOPC == 6'o33) & !rRB[4];
|
|
|
// --- OPERAND SELECTOR ---------------------------------
|
|
|
|
wire fRDWE = |rRW;
|
wire wSFT = (wOPC == 6'o44);
|
wire fAFWD_M = (rRW == rRA) & (rMXDST == 2'o2) & fRDWE;
|
wire wLOG = ({wOPC[5:4],wOPC[2]} == 3'o4);
|
wire fBFWD_M = (rRW == rRB) & (rMXDST == 2'o2) & fRDWE;
|
|
wire fAFWD_R = (rRW == rRA) & (rMXDST == 2'o0) & fRDWE;
|
|
wire fBFWD_R = (rRW == rRB) & (rMXDST == 2'o0) & fRDWE;
|
|
|
|
assign rMXSRC = (fBRU | fBCC) ? 2'o3 : // PC
|
|
(fAFWD_M) ? 2'o2: // RAM
|
|
(fAFWD_R) ? 2'o1: // FWD
|
|
2'o0; // REG
|
|
|
|
assign rMXTGT = (rOPC[3]) ? 2'o3 : // IMM
|
wire wMUL = (wOPC == 6'o20) | (wOPC == 6'o30);
|
(fBFWD_M) ? 2'o2 : // RAM
|
wire wBSF = (wOPC == 6'o21) | (wOPC == 6'o31);
|
(fBFWD_R) ? 2'o1 : // FWD
|
wire wDIV = (wOPC == 6'o22);
|
2'o0; // REG
|
|
|
|
assign rMXALT = (fAFWD_M) ? 2'o2 : // RAM
|
wire wRTD = (wOPC == 6'o55);
|
(fAFWD_R) ? 2'o1 : // FWD
|
wire wBCC = (wOPC == 6'o47) | (wOPC == 6'o57);
|
2'o0; // REG
|
wire wBRU = (wOPC == 6'o46) | (wOPC == 6'o56);
|
|
wire wBRA = wBRU & wRA[3];
|
|
|
|
wire wIMM = (wOPC == 6'o54);
|
|
wire wMOV = (wOPC == 6'o45);
|
|
|
// --- ALU CONTROL ---------------------------------------
|
wire wLOD = ({wOPC[5:4],wOPC[2]} == 3'o6);
|
|
wire wSTR = ({wOPC[5:4],wOPC[2]} == 3'o7);
|
|
wire wLDST = (&wOPC[5:4]);
|
|
|
reg [2:0] rMXALU;
|
wire wPUT = (wOPC == 6'o33) & wRB[4];
|
always @(/*AUTOSENSE*/fBRA or fBSF or fDIV or fLOG or fMOV or fMUL
|
wire wGET = (wOPC == 6'o33) & !wRB[4];
|
or fSFT) begin
|
|
rMXALU <= (fBRA | fMOV) ? 3'o3 :
|
|
(fSFT) ? 3'o2 :
|
|
(fLOG) ? 3'o1 :
|
|
(fMUL) ? 3'o4 :
|
|
(fBSF) ? 3'o5 :
|
|
(fDIV) ? 3'o6 :
|
|
3'o0;
|
|
end
|
|
|
|
|
|
// --- DELAY SLOT REGISTERS ------------------------------
|
// --- BRANCH SLOT REGISTERS ---------------------------
|
|
|
reg [31:2] rPCLNK, xPCLNK;
|
reg [31:2] rPCLNK, xPCLNK;
|
reg [1:0] rMXDST, xMXDST;
|
reg [1:0] rMXDST, xMXDST;
|
reg [4:0] rRW, xRW;
|
reg [4:0] rRW, xRW;
|
|
|
|
reg [1:0] rMXSRC, xMXSRC;
|
|
reg [1:0] rMXTGT, xMXTGT;
|
|
reg [1:0] rMXALT, xMXALT;
|
|
|
|
|
|
// --- OPERAND SELECTOR ---------------------------------
|
|
|
|
/*
|
|
wire fRDWE = |rRW;
|
|
wire fAFWD_M = (rRW == rRA) & (rMXDST == 2'o2) & fRDWE;
|
|
wire fBFWD_M = (rRW == rRB) & (rMXDST == 2'o2) & fRDWE;
|
|
wire fAFWD_R = (rRW == rRA) & (rMXDST == 2'o0) & fRDWE;
|
|
wire fBFWD_R = (rRW == rRB) & (rMXDST == 2'o0) & fRDWE;
|
|
|
|
assign rMXSRC = (fBRU | fBCC) ? 2'o3 : // PC
|
|
(fAFWD_M) ? 2'o2: // RAM
|
|
(fAFWD_R) ? 2'o1: // FWD
|
|
2'o0; // REG
|
|
|
|
assign rMXTGT = (rOPC[3]) ? 2'o3 : // IMM
|
|
(fBFWD_M) ? 2'o2 : // RAM
|
|
(fBFWD_R) ? 2'o1 : // FWD
|
|
2'o0; // REG
|
|
|
|
assign rMXALT = (fAFWD_M) ? 2'o2 : // RAM
|
|
(fAFWD_R) ? 2'o1 : // FWD
|
|
2'o0; // REG
|
|
*/
|
|
|
|
wire wRDWE = |xRW;
|
|
wire wAFWD_M = (xRW == wRA) & (xMXDST == 2'o2) & wRDWE;
|
|
wire wBFWD_M = (xRW == wRB) & (xMXDST == 2'o2) & wRDWE;
|
|
wire wAFWD_R = (xRW == wRA) & (xMXDST == 2'o0) & wRDWE;
|
|
wire wBFWD_R = (xRW == wRB) & (xMXDST == 2'o0) & wRDWE;
|
|
|
|
always @(/*AUTOSENSE*/rBRA or rXCE or wAFWD_M or wAFWD_R or wBCC
|
|
or wBFWD_M or wBFWD_R or wBRU or wOPC)
|
|
if (rBRA | |rXCE) begin
|
|
/*AUTORESET*/
|
|
// Beginning of autoreset for uninitialized flops
|
|
xMXALT <= 2'h0;
|
|
xMXSRC <= 2'h0;
|
|
xMXTGT <= 2'h0;
|
|
// End of automatics
|
|
end else begin
|
|
xMXSRC <= (wBRU | wBCC) ? 2'o3 : // PC
|
|
(wAFWD_M) ? 2'o2 : // RAM
|
|
(wAFWD_R) ? 2'o1 : // FWD
|
|
2'o0; // REG
|
|
xMXTGT <= (wOPC[3]) ? 2'o3 : // IMM
|
|
(wBFWD_M) ? 2'o2 : // RAM
|
|
(wBFWD_R) ? 2'o1 : // FWD
|
|
2'o0; // REG
|
|
xMXALT <= (wAFWD_M) ? 2'o2 : // RAM
|
|
(wAFWD_R) ? 2'o1 : // FWD
|
|
2'o0; // REG
|
|
end
|
|
|
|
// --- ALU CONTROL ---------------------------------------
|
|
|
|
/*
|
|
reg [2:0] rMXALU;
|
|
always @(fBRA or fBSF or fDIV or fLOG or fMOV or fMUL
|
|
or fSFT) begin
|
|
rMXALU <= (fBRA | fMOV) ? 3'o3 :
|
|
(fSFT) ? 3'o2 :
|
|
(fLOG) ? 3'o1 :
|
|
(fMUL) ? 3'o4 :
|
|
(fBSF) ? 3'o5 :
|
|
(fDIV) ? 3'o6 :
|
|
3'o0;
|
|
end
|
|
*/
|
|
|
|
reg [2:0] rMXALU, xMXALU;
|
|
|
|
always @(/*AUTOSENSE*/rBRA or rXCE or wBRA or wBSF or wDIV or wLOG
|
|
or wMOV or wMUL or wSFT)
|
|
if (rBRA | |rXCE) begin
|
|
/*AUTORESET*/
|
|
// Beginning of autoreset for uninitialized flops
|
|
xMXALU <= 3'h0;
|
|
// End of automatics
|
|
end else begin
|
|
xMXALU <= (wBRA | wMOV) ? 3'o3 :
|
|
(wSFT) ? 3'o2 :
|
|
(wLOG) ? 3'o1 :
|
|
(wMUL) ? 3'o4 :
|
|
(wBSF) ? 3'o5 :
|
|
(wDIV) ? 3'o6 :
|
|
3'o0;
|
|
end
|
|
|
|
// --- DELAY SLOT REGISTERS ------------------------------
|
|
|
wire fSKIP = (rBRA & !rDLY);
|
wire fSKIP = (rBRA & !rDLY);
|
|
|
always @(/*AUTOSENSE*/fBCC or fBRU or fGET or fLOD or fRTD or fSKIP
|
always @(/*AUTOSENSE*/fBCC or fBRU or fGET or fLOD or fRTD or fSKIP
|
or fSTR or rRD or rXCE)
|
or fSTR or rRD or rXCE)
|
if (fSKIP) begin
|
if (fSKIP) begin
|
Line 249... |
Line 340... |
|
|
always @(posedge gclk)
|
always @(posedge gclk)
|
if (grst) begin
|
if (grst) begin
|
/*AUTORESET*/
|
/*AUTORESET*/
|
// Beginning of autoreset for uninitialized flops
|
// Beginning of autoreset for uninitialized flops
|
|
rMXALT <= 2'h0;
|
|
rMXALU <= 3'h0;
|
rMXDST <= 2'h0;
|
rMXDST <= 2'h0;
|
|
rMXSRC <= 2'h0;
|
|
rMXTGT <= 2'h0;
|
rRW <= 5'h0;
|
rRW <= 5'h0;
|
// End of automatics
|
// End of automatics
|
end else if (gena) begin
|
end else if (gena) begin
|
//rPCLNK <= #1 xPCLNK;
|
//rPCLNK <= #1 xPCLNK;
|
rMXDST <= #1 xMXDST;
|
rMXDST <= #1 xMXDST;
|
rRW <= #1 xRW;
|
rRW <= #1 xRW;
|
|
rMXSRC <= #1 xMXSRC;
|
|
rMXTGT <= #1 xMXTGT;
|
|
rMXALT <= #1 xMXALT;
|
|
rMXALU <= #1 xMXALU;
|
end
|
end
|
|
|
|
|
endmodule // aeMB_ctrl
|
endmodule // aeMB_ctrl
|
|
|
No newline at end of file
|
No newline at end of file
|