📄 dispatchunit.cpp
字号:
/*************************************************************************** DispatchUnit.cpp - Unite de dispatch ------------------- 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 <DispatchUnit.h>#include <FloatingPointUnit.h>DispatchUnit::DispatchUnit(const sc_module_name& name, ReorderBuffer *rob, RegistersBinding *registersBinding){ SC_HAS_PROCESS(DispatchUnit); SC_METHOD(Decode); sensitive << inDecode; SC_METHOD(Dispatch); sensitive_neg << inClock; this->rob = rob; this->registersBinding = registersBinding; Reset(); }/* This method returns the integer unit number which is able to execute the class of instruction and which is the less loaded unit */int DispatchUnit::GetLessLoadedIntegerRSQueue(int ic /* instruction class */){ int j; int i = -1; int n = 0; for(j = 0; j < nIntegerUnit; j++) { if(intflags[j] & ic) { int nfree = integerRSQueue[j].GetFreeSpace(); if(i >= 0) { if(nfree > n) { i = j; n = nfree; } } else { i = j; n = nfree; } } } return i;}/* This method returns the floating point unit number which is able to execute the class of instruction and which is the less loaded unit */int DispatchUnit::GetLessLoadedFloatingPointRSQueue(){ int j; int i = -1; int n = 0; for(j = 0; j < nFloatingPointUnits; j++) { int nfree = floatingPointRSQueue[j].GetFreeSpace(); if(i >= 0) { if(nfree > n) { i = j; n = nfree; } } else { i = j; n = nfree; } } return i;}/* This methods allocates an integer reservation station */IntegerRS *DispatchUnit::AllocateIntegerRS(int ic /* instruction class */){ int j = GetLessLoadedIntegerRSQueue(ic); if(j >= 0) { if(integerRSQueue[j].Full()) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": No remaining integer RS" << endl;#endif return 0; } else {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Allocating one integer RS (integer unit " << j << ")" << endl;#endif IntegerRS& rs = integerRSQueue[j].Allocate(); rs.unitNumber = j; return &rs; } } return 0;}/* This methods allocates a floating point reservation station */FloatingPointRS *DispatchUnit::AllocateFloatingPointRS(){ int j = GetLessLoadedFloatingPointRSQueue(); if(j >= 0) { if(floatingPointRSQueue[j].Full()) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": No remaining floating point RS" << endl;#endif return 0; } else {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Allocating one floating point RS (floating point unit " << j << ")" << endl;#endif FloatingPointRS& rs = floatingPointRSQueue[j].Allocate(); rs.unitNumber = j; return &rs; } } return 0;}/* this method allocates a load/store reservation station */LoadStoreRS *DispatchUnit::AllocateLoadStoreRS(){ if(!loadStoreRSQueue.Full()) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Allocating one load/store RS" << endl;#endif return &loadStoreRSQueue.Allocate(); } else {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": No remaining load/store RS" << endl;#endif return 0; }}/* This method allocates a branch reservation station */BranchRS *DispatchUnit::AllocateBranchRS(){ if(!branchRSQueue.Full()) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Allocating one branch RS" << endl;#endif return &branchRSQueue.Allocate(); } else {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": No remaining branch RS" << endl;#endif return 0; }}/* This methods allocates a system register unit reservation station */SystemRegisterRS *DispatchUnit::AllocateSystemRegisterRS(){ if(!systemRegisterRSQueue.Full()) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Allocating one system register RS" << endl;#endif return &systemRegisterRSQueue.Allocate(); } else {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": No remaining system register RS" << endl;#endif return 0; }}/* This method tries to allocate n reservation stations (type of reservation station depends on the instruction which have been previously decoded). It returns the number of reservation stations that have been successfully allocated */int DispatchUnit::AllocateRS(int n){ int i; for(i = 0; i < n; i++) { switch(units[i]) { case IntegerUnitIdent: rs[i].integer = AllocateIntegerRS(decodedInstructions[i].iclass); if(!rs[i].integer) return i; break; case LoadStoreUnitIdent: rs[i].loadStore = AllocateLoadStoreRS(); if(!rs[i].loadStore) return i; break; case BranchUnitIdent: rs[i].branch = AllocateBranchRS(); if(!rs[i].branch) return i; break; case SystemRegisterUnitIdent: rs[i].systemRegister = AllocateSystemRegisterRS(); if(!rs[i].systemRegister) return i; break; case FloatingPointUnitIdent: rs[i].floatingPoint = AllocateFloatingPointRS(); if(!rs[i].floatingPoint) return i; break; } } return i;}/* This methods checks the ressources necessary to dispatch nInstructions instructions (those instructions that have been previously decoded). It returns the number of instructions that can be dispatched according to the available ressources (rename buffer, ROB, etc...) */int DispatchUnit::CheckResources(int nInstructions){ int j; int nInstructionsToDispatch; int nFreeROBEntries = rob->GetFreeSpace(); int nFreeRenameBuffers = registersBinding->GetFreeRenameBuffers(); int nFreeFloatingPointRenameBuffers = registersBinding->GetFreeFloatingPointRenameBuffers(); int nFreeCRRenameBuffers = registersBinding->GetFreeCRRenameBuffers(); int nFreeLRRenameBuffers = registersBinding->GetFreeLRRenameBuffers(); int nFreeCTRRenameBuffers = registersBinding->GetFreeCTRRenameBuffers(); #ifdef DEBUG if(Debug(DebugDispatchUnit)) { cout << name() << ": " << nFreeROBEntries << " Free ROB Entries" << endl; cout << name() << ": " << nFreeRenameBuffers << " Free Rename Buffers" << endl; cout << name() << ": " << nFreeFloatingPointRenameBuffers << " Free Floating Point Rename Buffers" << endl; cout << name() << ": " << nFreeCRRenameBuffers << " Free CR Rename Buffers" << endl; cout << name() << ": " << nFreeLRRenameBuffers << " Free LR Rename Buffers" << endl; cout << name() << ": " << nFreeCTRRenameBuffers << " Free CTR Rename Buffers" << endl; }#endif for(nInstructionsToDispatch = 0; nInstructionsToDispatch < nInstructions && nFreeROBEntries > 0; nInstructionsToDispatch++) { switch(units[nInstructionsToDispatch]) { case IntegerUnitIdent: nFreeROBEntries--; if(decodedInstructions[nInstructionsToDispatch].io.integer.dstReg >= 0) if(--nFreeRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free rename buffers to dispatch IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } if(decodedInstructions[nInstructionsToDispatch].io.integer.outCR) if(--nFreeCRRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free cr rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } break; case FloatingPointUnitIdent: nFreeROBEntries--; if(decodedInstructions[nInstructionsToDispatch].io.floatingPoint.dstReg >= 0) if(--nFreeFloatingPointRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free floating point rename buffers to dispatch IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } if(decodedInstructions[nInstructionsToDispatch].io.floatingPoint.outCR) if(--nFreeCRRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free cr rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } break; case LoadStoreUnitIdent: nFreeROBEntries--; if(decodedInstructions[nInstructionsToDispatch].iclass & ICIntLoadStore) { for(j = 0; j < 2; j++) { if(decodedInstructions[nInstructionsToDispatch].io.loadStore.dstReg[j] >= 0) if(--nFreeRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } } } else if(decodedInstructions[nInstructionsToDispatch].iclass & ICFloatLoadStore) { if(decodedInstructions[nInstructionsToDispatch].io.loadStore.dstReg[0] >= 0) if(--nFreeFloatingPointRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free floating point rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } for(j = 1; j < 2; j++) { if(decodedInstructions[nInstructionsToDispatch].io.loadStore.dstReg[j] >= 0) if(--nFreeRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } } } break; case BranchUnitIdent: nFreeROBEntries--; if(decodedInstructions[nInstructionsToDispatch].io.branch.outLR) if(--nFreeLRRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free lr rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" <<endl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -