diff options
Diffstat (limited to 'opencores/aemb/rtl/verilog/aeMB_regf.v')
-rw-r--r-- | opencores/aemb/rtl/verilog/aeMB_regf.v | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/opencores/aemb/rtl/verilog/aeMB_regf.v b/opencores/aemb/rtl/verilog/aeMB_regf.v new file mode 100644 index 000000000..9ac45299b --- /dev/null +++ b/opencores/aemb/rtl/verilog/aeMB_regf.v @@ -0,0 +1,241 @@ +// $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: aeMB_regf.v,v $ +// Revision 1.3 2007/11/10 16:39:38 sybreon +// Upgraded license to LGPLv3. +// Significant performance optimisations. +// +// 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 |