OpenCores
URL https://opencores.org/ocsvn/aemb/aemb/trunk

Subversion Repositories aemb

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /aemb/tags/AEMB_711/rtl
    from Rev 75 to Rev 191
    Reverse comparison

Rev 75 → Rev 191

/verilog/aeMB_edk32.v
0,0 → 1,470
// $Id: aeMB_edk32.v,v 1.11 2007-11-30 17:08:29 sybreon Exp $
//
// AEMB EDK 3.2 Compatible Core
//
// Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
//
// This file is part of AEMB.
//
// AEMB 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 3 of the
// License, or (at your option) any later version.
//
// AEMB 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 AEMB. If not, see <http://www.gnu.org/licenses/>.
//
// $Log: not supported by cvs2svn $
// Revision 1.10 2007/11/16 21:52:03 sybreon
// Added fsl_tag_o to FSL bus (tag either address or data).
//
// Revision 1.9 2007/11/14 23:19:24 sybreon
// Fixed minor typo.
//
// Revision 1.8 2007/11/14 22:14:34 sybreon
// Changed interrupt handling system (reported by M. Ettus).
//
// Revision 1.7 2007/11/10 16:39:38 sybreon
// Upgraded license to LGPLv3.
// Significant performance optimisations.
//
// Revision 1.6 2007/11/09 20:51:52 sybreon
// Added GET/PUT support through a FSL bus.
//
// Revision 1.5 2007/11/08 17:48:14 sybreon
// Fixed data WISHBONE arbitration problem (reported by J Lee).
//
// Revision 1.4 2007/11/08 14:17:47 sybreon
// Parameterised optional components.
//
// Revision 1.3 2007/11/03 08:34:55 sybreon
// Minor code cleanup.
//
// Revision 1.2 2007/11/02 19:20:58 sybreon
// Added better (beta) interrupt support.
// Changed MSR_IE to disabled at reset as per MB docs.
//
// Revision 1.1 2007/11/02 03:25:40 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_edk32 (/*AUTOARG*/
// Outputs
iwb_stb_o, iwb_adr_o, fsl_wre_o, fsl_tag_o, fsl_stb_o, fsl_dat_o,
fsl_adr_o, dwb_wre_o, dwb_stb_o, dwb_sel_o, dwb_dat_o, dwb_adr_o,
// Inputs
sys_int_i, iwb_dat_i, iwb_ack_i, fsl_dat_i, fsl_ack_i, dwb_dat_i,
dwb_ack_i, sys_clk_i, sys_rst_i
);
// Bus widths
parameter IW = 32; /// Instruction bus address width
parameter DW = 32; /// Data bus address width
 
// Optional functions
parameter MUL = 1; // Multiplier
parameter BSF = 1; // Barrel Shifter
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output [DW-1:2] dwb_adr_o; // From xecu of aeMB_xecu.v
output [31:0] dwb_dat_o; // From regf of aeMB_regf.v
output [3:0] dwb_sel_o; // From xecu of aeMB_xecu.v
output dwb_stb_o; // From ctrl of aeMB_ctrl.v
output dwb_wre_o; // From ctrl of aeMB_ctrl.v
output [6:2] fsl_adr_o; // From xecu of aeMB_xecu.v
output [31:0] fsl_dat_o; // From regf of aeMB_regf.v
output fsl_stb_o; // From ctrl of aeMB_ctrl.v
output [1:0] fsl_tag_o; // From xecu of aeMB_xecu.v
output fsl_wre_o; // From ctrl of aeMB_ctrl.v
output [IW-1:2] iwb_adr_o; // From bpcu of aeMB_bpcu.v
output iwb_stb_o; // From ibuf of aeMB_ibuf.v
// End of automatics
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input dwb_ack_i; // To ctrl of aeMB_ctrl.v
input [31:0] dwb_dat_i; // To regf of aeMB_regf.v
input fsl_ack_i; // To ctrl of aeMB_ctrl.v
input [31:0] fsl_dat_i; // To regf of aeMB_regf.v
input iwb_ack_i; // To ibuf of aeMB_ibuf.v, ...
input [31:0] iwb_dat_i; // To ibuf of aeMB_ibuf.v
input sys_int_i; // To ibuf of aeMB_ibuf.v
// End of automatics
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [10:0] rALT; // From ibuf of aeMB_ibuf.v
wire rBRA; // From bpcu of aeMB_bpcu.v
wire rDLY; // From bpcu of aeMB_bpcu.v
wire [31:0] rDWBDI; // From regf of aeMB_regf.v
wire [3:0] rDWBSEL; // From xecu of aeMB_xecu.v
wire [15:0] rIMM; // From ibuf of aeMB_ibuf.v
wire rMSR_BIP; // From xecu of aeMB_xecu.v
wire rMSR_IE; // From xecu of aeMB_xecu.v
wire [1:0] rMXALT; // From ctrl of aeMB_ctrl.v
wire [2:0] rMXALU; // From ctrl of aeMB_ctrl.v
wire [1:0] rMXDST; // From ctrl of aeMB_ctrl.v
wire [1:0] rMXSRC; // From ctrl of aeMB_ctrl.v
wire [1:0] rMXTGT; // From ctrl of aeMB_ctrl.v
wire [5:0] rOPC; // From ibuf of aeMB_ibuf.v
wire [31:2] rPC; // From bpcu of aeMB_bpcu.v
wire [31:2] rPCLNK; // From bpcu of aeMB_bpcu.v
wire [4:0] rRA; // From ibuf of aeMB_ibuf.v
wire [4:0] rRB; // From ibuf of aeMB_ibuf.v
wire [4:0] rRD; // From ibuf of aeMB_ibuf.v
wire [31:0] rREGA; // From regf of aeMB_regf.v
wire [31:0] rREGB; // From regf of aeMB_regf.v
wire [31:0] rRESULT; // From xecu of aeMB_xecu.v
wire [4:0] rRW; // From ctrl of aeMB_ctrl.v
wire [31:0] rSIMM; // From ibuf of aeMB_ibuf.v
wire [31:0] xIREG; // From ibuf of aeMB_ibuf.v
// End of automatics
 
input sys_clk_i;
input sys_rst_i;
wire grst = sys_rst_i;
wire gclk = sys_clk_i;
wire gena = !((dwb_stb_o ^ dwb_ack_i) | (fsl_stb_o ^ fsl_ack_i) | !iwb_ack_i);
// --- INSTANTIATIONS -------------------------------------
aeMB_ibuf
ibuf (/*AUTOINST*/
// Outputs
.rIMM (rIMM[15:0]),
.rRA (rRA[4:0]),
.rRD (rRD[4:0]),
.rRB (rRB[4:0]),
.rALT (rALT[10:0]),
.rOPC (rOPC[5:0]),
.rSIMM (rSIMM[31:0]),
.xIREG (xIREG[31:0]),
.iwb_stb_o (iwb_stb_o),
// Inputs
.rBRA (rBRA),
.rMSR_IE (rMSR_IE),
.rMSR_BIP (rMSR_BIP),
.iwb_dat_i (iwb_dat_i[31:0]),
.iwb_ack_i (iwb_ack_i),
.sys_int_i (sys_int_i),
.gclk (gclk),
.grst (grst),
.gena (gena));
aeMB_ctrl
ctrl (/*AUTOINST*/
// Outputs
.rMXDST (rMXDST[1:0]),
.rMXSRC (rMXSRC[1:0]),
.rMXTGT (rMXTGT[1:0]),
.rMXALT (rMXALT[1:0]),
.rMXALU (rMXALU[2:0]),
.rRW (rRW[4:0]),
.dwb_stb_o (dwb_stb_o),
.dwb_wre_o (dwb_wre_o),
.fsl_stb_o (fsl_stb_o),
.fsl_wre_o (fsl_wre_o),
// Inputs
.rDLY (rDLY),
.rIMM (rIMM[15:0]),
.rALT (rALT[10:0]),
.rOPC (rOPC[5:0]),
.rRD (rRD[4:0]),
.rRA (rRA[4:0]),
.rRB (rRB[4:0]),
.rPC (rPC[31:2]),
.rBRA (rBRA),
.rMSR_IE (rMSR_IE),
.xIREG (xIREG[31:0]),
.dwb_ack_i (dwb_ack_i),
.iwb_ack_i (iwb_ack_i),
.fsl_ack_i (fsl_ack_i),
.gclk (gclk),
.grst (grst),
.gena (gena));
 
aeMB_bpcu #(IW)
bpcu (/*AUTOINST*/
// Outputs
.iwb_adr_o (iwb_adr_o[IW-1:2]),
.rPC (rPC[31:2]),
.rPCLNK (rPCLNK[31:2]),
.rBRA (rBRA),
.rDLY (rDLY),
// Inputs
.rMXALT (rMXALT[1:0]),
.rOPC (rOPC[5:0]),
.rRD (rRD[4:0]),
.rRA (rRA[4:0]),
.rRESULT (rRESULT[31:0]),
.rDWBDI (rDWBDI[31:0]),
.rREGA (rREGA[31:0]),
.gclk (gclk),
.grst (grst),
.gena (gena));
 
aeMB_regf
regf (/*AUTOINST*/
// Outputs
.rREGA (rREGA[31:0]),
.rREGB (rREGB[31:0]),
.rDWBDI (rDWBDI[31:0]),
.dwb_dat_o (dwb_dat_o[31:0]),
.fsl_dat_o (fsl_dat_o[31:0]),
// Inputs
.rOPC (rOPC[5:0]),
.rRA (rRA[4:0]),
.rRB (rRB[4:0]),
.rRW (rRW[4:0]),
.rRD (rRD[4:0]),
.rMXDST (rMXDST[1:0]),
.rPCLNK (rPCLNK[31:2]),
.rRESULT (rRESULT[31:0]),
.rDWBSEL (rDWBSEL[3:0]),
.rBRA (rBRA),
.rDLY (rDLY),
.dwb_dat_i (dwb_dat_i[31:0]),
.fsl_dat_i (fsl_dat_i[31:0]),
.gclk (gclk),
.grst (grst),
.gena (gena));
 
aeMB_xecu #(DW, MUL, BSF)
xecu (/*AUTOINST*/
// Outputs
.dwb_adr_o (dwb_adr_o[DW-1:2]),
.dwb_sel_o (dwb_sel_o[3:0]),
.fsl_adr_o (fsl_adr_o[6:2]),
.fsl_tag_o (fsl_tag_o[1:0]),
.rRESULT (rRESULT[31:0]),
.rDWBSEL (rDWBSEL[3:0]),
.rMSR_IE (rMSR_IE),
.rMSR_BIP (rMSR_BIP),
// Inputs
.rREGA (rREGA[31:0]),
.rREGB (rREGB[31:0]),
.rMXSRC (rMXSRC[1:0]),
.rMXTGT (rMXTGT[1:0]),
.rRA (rRA[4:0]),
.rRB (rRB[4:0]),
.rMXALU (rMXALU[2:0]),
.rBRA (rBRA),
.rDLY (rDLY),
.rALT (rALT[10:0]),
.rSIMM (rSIMM[31:0]),
.rIMM (rIMM[15:0]),
.rOPC (rOPC[5:0]),
.rRD (rRD[4:0]),
.rDWBDI (rDWBDI[31:0]),
.rPC (rPC[31:2]),
.gclk (gclk),
.grst (grst),
.gena (gena));
 
// --- SIMULATION KERNEL ----------------------------------
// synopsys translate_off
`ifdef AEMB_SIMULATION_KERNEL
 
wire [IW-1:0] iwb_adr = {iwb_adr_o, 2'd0};
wire [DW-1:0] dwb_adr = {dwb_adr_o,2'd0};
wire [1:0] wBRA = {rBRA, rDLY};
wire [3:0] wMSR = {xecu.rMSR_BIP, xecu.rMSR_C, xecu.rMSR_IE, xecu.rMSR_BE};
always @(posedge gclk) if (gena) begin
$write ("\n", ($stime/10));
$writeh (" PC=", iwb_adr );
$writeh ("\t");
case (wBRA)
2'b00: $write(" ");
2'b01: $write(".");
2'b10: $write("-");
2'b11: $write("+");
endcase // case (wBRA)
case (rOPC)
6'o00: if (rRD == 0) $write(" "); else $write("ADD");
6'o01: $write("RSUB");
6'o02: $write("ADDC");
6'o03: $write("RSUBC");
6'o04: $write("ADDK");
6'o05: case (rIMM[1:0])
2'o0: $write("RSUBK");
2'o1: $write("CMP");
2'o3: $write("CMPU");
default: $write("XXX");
endcase // case (rIMM[1:0])
6'o06: $write("ADDKC");
6'o07: $write("RSUBKC");
6'o10: $write("ADDI");
6'o11: $write("RSUBI");
6'o12: $write("ADDIC");
6'o13: $write("RSUBIC");
6'o14: $write("ADDIK");
6'o15: $write("RSUBIK");
6'o16: $write("ADDIKC");
6'o17: $write("RSUBIKC");
 
6'o20: $write("MUL");
6'o21: case (rALT[10:9])
2'o0: $write("BSRL");
2'o1: $write("BSRA");
2'o2: $write("BSLL");
default: $write("XXX");
endcase // case (rALT[10:9])
6'o22: $write("IDIV");
 
6'o30: $write("MULI");
6'o31: case (rALT[10:9])
2'o0: $write("BSRLI");
2'o1: $write("BSRAI");
2'o2: $write("BSLLI");
default: $write("XXX");
endcase // case (rALT[10:9])
6'o33: case (rRB[4:2])
3'o0: $write("GET");
3'o4: $write("PUT");
3'o2: $write("NGET");
3'o6: $write("NPUT");
3'o1: $write("CGET");
3'o5: $write("CPUT");
3'o3: $write("NCGET");
3'o7: $write("NCPUT");
endcase // case (rRB[4:2])
 
6'o40: $write("OR");
6'o41: $write("AND");
6'o42: if (rRD == 0) $write(" "); else $write("XOR");
6'o43: $write("ANDN");
6'o44: case (rIMM[6:5])
2'o0: $write("SRA");
2'o1: $write("SRC");
2'o2: $write("SRL");
2'o3: if (rIMM[0]) $write("SEXT16"); else $write("SEXT8");
endcase // case (rIMM[6:5])
6'o45: $write("MOV");
6'o46: case (rRA[3:2])
3'o0: $write("BR");
3'o1: $write("BRL");
3'o2: $write("BRA");
3'o3: $write("BRAL");
endcase // case (rRA[3:2])
6'o47: case (rRD[2:0])
3'o0: $write("BEQ");
3'o1: $write("BNE");
3'o2: $write("BLT");
3'o3: $write("BLE");
3'o4: $write("BGT");
3'o5: $write("BGE");
default: $write("XXX");
endcase // case (rRD[2:0])
6'o50: $write("ORI");
6'o51: $write("ANDI");
6'o52: $write("XORI");
6'o53: $write("ANDNI");
6'o54: $write("IMMI");
6'o55: case (rRD[1:0])
2'o0: $write("RTSD");
2'o1: $write("RTID");
2'o2: $write("RTBD");
default: $write("XXX");
endcase // case (rRD[1:0])
6'o56: case (rRA[3:2])
3'o0: $write("BRI");
3'o1: $write("BRLI");
3'o2: $write("BRAI");
3'o3: $write("BRALI");
endcase // case (rRA[3:2])
6'o57: case (rRD[2:0])
3'o0: $write("BEQI");
3'o1: $write("BNEI");
3'o2: $write("BLTI");
3'o3: $write("BLEI");
3'o4: $write("BGTI");
3'o5: $write("BGEI");
default: $write("XXX");
endcase // case (rRD[2:0])
6'o60: $write("LBU");
6'o61: $write("LHU");
6'o62: $write("LW");
6'o64: $write("SB");
6'o65: $write("SH");
6'o66: $write("SW");
6'o70: $write("LBUI");
6'o71: $write("LHUI");
6'o72: $write("LWI");
6'o74: $write("SBI");
6'o75: $write("SHI");
6'o76: $write("SWI");
 
default: $write("XXX");
endcase // case (rOPC)
 
case (rOPC[3])
1'b1: $writeh("\tr",rRD,", r",rRA,", h",rIMM);
1'b0: $writeh("\tr",rRD,", r",rRA,", r",rRB," ");
endcase // case (rOPC[3])
 
// ALU
$write("\t");
$writeh(" A=",xecu.rOPA);
$writeh(" B=",xecu.rOPB);
case (rMXALU)
3'o0: $write(" ADD");
3'o1: $write(" LOG");
3'o2: $write(" SFT");
3'o3: $write(" MOV");
3'o4: $write(" MUL");
3'o5: $write(" BSF");
default: $write(" XXX");
endcase // case (rMXALU)
$writeh("=h",xecu.xRESULT);
 
// WRITEBACK
$writeh("\tSR=", wMSR," ");
if (regf.fRDWE) begin
case (rMXDST)
2'o2: begin
if (dwb_stb_o) $writeh("R",rRW,"=RAM(h",regf.xWDAT,")");
if (fsl_stb_o) $writeh("R",rRW,"=FSL(h",regf.xWDAT,")");
end
2'o1: $writeh("R",rRW,"=LNK(h",regf.xWDAT,")");
2'o0: $writeh("R",rRW,"=ALU(h",regf.xWDAT,")");
endcase // case (rMXDST)
end
// STORE
if (dwb_stb_o & dwb_wre_o) begin
$writeh("RAM(", dwb_adr ,")=", dwb_dat_o);
case (dwb_sel_o)
4'hF: $write(":L");
4'h3,4'hC: $write(":W");
4'h1,4'h2,4'h4,4'h8: $write(":B");
endcase // case (dwb_sel_o)
end
end // if (gena)
`endif // `ifdef AEMB_SIMULATION_KERNEL
// synopsys translate_on
endmodule // aeMB_edk32
/verilog/aeMB_ctrl.v
0,0 → 1,333
// $Id: aeMB_ctrl.v,v 1.10 2007-11-30 16:44:40 sybreon Exp $
//
// AEMB CONTROL UNIT
//
// Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
//
// This file is part of AEMB.
//
// AEMB 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 3 of the
// License, or (at your option) any later version.
//
// AEMB 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 AEMB. If not, see <http://www.gnu.org/licenses/>.
//
// $Log: not supported by cvs2svn $
// Revision 1.9 2007/11/15 09:26:43 sybreon
// Fixed minor typo causing synthesis failure.
//
// Revision 1.8 2007/11/14 23:19:24 sybreon
// Fixed minor typo.
//
// Revision 1.7 2007/11/14 22:14:34 sybreon
// Changed interrupt handling system (reported by M. Ettus).
//
// Revision 1.6 2007/11/10 16:39:38 sybreon
// Upgraded license to LGPLv3.
// Significant performance optimisations.
//
// 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
// Fixed data WISHBONE arbitration problem (reported by J Lee).
//
// Revision 1.3 2007/11/08 14:17:47 sybreon
// Parameterised optional components.
//
// Revision 1.2 2007/11/02 19:20:58 sybreon
// Added better (beta) interrupt support.
// Changed MSR_IE to disabled at reset as per MB docs.
//
// Revision 1.1 2007/11/02 03:25:40 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_ctrl (/*AUTOARG*/
// Outputs
rMXDST, rMXSRC, rMXTGT, rMXALT, rMXALU, rRW, dwb_stb_o, dwb_wre_o,
fsl_stb_o, fsl_wre_o,
// Inputs
rDLY, rIMM, rALT, rOPC, rRD, rRA, rRB, rPC, rBRA, rMSR_IE, xIREG,
dwb_ack_i, iwb_ack_i, fsl_ack_i, gclk, grst, gena
);
// INTERNAL
//output [31:2] rPCLNK;
output [1:0] rMXDST;
output [1:0] rMXSRC, rMXTGT, rMXALT;
output [2:0] rMXALU;
output [4:0] rRW;
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;
input [31:0] xIREG;
// DATA WISHBONE
output dwb_stb_o;
output dwb_wre_o;
input dwb_ack_i;
 
