⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.cpp

📁 ppc750 system design simulator using system c
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************                          Cache.cpp  -  Cache                             -------------------    begin                : Mon Apr 30 2001    copyright            : (C) 2001 Universite Paris Sud and CEA    author               : Gilles Mouchard    email                : gilles.mouchard@lri.fr, gilles.mouchard@.cea.fr ***************************************************************************/#include <Cache.h>#if defined(ICACHE) || defined(DCACHE)#ifdef ICACHE#define CLASSNAME ICache#define CPU2CACHE fetch2icache#define CACHE2MEM icache2biu#else#define CLASSNAME DCache#define CPU2CACHE lsu2dcache#define CACHE2MEM dcache2biu#endifvoid CLASSNAME::DecodeAddress(UInt32 addr, UInt32& tag, UInt32& index, UInt32& offset){	offset = addr & offsetMask;	index = (addr >> indexShift) & indexMask;	tag = addr >> tagShift;#ifdef DEBUG	if(Debug(DebugCache))	{		cout << name() << ": Decoding address ";		WriteHex(cout, addr);		cout << " (tag = " << tag << ", index = " << index << ", offset = " << offset << ")" << endl;	}	if(offset >= linesize)	{		cout << name() << ": Error while decoding address : offset is out of range" << endl;		ABORT();	}	if(index >= nlines)	{		cout << name() << ": Error while decoding address : index is out of range" << endl;		ABORT();	}#endif}int CLASSNAME::Search(UInt32 index, UInt32 tag){	int bank;	#ifdef DEBUG	if(Debug(DebugCache))		cout << name() << ": Searching for tag " << tag << " at index " << index << endl;#endif		for(bank = 0; bank < associativity; bank++)	{		if(directory[bank][index].valid && directory[bank][index].tag == tag)		{#ifdef DEBUG	if(Debug(DebugCache))		cout << name() << ": tag found in bank " << bank << endl;#endif			return bank;		}	}#ifdef DEBUG	if(Debug(DebugCache))		cout << name() << ": tag not found" << endl;#endif	return -1;}const int B0 = 1 << 0;const int B1 = 1 << 1;const int B2 = 1 << 2;const int B3 = 1 << 3;const int B4 = 1 << 4;const int B5 = 1 << 5;const int B6 = 1 << 6;void CLASSNAME::UpdatePLRUBits(UInt32 bank, UInt32 index){	switch(associativity)	{		case 4:			switch(bank)			{				case 0:					plrubits[index] |= B0  + B1;					break;									case 1:					plrubits[index] |= B0;					plrubits[index] &= B1;					break;									case 2:					plrubits[index] |= B2;					plrubits[index] &= B0;					break;									case 3:					plrubits[index] &= B0 + B2;					break;			}			break;			case 8:			switch(bank)			{				case 0:					plrubits[index] |= B0 + B1 + B3;					break;				case 1:					plrubits[index] |= B0 + B1;					plrubits[index] &= ~B3;					break;							case 2:					plrubits[index] |= B0 + B4;					plrubits[index] &= ~B1;					break;							case 3:					plrubits[index] |= B0;					plrubits[index] &= ~(B1 + B4);					break;							case 4:					plrubits[index] |= B2 + B5;					plrubits[index] &= ~B0;					break;							case 5:					plrubits[index] |= B2;					plrubits[index] &= ~(B0 + B5);					break;								case 6:					plrubits[index] |=B6;					plrubits[index] &=~(B0 + B2);					break;							case 7:					plrubits[index] &= ~(B0 + B2 + B6);					break;			}			break;	}}void CLASSNAME::Read(UInt32 bank, UInt32 index, UInt32 offset, UInt8 *data, int size){	memcpy(data, &storage[bank][index][offset], size);		UpdatePLRUBits(bank, index);}UInt32 CLASSNAME::MakeAddr(UInt32 bank, UInt32 index, UInt32 offset){	return (directory[bank][index].tag << tagShift) | (index << indexShift) | offset;}#ifndef ICACHEvoid CLASSNAME::Write(UInt32 bank, UInt32 index, UInt32 offset, const UInt8 *data, int size){	memcpy(&storage[bank][index][offset], data, size);		UpdatePLRUBits(bank, index);	directory[bank][index].dirty = true;}void CLASSNAME::Zero(UInt32 bank, UInt32 index){	memset(&storage[bank][index], 0, linesize);		UpdatePLRUBits(bank, index);	directory[bank][index].dirty = true;}#endifint CLASSNAME::Choose(UInt32 index){	/* See figure 3-5. PLRU Replacement Algorithm  */	/*     table 3-2. PLRU Bit Update Rules */	/* of MPC750 RISC Microprocessor User's Manual */	int bank;		for(bank = 0; bank < associativity; bank++)	{		if(!directory[bank][index].valid)		{			return bank;		}	}		switch(associativity)	{		case 4:			if(plrubits[index] & B0)			{				if(plrubits[index] & B2) return 3; else return 2;			}			else			{				if(plrubits[index] & B1) return 1; else return 0;			}			break;					case 8:			if(plrubits[index] & B0)			{				if(plrubits[index] & B2)				{					if(plrubits[index] & B5) return 5; else return 4;				}				else				{					if(plrubits[index] & B6) return 7; else return 6;				}			}			else			{				if(plrubits[index] & B1)				{					if(plrubits[index] & B4) return 3; else return 2;				}				else				{					if(plrubits[index] & B3) return 1; else return 0;				}			}	}		return -1;}bool CLASSNAME::IsValid(UInt32 bank, UInt32 index){	return directory[bank][index].valid;}#ifndef ICACHEbool CLASSNAME::IsDirty(UInt32 bank, UInt32 index){	return directory[bank][index].dirty;}#endifUInt32 CLASSNAME::GetLineAddr(UInt32 bank, UInt32 index){	return (directory[bank][index].tag << tagShift) | (index << indexShift);}UInt32 CLASSNAME::AlignToLineBoundary(UInt32 addr){	return addr - (addr % linesize);}UInt32 CLASSNAME::AlignToMemoryWord(UInt32 addr){	return addr - (addr % memoryWord);}UInt8 *CLASSNAME::GetLineStorage(UInt32 bank, UInt32 index){	return &storage[bank][index][0];}void CLASSNAME::ReplaceLine(UInt32 bank, UInt32 index, UInt32 tag){	directory[bank][index].tag = tag;	directory[bank][index].valid = true;#ifndef ICACHE	directory[bank][index].dirty = false;#endif}void CLASSNAME::GetRequest(){	bool ack = false;	if(inReq)	{		// CPU has made a request		UInt32 /*curInstructionTag,*/ curTag, curIndex, curOffset, curSize, curAddr;#ifndef ICACHE		bool curZeroBlock;#endif		int curBank;				curAddr = inAddr;//		curInstructionTag = inTag;		curSize = inSize;#ifndef ICACHE		curZeroBlock = inZeroBlock;#endif		#ifdef DEBUG		if(Debug(DebugCache))		{			cout << name() << ": Getting a CPU request at ";			WriteHex(cout, curAddr);			cout << " for " << curSize << " bytes " << endl;		}#endif		DecodeAddress(curAddr, curTag, curIndex, curOffset);				curBank = Search(curIndex, curTag);				hit = curBank >= 0;				if(hit)		{			hits++;			// Hit			ack = true;//			outTag = curInstructionTag;			#ifndef ICACHE			if(!inWrite)			{#endif				// Read				DataArray<CPU2CACHE> data;								Read(curBank, curIndex, curOffset, data.buffer, curSize);#ifdef DEBUG				if(Debug(DebugCache))					cout << name() << ": Reading " << curSize << " bytes (" << data << ")" << endl;#endif				outData = data;#ifndef ICACHE			}			else			{				writeBank = curBank;				writeIndex = curIndex;				writeOffset = curOffset;				writeZeroBlock = curZeroBlock;			}#endif		}		else		{			misses++;#ifdef DEBUG			if(Debug(DebugCache))				cout << name() << ": Miss" << endl;#endif			// Miss						if(!busy)			{				busy = true;								tag = curTag;				offset = curOffset;				index = curIndex;				addr = curAddr;				size = curSize;#ifndef ICACHE				zeroBlock = curZeroBlock;#endif//				instructionTag = curInstructionTag;								bankToReplace = Choose(index);#ifdef DEBUG				if(Debug(DebugCache))					cout << name() << ": Choosing bank " << bankToReplace << endl;#endif									#ifndef ICACHE						if(inWrite)				{//			ack = true;					// Miss on write					if(IsValid(bankToReplace, index) && IsDirty(bankToReplace, index))					{						// Cache line eject						state = 1;					}					else					{						if(zeroBlock)						{							// Cache line fill with zeros							state = 5;						}						else						{							// Cache line fill							state = 3;						}					}				}				else#endif				{					// Miss on read#ifndef ICACHE					if(IsValid(bankToReplace, index) && IsDirty(bankToReplace, index))					{						// Cache line eject						state = 6;					}					else#endif					{						// Cache line fill#ifdef DEBUG						if(Debug(DebugCache))							cout << name() << ": Filling line" << endl;#endif						state = 8;					}				}			}		}	}#ifdef DEBUG	if(Debug(DebugCache))		if(ack)			cout << name() << ": Sending an ack" << endl;#endif	outAck = ack;}void CLASSNAME::Async(){	if(state == 0) GetRequest();}void CLASSNAME::OnFrontEdge(){	hit = false;	#ifdef ICACHE	if((state == 6 || state == 8) && inCancel)	{#ifdef DEBUG		if(Debug(DebugCache))			cout << name() << ": canceling previous request" << endl;#endif		busy = false;		state = 0;	}#endif#ifdef DEBUG	if(Debug(DebugCache))		cout << name() << ": state " << state << endl;#endif	switch(state)	{		case 0:			GetRequest();			break;#ifndef ICACHE		case 1: // Write request to eject the cache line before a write			{#ifdef DEBUG				if(Debug(DebugCache))					cout << name() << ": Memory write request for ejecting a cache line before a write" << endl;#endif				DataArray<CACHE2MEM> data;											line = GetLineStorage(bankToReplace, index);				lineOffset = 0;				length = 0;				memcpy(data.buffer, &line[lineOffset], CACHE2MEM);				lineOffset = (lineOffset + CACHE2MEM) % linesize;				length += CACHE2MEM;										if(length == linesize)				{					if(zeroBlock)						state = 5;					else						state = 3;				}				else				{					state = 2;				}											outMemReq = true;				outMemAddr = GetLineAddr(bankToReplace, index);				outMemWrite = true;				outMemData = data;				waitingForAck = true;			}			break;		case 2: // Cache line eject before a write			if(!waitingForAck)			{#ifdef DEBUG				if(Debug(DebugCache))					cout << name() << ": Ejecting a cache line before a write" << endl;#endif				DataArray<CACHE2MEM> data;								memcpy(data.buffer, &line[lineOffset], CACHE2MEM);				lineOffset = (lineOffset + CACHE2MEM) % linesize;				length += CACHE2MEM;				if(length == linesize)				{					if(zeroBlock)						state = 5;					else						state = 3;				}								outMemReq = false;				outMemData = data;			}			break;			

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -