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

Subversion Repositories m32632

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

Compare with Previous | Blame | View Log

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// This file is part of the M32632 project
// http://opencores.org/project,m32632
//
//	Filename:	ICACHE.v
//	Version:	3.2 bug fix	
//	History:	3.1 bug fix of 25 February 2019
//				3.0 Cache Interface reworked
//				2.0 50 MHz release of 14 August 2016
//				1.0 first release of 30 Mai 2015
//	Date:		17 January 2021
//
// Copyright (C) 2021 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:
//	ICACHE		the instruction cache of M32632
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
module ICACHE( BCLK, DRAMSZ, MDONE, BRESET, READ_I, IO_READY, PSR_USER, DATA_HOLD, PTB_WR, PTB_SEL, DRAM_WR,
			   KDET, HOLD, CFG, DRAM_Q, CINVAL, IC_SIGS, IO_Q, IVAR, IVAR_MUX, VADR_D, KOLLI_A, MCR_FLAGS, MMU_DIN, VADR_I,
			   INHIBIT, IO_RD, DRAM_ACC, INIT_RUN, PROT_ERROR, ACC_OK, IC_PREQ, KOLLISION, ENA_HK, STOP_CINV,
			   DRAM_A, IC_DQ, IC_VA, ICTODC, IO_A, ENDRAM );
 
input			BCLK;
input	 [2:0]	DRAMSZ;
input			MDONE;
input			BRESET;
input			READ_I;
input			IO_READY;
input			PSR_USER;
input			DATA_HOLD;
input			PTB_WR;
input			PTB_SEL;
input			DRAM_WR;
input			KDET;
input			HOLD;
input	 [1:0]	CFG;
input  [127:0]	DRAM_Q;
input	 [1:0]	CINVAL;
input	 [1:0]	IC_SIGS;
input	[31:0]	IO_Q;
input	 [1:0]	IVAR;
input			IVAR_MUX;
input  [31:12]	VADR_D;
input	[28:4]	KOLLI_A;
input	 [3:0]	MCR_FLAGS;
input	[23:0]	MMU_DIN;
input	[31:0]	VADR_I;
input	 		INHIBIT;
input			ENA_HK;
input			ENDRAM;
 
output			IO_RD;
output			DRAM_ACC;
output			INIT_RUN;
output			PROT_ERROR;
output			ACC_OK;
output			IC_PREQ;
output			KOLLISION;
output			STOP_CINV;
output	[31:0]	IC_DQ;
output [31:12]	IC_VA;
output	 [3:0]	ICTODC;
output reg	[28:0]	DRAM_A;
output reg	[31:0]	IO_A;
 
reg		[31:0]	VADR_R;
reg		[31:0]	CAPDAT;
reg		[31:0]	DFFE_IOR;
reg				HOLD_ON;
reg				DFF_HDFF1;
reg				DFF_IRD_REG;
 
wire	[31:0]	VADR;
wire	 [4:0]	A_CV;
wire			ACOK;
wire	 [4:0]	ACV;
wire			AUX_DAT;
wire			CA_HIT;
wire			CA_SET;
wire			CUPDATE;
wire	[23:0]	D_CV;
wire			HIT_ALL;
wire			INIT_CA_RUN;
wire			IO_ACC;
wire			KILL;
wire			NEW_PTB;
wire			PTB_ONE;
wire   [31:12]	RADR;
wire			READ;
wire			RUN_ICRD;
wire			STOP_ICRD;
wire	[23:0]	UPCD;
wire	[23:0]	UPDATE_C;
wire	[31:0]	UPDATE_M;
wire			USE_CA;
wire			USER;
wire	[11:7]	V_ADR;
wire			WE_CV;
wire			WEMV;
wire			WRCRAM0;
wire			WRCRAM1;
wire			WRSET0;
wire			WRSET1;
wire			WRITE;
wire	[11:7]	KILLADR;
wire			AUX_ALT;
wire			VIRT_A;
wire			CI;
wire			MMU_HIT;
wire			LD_DRAM_A;
wire			IO_SPACE;
wire			LAST_MUX;
wire			VIRTUELL;
wire			NEW_PTB_RUN;
wire	[31:0]	SET_DAT;
wire	[31:0]	ALT_DAT;
wire	[31:0]	DAT_MV;
wire	 [3:0]	RADR_MV;
wire	 [3:0]	WADR_MV;
wire	[23:0]	NEWCVAL;
wire			KILL_C,KILL_K;
wire			RMW;
wire	[31:0]	CAP_Q;
wire   [28:12]	TAGDAT;
wire			clr_up;
 
// +++++++++++++++++++ Memories ++++++++++++++++++++
 
