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

Subversion Repositories aemb

[/] [aemb/] [tags/] [AEMB_7_05/] [rtl/] [verilog/] [aeMB_regfile.v] - Rev 18

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 * $Id: aeMB_regfile.v,v 1.8 2007-04-12 20:21:33 sybreon Exp $
 * 
 * AEMB Register File
 * Copyright (C) 2006 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 
 *
 * DESCRIPTION
 * Implements the 32 registers as registers. Some registers require
 * special actions during hardware exception/interrupts. Data forwarding
 * is also taken care of inside here to simplify decode logic.
 *
 * HISTORY
 * $Log: not supported by cvs2svn $
 * Revision 1.7  2007/04/11 16:30:06  sybreon
 * Cosmetic changes
 *
 * Revision 1.6  2007/04/11 04:30:43  sybreon
 * Added pipeline stalling from incomplete bus cycles.
 * Separated sync and async portions of code.
 *
 * Revision 1.5  2007/04/04 14:08:34  sybreon
 * Added initial interrupt/exception support.
 *
 * Revision 1.4  2007/04/04 06:11:47  sybreon
 * Fixed memory read-write data hazard
 *
 * Revision 1.3  2007/04/03 14:46:26  sybreon
 * Fixed endian correction issues on data bus.
 *
 * Revision 1.2  2007/03/26 12:21:31  sybreon
 * Fixed a minor bug where RD is trashed by a STORE instruction. Spotted by Joon Lee.
 *
 * Revision 1.1  2007/03/09 17:52:17  sybreon
 * initial import
 *
 */
 
