📄 completionunit.cpp
字号:
/*************************************************************************** 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 + -