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

Subversion Repositories m32632

[/] [m32632/] [trunk/] [rtl/] [REGISTERS.v] - Rev 49

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

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// This file is part of the M32632 project
// http://opencores.org/project,m32632
//
//	Filename:	REGISTERS.v
//	Project:	M32632
//  Version:	3.1 bug fix of 25 February 2019
//	History:	1.0 first release of 30 Mai 2015
//	Author:		Udo Moeller
//	Date:		8 July 2017
//
// Copyright (C) 2019 Udo Moeller
// 
// This source file may be used and distributed without 
// restriction provided that this copyright statement is not 
// removed from the file and that any derivative work contains 
// the original copyright notice and the associated disclaimer.
// 
// This source file 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 source 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 source; if not, download it 
// from http://www.opencores.org/lgpl.shtml 
// 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//	Modules contained in this file:
//	1. CONFIG_REGS	Configuration and Debug Registers
//	2. FP_STAT_REG	Floating Point Status Register
//	3. REGISTER		General Purpose Registers
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//	1. CONFIG_REGS	Configuration and Debug Registers
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module CONFIG_REGS ( BCLK, BRESET, WREN, LD_OUT, OPCODE, SRC1, WRADR, PC_ARCHI, USER, PCMATCH, DBG_HIT, READ,
					 CFG, MCR, PTB_WR, PTB_SEL, IVAR, IVAR_MUX, CINV, Y_INIT, DSR, DBG_TRAPS, DBG_IN );
 
	input			BCLK,BRESET;
	input			WREN,LD_OUT;
	input	 [7:0]	OPCODE;
	input	[31:0]	SRC1;
	input	 [5:0]	WRADR;
	input	[31:0]	PC_ARCHI;
	input			USER;
	input			PCMATCH;
	input			DBG_HIT;
	input			READ;
 
	output	[12:0]	CFG;
	output	 [3:0]	MCR;
	output			PTB_WR;
	output			PTB_SEL;
	output	 [1:0]	IVAR;
	output			IVAR_MUX;
	output	 [3:0]	CINV;
	output			Y_INIT;
	output	 [3:0]	DSR;
	output	 [2:0]	DBG_TRAPS;
	output	[40:2]	DBG_IN;
 
	reg		 [3:0]	MCR;
	reg		[12:0]	CFG;
	reg		 [1:0]	old_cfg;
	reg				PTB_WR,PTB_SEL;
	reg				ivarreg;
	reg		 [1:0]	ci_all,ci_line;
	reg				check_y;
 
	wire			ld_cfg,ld_mcr,do_cinv;
	wire			init_ic,init_dc;
	wire			op_ok;
 
	assign op_ok = (OPCODE == 8'h6A);	// Special Opcode - for security reason
 
	assign ld_cfg  = op_ok & (WRADR == 6'h1C)	   & WREN;
	assign ld_mcr  = op_ok & (WRADR == 6'd9)	   & WREN;
	assign do_cinv = op_ok & (WRADR[5:4] == 2'b11) & WREN;
 
	// PF is not implemented
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) CFG <= 13'h0;
			else if (ld_cfg) CFG <= SRC1[12:0];
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) MCR <= 4'h0;
			else if (ld_mcr) MCR <= SRC1[3:0];
 
	assign IVAR_MUX = op_ok & (WRADR[5:1] == 5'd7) & WREN;	// IVAR0/1 = Reg. Nr. 14/15
	always @(posedge BCLK) ivarreg <= IVAR_MUX;
	assign IVAR = {ivarreg,PTB_SEL};
 
	always @(posedge BCLK) PTB_WR  <= op_ok & (WRADR[5:1] == 5'd6) & WREN;	// PTB0/1 = Reg. Nr. 12/13
	always @(posedge BCLK) PTB_SEL <= WRADR[0];
 
	// The Cache content will be invalid if the Enable-Bit is set to 0
	always @(posedge BCLK) old_cfg <= {CFG[11],CFG[9]};
 
	// Cache Invalidate : the Flags are coming out of the Short-field which is otherwise used for Register selection
	always @(posedge BCLK) ci_all  <= do_cinv &  WRADR[2] ? WRADR[1:0] : 2'b0;	// clear all
	always @(posedge BCLK) ci_line <= do_cinv & ~WRADR[2] ? WRADR[1:0] : 2'b0;	// clear cache line
 
	assign init_ic = old_cfg[1] & (~CFG[11] | ci_all[1]);
	assign init_dc = old_cfg[0] & (~CFG[9]  | ci_all[0]);
 
	assign CINV = {init_ic,ci_line[1],init_dc,ci_line[0]};
 
	// Y_INIT is neccessary if nothing has changed and therefore no DC/IC_INIT is generated
	always @(posedge BCLK) check_y <= ld_cfg | do_cinv;
	assign Y_INIT = check_y & ~init_ic & ~init_dc;	// goes to register "old_init"
 
	// +++++++++++++  DEBUG Unit  +++++++++++++++
 
	reg		 [3:0]	DSR;
	reg		[12:0]	dcr;
	reg		[31:0]	bpc;
	reg		[31:2]	car;
 
	wire			op_dbg,ld_dcr,ld_bpc,ld_dsr,ld_car;
	wire			enable;
 
	assign op_dbg = (OPCODE == 8'h76);
 
	assign ld_dcr = op_dbg & (WRADR == 6'h11) & WREN;
	assign ld_bpc = op_dbg & (WRADR == 6'h12) & WREN;
	assign ld_dsr = op_dbg & (WRADR == 6'h13) & WREN;
	assign ld_car = op_dbg & (WRADR == 6'h14) & WREN;
 
	assign enable = dcr[12] & (USER ? dcr[10] : dcr[11]);	// DEN & (USER ? UD : SD)
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) dcr <= 13'd0;
			else if (ld_dcr) dcr <= {SRC1[23:19],SRC1[7:0]};
 
	always @(posedge BCLK) if (ld_bpc) bpc <= SRC1;
	always @(posedge BCLK) if (ld_car) car <= SRC1[31:2];
 
	//					DEN		  SD        DEN       UD       CAE      CRD      CAE      CWR    VNP/CBE  CAR
	assign DBG_IN = {(dcr[12] & dcr[11]),(dcr[12] & dcr[10]),(dcr[7] & dcr[6]),(dcr[7] & dcr[5]),dcr[4:0],car};
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) DSR <= 4'd0;
		  else
			if (ld_dsr) DSR <= SRC1[31:28];
			  else
				begin
				  DSR[3] <= DBG_HIT ? READ : DSR[3];
				  DSR[2] <= DSR[2] | PCMATCH;
				  DSR[1] <= DSR[1];
				  DSR[0] <= DSR[0] | DBG_HIT;
				end
 
	assign DBG_TRAPS[0] = enable & dcr[9] & (PC_ARCHI == bpc);	// dcr[9]=PCE
	assign DBG_TRAPS[1] = DBG_HIT;	// Compare Adress Hit
	assign DBG_TRAPS[2] = dcr[8];	// TR, Trap enable
 
endmodule
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//	2. FP_STAT_REG	Floating Point Status Register
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module FP_STAT_REG ( BCLK, BRESET, LFSR, UP_SP, UP_DP, TT_SP, TT_DP, WREN, WRADR, DIN, FSR, TWREN, FPU_TRAP, SAVE_PC);
 
	input			BCLK;
	input			BRESET;
	input			LFSR;	// Load by LFSR opcode
	input			UP_SP,UP_DP;	// update if calculation operation
	input 	 [4:0]	TT_SP,TT_DP;
	input			WREN;	// for RMB and LFSR
	input	 [5:4]	WRADR;
	input 	[16:0] 	DIN;	// Data for LFSR opcode
 
	output	[31:0] 	FSR;
	output			TWREN;
	output	reg		FPU_TRAP;
	output			SAVE_PC;
 
	reg		 [4:3]	trap_d;
	reg				update_d;
	reg				set_rm_d;
	reg		[10:0]	set_bits;
	reg		 [4:0]	flags;
	reg				rm_bit;
 
	wire			load_fsr;
	wire			update,update_i;
	wire	 [4:0]	trap;
	wire			uflag,iflag,rmflag;
 
	assign load_fsr = LFSR & WREN;
 
	assign trap = UP_SP ? TT_SP : TT_DP;
 
	// This signal suppresses write into registers if FPU Trap, timing critical signal !
	assign TWREN = ~((UP_SP & (TT_SP[2:0] != 3'b0)) | (UP_DP & (TT_DP[2:0] != 3'b0)));
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) FPU_TRAP <= 1'b0;
		  else FPU_TRAP <= ~FPU_TRAP & ~TWREN;	// one pulse of one cycle informs the Opcode Decoder
 
	assign update_i = (UP_SP | UP_DP) & ~FPU_TRAP;	// unfortunately one FPU opcode may follow !
	always @(posedge BCLK) update_d	<= update_i;
	always @(posedge BCLK) trap_d	<= trap[4:3];
	always @(posedge BCLK) set_rm_d	<= WREN & (WRADR == 2'b10);
	assign update = update_d & ~FPU_TRAP;
 
	// The Flags are set and stay "1" 
	assign iflag  = (update & trap_d[4]) | flags[4];	// Inexact Result
	assign uflag  = (update & trap_d[3]) | flags[3];	// Underflow
	assign rmflag = (set_rm_d & ~FPU_TRAP) | rm_bit;	// Register Modify
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) flags[4:3] <= 2'b0;	// Inexact = Bit6, Underflow = Bit4
		  else
		  begin
			if (load_fsr) flags[4:3] <= {DIN[6],DIN[4]};
			  else
				if (update) flags[4:3] <= {iflag,uflag};
		  end
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) flags[2:0] <= 3'b0;	// TT Field = Bit2-0
		  else
		  begin
			if (load_fsr) flags[2:0] <= DIN[2:0];
			  else
				if (update_i) flags[2:0] <= trap[2:0];
		  end
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) rm_bit <= 1'b0;	// Register Modify Bit
		  else
		  begin
			if (load_fsr) rm_bit <= DIN[16];
			  else
				if (set_rm_d & ~FPU_TRAP) rm_bit <= 1'b1;	// in case of TRAP there is no writing to Register
		  end
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) set_bits <= 11'b0;	// all other Bits
		  else
			if (load_fsr) set_bits <= {DIN[15:7],DIN[5],DIN[3]};
 
	assign FSR = {15'h0,rmflag,set_bits[10:2],iflag,set_bits[1],uflag,set_bits[0],flags[2:0]};
 
	assign SAVE_PC = (UP_SP | UP_DP) & ~FPU_TRAP;	// Store the correct PC for FPU Trap
 
endmodule
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//	3. REGISTER		General Purpose Registers
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module REGISTER( BCLK, ENWR, DOWR, BYDIN, DIN, RADR, WADR, WMASKE, DOUT, SELI );
 
input			BCLK;
input			DOWR,ENWR;
input	[31:0]	BYDIN,DIN;
input	 [7:0]	RADR;
input	 [5:0]	WADR;
input	 [1:0]	WMASKE;
 
output	[31:0]	DOUT;
output reg 		SELI;
 
reg	 	 [2:0] 	mx;
 
wire	 [2:0]	be;
wire			eq_rw;
 
// +++++++++++++++++++ Memories ++++++++++++++++++++
 
reg	 	[15:0]	REGFILE_C [0:63];	// Byte 3 and 2 , Verilog allows no "Byte Write" in wider memories !!!
reg	 	 [7:0]	REGFILE_B [0:63];	// Byte 1
reg	 	 [7:0]	REGFILE_A [0:63];	// Byte 0
reg		[31:0]	RF;
 
assign	be = {WMASKE[1],(WMASKE[1] | WMASKE[0]),1'b1};
 
assign	eq_rw = ENWR & (RADR[5:0] == WADR);
 
always @(posedge BCLK) if (RADR[7]) mx[2:0] <= be[2:0] & {{3{eq_rw}}};
 
always @(posedge BCLK) if (RADR[7]) SELI <= RADR[6];
 
assign DOUT[31:16] = mx[2] ? BYDIN[31:16] : RF[31:16];
assign DOUT[15:8]  = mx[1] ? BYDIN[15:8]  : RF[15:8];
assign DOUT[7:0]   = mx[0] ? BYDIN[7:0]   : RF[7:0];
 
// ++++++++++++++++ Register File 64 * 32 Bits ++++++++++++
 
always @(posedge BCLK)
	if (RADR[7])
		begin
			RF[31:16] <= REGFILE_C[RADR[5:0]];
			RF[15:8]  <= REGFILE_B[RADR[5:0]];
			RF[7:0]   <= REGFILE_A[RADR[5:0]];
		end
 
always @(posedge BCLK)
	if (DOWR)
		begin
			if (be[2]) REGFILE_C[WADR] <= DIN[31:16];
			if (be[1]) REGFILE_B[WADR] <= DIN[15:8];
			if (be[0]) REGFILE_A[WADR] <= DIN[7:0];
		end
 
endmodule
 
 

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.