// 1284@78 - REG
// 227@141 - RAM
module aeMB_regfile(/*AUTOARG*/
   // Outputs
   dwb_dat_o, rREGA, rREGB,
   // Inputs
   dwb_dat_i, rDWBSTB, rDWBWE, rRA, rRB, rRD, rRD_, rRESULT, rFSM,
   rPC, rLNK, rRWE, nclk, nrst, drun, nrun
   );
   // Data WB bus width
   parameter DSIZ = 32;
 
   // Data WB I/F
   output [31:0] dwb_dat_o;
   input [31:0]  dwb_dat_i;
 
   // Internal I/F
   output [31:0] rREGA, rREGB;
   input 	 rDWBSTB, rDWBWE;   
   input [4:0] 	 rRA, rRB, rRD, rRD_;   
   input [31:0]  rRESULT;
   input [1:0] 	 rFSM;   
   input [31:0]  rPC;
   //, rPCNXT;
   input 	 rLNK, rRWE;
   input 	 nclk, nrst, drun, nrun;   
 
   // Register File
   reg [31:0] 	 r00,r01,r02,r03,r04,r05,r06,r07;
   reg [31:0] 	 r08,r09,r0A,r0B,r0C,r0D,r0E,r0F;
   reg [31:0] 	 r10,r11,r12,r13,r14,r15,r16,r17;
   reg [31:0] 	 r18,r19,r1A,r1B,r1C,r1D,r1E,r1F; 		 
 
   // FLAGS
   wire fWE = rRWE & ~rDWBWE;
   wire fLNK = rLNK;
   wire fLD = rDWBSTB ^ rDWBWE;   
 
   // PC Latch
   reg [31:0] 	 rPC_;
   always @(negedge nclk or negedge nrst)
     if (!nrst) begin
	/*AUTORESET*/
	// Beginning of autoreset for uninitialized flops
	rPC_ <= 32'h0;
	// End of automatics
     end else if (nrun) begin
	rPC_ <= #1 rPC;	
     end
 
   // DWB data - Endian Correction
   reg [31:0] 	 rDWBDAT, xDWBDAT;
   //assign 	 dwb_dat_o = rDWBDAT;
   //wire [31:0] 	 wDWBDAT = dwb_dat_i;
   assign 	 dwb_dat_o = {rDWBDAT[7:0],rDWBDAT[15:8],rDWBDAT[23:16],rDWBDAT[31:24]};   
   wire [31:0] 	 wDWBDAT = {dwb_dat_i[7:0],dwb_dat_i[15:8],dwb_dat_i[23:16],dwb_dat_i[31:24]};   
 
   // Forwarding Control
   wire 	 fDFWD = (rRD == rRD_) & fWE;
   wire 	 fMFWD = rDWBSTB & ~rDWBWE;   
   wire [31:0] 	 wRESULT = (fMFWD) ? wDWBDAT : rRESULT;   
 
   // Register Load
   always @(/*AUTOSENSE*/drun or fDFWD or r00 or r01 or r02 or r03
	    or r04 or r05 or r06 or r07 or r08 or r09 or r0A or r0B
	    or r0C or r0D or r0E or r0F or r10 or r11 or r12 or r13
	    or r14 or r15 or r16 or r17 or r18 or r19 or r1A or r1B
	    or r1C or r1D or r1E or r1F or rRD or wRESULT)
     if (drun) begin
	case (rRD)
	  5'h00: xDWBDAT <= (fDFWD) ? wRESULT : r00;
	  5'h01: xDWBDAT <= (fDFWD) ? wRESULT : r01;
	  5'h02: xDWBDAT <= (fDFWD) ? wRESULT : r02;
	  5'h03: xDWBDAT <= (fDFWD) ? wRESULT : r03;
	  5'h04: xDWBDAT <= (fDFWD) ? wRESULT : r04;
	  5'h05: xDWBDAT <= (fDFWD) ? wRESULT : r05;
	  5'h06: xDWBDAT <= (fDFWD) ? wRESULT : r06;
	  5'h07: xDWBDAT <= (fDFWD) ? wRESULT : r07;
	  5'h08: xDWBDAT <= (fDFWD) ? wRESULT : r08;
	  5'h09: xDWBDAT <= (fDFWD) ? wRESULT : r09;
	  5'h0A: xDWBDAT <= (fDFWD) ? wRESULT : r0A;
	  5'h0B: xDWBDAT <= (fDFWD) ? wRESULT : r0B;
	  5'h0C: xDWBDAT <= (fDFWD) ? wRESULT : r0C;
	  5'h0D: xDWBDAT <= (fDFWD) ? wRESULT : r0D;
	  5'h0E: xDWBDAT <= (fDFWD) ? wRESULT : r0E;
	  5'h0F: xDWBDAT <= (fDFWD) ? wRESULT : r0F;
	  5'h10: xDWBDAT <= (fDFWD) ? wRESULT : r10;
	  5'h11: xDWBDAT <= (fDFWD) ? wRESULT : r11;
	  5'h12: xDWBDAT <= (fDFWD) ? wRESULT : r12;
	  5'h13: xDWBDAT <= (fDFWD) ? wRESULT : r13;
	  5'h14: xDWBDAT <= (fDFWD) ? wRESULT : r14;
	  5'h15: xDWBDAT <= (fDFWD) ? wRESULT : r15;
	  5'h16: xDWBDAT <= (fDFWD) ? wRESULT : r16;
	  5'h17: xDWBDAT <= (fDFWD) ? wRESULT : r17;
	  5'h18: xDWBDAT <= (fDFWD) ? wRESULT : r18;
	  5'h19: xDWBDAT <= (fDFWD) ? wRESULT : r19;
	  5'h1A: xDWBDAT <= (fDFWD) ? wRESULT : r1A;
	  5'h1B: xDWBDAT <= (fDFWD) ? wRESULT : r1B;
	  5'h1C: xDWBDAT <= (fDFWD) ? wRESULT : r1C;
	  5'h1D: xDWBDAT <= (fDFWD) ? wRESULT : r1D;
	  5'h1E: xDWBDAT <= (fDFWD) ? wRESULT : r1E;
	  5'h1F: xDWBDAT <= (fDFWD) ? wRESULT : r1F;
	endcase // case (rRD)
     end else begin // if (drun)
	/*AUTORESET*/
	// Beginning of autoreset for uninitialized flops
	xDWBDAT <= 32'h0;
	// End of automatics
     end // else: !if(drun)
 
   // Load Registers
   reg [31:0] 	     xREGA, xREGB;
   always @(/*AUTOSENSE*/drun or r00 or r01 or r02 or r03 or r04
	    or r05 or r06 or r07 or r08 or r09 or r0A or r0B or r0C
	    or r0D or r0E or r0F or r10 or r11 or r12 or r13 or r14
	    or r15 or r16 or r17 or r18 or r19 or r1A or r1B or r1C
	    or r1D or r1E or r1F or rRA or rRB)
     if (drun) begin
	case (rRA)
	  5'h1F: xREGA <= r1F;	  
	  5'h1E: xREGA <= r1E;	  
	  5'h1D: xREGA <= r1D;	  
	  5'h1C: xREGA <= r1C;	  
	  5'h1B: xREGA <= r1B;	  
	  5'h1A: xREGA <= r1A;	  
	  5'h19: xREGA <= r19;	  
	  5'h18: xREGA <= r18;	  
	  5'h17: xREGA <= r17;	  
	  5'h16: xREGA <= r16;	  
	  5'h15: xREGA <= r15;	  
	  5'h14: xREGA <= r14;	  
	  5'h13: xREGA <= r13;	  
	  5'h12: xREGA <= r12;	  
	  5'h11: xREGA <= r11;	  
	  5'h10: xREGA <= r10;	  
	  5'h0F: xREGA <= r0F;	  
	  5'h0E: xREGA <= r0E;	  
	  5'h0D: xREGA <= r0D;	  
	  5'h0C: xREGA <= r0C;	  
	  5'h0B: xREGA <= r0B;	  
	  5'h0A: xREGA <= r0A;	  
	  5'h09: xREGA <= r09;	  
	  5'h08: xREGA <= r08;	  
	  5'h07: xREGA <= r07;	  
	  5'h06: xREGA <= r06;	  
	  5'h05: xREGA <= r05;	  
	  5'h04: xREGA <= r04;	  
	  5'h03: xREGA <= r03;	  
	  5'h02: xREGA <= r02;	  
	  5'h01: xREGA <= r01;	  
	  5'h00: xREGA <= r00;	  
	endcase // case (rRA)
 
	case (rRB)
	  5'h1F: xREGB <= r1F;	  
	  5'h1E: xREGB <= r1E;	  
	  5'h1D: xREGB <= r1D;	  
	  5'h1C: xREGB <= r1C;	  
	  5'h1B: xREGB <= r1B;	  
	  5'h1A: xREGB <= r1A;	  
	  5'h19: xREGB <= r19;	  
	  5'h18: xREGB <= r18;	  
	  5'h17: xREGB <= r17;	  
	  5'h16: xREGB <= r16;	  
	  5'h15: xREGB <= r15;	  
	  5'h14: xREGB <= r14;	  
	  5'h13: xREGB <= r13;	  
	  5'h12: xREGB <= r12;	  
	  5'h11: xREGB <= r11;	  
	  5'h10: xREGB <= r10;	  
	  5'h0F: xREGB <= r0F;	  
	  5'h0E: xREGB <= r0E;	  
	  5'h0D: xREGB <= r0D;	  
	  5'h0C: xREGB <= r0C;	  
	  5'h0B: xREGB <= r0B;	  
	  5'h0A: xREGB <= r0A;	  
	  5'h09: xREGB <= r09;	  
	  5'h08: xREGB <= r08;	  
	  5'h07: xREGB <= r07;	  
	  5'h06: xREGB <= r06;	  
	  5'h05: xREGB <= r05;	  
	  5'h04: xREGB <= r04;	  
	  5'h03: xREGB <= r03;	  
	  5'h02: xREGB <= r02;	  
	  5'h01: xREGB <= r01;	  
	  5'h00: xREGB <= r00;	  
	endcase // case (rRB)
     end else begin // if (drun)
	/*AUTORESET*/
	// Beginning of autoreset for uninitialized flops
	xREGA <= 32'h0;
	xREGB <= 32'h0;
	// End of automatics
     end // else: !if(drun)
 
 
   // Normal Registers
   wire fR00 = (rRD_ == 5'h00);
   wire fR01 = (rRD_ == 5'h01);
   wire fR02 = (rRD_ == 5'h02);
   wire fR03 = (rRD_ == 5'h03);
   wire fR04 = (rRD_ == 5'h04);
   wire fR05 = (rRD_ == 5'h05);
   wire fR06 = (rRD_ == 5'h06);
   wire fR07 = (rRD_ == 5'h07);
   wire fR08 = (rRD_ == 5'h08);
   wire fR09 = (rRD_ == 5'h09);
   wire fR0A = (rRD_ == 5'h0A);
   wire fR0B = (rRD_ == 5'h0B);
   wire fR0C = (rRD_ == 5'h0C);
   wire fR0D = (rRD_ == 5'h0D);
   wire fR0E = (rRD_ == 5'h0E);
   wire fR0F = (rRD_ == 5'h0F);
   wire fR10 = (rRD_ == 5'h10);
   wire fR11 = (rRD_ == 5'h11);
   wire fR12 = (rRD_ == 5'h12);
   wire fR13 = (rRD_ == 5'h13);
   wire fR14 = (rRD_ == 5'h14);
   wire fR15 = (rRD_ == 5'h15);
   wire fR16 = (rRD_ == 5'h16);
   wire fR17 = (rRD_ == 5'h17);
   wire fR18 = (rRD_ == 5'h18);
   wire fR19 = (rRD_ == 5'h19);
   wire fR1A = (rRD_ == 5'h1A);
   wire fR1B = (rRD_ == 5'h1B);
   wire fR1C = (rRD_ == 5'h1C);
   wire fR1D = (rRD_ == 5'h1D);
   wire fR1E = (rRD_ == 5'h1E);
   wire fR1F = (rRD_ == 5'h1F);
 
   always @(negedge nclk or negedge nrst)
     if (!nrst) begin
	/*AUTORESET*/
	// Beginning of autoreset for uninitialized flops
	r01 <= 32'h0;
	r02 <= 32'h0;
	r03 <= 32'h0;
	r04 <= 32'h0;
	r05 <= 32'h0;
	r06 <= 32'h0;
	r07 <= 32'h0;
	r08 <= 32'h0;
	r09 <= 32'h0;
	r0A <= 32'h0;
	r0B <= 32'h0;
	r0C <= 32'h0;
	r0D <= 32'h0;
	r0F <= 32'h0;
	r10 <= 32'h0;
	r12 <= 32'h0;
	r13 <= 32'h0;
	r14 <= 32'h0;
	r15 <= 32'h0;
	r16 <= 32'h0;
	r17 <= 32'h0;
	r18 <= 32'h0;
	r19 <= 32'h0;
	r1A <= 32'h0;
	r1B <= 32'h0;
	r1C <= 32'h0;
	r1D <= 32'h0;
	r1E <= 32'h0;
	r1F <= 32'h0;
	// End of automatics
     end else begin // if (!nrst)
	r01 <= #1 (!fR01) ? r01 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r01;	
	r02 <= #1 (!fR02) ? r02 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r02;	
	r03 <= #1 (!fR03) ? r03 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r03;	
	r04 <= #1 (!fR04) ? r04 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r04;	
	r05 <= #1 (!fR05) ? r05 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r05;	
	r06 <= #1 (!fR06) ? r06 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r06;	
	r07 <= #1 (!fR07) ? r07 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r07;	
	r08 <= #1 (!fR08) ? r08 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r08;	
	r09 <= #1 (!fR09) ? r09 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r09;	
	r0A <= #1 (!fR0A) ? r0A : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r0A;	
	r0B <= #1 (!fR0B) ? r0B : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r0B;	
	r0C <= #1 (!fR0C) ? r0C : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r0C;	
	r0D <= #1 (!fR0D) ? r0D : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r0D;	
	r0F <= #1 (!fR0F) ? r0F : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r0F;	
	r10 <= #1 (!fR10) ? r10 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r10;	
	r12 <= #1 (!fR12) ? r12 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r12;	
	r13 <= #1 (!fR13) ? r13 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r13;	
	r14 <= #1 (!fR14) ? r14 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r14;	
	r15 <= #1 (!fR15) ? r15 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r15;	
	r16 <= #1 (!fR16) ? r16 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r16;	
	r17 <= #1 (!fR17) ? r17 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r17;	
	r18 <= #1 (!fR18) ? r18 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r18;	
	r19 <= #1 (!fR19) ? r19 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r19;	
	r1A <= #1 (!fR1A) ? r1A : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r1A;	
	r1B <= #1 (!fR1B) ? r1B : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r1B;	
	r1C <= #1 (!fR1C) ? r1C : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r1C;	
	r1D <= #1 (!fR1D) ? r1D : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r1D;	
	r1E <= #1 (!fR1E) ? r1E : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r1E;	
	r1F <= #1 (!fR1F) ? r1F : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r1F;	
 
     end // else: !if(!nrst)
 
   // Special Registers
   always @(negedge nclk or negedge nrst)
     if (!nrst) begin
	/*AUTORESET*/
	// Beginning of autoreset for uninitialized flops
	r00 <= 32'h0;
	r0E <= 32'h0;
	r11 <= 32'h0;
	// End of automatics
     end else begin
	// R00 - Zero
	r00 <= #1 r00;	
	// R0E - Interrupt
	r0E <= #1 //(rFSM == 2'b01) ? rPCNXT :
	       (!fR0E) ? r0E : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r0E;
	// R11 - Exception
	r11 <= #1 //(rFSM == 2'b10) ? rPCNXT :
	       (!fR11) ? r11 : (fLD) ? wDWBDAT : (fLNK) ? rPC_ : (fWE) ? rRESULT : r11;	
     end // else: !if(!nrst)
 
   // Alternative Design
   reg [31:0]  rMEMA[0:31], rMEMB[0:31], rMEMD[0:31];
   wire [31:0] wDDAT, wREGA, wREGB, wREGD, wWBDAT;   
   wire        wDWE = (fLD | fLNK | fWE) & |rRD_ & nrun;
   assign      wDDAT = (fLD) ? wDWBDAT :
		       (fLNK) ? rPC_ : rRESULT;		       
   assign      wWBDAT = (fDFWD) ? wRESULT : wREGD;   
 
   assign      wREGA = rMEMA[rRA];
   assign      wREGB = rMEMB[rRB];
   assign      wREGD = rMEMD[rRD];
 
   always @(negedge nclk)
     if (wDWE) begin
	rMEMA[rRD_] <= wDDAT;
	rMEMB[rRD_] <= wDDAT;
	rMEMD[rRD_] <= wDDAT;	 
     end
 
   // PIPELINE REGISTERS //////////////////////////////////////////////////
 
   reg [31:0] rREGA, rREGB;   
   always @(/*AUTOSENSE*/wREGA or wREGB)
     begin
	//rREGA <= #1 xREGA;
	//rREGB <= #1 xREGB;
	rREGA <= #1 wREGA;
	rREGB <= #1 wREGB;	
     end
 
   always @(negedge nclk or negedge nrst)
     if (!nrst) begin
	/*AUTORESET*/
	// Beginning of autoreset for uninitialized flops
	rDWBDAT <= 32'h0;
	// End of automatics
     end else if (nrun) begin
	//rDWBDAT <= #1 xDWBDAT;	
	rDWBDAT <= #1 wWBDAT;	
     end
 
   // SIMULATION ONLY ///////////////////////////////////////////////////
   integer i;
   initial begin
      for (i=0;i<31;i=i+1) begin
	 rMEMA[i] <= 0;
	 rMEMB[i] <= 0;
	 rMEMD[i] <= 0;	 
      end
   end
 
endmodule // aeMB_regfile
 
 
// Local Variables:
// verilog-library-directories:(".")
// verilog-library-files:("")
// End:

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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