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

📄 completionunit.cpp

📁 ppc750 system design simulator using system c
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************                          CompletionUnit.cpp  -  unite de completion                             -------------------    begin                : Fri Apr 6 2001    copyright            : (C) 2001 Universite Paris Sud and CEA    author               : Gilles Mouchard    email                : gilles.mouchard@lri.fr, gilles.mouchard@.cea.fr ***************************************************************************/#include <CompletionUnit.h>CompletionUnit::CompletionUnit(const sc_module_name& name, ReorderBuffer *rob, RegistersBinding *registersBinding){	SC_HAS_PROCESS(CompletionUnit);	SC_METHOD(Retire);	sensitive_pos << inClock;			SC_METHOD(OnFallingEdge);	sensitive_neg << inClock;		SC_METHOD(Finish);	sensitive << inFinish;	this->rob = rob;	this->registersBinding = registersBinding;		Reset();		}/* This method computes the number of instructions that can be commited by checking */int CompletionUnit::GetInstructionsToWriteBack(){	int i, n;	int writeBackPort = 0;	int writeBackFloatingPointPort = 0;	int writeBackCRPort = 0;	int writeBackLRPort = 0;	int writeBackCTRPort = 0;	int memoryWriteBackPort = 0;	n = rob->Size();	if(n > nCQ) n = nCQ;		for(i = 0; i < n; i++)	{		ReorderBufferEntry& robEntry = (*rob)[i];				if(!robEntry.finished || robEntry.branchCounter > 0) return i;				switch(robEntry.unitIdent)		{			case IntegerUnitIdent:				if(robEntry.extra.integer.tags.resultTag >= 0)				{					if(writeBackPort >= nWriteBackPorts) return i;					writeBackPort++;				}								if(robEntry.extra.integer.tags.CRTag >= 0)				{					if(writeBackCRPort >= nWriteBackCRPorts) return i;					writeBackCRPort++;				}				break;							case FloatingPointUnitIdent:				if(robEntry.extra.floatingPoint.tags.resultTag >= 0)				{					if(writeBackFloatingPointPort >= nWriteBackFloatingPointPorts) return i;					writeBackFloatingPointPort++;				}								if(robEntry.extra.floatingPoint.tags.CRTag >= 0)				{					if(writeBackCRPort >= nWriteBackCRPorts) return i;					writeBackCRPort++;				}				break;							case LoadStoreUnitIdent:				if(robEntry.extra.loadStore.write)				{					if(memoryWriteBackPort >= nMemoryWriteBackPorts) return i;					memoryWriteBackPort++;				}							if(robEntry.extra.loadStore.tags.resultTags[0] >= 0)				{					if(robEntry.extra.loadStore.floatingPoint)					{						if(writeBackFloatingPointPort >= nWriteBackFloatingPointPorts) return i;						writeBackFloatingPointPort++;					}					else					{						if(writeBackPort >= nWriteBackPorts) return i;						writeBackPort++;					}				}								if(robEntry.extra.loadStore.tags.resultTags[1] >= 0)				{					if(writeBackPort >= nWriteBackPorts) return i;					writeBackPort++;				}				break;							case BranchUnitIdent:				if(robEntry.extra.branch.tags.LRTag >= 0)				{					if(writeBackLRPort >= nWriteBackLRPorts) return i;					writeBackLRPort++;				}								if(robEntry.extra.branch.tags.CTRTag >= 0)				{					if(writeBackCTRPort >= nWriteBackCTRPorts) return i;					writeBackCTRPort++;				}				break;							case SystemRegisterUnitIdent:				if(robEntry.extra.systemRegister.tags.resultTag >= 0)				{					if(writeBackPort >= nWriteBackPorts) return i;					writeBackPort++;				}								if(robEntry.extra.systemRegister.tags.LRTag >= 0)				{					if(writeBackLRPort >= nWriteBackLRPorts) return i;					writeBackLRPort++;				}								if(robEntry.extra.systemRegister.tags.CTRTag >= 0)				{					if(writeBackCTRPort >= nWriteBackCTRPorts) return i;					writeBackCTRPort++;				}								if(robEntry.extra.systemRegister.tags.CRTag >= 0)				{					if(writeBackCRPort >= nWriteBackCRPorts) return i;					writeBackCRPort++;				}				break;		}	}	return i;	}void CompletionUnit::Retire(){	int i, j;	/* Write Back */		int writeBackPort = 0;	int writeBackFloatingPointPort = 0;	int writeBackCRPort = 0;	int writeBackLRPort = 0;	int writeBackCTRPort = 0;	int memoryWriteBackPort = 0;	bool writeCarry = false;	bool writeOverflow = false;	bool writeCR = false;	/* Get the number of instructions that can be written back */	int nInstructionsToWriteBack = GetInstructionsToWriteBack();	#ifdef DEBUG	if(Debug(DebugCompletionUnit))	{		if(nInstructionsToWriteBack > 0)			cout << name() << ": Write Back " << nInstructionsToWriteBack << " instructions" << endl;				cout << name() << ": Registers binding :" << endl;		cout << *registersBinding << endl;	}#endif	/* Write Back */		for(i = 0; i < nInstructionsToWriteBack; i++)	{		/* Get the instructions from the oldest to the newest */		ReorderBufferEntry& robEntry = (*rob)[i];				switch(robEntry.unitIdent)		{			case IntegerUnitIdent:#ifdef DEBUG				if(Debug(DebugCompletionUnit))					cout << name() << ": Write Back an integer instruction (tag = " << (int) robEntry.extra.integer.tags.tag << ")" << endl;#endif				if(robEntry.extra.integer.tags.resultTag >= 0)				{					/* Instruction has a rename buffer to transfer to a register */					/* Get the register number in which the rename buffer value has to be written */					int dstReg = registersBinding->GetRegister(robEntry.extra.integer.tags.resultTag);#ifdef DEBUG					if(Debug(DebugCompletionUnit))						cout << name() << ": Write Back rr" << (int) robEntry.extra.integer.tags.resultTag << " to r" << dstReg << endl;#endif					/* Ask to the register file to do the data transfer between the rename buffer and the register */					outWriteBack[writeBackPort] = true;					outWriteBackRegisterNumber[writeBackPort] = dstReg;					outWriteBackRenameNumber[writeBackPort] = robEntry.extra.integer.tags.resultTag;					writeBackPort++;				}								if(robEntry.extra.integer.tags.CRTag >= 0)				{					/* Instruction has a CR field rename buffer to transfer into CR */#ifdef DEBUG					if(Debug(DebugCompletionUnit))						cout << name() << ": Write Back CR rename buffer #" << (int) robEntry.extra.integer.tags.CRTag << endl;#endif					outWriteBackCR[writeBackCRPort] = true;					outWriteBackCRRenameNumber[writeBackCRPort] = robEntry.extra.integer.tags.CRTag;					outWriteBackCRFieldNumber[writeBackCRPort] = registersBinding->GetField(robEntry.extra.integer.tags.CRTag);					writeBackCRPort++;				}				if(robEntry.extra.integer.writeCarry)				{					/* Instruction modifies the carry bit XER[CA] */#ifdef DEBUG					if(Debug(DebugCompletionUnit))						cout << name() << ": Write Back carry (" << robEntry.extra.integer.carry << ")" << endl;#endif					writeCarry = true;					outCarry = robEntry.extra.integer.carry;				}								if(robEntry.extra.integer.writeOverflow)				{					/* Instruction modifies the overflow bit XER[SO] */#ifdef DEBUG					if(Debug(DebugCompletionUnit))						cout << name() << ": Write Back overflow" << endl;#endif					writeOverflow = true;					outOverflow = robEntry.extra.integer.overflow;				}				break;			case FloatingPointUnitIdent:#ifdef DEBUG				if(Debug(DebugCompletionUnit))					cout << name() << ": Write Back a floating point instruction (tag = " << (int) robEntry.extra.floatingPoint.tags.tag << ")" << endl;#endif				if(robEntry.extra.floatingPoint.tags.resultTag >= 0)				{					/* Instruction has to transfer the floating point rename buffer to a floating point register */					/* Get the floating point register number where the floating point rename buffer value must be written */					int dstReg = registersBinding->GetFloatingPointRegister(robEntry.extra.floatingPoint.tags.resultTag);#ifdef DEBUG					if(Debug(DebugCompletionUnit))						cout << name() << ": Write Back rfp" << (int) robEntry.extra.floatingPoint.tags.resultTag << " to fp" << dstReg << endl;#endif					/* Ask to the register file to do the transfer between the floating point rename buffer ans the floating point register */					outWriteBackFloatingPoint[writeBackFloatingPointPort] = true;					outWriteBackFloatingPointRegisterNumber[writeBackFloatingPointPort] = dstReg;					outWriteBackFloatingPointRenameNumber[writeBackFloatingPointPort] = robEntry.extra.floatingPoint.tags.resultTag;					writeBackFloatingPointPort++;				}								if(robEntry.extra.floatingPoint.tags.CRTag >= 0)				{					/* Instruction has a CR field to write back */#ifdef DEBUG					if(Debug(DebugCompletionUnit))						cout << name() << ": Write Back CR rename buffer #" << (int) robEntry.extra.floatingPoint.tags.CRTag << endl;#endif					outWriteBackCR[writeBackCRPort] = true;					outWriteBackCRRenameNumber[writeBackCRPort] = robEntry.extra.floatingPoint.tags.CRTag;					outWriteBackCRFieldNumber[writeBackCRPort] = registersBinding->GetField(robEntry.extra.floatingPoint.tags.CRTag);					writeBackCRPort++;				}				break;							case LoadStoreUnitIdent:#ifdef DEBUG				if(Debug(DebugCompletionUnit))					cout << name() << ": Write Back a load/store instruction (tag = " << (int) robEntry.extra.loadStore.tags.tag << ")" << endl;#endif				if(robEntry.extra.loadStore.write)				{					/* Store can go to the data cache */					outMemoryWriteBack[memoryWriteBackPort] = true;					outMemoryWriteBackTag[memoryWriteBackPort] = robEntry.extra.loadStore.tags.tag;					memoryWriteBackPort++;				}								if(robEntry.extra.loadStore.tags.resultTags[0] >= 0)				{					if(robEntry.extra.loadStore.floatingPoint)					{						/* Instruction has a floating point result to write back */											regnum_t dstReg = registersBinding->GetFloatingPointRegister(robEntry.extra.loadStore.tags.resultTags[0]);#ifdef DEBUG						if(Debug(DebugCompletionUnit))							cout << name() << ": Write Back rfp" << (int) robEntry.extra.loadStore.tags.resultTags[0] << " to fp" << (int) dstReg << endl;#endif						outWriteBackFloatingPoint[writeBackFloatingPointPort] = true;						outWriteBackFloatingPointRegisterNumber[writeBackFloatingPointPort] = dstReg;						outWriteBackFloatingPointRenameNumber[writeBackFloatingPointPort] = robEntry.extra.loadStore.tags.resultTags[0];						writeBackFloatingPointPort++;					}					else					{						/* Instruction has a result to write back */												regnum_t dstReg = registersBinding->GetRegister(robEntry.extra.loadStore.tags.resultTags[0]);#ifdef DEBUG						if(Debug(DebugCompletionUnit))							cout << name() << ": Write Back rr" << (int) robEntry.extra.loadStore.tags.resultTags[0] << " to r" << (int) dstReg << endl;#endif						outWriteBack[writeBackPort] = true;						outWriteBackRegisterNumber[writeBackPort] = dstReg;						outWriteBackRenameNumber[writeBackPort] = robEntry.extra.loadStore.tags.resultTags[0];						writeBackPort++;					}				}								if(robEntry.extra.loadStore.tags.resultTags[1] >= 0)				{					/* Instruction has a result to write back */					regnum_t dstReg = registersBinding->GetRegister(robEntry.extra.loadStore.tags.resultTags[1]);#ifdef DEBUG					if(Debug(DebugCompletionUnit))						cout << name() << ": Write Back rr" << (int) robEntry.extra.loadStore.tags.resultTags[1] << " to r" << (int) dstReg << endl;#endif					outWriteBack[writeBackPort] = true;					outWriteBackRegisterNumber[writeBackPort] = dstReg;					outWriteBackRenameNumber[writeBackPort] = robEntry.extra.loadStore.tags.resultTags[1];					writeBackPort++;				}				break;							case BranchUnitIdent:#ifdef DEBUG				if(Debug(DebugCompletionUnit))					cout << name() << ": Write Back a branch instruction (tag = " << (int) robEntry.extra.branch.tags.tag << ")" << endl;#endif				if(robEntry.extra.branch.tags.LRTag >= 0)				{					/* Instruction has to write LR */#ifdef DEBUG					if(Debug(DebugCompletionUnit))						cout << name() << ": Write Back LR rename buffer #" << (int) robEntry.extra.branch.tags.LRTag << endl;#endif					outWriteBackLR[writeBackLRPort] = true;					outWriteBackLRRenameNumber[writeBackLRPort] = robEntry.extra.branch.tags.LRTag;					writeBackLRPort++;				}						if(robEntry.extra.branch.tags.CTRTag >= 0)				{					/* Instruction has to write CTR */#ifdef DEBUG					if(Debug(DebugCompletionUnit))						cout << name() << ": Write Back CTR rename buffer #" << (int) robEntry.extra.branch.tags.CTRTag << endl;#endif					outWriteBackCTR[writeBackCTRPort] = true;					outWriteBackCTRRenameNumber[writeBackCTRPort] = robEntry.extra.branch.tags.CTRTag;					writeBackCTRPort++;				}				break;						case SystemRegisterUnitIdent:#ifdef DEBUG				if(Debug(DebugCompletionUnit))					cout << name() << ": Write Back a system register instruction (tag = " << (int) robEntry.extra.systemRegister.tags.tag << ")" << endl;#endif				if(robEntry.extra.systemRegister.tags.resultTag >= 0)				{					/* Instruction has to write a result */					int dstReg = registersBinding->GetRegister(robEntry.extra.systemRegister.tags.resultTag);;#ifdef DEBUG

⌨️ 快捷键说明

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