// INST WISHBONE
input iwb_ack_i;
// FSL WISHBONE
output fsl_stb_o;
output fsl_wre_o;
input fsl_ack_i;
// SYSTEM
input gclk, grst, gena;
 
// --- DECODE INSTRUCTIONS
// TODO: Simplify
 
wire [5:0] wOPC;
wire [4:0] wRD, wRA, wRB;
wire [10:0] wALT;
assign {wOPC, wRD, wRA, wRB, wALT} = xIREG; // FIXME: Endian
 
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]);
 
wire fPUT = (rOPC == 6'o33) & rRB[4];
wire fGET = (rOPC == 6'o33) & !rRB[4];
 
 
wire wSFT = (wOPC == 6'o44);
wire wLOG = ({wOPC[5:4],wOPC[2]} == 3'o4);
 
wire wMUL = (wOPC == 6'o20) | (wOPC == 6'o30);
wire wBSF = (wOPC == 6'o21) | (wOPC == 6'o31);
wire wDIV = (wOPC == 6'o22);
wire wRTD = (wOPC == 6'o55);
wire wBCC = (wOPC == 6'o47) | (wOPC == 6'o57);
wire wBRU = (wOPC == 6'o46) | (wOPC == 6'o56);
wire wBRA = wBRU & wRA[3];
 
wire wIMM = (wOPC == 6'o54);
wire wMOV = (wOPC == 6'o45);
wire wLOD = ({wOPC[5:4],wOPC[2]} == 3'o6);
wire wSTR = ({wOPC[5:4],wOPC[2]} == 3'o7);
wire wLDST = (&wOPC[5:4]);
 
wire wPUT = (wOPC == 6'o33) & wRB[4];
wire wGET = (wOPC == 6'o33) & !wRB[4];
 
// --- BRANCH SLOT REGISTERS ---------------------------
 
reg [31:2] rPCLNK, xPCLNK;
reg [1:0] rMXDST, xMXDST;
reg [4:0] rRW, xRW;
 
reg [1:0] rMXSRC, xMXSRC;
reg [1:0] rMXTGT, xMXTGT;
reg [1:0] rMXALT, xMXALT;
// --- OPERAND SELECTOR ---------------------------------
 
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 wAFWD_M or wAFWD_R or wBCC or wBFWD_M
or wBFWD_R or wBRU or wOPC)
//if (rBRA | |rXCE) begin
if (rBRA) 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 // else: !if(rBRA)
// --- ALU CONTROL ---------------------------------------
 
reg [2:0] rMXALU, xMXALU;
 
always @(/*AUTOSENSE*/rBRA or wBRA or wBSF or wDIV or wLOG or wMOV
or wMUL or wSFT)
//if (rBRA | |rXCE) begin
if (rBRA) 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 // else: !if(rBRA)
// --- DELAY SLOT REGISTERS ------------------------------
wire fSKIP = (rBRA & !rDLY);
always @(/*AUTOSENSE*/fBCC or fBRU or fGET 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
xMXDST <= (fSTR | fRTD | fBCC) ? 2'o3 :
(fLOD | fGET) ? 2'o2 :
(fBRU) ? 2'o1 :
2'o0;
xRW <= rRD;
end // else: !if(fSKIP)
 
 
// --- DATA WISHBONE ----------------------------------
 
wire fDACK = !(dwb_stb_o ^ dwb_ack_i);
reg rDWBSTB, xDWBSTB;
reg rDWBWRE, xDWBWRE;
 
assign dwb_stb_o = rDWBSTB;
assign dwb_wre_o = rDWBWRE;
always @(/*AUTOSENSE*/fLOD or fSKIP or fSTR or iwb_ack_i)
//if (fSKIP | |rXCE) begin
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) & iwb_ack_i;
xDWBWRE <= fSTR & iwb_ack_i;
end
always @(posedge gclk)
if (grst) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
rDWBSTB <= 1'h0;
rDWBWRE <= 1'h0;
// End of automatics
end else if (fDACK) begin
rDWBSTB <= #1 xDWBSTB;
rDWBWRE <= #1 xDWBWRE;
end
 
// --- FSL WISHBONE -----------------------------------
 
wire fFACK = !(fsl_stb_o ^ fsl_ack_i);
reg rFSLSTB, xFSLSTB;
reg rFSLWRE, xFSLWRE;
 
assign fsl_stb_o = rFSLSTB;
assign fsl_wre_o = rFSLWRE;
 
always @(/*AUTOSENSE*/fGET or fPUT or fSKIP or iwb_ack_i)
//if (fSKIP | |rXCE) begin
if (fSKIP) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
xFSLSTB <= 1'h0;
xFSLWRE <= 1'h0;
// End of automatics
end else begin
xFSLSTB <= (fPUT | fGET) & iwb_ack_i;
xFSLWRE <= fPUT & iwb_ack_i;
end
 
always @(posedge gclk)
if (grst) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
rFSLSTB <= 1'h0;
rFSLWRE <= 1'h0;
// End of automatics
end else if (fFACK) begin
rFSLSTB <= #1 xFSLSTB;
rFSLWRE <= #1 xFSLWRE;
end
// --- PIPELINE CONTROL DELAY ----------------------------
 
always @(posedge gclk)
if (grst) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
rMXALT <= 2'h0;
rMXALU <= 3'h0;
rMXDST <= 2'h0;
rMXSRC <= 2'h0;
rMXTGT <= 2'h0;
rRW <= 5'h0;
// End of automatics
end else if (gena) begin // if (grst)
//rPCLNK <= #1 xPCLNK;
rMXDST <= #1 xMXDST;
rRW <= #1 xRW;
rMXSRC <= #1 xMXSRC;
rMXTGT <= #1 xMXTGT;
rMXALT <= #1 xMXALT;
rMXALU <= #1 xMXALU;
end
 
endmodule // aeMB_ctrl
/verilog/aeMB_xecu.v
0,0 → 1,376
// $Id: aeMB_xecu.v,v 1.9 2007-11-30 16:42:51 sybreon Exp $
//
// AEMB MAIN EXECUTION ALU
//
// Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
//
// This file is part of AEMB.
//
// AEMB 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 3 of the
// License, or (at your option) any later version.
//
// AEMB 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 AEMB. If not, see <http://www.gnu.org/licenses/>.
//
// $Log: not supported by cvs2svn $
// Revision 1.8 2007/11/16 21:52:03 sybreon
// Added fsl_tag_o to FSL bus (tag either address or data).
//
// Revision 1.7 2007/11/14 22:14:34 sybreon
// Changed interrupt handling system (reported by M. Ettus).
//
// Revision 1.6 2007/11/10 16:39:38 sybreon
// Upgraded license to LGPLv3.
// Significant performance optimisations.
//
// Revision 1.5 2007/11/09 20:51:52 sybreon
// Added GET/PUT support through a FSL bus.
//
// Revision 1.4 2007/11/08 14:17:47 sybreon
// Parameterised optional components.
//
// Revision 1.3 2007/11/03 08:34:55 sybreon
// Minor code cleanup.
//
// Revision 1.2 2007/11/02 19:20:58 sybreon
// Added better (beta) interrupt support.
// Changed MSR_IE to disabled at reset as per MB docs.
//
// 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*/
// Outputs
dwb_adr_o, dwb_sel_o, fsl_adr_o, fsl_tag_o, rRESULT, rDWBSEL,
rMSR_IE, rMSR_BIP,
// Inputs
rREGA, rREGB, rMXSRC, rMXTGT, rRA, rRB, rMXALU, rBRA, rDLY, rALT,
rSIMM, rIMM, rOPC, rRD, rDWBDI, rPC, gclk, grst, gena
);
parameter DW=32;
 
parameter MUL=0;
parameter BSF=0;
// DATA WISHBONE
output [DW-1:2] dwb_adr_o;
output [3:0] dwb_sel_o;
 
// FSL WISHBONE
output [6:2] fsl_adr_o;
output [1:0] fsl_tag_o;
// INTERNAL
output [31:0] rRESULT;
output [3:0] rDWBSEL;
output rMSR_IE;
output rMSR_BIP;
input [31:0] rREGA, rREGB;
input [1:0] rMXSRC, rMXTGT;
input [4:0] rRA, rRB;
input [2:0] rMXALU;
input rBRA, rDLY;
input [10:0] rALT;
input [31:0] rSIMM;
input [15:0] rIMM;
input [5:0] rOPC;
input [4:0] rRD;
input [31:0] rDWBDI;
input [31:2] rPC;
// SYSTEM
input gclk, grst, gena;
 
reg rMSR_C, xMSR_C;
reg rMSR_IE, xMSR_IE;
reg rMSR_BE, xMSR_BE;
reg rMSR_BIP, xMSR_BIP;
wire fSKIP = rBRA & !rDLY;
 
// --- OPERAND SELECT
 
reg [31:0] rOPA, rOPB;
always @(/*AUTOSENSE*/rDWBDI or rMXSRC or rPC or rREGA or rRESULT)
case (rMXSRC)
2'o0: rOPA <= rREGA;
2'o1: rOPA <= rRESULT;
2'o2: rOPA <= rDWBDI;
2'o3: rOPA <= {rPC, 2'o0};
endcase // case (rMXSRC)
always @(/*AUTOSENSE*/rDWBDI or rMXTGT or rREGB or rRESULT or rSIMM)
case (rMXTGT)
2'o0: rOPB <= rREGB;
2'o1: rOPB <= rRESULT;
2'o2: rOPB <= rDWBDI;
2'o3: rOPB <= rSIMM;
endcase // case (rMXTGT)
 
// --- ADD/SUB SELECTOR ----
// FIXME: Redesign
// 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 --------------------------------------
 
reg [31:0] rRES_LOG;
always @(/*AUTOSENSE*/rOPA or rOPB or rOPC)
case (rOPC[1:0])
2'o0: rRES_LOG <= #1 rOPA | rOPB;
2'o1: rRES_LOG <= #1 rOPA & rOPB;
2'o2: rRES_LOG <= #1 rOPA ^ rOPB;
2'o3: rRES_LOG <= #1 rOPA & ~rOPB;
endcase // case (rOPC[1:0])
 
// --- SHIFTER SELECTOR ------------------------------------
reg [31:0] rRES_SFT;
reg rRES_SFTC;
always @(/*AUTOSENSE*/rIMM or rMSR_C or rOPA)
case (rIMM[6:5])
2'o0: {rRES_SFT, rRES_SFTC} <= #1 {rOPA[31],rOPA[31:0]};
2'o1: {rRES_SFT, rRES_SFTC} <= #1 {rMSR_C,rOPA[31:0]};
2'o2: {rRES_SFT, rRES_SFTC} <= #1 {1'b0,rOPA[31:0]};
2'o3: {rRES_SFT, rRES_SFTC} <= #1 (rIMM[0]) ? { {(16){rOPA[15]}}, rOPA[15:0], rMSR_C} :
{ {(24){rOPA[7]}}, rOPA[7:0], rMSR_C};
endcase // case (rIMM[6:5])
 
// --- MOVE SELECTOR ---------------------------------------
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 fMFPC = (rOPC == 6'o45) & !rIMM[14] & !rIMM[0];
reg [31:0] rRES_MOV;
always @(/*AUTOSENSE*/fMFPC or fMFSR or rOPA or rOPB or rPC or rRA
or wMSR)
rRES_MOV <= (fMFSR) ? wMSR :
(fMFPC) ? rPC :
(rRA[3]) ? rOPB :
rOPA;
// --- MULTIPLIER ------------------------------------------
// TODO: 2 stage multiplier
reg [31:0] rRES_MUL;
always @(/*AUTOSENSE*/rOPA or rOPB) begin
rRES_MUL <= (rOPA * rOPB);
end
 
// --- BARREL SHIFTER --------------------------------------
 
reg [31:0] rRES_BSF;
reg [31:0] xBSRL, xBSRA, xBSLL;
// Infer a logical left barrel shifter.
always @(/*AUTOSENSE*/rOPA or rOPB)
xBSLL <= rOPA << rOPB[4:0];
// Infer a logical right barrel shifter.
always @(/*AUTOSENSE*/rOPA or rOPB)
xBSRL <= rOPA >> rOPB[4:0];
 
// Infer a arithmetic right barrel shifter.
always @(/*AUTOSENSE*/rOPA or rOPB)
case (rOPB[4:0])
5'd00: xBSRA <= rOPA;
5'd01: xBSRA <= {{(1){rOPA[31]}}, rOPA[31:1]};
5'd02: xBSRA <= {{(2){rOPA[31]}}, rOPA[31:2]};
5'd03: xBSRA <= {{(3){rOPA[31]}}, rOPA[31:3]};
5'd04: xBSRA <= {{(4){rOPA[31]}}, rOPA[31:4]};
5'd05: xBSRA <= {{(5){rOPA[31]}}, rOPA[31:5]};
5'd06: xBSRA <= {{(6){rOPA[31]}}, rOPA[31:6]};
5'd07: xBSRA <= {{(7){rOPA[31]}}, rOPA[31:7]};
5'd08: xBSRA <= {{(8){rOPA[31]}}, rOPA[31:8]};
5'd09: xBSRA <= {{(9){rOPA[31]}}, rOPA[31:9]};
5'd10: xBSRA <= {{(10){rOPA[31]}}, rOPA[31:10]};
5'd11: xBSRA <= {{(11){rOPA[31]}}, rOPA[31:11]};
5'd12: xBSRA <= {{(12){rOPA[31]}}, rOPA[31:12]};
5'd13: xBSRA <= {{(13){rOPA[31]}}, rOPA[31:13]};
5'd14: xBSRA <= {{(14){rOPA[31]}}, rOPA[31:14]};
5'd15: xBSRA <= {{(15){rOPA[31]}}, rOPA[31:15]};
5'd16: xBSRA <= {{(16){rOPA[31]}}, rOPA[31:16]};
5'd17: xBSRA <= {{(17){rOPA[31]}}, rOPA[31:17]};
5'd18: xBSRA <= {{(18){rOPA[31]}}, rOPA[31:18]};
5'd19: xBSRA <= {{(19){rOPA[31]}}, rOPA[31:19]};
5'd20: xBSRA <= {{(20){rOPA[31]}}, rOPA[31:20]};
5'd21: xBSRA <= {{(21){rOPA[31]}}, rOPA[31:21]};
5'd22: xBSRA <= {{(22){rOPA[31]}}, rOPA[31:22]};
5'd23: xBSRA <= {{(23){rOPA[31]}}, rOPA[31:23]};
5'd24: xBSRA <= {{(24){rOPA[31]}}, rOPA[31:24]};
5'd25: xBSRA <= {{(25){rOPA[31]}}, rOPA[31:25]};
5'd26: xBSRA <= {{(26){rOPA[31]}}, rOPA[31:26]};
5'd27: xBSRA <= {{(27){rOPA[31]}}, rOPA[31:27]};
5'd28: xBSRA <= {{(28){rOPA[31]}}, rOPA[31:28]};
5'd29: xBSRA <= {{(29){rOPA[31]}}, rOPA[31:29]};
5'd30: xBSRA <= {{(30){rOPA[31]}}, rOPA[31:30]};
5'd31: xBSRA <= {{(31){rOPA[31]}}, rOPA[31]};
endcase // case (rOPB[4:0])
 
always @(/*AUTOSENSE*/rALT or xBSLL or xBSRA or xBSRL)
case (rALT[10:9])
2'd0: rRES_BSF <= xBSRL;
2'd1: rRES_BSF <= xBSRA;
2'd2: rRES_BSF <= xBSLL;
default: rRES_BSF <= 32'hX;
endcase // case (rALT[10:9])
// --- MSR REGISTER -----------------
// 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 | |rXCE) begin
if (fSKIP) 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
 
// IE/BIP/BE
wire fRTID = (rOPC == 6'o55) & rRD[0];
wire fRTBD = (rOPC == 6'o55) & rRD[1];
wire fBRK = ((rOPC == 6'o56) | (rOPC == 6'o66)) & (rRA == 5'hC);
wire fINT = ((rOPC == 6'o56) | (rOPC == 6'o66)) & (rRA == 5'hE);
always @(/*AUTOSENSE*/fINT or fMTS or fRTID or rMSR_IE or rOPA)
xMSR_IE <= (fINT) ? 1'b0 :
(fRTID) ? 1'b1 :
(fMTS) ? rOPA[1] :
rMSR_IE;
always @(/*AUTOSENSE*/fBRK or fMTS or fRTBD or rMSR_BIP or rOPA)
xMSR_BIP <= (fBRK) ? 1'b1 :
(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 -------------------------------------------
// Selects results from functional units.
reg [31:0] rRESULT, xRESULT;
 
// RESULT
always @(/*AUTOSENSE*/fSKIP or rMXALU or rRES_ADD or rRES_BSF
or rRES_LOG or rRES_MOV or rRES_MUL or rRES_SFT)
if (fSKIP)
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
xRESULT <= 32'h0;
// End of automatics
else
case (rMXALU)
3'o0: xRESULT <= rRES_ADD;
3'o1: xRESULT <= rRES_LOG;
3'o2: xRESULT <= rRES_SFT;
3'o3: xRESULT <= rRES_MOV;
3'o4: xRESULT <= (MUL) ? rRES_MUL : 32'hX;
3'o5: xRESULT <= (BSF) ? rRES_BSF : 32'hX;
default: xRESULT <= 32'hX;
endcase // case (rMXALU)
 
// --- DATA WISHBONE -----
reg [3:0] rDWBSEL, xDWBSEL;
assign dwb_adr_o = rRESULT[DW-1:2];
assign dwb_sel_o = rDWBSEL;
 
always @(/*AUTOSENSE*/rOPC or wADD)
case (rOPC[1:0])
2'o0: case (wADD[1:0]) // 8'bit
2'o0: xDWBSEL <= 4'h8;
2'o1: xDWBSEL <= 4'h4;
2'o2: xDWBSEL <= 4'h2;
2'o3: xDWBSEL <= 4'h1;
endcase // case (wADD[1:0])
2'o1: xDWBSEL <= (wADD[1]) ? 4'h3 : 4'hC; // 16'bit
2'o2: xDWBSEL <= 4'hF; // 32'bit
2'o3: xDWBSEL <= 4'h0; // FSL
endcase // case (rOPC[1:0])
 
// --- FSL WISHBONE --------------------
 
reg [14:2] rFSLADR, xFSLADR;
assign {fsl_adr_o, fsl_tag_o} = rFSLADR[8:2];
 
always @(/*AUTOSENSE*/rALT or rRB) begin
xFSLADR <= {rALT, rRB[3:2]};
end
// --- SYNC ---
 
always @(posedge gclk)
if (grst) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
rDWBSEL <= 4'h0;
rFSLADR <= 13'h0;
rMSR_BE <= 1'h0;
rMSR_BIP <= 1'h0;
rMSR_C <= 1'h0;
rMSR_IE <= 1'h0;
rRESULT <= 32'h0;
// End of automatics
end else if (gena) begin
rRESULT <= #1 xRESULT;
rDWBSEL <= #1 xDWBSEL;
rMSR_C <= #1 xMSR_C;
rMSR_IE <= #1 xMSR_IE;
rMSR_BE <= #1 xMSR_BE;
rMSR_BIP <= #1 xMSR_BIP;
rFSLADR <= #1 xFSLADR;
end
endmodule // aeMB_xecu
/verilog/aeMB_core.v
0,0 → 1,134
// $Id: aeMB_core.v,v 1.9 2007-11-23 14:06:41 sybreon Exp $
//
// AEMB 32'bit RISC MICROPROCESSOR CORE
//
// Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
//
// This file is part of AEMB.
//
// AEMB 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 3 of the
// License, or (at your option) any later version.
//
// AEMB 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 AEMB. If not, see <http://www.gnu.org/licenses/>.
//
// HISTORY
// $Log: not supported by cvs2svn $
// Revision 1.8 2007/10/22 19:12:59 sybreon
// Made some changes to the interrupt control. In some cases, the interrupt logic waits forever and doesn't execute. Bug was discovered by M. Ettus.
//
// Revision 1.7 2007/05/30 18:44:30 sybreon
// Added interrupt support.
//
// Revision 1.6 2007/05/17 09:08:21 sybreon
// Removed asynchronous reset signal.
//
// Revision 1.5 2007/04/27 00:23:55 sybreon
// Added code documentation.
// Improved size & speed of rtl/verilog/aeMB_aslu.v
//
// Revision 1.4 2007/04/25 22:15:04 sybreon
// Added support for 8-bit and 16-bit data types.
//
// Revision 1.3 2007/04/11 04:30:43 sybreon
// Added pipeline stalling from incomplete bus cycles.
// Separated sync and async portions of code.
//
// Revision 1.2 2007/04/04 06:13:23 sybreon
// Removed unused signals
//
// Revision 1.1 2007/03/09 17:52:17 sybreon
// initial import
//
 
 
module aeMB_core (/*AUTOARG*/
// Outputs
iwb_stb_o, iwb_adr_o, fsl_wre_o, fsl_tag_o, fsl_stb_o, fsl_dat_o,
fsl_adr_o, dwb_wre_o, dwb_stb_o, dwb_sel_o, dwb_dat_o, dwb_adr_o,
// Inputs
sys_rst_i, sys_int_i, sys_clk_i, iwb_dat_i, iwb_ack_i, fsl_dat_i,
fsl_ack_i, dwb_dat_i, dwb_ack_i
);
// Instruction WB address space
parameter ISIZ = 32;
// Data WB address space
parameter DSIZ = 32;
// Multiplier
parameter MUL = 1;
// Barrel Shifter
parameter BSF = 1;
 
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output [DSIZ-1:2] dwb_adr_o; // From edk32 of aeMB_edk32.v
output [31:0] dwb_dat_o; // From edk32 of aeMB_edk32.v
output [3:0] dwb_sel_o; // From edk32 of aeMB_edk32.v
output dwb_stb_o; // From edk32 of aeMB_edk32.v
output dwb_wre_o; // From edk32 of aeMB_edk32.v
output [6:2] fsl_adr_o; // From edk32 of aeMB_edk32.v
output [31:0] fsl_dat_o; // From edk32 of aeMB_edk32.v
output fsl_stb_o; // From edk32 of aeMB_edk32.v
output [1:0] fsl_tag_o; // From edk32 of aeMB_edk32.v
output fsl_wre_o; // From edk32 of aeMB_edk32.v
output [ISIZ-1:2] iwb_adr_o; // From edk32 of aeMB_edk32.v
output iwb_stb_o; // From edk32 of aeMB_edk32.v
// End of automatics
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input dwb_ack_i; // To edk32 of aeMB_edk32.v
input [31:0] dwb_dat_i; // To edk32 of aeMB_edk32.v
input fsl_ack_i; // To edk32 of aeMB_edk32.v
input [31:0] fsl_dat_i; // To edk32 of aeMB_edk32.v
input iwb_ack_i; // To edk32 of aeMB_edk32.v
input [31:0] iwb_dat_i; // To edk32 of aeMB_edk32.v
input sys_clk_i; // To edk32 of aeMB_edk32.v
input sys_int_i; // To edk32 of aeMB_edk32.v
input sys_rst_i; // To edk32 of aeMB_edk32.v
// End of automatics
/*AUTOWIRE*/
 
// INSTANTIATIONS /////////////////////////////////////////////////////////////////
 
/*
aeMB_edk32 AUTO_TEMPLATE (
.dwb_adr_o(dwb_adr_o[DSIZ-1:2]),
.iwb_adr_o(iwb_adr_o[ISIZ-1:2]),
);
*/
aeMB_edk32 #(ISIZ, DSIZ, MUL, BSF)
edk32 (/*AUTOINST*/
// Outputs
.dwb_adr_o (dwb_adr_o[DSIZ-1:2]), // Templated
.dwb_dat_o (dwb_dat_o[31:0]),
.dwb_sel_o (dwb_sel_o[3:0]),
.dwb_stb_o (dwb_stb_o),
.dwb_wre_o (dwb_wre_o),
.fsl_adr_o (fsl_adr_o[6:2]),
.fsl_dat_o (fsl_dat_o[31:0]),
.fsl_stb_o (fsl_stb_o),
.fsl_tag_o (fsl_tag_o[1:0]),
.fsl_wre_o (fsl_wre_o),
.iwb_adr_o (iwb_adr_o[ISIZ-1:2]), // Templated
.iwb_stb_o (iwb_stb_o),
// Inputs
.dwb_ack_i (dwb_ack_i),
.dwb_dat_i (dwb_dat_i[31:0]),
.fsl_ack_i (fsl_ack_i),
.fsl_dat_i (fsl_dat_i[31:0]),
.iwb_ack_i (iwb_ack_i),
.iwb_dat_i (iwb_dat_i[31:0]),
.sys_int_i (sys_int_i),
.sys_clk_i (sys_clk_i),
.sys_rst_i (sys_rst_i));
endmodule // aeMB_core
/verilog/aeMB_ibuf.v
0,0 → 1,156
// $Id: aeMB_ibuf.v,v 1.7 2007-11-22 15:11:15 sybreon Exp $
//
// AEMB INSTRUCTION BUFFER
//
// Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
//
// This file is part of AEMB.
//
// AEMB 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 3 of the
// License, or (at your option) any later version.
//
// AEMB 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 AEMB. If not, see <http://www.gnu.org/licenses/>.
//
// $Log: not supported by cvs2svn $
// Revision 1.6 2007/11/14 23:39:51 sybreon
// Fixed interrupt signal synchronisation.
//
// Revision 1.5 2007/11/14 22:14:34 sybreon
// Changed interrupt handling system (reported by M. Ettus).
//
// Revision 1.4 2007/11/10 16:39:38 sybreon
// Upgraded license to LGPLv3.
// Significant performance optimisations.
//
// Revision 1.3 2007/11/03 08:34:55 sybreon
// Minor code cleanup.
//
// Revision 1.2 2007/11/02 19:20:58 sybreon
// Added better (beta) interrupt support.
// Changed MSR_IE to disabled at reset as per MB docs.
//
// Revision 1.1 2007/11/02 03:25:40 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_ibuf (/*AUTOARG*/
// Outputs
rIMM, rRA, rRD, rRB, rALT, rOPC, rSIMM, xIREG, iwb_stb_o,
// Inputs
rBRA, rMSR_IE, rMSR_BIP, iwb_dat_i, iwb_ack_i, sys_int_i, gclk,
grst, gena
);
// INTERNAL
output [15:0] rIMM;
output [4:0] rRA, rRD, rRB;
output [10:0] rALT;
output [5:0] rOPC;
output [31:0] rSIMM;
output [31:0] xIREG;
input rBRA;
//input [1:0] rXCE;
input rMSR_IE;
input rMSR_BIP;
// INST WISHBONE
output iwb_stb_o;
input [31:0] iwb_dat_i;
input iwb_ack_i;
 
// SYSTEM
input sys_int_i;
 
// SYSTEM
input gclk, grst, gena;
 
reg [15:0] rIMM;
reg [4:0] rRA, rRD;
reg [5:0] rOPC;
 
// FIXME: Endian
wire [31:0] wIDAT = iwb_dat_i;
assign {rRB, rALT} = rIMM;
// TODO: Assign to FIFO not full.
assign iwb_stb_o = 1'b1;
 
reg [31:0] rSIMM, xSIMM;
 
wire [31:0] wXCEOP = 32'hBA2D0008; // Vector 0x08
wire [31:0] wINTOP = 32'hB9CE0010; // Vector 0x10
wire [31:0] wBRKOP = 32'hBA0C0018; // Vector 0x18
wire [31:0] wBRAOP = 32'h88000000; // NOP for branches
wire [31:0] wIREG = {rOPC, rRD, rRA, rRB, rALT};
reg [31:0] xIREG;
 
 
// --- INTERRUPT LATCH --------------------------------------
// Debounce and latch onto the positive level. This is independent
// of the pipeline so that stalls do not affect it.
reg rFINT;
reg [1:0] rDINT;
wire wSHOT = rDINT[0];
 
always @(posedge gclk)
if (grst) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
rDINT <= 2'h0;
rFINT <= 1'h0;
// End of automatics
end else if (rMSR_IE) begin
rDINT <= #1 {rDINT[0], sys_int_i};
rFINT <= #1 (wIREG == wINTOP) ? 1'b0 : (rFINT | wSHOT);
end
 
wire fIMM = (rOPC == 6'o54);
wire fRTD = (rOPC == 6'o55);
wire fBRU = ((rOPC == 6'o46) | (rOPC == 6'o56));
wire fBCC = ((rOPC == 6'o47) | (rOPC == 6'o57));
// --- DELAY SLOT -------------------------------------------
always @(/*AUTOSENSE*/fBCC or fBRU or fIMM or fRTD or rBRA or rFINT
or wBRAOP or wIDAT or wINTOP) begin
xIREG <= (rBRA) ? wBRAOP :
(!fIMM & rFINT & !fRTD & !fBRU & !fBCC) ? wINTOP :
wIDAT;
end
always @(/*AUTOSENSE*/fIMM or rBRA or rIMM or wIDAT or xIREG) begin
xSIMM <= (!fIMM | rBRA) ? { {(16){xIREG[15]}}, xIREG[15:0]} :
{rIMM, wIDAT[15:0]};
end
 
// --- PIPELINE --------------------------------------------
always @(posedge gclk)
if (grst) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
rIMM <= 16'h0;
rOPC <= 6'h0;
rRA <= 5'h0;
rRD <= 5'h0;
rSIMM <= 32'h0;
// End of automatics
end else if (gena) begin
{rOPC, rRD, rRA, rIMM} <= #1 xIREG;
rSIMM <= #1 xSIMM;
end
endmodule // aeMB_ibuf
/verilog/aeMB_bpcu.v
0,0 → 1,181
// $Id: aeMB_bpcu.v,v 1.4 2007-11-14 22:14:34 sybreon Exp $
//
// AEMB BRANCH PROGRAMME COUNTER UNIT
//
// Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
//
// This file is part of AEMB.
//
// AEMB 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 3 of the
// License, or (at your option) any later version.
//
// AEMB 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 AEMB. If not, see <http://www.gnu.org/licenses/>.
//
// $Log: not supported by cvs2svn $
// Revision 1.3 2007/11/10 16:39:38 sybreon
// Upgraded license to LGPLv3.
// Significant performance optimisations.
//
// Revision 1.2 2007/11/02 19:20:58 sybreon
// Added better (beta) interrupt support.
// Changed MSR_IE to disabled at reset as per MB docs.
//
// Revision 1.1 2007/11/02 03:25:39 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_bpcu (/*AUTOARG*/
// Outputs
iwb_adr_o, rPC, rPCLNK, rBRA, rDLY,
// Inputs
rMXALT, rOPC, rRD, rRA, rRESULT, rDWBDI, rREGA, gclk, grst, gena
);
parameter IW = 24;
 
// INST WISHBONE
output [IW-1:2] iwb_adr_o;
 
// INTERNAL
output [31:2] rPC, rPCLNK;
output rBRA;
output rDLY;
//output [1:0] rATOM;
//output [1:0] xATOM;
input [1:0] rMXALT;
input [5:0] rOPC;
input [4:0] rRD, rRA;
input [31:0] rRESULT; // ALU
input [31:0] rDWBDI; // RAM
input [31:0] rREGA;
//input [1:0] rXCE;
// SYSTEM
input gclk, grst, gena;
 
// --- BRANCH CONTROL --------------------------------------------
// Controls the branch and delay flags
wire fRTD = (rOPC == 6'o55);
wire fBCC = (rOPC == 6'o47) | (rOPC == 6'o57);
wire fBRU = (rOPC == 6'o46) | (rOPC == 6'o56);
 
wire [31:0] wREGA;
assign wREGA = (rMXALT == 2'o2) ? rDWBDI :
(rMXALT == 2'o1) ? rRESULT :
rREGA;
wire wBEQ = (wREGA == 32'd0);
wire wBNE = ~wBEQ;
wire wBLT = wREGA[31];
wire wBLE = wBLT | wBEQ;
wire wBGE = ~wBLT;
wire wBGT = ~wBLE;
 
reg xXCC;
always @(/*AUTOSENSE*/rRD or wBEQ or wBGE or wBGT or wBLE or wBLT
or wBNE)
case (rRD[2:0])
3'o0: xXCC <= wBEQ;
3'o1: xXCC <= wBNE;
3'o2: xXCC <= wBLT;
3'o3: xXCC <= wBLE;
3'o4: xXCC <= wBGT;
3'o5: xXCC <= wBGE;
default: xXCC <= 1'bX;
endcase // case (rRD[2:0])
 
reg rBRA, xBRA;
reg rDLY, xDLY;
wire fSKIP = rBRA & !rDLY;
always @(/*AUTOSENSE*/fBCC or fBRU or fRTD or rBRA or rRA or rRD
or xXCC)
//if (rBRA | |rXCE) begin
if (rBRA) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
xBRA <= 1'h0;
xDLY <= 1'h0;
// End of automatics
end else begin
xDLY <= (fBRU & rRA[4]) | (fBCC & rRD[4]) | fRTD;
xBRA <= (fRTD | fBRU) ? 1'b1 :
(fBCC) ? xXCC :
1'b0;
end
 
// --- PC PIPELINE ------------------------------------------------
// PC and related changes
reg [31:2] rIPC, xIPC;
reg [31:2] rPC, xPC;
reg [31:2] rPCLNK, xPCLNK;
assign iwb_adr_o = rIPC[IW-1:2];
always @(/*AUTOSENSE*/rBRA or rIPC or rPC or rRESULT) begin
//xPCLNK <= (^rATOM) ? rPC : rPC;
xPCLNK <= rPC;
//xPC <= (^rATOM) ? rIPC : rRESULT[31:2];
xPC <= rIPC;
//xIPC <= (rBRA) ? rRESULT[31:2] : (rIPC + 1);
/*
case (rXCE)
2'o1: xIPC <= 30'h2;
2'o2: xIPC <= 30'h4;
2'o3: xIPC <= 30'h6;
default: xIPC <= (rBRA) ? rRESULT[31:2] : (rIPC + 1);
endcase // case (rXCE)
*/
xIPC <= (rBRA) ? rRESULT[31:2] : (rIPC + 1);
end
 
// --- ATOMIC CONTROL ---------------------------------------------
// This is used to indicate 'safe' instruction borders.
wire wIMM = (rOPC == 6'o54) & !fSKIP;
wire wRTD = (rOPC == 6'o55) & !fSKIP;
wire wBCC = xXCC & ((rOPC == 6'o47) | (rOPC == 6'o57)) & !fSKIP;
wire wBRU = ((rOPC == 6'o46) | (rOPC == 6'o56)) & !fSKIP;
wire fATOM = ~(wIMM | wRTD | wBCC | wBRU | rBRA);
reg [1:0] rATOM, xATOM;
 
always @(/*AUTOSENSE*/fATOM or rATOM)
xATOM <= {rATOM[0], (rATOM[0] ^ fATOM)};
// --- SYNC PIPELINE ----------------------------------------------
always @(posedge gclk)
if (grst) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
rATOM <= 2'h0;
rBRA <= 1'h0;
rDLY <= 1'h0;
rIPC <= 30'h0;
rPC <= 30'h0;
rPCLNK <= 30'h0;
// End of automatics
end else if (gena) begin
rIPC <= #1 xIPC;
rBRA <= #1 xBRA;
rPC <= #1 xPC;
rPCLNK <= #1 xPCLNK;
rDLY <= #1 xDLY;
rATOM <= #1 xATOM;
end
endmodule // aeMB_bpcu
/verilog/aeMB_regf.v
0,0 → 1,237
// $Id: aeMB_regf.v,v 1.3 2007-11-10 16:39:38 sybreon Exp $
//
// AEMB REGISTER FILE
//
// Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
//
// This file is part of AEMB.
//
// AEMB 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 3 of the
// License, or (at your option) any later version.
//
// AEMB 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 AEMB. If not, see <http://www.gnu.org/licenses/>.
//
// $Log: not supported by cvs2svn $
// Revision 1.2 2007/11/09 20:51:52 sybreon
// Added GET/PUT support through a FSL bus.
//
// 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_regf (/*AUTOARG*/
// Outputs
rREGA, rREGB, rDWBDI, dwb_dat_o, fsl_dat_o,
// Inputs
rOPC, rRA, rRB, rRW, rRD, rMXDST, rPCLNK, rRESULT, rDWBSEL, rBRA,
rDLY, dwb_dat_i, fsl_dat_i, gclk, grst, gena
);
// INTERNAL
output [31:0] rREGA, rREGB;
output [31:0] rDWBDI;
input [5:0] rOPC;
input [4:0] rRA, rRB, rRW, rRD;
input [1:0] rMXDST;
input [31:2] rPCLNK;
input [31:0] rRESULT;
input [3:0] rDWBSEL;
input rBRA, rDLY;
// DATA WISHBONE
output [31:0] dwb_dat_o;
input [31:0] dwb_dat_i;
 
// FSL WISHBONE
output [31:0] fsl_dat_o;
input [31:0] fsl_dat_i;
// SYSTEM
input gclk, grst, gena;
 
// --- LOAD SIZER ----------------------------------------------
// Moves the data bytes around depending on the size of the
// operation.
 
wire [31:0] wDWBDI = dwb_dat_i; // FIXME: Endian
wire [31:0] wFSLDI = fsl_dat_i; // FIXME: Endian
reg [31:0] rDWBDI;
reg [1:0] rSIZ;
always @(/*AUTOSENSE*/rDWBSEL or wDWBDI or wFSLDI) begin
/* 51.2
case (rSIZ)
// FSL
2'o3: rDWBDI <= wFSLDI;
// 32'bit
2'o2: rDWBDI <= wDWBDI;
// 16'bit
2'o1: case (rRESULT[1])
1'b0: rDWBDI <= {16'd0, wDWBDI[31:16]};
1'b1: rDWBDI <= {16'd0, wDWBDI[15:0]};
endcase // case (rRESULT[1])
// 8'bit
2'o0: case (rRESULT[1:0])
2'o0: rDWBDI <= {24'd0, wDWBDI[31:24]};
2'o1: rDWBDI <= {24'd0, wDWBDI[23:16]};
2'o2: rDWBDI <= {24'd0, wDWBDI[15:8]};
2'o3: rDWBDI <= {24'd0, wDWBDI[7:0]};
endcase // case (rRESULT[1:0])
endcase // case (rSIZ)
*/
/* 50.6
case ({rSIZ, rRESULT[1:0]})
// FSL
4'hC, 4'hD, 4'hE, 4'hF: rDWBDI <= wFSLDI;
// 32'bit
4'h8: rDWBDI <= wDWBDI;
// 16'bit
4'h4: rDWBDI <= {16'd0, wDWBDI[31:16]};
4'h6: rDWBDI <= {16'd0, wDWBDI[15:0]};
// 8'bit
4'h0: rDWBDI <= {24'd0, wDWBDI[31:24]};
4'h1: rDWBDI <= {24'd0, wDWBDI[23:16]};
4'h2: rDWBDI <= {24'd0, wDWBDI[15:8]};
4'h3: rDWBDI <= {24'd0, wDWBDI[7:0]};
default: rDWBDI <= 32'hX;
endcase // case (rSIZ)
*/
 
// 52.0
case (rDWBSEL)
// 8'bit
4'h8: rDWBDI <= {24'd0, wDWBDI[31:24]};
4'h4: rDWBDI <= {24'd0, wDWBDI[23:16]};
4'h2: rDWBDI <= {24'd0, wDWBDI[15:8]};
4'h1: rDWBDI <= {24'd0, wDWBDI[7:0]};
// 16'bit
4'hC: rDWBDI <= {16'd0, wDWBDI[31:16]};
4'h3: rDWBDI <= {16'd0, wDWBDI[15:0]};
// 32'bit
4'hF: rDWBDI <= wDWBDI;
// FSL
4'h0: rDWBDI <= wFSLDI;
// Undefined
default: rDWBDI <= 32'hX;
endcase
end
 
always @(posedge gclk)
if (grst) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
rSIZ <= 2'h0;
// End of automatics
end else if (gena) begin
rSIZ <= rOPC[1:0];
end
// --- GENERAL PURPOSE REGISTERS (R0-R31) -----------------------
// LUT RAM implementation is smaller and faster. R0 gets written
// during reset with 0x00 and doesn't change after.
reg [31:0] mARAM[0:31],
mBRAM[0:31],
mDRAM[0:31];
 
wire [31:0] rREGW = mDRAM[rRW];
wire [31:0] rREGD = mDRAM[rRD];
assign rREGA = mARAM[rRA];
assign rREGB = mBRAM[rRB];
 
wire fRDWE = |rRW;
reg [31:0] xWDAT;
 
always @(/*AUTOSENSE*/rDWBDI or rMXDST or rPCLNK or rREGW
or rRESULT)
case (rMXDST)
2'o2: xWDAT <= rDWBDI;
2'o1: xWDAT <= {rPCLNK, 2'o0};
2'o0: xWDAT <= rRESULT;
2'o3: xWDAT <= rREGW; // No change
endcase // case (rMXDST)
always @(posedge gclk)
if (grst | fRDWE) begin
mARAM[rRW] <= xWDAT;
mBRAM[rRW] <= xWDAT;
mDRAM[rRW] <= xWDAT;
end
 
// --- STORE SIZER ---------------------------------------------
// Replicates the data bytes across depending on the size of the
// operation.
 
reg [31:0] rDWBDO, xDWBDO;
wire [31:0] xFSL;
wire fFFWD_M = (rRA == rRW) & (rMXDST == 2'o2) & fRDWE;
wire fFFWD_R = (rRA == rRW) & (rMXDST == 2'o0) & fRDWE;
assign fsl_dat_o = rDWBDO;
assign xFSL = (fFFWD_M) ? rDWBDI :
(fFFWD_R) ? rRESULT :
rREGA;
 
wire [31:0] xDST;
wire fDFWD_M = (rRW == rRD) & (rMXDST == 2'o2) & fRDWE;
wire fDFWD_R = (rRW == rRD) & (rMXDST == 2'o0) & fRDWE;
assign dwb_dat_o = rDWBDO;
assign xDST = (fDFWD_M) ? rDWBDI :
(fDFWD_R) ? rRESULT :
rREGD;
always @(/*AUTOSENSE*/rOPC or xDST or xFSL)
case (rOPC[1:0])
// 8'bit
2'h0: xDWBDO <= {(4){xDST[7:0]}};
// 16'bit
2'h1: xDWBDO <= {(2){xDST[15:0]}};
// 32'bit
2'h2: xDWBDO <= xDST;
// FSL
2'h3: xDWBDO <= xFSL;
//default: xDWBDO <= 32'hX;
endcase // case (rOPC[1:0])
 
always @(posedge gclk)
if (grst) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
rDWBDO <= 32'h0;
// End of automatics
end else if (gena) begin
rDWBDO <= #1 xDWBDO;
end
// --- SIMULATION ONLY ------------------------------------------
// Randomise memory to simulate real-world memory
// synopsys translate_off
integer i;
initial begin
for (i=0; i<32; i=i+1) begin
mARAM[i] <= $random;
mBRAM[i] <= $random;
mDRAM[i] <= $random;
end
end
// synopsys translate_on
endmodule // aeMB_regf

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.