URL
https://opencores.org/ocsvn/aemb/aemb/trunk
Subversion Repositories aemb
[/] [aemb/] [trunk/] [rtl/] [verilog/] [aeMB_ctrl.v] - Rev 41
Go to most recent revision | Compare with Previous | Blame | View Log
// $Id: aeMB_ctrl.v,v 1.1 2007-11-02 03:25:40 sybreon Exp $ // // AEMB CONTROL UNIT // // Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net> // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation; either version 2.1 of // the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT 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 // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA // // $Log: not supported by cvs2svn $ module aeMB_ctrl (/*AUTOARG*/ // Outputs rMXDST, rMXSRC, rMXTGT, rMXALT, rMXALU, rRW, rDWBSTB, rXCE, dwb_stb_o, dwb_wre_o, // Inputs rDLY, rIMM, rALT, rOPC, rRD, rRA, rRB, rPC, rBRA, rMSR_IE, gclk, grst, gena, sys_int_i ); // INTERNAL //output [31:2] rPCLNK; output [1:0] rMXDST; output [1:0] rMXSRC, rMXTGT, rMXALT; output [2:0] rMXALU; output [4:0] rRW; output rDWBSTB; output [1:0] rXCE; input rDLY; input [15:0] rIMM; input [10:0] rALT; input [5:0] rOPC; input [4:0] rRD, rRA, rRB; input [31:2] rPC; input rBRA; input rMSR_IE; // DATA WISHBONE output dwb_stb_o; output dwb_wre_o; // SYSTEM input gclk, grst, gena; input sys_int_i; // --- DECODE INSTRUCTIONS // TODO: Simplify wire fSFT = (rOPC == 6'o44); wire fLOG = ({rOPC[5:4],rOPC[2]} == 3'o4); wire fMUL = (rOPC == 6'o20) | (rOPC == 6'o30); wire fBSF = (rOPC == 6'o21) | (rOPC == 6'o31); wire fDIV = (rOPC == 6'o22); wire fRTD = (rOPC == 6'o55); wire fBCC = (rOPC == 6'o47) | (rOPC == 6'o57); wire fBRU = (rOPC == 6'o46) | (rOPC == 6'o56); wire fBRA = fBRU & rRA[3]; wire fIMM = (rOPC == 6'o54); wire fMOV = (rOPC == 6'o45); wire fLOD = ({rOPC[5:4],rOPC[2]} == 3'o6); wire fSTR = ({rOPC[5:4],rOPC[2]} == 3'o7); wire fLDST = (&rOPC[5:4]); // --- 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 // --- ALU CONTROL --------------------------------------- reg [2:0] rMXALU; always @(/*AUTOSENSE*/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 // --- RAM CONTROL --------------------------------------- reg rDWBSTB, xDWBSTB; reg rDWBWRE, xDWBWRE; assign dwb_stb_o = rDWBSTB; assign dwb_wre_o = rDWBWRE; // --- DELAY SLOT REGISTERS ------------------------------ reg [31:2] rPCLNK, xPCLNK; reg [1:0] rMXDST, xMXDST; reg [4:0] rRW, xRW; wire fSKIP = rBRA & !rDLY; always @(/*AUTOSENSE*/fLOD or fSKIP or fSTR) if (fSKIP) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops xDWBSTB <= 1'h0; xDWBWRE <= 1'h0; // End of automatics end else begin xDWBSTB <= fLOD | fSTR; xDWBWRE <= fSTR; end always @(/*AUTOSENSE*/fBCC or fBRU or fLOD or fRTD or fSKIP or fSTR or rRD) if (fSKIP) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops xMXDST <= 2'h0; xRW <= 5'h0; // End of automatics end else begin //xPCLNK <= rPC; /* case (rXCE) 2'o1: xMXDST <= 2'o1; default: xMXDST <= (fSTR | fRTD | fBCC) ? 2'o3 : (fLOD) ? 2'o2 : (fBRU) ? 2'o1 : 2'o0; endcase // case (rXCE) case (rXCE) 2'o1: xRW <= 5'd14; default: xRW <= rRD; endcase // case (rXCE) */ xMXDST <= (fSTR | fRTD | fBCC) ? 2'o3 : (fLOD) ? 2'o2 : (fBRU) ? 2'o1 : 2'o0; xRW <= rRD; end // --- INTERRUPT CONTROL --------------------------------- wire fNCLR; assign fNCLR = (rOPC == 6'o46) | (rOPC == 6'o56) | // BRU (rOPC == 6'o47) | (rOPC == 6'o57) | // BCC (rOPC == 6'o55) | // RTD (rOPC == 6'o54); // IMM reg [2:0] rINT; reg [1:0] rXCE, xXCE; //wire fINT = rINT[0] & rINT[1] & !rINT[2] & rMSR_IE; // +Edge wire fINT = rINT[2] & rMSR_IE; always @(/*AUTOSENSE*/fINT or fNCLR or rXCE) case (rXCE) 2'o0: xXCE <= (fINT & !fNCLR) ? 2'o1 : 2'o0; default: xXCE <= 2'o0; endcase // case (rXCE) always @(posedge gclk) if (grst) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops rINT <= 3'h0; // End of automatics end else if (gena) begin rINT <= #1 {rINT[1:0], sys_int_i & rMSR_IE}; end // --- PIPELINE CONTROL DELAY ---------------------------- always @(posedge gclk) if (grst) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops rDWBSTB <= 1'h0; rDWBWRE <= 1'h0; rMXDST <= 2'h0; rRW <= 5'h0; rXCE <= 2'h0; // End of automatics end else if (gena) begin //rPCLNK <= #1 xPCLNK; rMXDST <= #1 xMXDST; rRW <= #1 xRW; rDWBSTB <= #1 xDWBSTB; rDWBWRE <= #1 xDWBWRE; rXCE <= #1 xXCE; end endmodule // aeMB_ctrl
Go to most recent revision | Compare with Previous | Blame | View Log