reg	   [127:0]	DATA0 [0:255];		// Data Set 0 : 4 kBytes
reg	   [127:0]	RDDATA0;
reg		[31:0]	SET_DAT0;
 
reg	   [127:0]	DATA1 [0:255];		// Data Set 1 : 4 kBytes
reg	   [127:0]	RDDATA1;
reg		[31:0]	SET_DAT1;
 
reg		[16:0]	TAGSET_0 [0:255];	// Tag Set for Data Set 0 : 256 entries of 17 bits
reg		[16:0]	TAG0;
 
reg		[16:0]	TAGSET_1 [0:255];	// Tag Set for Data Set 1 : 256 entries of 17 bits
reg		[16:0]	TAG1;
 
wire	[23:0]	CVALID;
 
reg		[35:0]	MMU_TAGS [0:255];	// Tag Set for MMU : 256 entries of 36 bits
reg		[35:0]	MMU_Q;
 
reg		[31:0]	MMU_VALID [0:15];	// Valid bits for MMU Tag Set : 16 entries of 32 bits
reg		[31:0]	MVALID;
 
reg		[16:0]	KTAGSET_0 [0:255];	// Kollision Tag Set for Data Set 0 : 256 entries of 17 bits
reg		[16:0]	KTAG0;
 
reg		[16:0]	KTAGSET_1 [0:255];	// Kollision Tag Set for Data Set 1 : 256 entries of 17 bits
reg		[16:0]	KTAG1;
 
wire	[23:0]	KCVALID;
 
assign	READ	= READ_I & ~HOLD_ON & RUN_ICRD;
assign	WRITE	= 1'b0;
assign	RMW		= 1'b0;
 
assign	ALT_DAT	= AUX_ALT ? DFFE_IOR : CAPDAT ;
 
assign	RADR	= VIRT_A ? MMU_Q[19:0] : VADR_R[31:12] ;
 
assign	V_ADR	= STOP_ICRD ? KILLADR : VADR[11:7] ;
assign	ACV		= STOP_ICRD ? KILLADR : A_CV ;
assign	UPCD	= STOP_ICRD ? NEWCVAL : UPDATE_C ;
 
assign	IC_DQ	= LAST_MUX ? ALT_DAT : SET_DAT ;
 
assign	SET_DAT = CA_SET ? SET_DAT1 : SET_DAT0 ;
 
assign	KILL	= KILL_C | KILL_K;
 
assign	IC_VA	= VADR_R[31:12];
 
assign	VIRT_A	= ~CINVAL[0] & VIRTUELL;
 
assign	ACC_OK	= HOLD_ON | ACOK;
 
assign	USER	= ~MCR_FLAGS[3] & PSR_USER;
 
assign	AUX_ALT = HOLD_ON | DFF_IRD_REG;
 
assign	LAST_MUX = AUX_ALT | AUX_DAT;
 
assign	INIT_RUN = NEW_PTB_RUN | INIT_CA_RUN;
 
assign	LD_DRAM_A = ~DRAM_ACC | MDONE;
 
assign	ICTODC[3] = USER;
 
assign	VADR[31:12] = IVAR_MUX ? VADR_D : VADR_I[31:12];
assign	VADR[11:0]  = VADR_I[11:0];
 
always @(posedge BCLK) VADR_R[23:0] <= VADR[23:0];
 
assign clr_up = ~(DRAMSZ == 3'd0);
always @(posedge BCLK or negedge clr_up)
	if (!clr_up) VADR_R[31:24] <= 8'd0;
		else VADR_R[31:24] <= VADR[31:24];
 
always @(posedge BCLK) DFF_IRD_REG <= IO_RD;
 
always @(posedge BCLK) DFF_HDFF1 <= IO_READY;
 
always @(posedge BCLK) if (LD_DRAM_A) DRAM_A <= {RADR[28:12],VADR_R[11:2],USE_CA,CA_SET};
 
always @(posedge BCLK) if (IO_ACC) IO_A <= {RADR[31:12],VADR_R[11:0]};
 
always @(posedge BCLK) if (IO_RD) DFFE_IOR <= IO_Q;
 
always @(posedge BCLK or negedge BRESET)
	if (!BRESET) HOLD_ON <= 1'b0;
		else HOLD_ON <= (DATA_HOLD & DFF_HDFF1) | (HOLD_ON & DATA_HOLD);
 
DMUX  DMUX_4TO1 (
	.DRAM_Q(DRAM_Q),
	.ADDR(VADR_R[3:2]),
	.CAP_Q(CAP_Q) );
 
always @(posedge BCLK) if (MDONE) CAPDAT <= CAP_Q;
 
FILTCMP  FILT_CMP(
	.RADR({RADR[28:12],VADR_R[11:4]}),
	.DRAMSZ(DRAMSZ),
	.DRAM_A(25'd0),
	.TAGDAT(TAGDAT),
	.ADR_EQU());
 
// +++++++++++++++++++++++++  Cache Valid  +++++++++++++++++++
 
NEU_VALID	VALID_RAM(
	.BCLK(BCLK),
	.VALIN(D_CV),
	.WADR(ACV),
	.WREN(WE_CV),
	.RADR(V_ADR[11:7]),
	.VALOUT(CVALID) );
 
// +++++++++++++++++++++++++  Tag Set 0  +++++++++++++++++++++
 
always @(posedge BCLK) TAG0 <= TAGSET_0[VADR[11:4]];
 
always @(negedge BCLK) if (WRCRAM0) TAGSET_0[VADR_R[11:4]] <= TAGDAT;
 
// +++++++++++++++++++++++++  Tag Set 1  +++++++++++++++++++++
 
always @(posedge BCLK) TAG1 <= TAGSET_1[VADR[11:4]];
 
always @(negedge BCLK) if (WRCRAM1) TAGSET_1[VADR_R[11:4]] <= TAGDAT;
 
// +++++++++++++++++++++++++  Data Set 0  ++++++++++++++++++++
 
always @(posedge BCLK) RDDATA0 <= DATA0[VADR[11:4]];
 
always @(RDDATA0 or VADR_R)
	case (VADR_R[3:2])
	  2'b00 : SET_DAT0 <= RDDATA0[31:0];
	  2'b01 : SET_DAT0 <= RDDATA0[63:32];
	  2'b10 : SET_DAT0 <= RDDATA0[95:64];
	  2'b11 : SET_DAT0 <= RDDATA0[127:96];
	endcase
 
always @(posedge BCLK) if (WRSET0) DATA0[VADR_R[11:4]] <= DRAM_Q;
 
// +++++++++++++++++++++++++  Data Set 1  ++++++++++++++++++++
 
always @(posedge BCLK) RDDATA1 <= DATA1[VADR[11:4]];
 
always @(RDDATA1 or VADR_R)
	case (VADR_R[3:2])
	  2'b00 : SET_DAT1 <= RDDATA1[31:0];
	  2'b01 : SET_DAT1 <= RDDATA1[63:32];
	  2'b10 : SET_DAT1 <= RDDATA1[95:64];
	  2'b11 : SET_DAT1 <= RDDATA1[127:96];
	endcase
 
always @(posedge BCLK) if (WRSET1) DATA1[VADR_R[11:4]] <= DRAM_Q;
 
CA_MATCH	DCA_COMPARE(
	.INVAL_L(CINVAL[0]),
	.CI(CI),
	.MMU_HIT(MMU_HIT),
	.WRITE(WRITE),
	.KDET(1'b0),
	.ADDR({RADR[31:12],VADR_R[11:4]}),
	.CFG(CFG),
	.ENDRAM(ENDRAM),
	.CVALID(CVALID),
	.TAG0(TAG0),
	.TAG1(TAG1),
	.CA_HIT(CA_HIT),
	.CA_SET(CA_SET),
	.WB_ACC(),
	.USE_CA(USE_CA),
	.DRAMSZ(DRAMSZ),
	.IO_SPACE(IO_SPACE),
	.DC_ILO(1'b0),
	.KILL(KILL_C),
	.UPDATE(UPDATE_C));
 
DCA_CONTROL	DCA_CTRL(
	.BCLK(BCLK),
	.BRESET(BRESET),
	.CA_SET(CA_SET),
	.HIT_ALL(HIT_ALL),
	.UPDATE(UPCD),
	.VADR_R(VADR_R[11:7]),
	.DRAM_ACC(DRAM_ACC),
	.CUPDATE(CUPDATE),
	.KILL(KILL),
	.WRITE(WRITE),
	.USE_CA(DRAM_A[1]),
	.INHIBIT(INHIBIT),
	.INVAL_A(CINVAL[1]),
	.MDONE(MDONE),
	.DAT_CV(D_CV),
	.WADR_CV(A_CV),
	.WE_CV(WE_CV),
	.INIT_CA_RUN(INIT_CA_RUN),
	.WRCRAM0(WRCRAM0),
	.WRCRAM1(WRCRAM1),
	.WRSET0(WRSET0),
	.WRSET1(WRSET1));
 
ICACHE_SM	IC_SM(
	.BCLK(BCLK),
	.BRESET(BRESET),
	.IO_SPACE(IO_SPACE),
	.READ(READ),
	.MDONE(MDONE),
	.IO_READY(IO_READY),
	.MMU_HIT(MMU_HIT),
	.CA_HIT(CA_HIT),
	.USE_CA(USE_CA),
	.PTB_WR(PTB_WR),
	.PTB_SEL(PTB_SEL),
	.USER(USER),
	.PROT_ERROR(PROT_ERROR),
	.PTE_ACC(IC_SIGS[1]),
	.ACC_OK(ACOK),
	.PTB_ONE(PTB_ONE),
	.NEW_PTB(NEW_PTB),
	.AUX_DAT(AUX_DAT),
	.CUPDATE(CUPDATE),
	.IO_RD(IO_RD),
	.IO_ACC(IO_ACC),
	.DRAM_ACC(DRAM_ACC),
	.IC_PREQ(IC_PREQ),
	.HIT_ALL(HIT_ALL));
 
// +++++++++++++++++++++++++  Kollision Valid  +++++++++++++++
 
NEU_VALID	KOL_VAL(
	.BCLK(BCLK),
	.VALIN(D_CV),
	.WADR(ACV),
	.WREN(WE_CV),
	.RADR(KOLLI_A[11:7]),
	.VALOUT(KCVALID) );
 
// +++++++++++++++++++++++++  Kollision Tag Set 0  +++++++++++
 
always @(posedge BCLK) KTAG0 <= KTAGSET_0[KOLLI_A[11:4]];
 
always @(negedge BCLK) if (WRCRAM0) KTAGSET_0[VADR_R[11:4]] <= TAGDAT;
 
// +++++++++++++++++++++++++  Kollision Tag Set 1  +++++++++++
 
always @(posedge BCLK) KTAG1 <= KTAGSET_1[KOLLI_A[11:4]];
 
always @(negedge BCLK) if (WRCRAM1) KTAGSET_1[VADR_R[11:4]] <= TAGDAT;
 
KOLDETECT	KOLLOGIK(
	.DRAM_WR(DRAM_WR),
	.BCLK(BCLK),
	.READ_I(READ_I),
	.ACC_OK(ACC_OK),
	.BRESET(BRESET),
	.INVAL_A(CINVAL[1]),
	.KDET(KDET),
	.HOLD(HOLD),
	.ENA_HK(ENA_HK),
	.STOP_CINV(STOP_CINV),
	.ADDR(KOLLI_A),
	.C_VALID(KCVALID),
	.CFG(CFG),
	.CVALID(CVALID),
	.TAG0(KTAG0),
	.TAG1(KTAG1),
	.KOLLISION(KOLLISION),
	.STOP_ICRD(STOP_ICRD),
	.RUN_ICRD(RUN_ICRD),
	.KILL(KILL_K),
	.ICTODC(ICTODC[2:0]),
	.KILLADR(KILLADR),
	.NEWCVAL(NEWCVAL));
 
MMU_MATCH	MMU_COMPARE(
	.USER(USER),
	.READ(READ),
	.WRITE(WRITE),
	.RMW(RMW),
	.IVAR(IVAR),
	.MCR_FLAGS(MCR_FLAGS[2:0]),
	.MMU_VA(MMU_Q[35:20]),
	.MVALID(MVALID),
	.VADR_R(VADR_R[31:12]),
	.MMU_HIT(MMU_HIT),
	.PROT_ERROR(PROT_ERROR),
	.VIRTUELL(VIRTUELL),
	.CI(CI),
	.SEL_PTB1(),
	.UPDATE(UPDATE_M));
 
MMU_UP	MMU_CTRL(
	.NEW_PTB(NEW_PTB),
	.IVAR(IVAR[1]),
	.BRESET(BRESET),
	.PTB1(PTB_ONE),
	.BCLK(BCLK),
	.WR_MRAM(IC_SIGS[0]),
	.MVALID(MVALID),
	.UPDATE(UPDATE_M),
	.VADR(VADR[19:16]),
	.VADR_R(VADR_R[19:16]),
	.WE_MV(WEMV),
	.NEW_PTB_RUN(NEW_PTB_RUN),
	.DAT_MV(DAT_MV),
	.RADR_MV(RADR_MV),
	.WADR_MV(WADR_MV));
 
// +++++++++++++++++++++++++  MMU Valid  +++++++++++++++++++++
 
always @(posedge BCLK) MVALID <= MMU_VALID[RADR_MV];
 
always @(negedge BCLK) if (WEMV) MMU_VALID[WADR_MV] <= DAT_MV;
 
// +++++++++++++++++++++++++  MMU Tags  ++++++++++++++++++++++
 
always @(posedge BCLK) MMU_Q <= MMU_TAGS[VADR[19:12]];
 
always @(negedge BCLK) if (IC_SIGS[0]) MMU_TAGS[VADR_R[19:12]] <= {VADR_R[31:20],MMU_DIN[23:0]};
 
endmodule
 

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.