inorder: inst count mgmt
This commit is contained in:
parent
be6724f7e7
commit
9357e353fc
14 changed files with 211 additions and 68 deletions
|
@ -54,6 +54,8 @@ if 'InOrderCPU' in env['CPU_MODELS']:
|
||||||
TraceFlag('InOrderGraduation')
|
TraceFlag('InOrderGraduation')
|
||||||
TraceFlag('ThreadModel')
|
TraceFlag('ThreadModel')
|
||||||
TraceFlag('RefCount')
|
TraceFlag('RefCount')
|
||||||
|
TraceFlag('AddrDep')
|
||||||
|
|
||||||
|
|
||||||
CompoundFlag('InOrderCPUAll', [ 'InOrderStage', 'InOrderStall', 'InOrderCPU',
|
CompoundFlag('InOrderCPUAll', [ 'InOrderStage', 'InOrderStall', 'InOrderCPU',
|
||||||
'InOrderMDU', 'InOrderAGEN', 'InOrderFetchSeq', 'InOrderTLB', 'InOrderBPred',
|
'InOrderMDU', 'InOrderAGEN', 'InOrderFetchSeq', 'InOrderTLB', 'InOrderBPred',
|
||||||
|
|
|
@ -333,6 +333,12 @@ InOrderCPU::InOrderCPU(Params *params)
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dummyReqInst = new InOrderDynInst(this, NULL, 0, 0, 0);
|
||||||
|
dummyReqInst->setSquashed();
|
||||||
|
|
||||||
|
dummyBufferInst = new InOrderDynInst(this, NULL, 0, 0, 0);
|
||||||
|
dummyBufferInst->setSquashed();
|
||||||
|
|
||||||
lastRunningCycle = curTick;
|
lastRunningCycle = curTick;
|
||||||
|
|
||||||
// Reset CPU to reset state.
|
// Reset CPU to reset state.
|
||||||
|
@ -343,6 +349,8 @@ InOrderCPU::InOrderCPU(Params *params)
|
||||||
reset();
|
reset();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
dummyBufferInst->resetInstCount();
|
||||||
|
|
||||||
// Schedule First Tick Event, CPU will reschedule itself from here on out.
|
// Schedule First Tick Event, CPU will reschedule itself from here on out.
|
||||||
scheduleTickEvent(0);
|
scheduleTickEvent(0);
|
||||||
}
|
}
|
||||||
|
@ -1176,6 +1184,8 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
|
||||||
removeInst(inst);
|
removeInst(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// currently unused function, but substitute repetitive code w/this function
|
||||||
|
// call
|
||||||
void
|
void
|
||||||
InOrderCPU::addToRemoveList(DynInstPtr &inst)
|
InOrderCPU::addToRemoveList(DynInstPtr &inst)
|
||||||
{
|
{
|
||||||
|
@ -1194,6 +1204,10 @@ InOrderCPU::removeInst(DynInstPtr &inst)
|
||||||
removeInstsThisCycle = true;
|
removeInstsThisCycle = true;
|
||||||
|
|
||||||
// Remove the instruction.
|
// Remove the instruction.
|
||||||
|
|
||||||
|
DPRINTF(RefCount, "Pushing instruction [tid:%i] PC %#x "
|
||||||
|
"[sn:%lli] to remove list\n",
|
||||||
|
inst->threadNumber, inst->readPC(), inst->seqNum);
|
||||||
removeList.push(inst->getInstListIt());
|
removeList.push(inst->getInstListIt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1208,7 +1222,7 @@ InOrderCPU::removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
|
||||||
|
|
||||||
inst_iter--;
|
inst_iter--;
|
||||||
|
|
||||||
DPRINTF(InOrderCPU, "Deleting instructions from CPU instruction "
|
DPRINTF(InOrderCPU, "Squashing instructions from CPU instruction "
|
||||||
"list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
|
"list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
|
||||||
tid, seq_num, (*inst_iter)->seqNum);
|
tid, seq_num, (*inst_iter)->seqNum);
|
||||||
|
|
||||||
|
@ -1238,6 +1252,9 @@ InOrderCPU::squashInstIt(const ListIt &instIt, ThreadID tid)
|
||||||
|
|
||||||
(*instIt)->setSquashed();
|
(*instIt)->setSquashed();
|
||||||
|
|
||||||
|
DPRINTF(RefCount, "Pushing instruction [tid:%i] PC %#x "
|
||||||
|
"[sn:%lli] to remove list\n",
|
||||||
|
(*instIt)->threadNumber, (*instIt)->readPC(), (*instIt)->seqNum);
|
||||||
removeList.push(instIt);
|
removeList.push(instIt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1251,7 +1268,7 @@ InOrderCPU::cleanUpRemovedInsts()
|
||||||
"[tid:%i] [sn:%lli] PC %#x\n",
|
"[tid:%i] [sn:%lli] PC %#x\n",
|
||||||
(*removeList.front())->threadNumber,
|
(*removeList.front())->threadNumber,
|
||||||
(*removeList.front())->seqNum,
|
(*removeList.front())->seqNum,
|
||||||
(*removeList.front())->readPC());
|
(*removeList.front())->readPC());
|
||||||
|
|
||||||
DynInstPtr inst = *removeList.front();
|
DynInstPtr inst = *removeList.front();
|
||||||
ThreadID tid = inst->threadNumber;
|
ThreadID tid = inst->threadNumber;
|
||||||
|
@ -1279,11 +1296,6 @@ InOrderCPU::cleanUpRemovedInsts()
|
||||||
instList[tid].erase(removeList.front());
|
instList[tid].erase(removeList.front());
|
||||||
|
|
||||||
removeList.pop();
|
removeList.pop();
|
||||||
|
|
||||||
DPRINTF(RefCount, "pop from remove list: [sn:%i]: Refcount = %i.\n",
|
|
||||||
inst->seqNum,
|
|
||||||
0/*inst->curCount()*/);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeInstsThisCycle = false;
|
removeInstsThisCycle = false;
|
||||||
|
@ -1295,22 +1307,18 @@ InOrderCPU::cleanUpRemovedReqs()
|
||||||
while (!reqRemoveList.empty()) {
|
while (!reqRemoveList.empty()) {
|
||||||
ResourceRequest *res_req = reqRemoveList.front();
|
ResourceRequest *res_req = reqRemoveList.front();
|
||||||
|
|
||||||
DPRINTF(RefCount, "[tid:%i]: Removing Request, "
|
DPRINTF(InOrderCPU, "[tid:%i] [sn:%lli]: Removing Request "
|
||||||
"[sn:%lli] [slot:%i] [stage_num:%i] [res:%s] [refcount:%i].\n",
|
"[stage_num:%i] [res:%s] [slot:%i] [completed:%i].\n",
|
||||||
res_req->inst->threadNumber,
|
res_req->inst->threadNumber,
|
||||||
res_req->inst->seqNum,
|
res_req->inst->seqNum,
|
||||||
res_req->getSlot(),
|
|
||||||
res_req->getStageNum(),
|
res_req->getStageNum(),
|
||||||
res_req->res->name(),
|
res_req->res->name(),
|
||||||
0/*res_req->inst->curCount()*/);
|
(res_req->isCompleted()) ? res_req->getComplSlot() : res_req->getSlot(),
|
||||||
|
res_req->isCompleted());
|
||||||
|
|
||||||
reqRemoveList.pop();
|
reqRemoveList.pop();
|
||||||
|
|
||||||
delete res_req;
|
delete res_req;
|
||||||
|
|
||||||
DPRINTF(RefCount, "after remove request: [sn:%i]: Refcount = %i.\n",
|
|
||||||
res_req->inst->seqNum,
|
|
||||||
0/*res_req->inst->curCount()*/);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -247,6 +247,8 @@ class InOrderCPU : public BaseCPU
|
||||||
/** Instruction used to signify that there is no *real* instruction in
|
/** Instruction used to signify that there is no *real* instruction in
|
||||||
buffer slot */
|
buffer slot */
|
||||||
DynInstPtr dummyInst[ThePipeline::MaxThreads];
|
DynInstPtr dummyInst[ThePipeline::MaxThreads];
|
||||||
|
DynInstPtr dummyBufferInst;
|
||||||
|
DynInstPtr dummyReqInst;
|
||||||
|
|
||||||
/** Used by resources to signify a denied access to a resource. */
|
/** Used by resources to signify a denied access to a resource. */
|
||||||
ResourceRequest *dummyReq[ThePipeline::MaxThreads];
|
ResourceRequest *dummyReq[ThePipeline::MaxThreads];
|
||||||
|
|
|
@ -164,7 +164,7 @@ InOrderDynInst::initVars()
|
||||||
|
|
||||||
// Update Instruction Count for this instruction
|
// Update Instruction Count for this instruction
|
||||||
++instcount;
|
++instcount;
|
||||||
if (instcount > 500) {
|
if (instcount > 100) {
|
||||||
fatal("Number of Active Instructions in CPU is too high. "
|
fatal("Number of Active Instructions in CPU is too high. "
|
||||||
"(Not Dereferencing Ptrs. Correctly?)\n");
|
"(Not Dereferencing Ptrs. Correctly?)\n");
|
||||||
}
|
}
|
||||||
|
@ -175,6 +175,12 @@ InOrderDynInst::initVars()
|
||||||
threadNumber, seqNum, instcount);
|
threadNumber, seqNum, instcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InOrderDynInst::resetInstCount()
|
||||||
|
{
|
||||||
|
instcount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
InOrderDynInst::~InOrderDynInst()
|
InOrderDynInst::~InOrderDynInst()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1032,14 +1032,15 @@ class InOrderDynInst : public FastAlloc, public RefCounted
|
||||||
/** Count of total number of dynamic instructions. */
|
/** Count of total number of dynamic instructions. */
|
||||||
static int instcount;
|
static int instcount;
|
||||||
|
|
||||||
|
void resetInstCount();
|
||||||
|
|
||||||
/** Dumps out contents of this BaseDynInst. */
|
/** Dumps out contents of this BaseDynInst. */
|
||||||
void dump();
|
void dump();
|
||||||
|
|
||||||
/** Dumps out contents of this BaseDynInst into given string. */
|
/** Dumps out contents of this BaseDynInst into given string. */
|
||||||
void dump(std::string &outstring);
|
void dump(std::string &outstring);
|
||||||
|
|
||||||
|
//inline int curCount() { return curCount(); }
|
||||||
//inline int curCount() { return curCount(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -101,8 +101,6 @@ PipelineStage::setCPU(InOrderCPU *cpu_ptr)
|
||||||
{
|
{
|
||||||
cpu = cpu_ptr;
|
cpu = cpu_ptr;
|
||||||
|
|
||||||
dummyBufferInst = new InOrderDynInst(cpu_ptr, NULL, 0, 0, 0);
|
|
||||||
|
|
||||||
DPRINTF(InOrderStage, "Set CPU pointer.\n");
|
DPRINTF(InOrderStage, "Set CPU pointer.\n");
|
||||||
|
|
||||||
tracer = dynamic_cast<Trace::InOrderTrace *>(cpu->getTracer());
|
tracer = dynamic_cast<Trace::InOrderTrace *>(cpu->getTracer());
|
||||||
|
@ -388,6 +386,8 @@ PipelineStage::squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid)
|
||||||
prevStage->insts[i]->seqNum,
|
prevStage->insts[i]->seqNum,
|
||||||
prevStage->insts[i]->readPC());
|
prevStage->insts[i]->readPC());
|
||||||
prevStage->insts[i]->setSquashed();
|
prevStage->insts[i]->setSquashed();
|
||||||
|
|
||||||
|
prevStage->insts[i] = cpu->dummyBufferInst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -609,7 +609,7 @@ PipelineStage::sortInsts()
|
||||||
|
|
||||||
skidBuffer[tid].push(prevStage->insts[i]);
|
skidBuffer[tid].push(prevStage->insts[i]);
|
||||||
|
|
||||||
prevStage->insts[i] = dummyBufferInst;
|
prevStage->insts[i] = cpu->dummyBufferInst;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -816,7 +816,7 @@ PipelineStage::processThread(bool &status_change, ThreadID tid)
|
||||||
// call processInsts()
|
// call processInsts()
|
||||||
// If status is Unblocking,
|
// If status is Unblocking,
|
||||||
// buffer any instructions coming from fetch
|
// buffer any instructions coming from fetch
|
||||||
// continue trying to empty skid buffer
|
// continue trying to empty skid buffer
|
||||||
// check if stall conditions have passed
|
// check if stall conditions have passed
|
||||||
|
|
||||||
// Stage should try to process as many instructions as its bandwidth
|
// Stage should try to process as many instructions as its bandwidth
|
||||||
|
@ -960,6 +960,8 @@ PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed)
|
||||||
}
|
}
|
||||||
|
|
||||||
reqs_processed++;
|
reqs_processed++;
|
||||||
|
|
||||||
|
req->stagePasses++;
|
||||||
} else {
|
} else {
|
||||||
DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s failed."
|
DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s failed."
|
||||||
"\n", tid, inst->seqNum, cpu->resPool->name(res_num));
|
"\n", tid, inst->seqNum, cpu->resPool->name(res_num));
|
||||||
|
@ -969,7 +971,7 @@ PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed)
|
||||||
if (req->isMemStall() &&
|
if (req->isMemStall() &&
|
||||||
cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) {
|
cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) {
|
||||||
// Save Stalling Instruction
|
// Save Stalling Instruction
|
||||||
DPRINTF(ThreadModel, "[tid:%i] Detected cache miss.\n", tid);
|
DPRINTF(ThreadModel, "[tid:%i] [sn:%i] Detected cache miss.\n", tid, inst->seqNum);
|
||||||
|
|
||||||
DPRINTF(InOrderStage, "Inserting [tid:%i][sn:%i] into switch out buffer.\n",
|
DPRINTF(InOrderStage, "Inserting [tid:%i][sn:%i] into switch out buffer.\n",
|
||||||
tid, inst->seqNum);
|
tid, inst->seqNum);
|
||||||
|
@ -994,6 +996,20 @@ PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed)
|
||||||
cpu->activateNextReadyContext();
|
cpu->activateNextReadyContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark request for deletion
|
||||||
|
// if it isnt currently being used by a resource
|
||||||
|
if (!req->hasSlot()) {
|
||||||
|
DPRINTF(InOrderStage, "[sn:%i] Deleting Request, has no slot in resource.\n",
|
||||||
|
inst->seqNum);
|
||||||
|
|
||||||
|
cpu->reqRemoveList.push(req);
|
||||||
|
} else {
|
||||||
|
DPRINTF(InOrderStage, "[sn:%i] Ignoring Request Deletion, in resource [slot:%i].\n",
|
||||||
|
inst->seqNum, req->getSlot());
|
||||||
|
//req = cpu->dummyReq[tid];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -235,3 +235,27 @@ RegDepMap::findBypassInst(unsigned idx)
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RegDepMap::dump()
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int idx=0; idx < regMap.size(); idx++) {
|
||||||
|
|
||||||
|
if (regMap[idx].size() > 0) {
|
||||||
|
cprintf("Reg #%i (size:%i): ", idx, regMap[idx].size());
|
||||||
|
|
||||||
|
std::list<DynInstPtr>::iterator list_it = regMap[idx].begin();
|
||||||
|
std::list<DynInstPtr>::iterator list_end = regMap[idx].end();
|
||||||
|
|
||||||
|
while (list_it != list_end) {
|
||||||
|
cprintf("[sn:%i] ", (*list_it)->seqNum);
|
||||||
|
|
||||||
|
list_it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
cprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -88,6 +88,8 @@ class RegDepMap
|
||||||
/** Size of Dependency of Map */
|
/** Size of Dependency of Map */
|
||||||
int depSize(unsigned idx);
|
int depSize(unsigned idx);
|
||||||
|
|
||||||
|
void dump();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Eventually make this a map of lists for
|
// Eventually make this a map of lists for
|
||||||
// efficiency sake!
|
// efficiency sake!
|
||||||
|
|
|
@ -101,12 +101,6 @@ Resource::slotsInUse()
|
||||||
void
|
void
|
||||||
Resource::freeSlot(int slot_idx)
|
Resource::freeSlot(int slot_idx)
|
||||||
{
|
{
|
||||||
DPRINTF(RefCount, "Removing [tid:%i] [sn:%i]'s request from resource "
|
|
||||||
"[slot:%i].\n",
|
|
||||||
reqMap[slot_idx]->inst->readTid(),
|
|
||||||
reqMap[slot_idx]->inst->seqNum,
|
|
||||||
slot_idx);
|
|
||||||
|
|
||||||
// Put slot number on this resource's free list
|
// Put slot number on this resource's free list
|
||||||
availSlots.push_back(slot_idx);
|
availSlots.push_back(slot_idx);
|
||||||
|
|
||||||
|
@ -181,7 +175,7 @@ Resource::request(DynInstPtr inst)
|
||||||
// See if the resource is already serving this instruction.
|
// See if the resource is already serving this instruction.
|
||||||
// If so, use that request;
|
// If so, use that request;
|
||||||
bool try_request = false;
|
bool try_request = false;
|
||||||
int slot_num;
|
int slot_num = -1;
|
||||||
int stage_num;
|
int stage_num;
|
||||||
ResReqPtr inst_req = findRequest(inst);
|
ResReqPtr inst_req = findRequest(inst);
|
||||||
|
|
||||||
|
@ -440,6 +434,10 @@ ResourceRequest::ResourceRequest(Resource *_res, DynInstPtr _inst,
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
stagePasses = 0;
|
||||||
|
complSlotNum = -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceRequest::~ResourceRequest()
|
ResourceRequest::~ResourceRequest()
|
||||||
|
@ -454,17 +452,29 @@ ResourceRequest::~ResourceRequest()
|
||||||
void
|
void
|
||||||
ResourceRequest::done(bool completed)
|
ResourceRequest::done(bool completed)
|
||||||
{
|
{
|
||||||
DPRINTF(Resource, "%s done with request from [sn:%i] [tid:%i].\n",
|
DPRINTF(Resource, "%s [slot:%i] done with request from [sn:%i] [tid:%i].\n",
|
||||||
res->name(), inst->seqNum, inst->readTid());
|
res->name(), slotNum, inst->seqNum, inst->readTid());
|
||||||
|
|
||||||
setCompleted(completed);
|
setCompleted(completed);
|
||||||
|
|
||||||
// Add to remove list
|
// Used for debugging purposes
|
||||||
res->cpu->reqRemoveList.push(res->reqMap[slotNum]);
|
if (completed) {
|
||||||
|
complSlotNum = slotNum;
|
||||||
|
|
||||||
|
// Would like to start a convention such as all requests deleted in resources/pipeline
|
||||||
|
// but a little more complex then it seems...
|
||||||
|
// For now, all COMPLETED requests deleted in resource..
|
||||||
|
// all FAILED requests deleted in pipeline stage
|
||||||
|
// *all SQUASHED requests deleted in resource
|
||||||
|
res->cpu->reqRemoveList.push(res->reqMap[slotNum]);
|
||||||
|
}
|
||||||
|
|
||||||
// Free Slot So Another Instruction Can Use This Resource
|
// Free Slot So Another Instruction Can Use This Resource
|
||||||
res->freeSlot(slotNum);
|
res->freeSlot(slotNum);
|
||||||
|
|
||||||
|
// change slot # to -1, since we check slotNum to see if request is still valid
|
||||||
|
slotNum = -1;
|
||||||
|
|
||||||
res->instReqsProcessed++;
|
res->instReqsProcessed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -331,6 +331,8 @@ class ResourceRequest
|
||||||
*/
|
*/
|
||||||
void done(bool completed = true);
|
void done(bool completed = true);
|
||||||
|
|
||||||
|
short stagePasses;
|
||||||
|
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// GET RESOURCE REQUEST IDENTIFICATION / INFO
|
// GET RESOURCE REQUEST IDENTIFICATION / INFO
|
||||||
|
@ -339,8 +341,11 @@ class ResourceRequest
|
||||||
/** Get Resource Index */
|
/** Get Resource Index */
|
||||||
int getResIdx() { return resIdx; }
|
int getResIdx() { return resIdx; }
|
||||||
|
|
||||||
|
|
||||||
/** Get Slot Number */
|
/** Get Slot Number */
|
||||||
int getSlot() { return slotNum; }
|
int getSlot() { return slotNum; }
|
||||||
|
int getComplSlot() { return complSlotNum; }
|
||||||
|
bool hasSlot() { return slotNum >= 0; }
|
||||||
|
|
||||||
/** Get Stage Number */
|
/** Get Stage Number */
|
||||||
int getStageNum() { return stageNum; }
|
int getStageNum() { return stageNum; }
|
||||||
|
@ -363,6 +368,9 @@ class ResourceRequest
|
||||||
/** Instruction being used */
|
/** Instruction being used */
|
||||||
DynInstPtr inst;
|
DynInstPtr inst;
|
||||||
|
|
||||||
|
/** Not guaranteed to be set, used for debugging */
|
||||||
|
InstSeqNum seqNum;
|
||||||
|
|
||||||
/** Fault Associated With This Resource Request */
|
/** Fault Associated With This Resource Request */
|
||||||
Fault fault;
|
Fault fault;
|
||||||
|
|
||||||
|
@ -396,7 +404,8 @@ class ResourceRequest
|
||||||
int stageNum;
|
int stageNum;
|
||||||
int resIdx;
|
int resIdx;
|
||||||
int slotNum;
|
int slotNum;
|
||||||
|
int complSlotNum;
|
||||||
|
|
||||||
/** Resource Request Status */
|
/** Resource Request Status */
|
||||||
bool completed;
|
bool completed;
|
||||||
bool squashed;
|
bool squashed;
|
||||||
|
|
|
@ -155,14 +155,11 @@ CacheUnit::getSlot(DynInstPtr inst)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
inst->memTime = curTick;
|
inst->memTime = curTick;
|
||||||
addrList[tid].push_back(req_addr);
|
setAddrDependency(inst);
|
||||||
addrMap[tid][req_addr] = inst->seqNum;
|
|
||||||
DPRINTF(InOrderCachePort,
|
|
||||||
"[tid:%i]: [sn:%i]: Address %08p added to dependency list\n",
|
|
||||||
inst->readTid(), inst->seqNum, req_addr);
|
|
||||||
return new_slot;
|
return new_slot;
|
||||||
} else {
|
} else {
|
||||||
// Allow same instruction multiple accesses to same address
|
// Allow same instruction multiple accesses to same address
|
||||||
|
// should only happen maybe after a squashed inst. needs to replay
|
||||||
if (addrMap[tid][req_addr] == inst->seqNum) {
|
if (addrMap[tid][req_addr] == inst->seqNum) {
|
||||||
int new_slot = Resource::getSlot(inst);
|
int new_slot = Resource::getSlot(inst);
|
||||||
|
|
||||||
|
@ -183,31 +180,45 @@ CacheUnit::getSlot(DynInstPtr inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CacheUnit::freeSlot(int slot_num)
|
CacheUnit::setAddrDependency(DynInstPtr inst)
|
||||||
{
|
{
|
||||||
ThreadID tid = reqMap[slot_num]->inst->readTid();
|
Addr req_addr = inst->getMemAddr();
|
||||||
|
ThreadID tid = inst->readTid();
|
||||||
vector<Addr>::iterator vect_it =
|
|
||||||
find(addrList[tid].begin(), addrList[tid].end(),
|
|
||||||
reqMap[slot_num]->inst->getMemAddr());
|
|
||||||
|
|
||||||
assert(vect_it != addrList[tid].end() ||
|
|
||||||
reqMap[slot_num]->inst->splitInst);
|
|
||||||
|
|
||||||
|
addrList[tid].push_back(req_addr);
|
||||||
|
addrMap[tid][req_addr] = inst->seqNum;
|
||||||
DPRINTF(InOrderCachePort,
|
DPRINTF(InOrderCachePort,
|
||||||
"[tid:%i]: Address %08p removed from dependency list\n",
|
"[tid:%i]: [sn:%i]: Address %08p added to dependency list\n",
|
||||||
reqMap[slot_num]->inst->readTid(), (*vect_it));
|
inst->readTid(), inst->seqNum, req_addr);
|
||||||
|
DPRINTF(AddrDep,
|
||||||
|
"[tid:%i]: [sn:%i]: Address %08p added to dependency list\n",
|
||||||
|
inst->readTid(), inst->seqNum, req_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CacheUnit::removeAddrDependency(DynInstPtr inst)
|
||||||
|
{
|
||||||
|
ThreadID tid = inst->readTid();
|
||||||
|
|
||||||
|
Addr mem_addr = inst->getMemAddr();
|
||||||
|
|
||||||
|
// Erase from Address List
|
||||||
|
vector<Addr>::iterator vect_it = find(addrList[tid].begin(), addrList[tid].end(),
|
||||||
|
mem_addr);
|
||||||
|
assert(vect_it != addrList[tid].end() || inst->splitInst);
|
||||||
|
|
||||||
if (vect_it != addrList[tid].end()) {
|
if (vect_it != addrList[tid].end()) {
|
||||||
|
DPRINTF(AddrDep,
|
||||||
DPRINTF(InOrderCachePort,
|
"[tid:%i]: [sn:%i] Address %08p removed from dependency list\n",
|
||||||
"[tid:%i]: Address %08p removed from dependency list\n",
|
inst->readTid(), inst->seqNum, (*vect_it));
|
||||||
reqMap[slot_num]->inst->readTid(), (*vect_it));
|
|
||||||
|
addrList[tid].erase(vect_it);
|
||||||
addrList[tid].erase(vect_it);
|
|
||||||
}
|
// Erase From Address Map (Used for Debugging)
|
||||||
|
addrMap[tid].erase(addrMap[tid].find(mem_addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Resource::freeSlot(slot_num);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResReqPtr
|
ResReqPtr
|
||||||
|
@ -687,8 +698,14 @@ CacheUnit::execute(int slot_num)
|
||||||
DPRINTF(InOrderCachePort, "[tid:%i]: Instruction [sn:%i] is: %s\n",
|
DPRINTF(InOrderCachePort, "[tid:%i]: Instruction [sn:%i] is: %s\n",
|
||||||
tid, seq_num, inst->staticInst->disassemble(inst->PC));
|
tid, seq_num, inst->staticInst->disassemble(inst->PC));
|
||||||
|
|
||||||
|
removeAddrDependency(inst);
|
||||||
|
|
||||||
delete cache_req->dataPkt;
|
delete cache_req->dataPkt;
|
||||||
//cache_req->setMemStall(false);
|
|
||||||
|
// Do not stall and switch threads for fetch... for now..
|
||||||
|
// TODO: We need to detect cache misses for latencies > 1
|
||||||
|
// cache_req->setMemStall(false);
|
||||||
|
|
||||||
cache_req->done();
|
cache_req->done();
|
||||||
} else {
|
} else {
|
||||||
DPRINTF(InOrderCachePort,
|
DPRINTF(InOrderCachePort,
|
||||||
|
@ -711,6 +728,7 @@ CacheUnit::execute(int slot_num)
|
||||||
if (cache_req->isMemAccComplete() ||
|
if (cache_req->isMemAccComplete() ||
|
||||||
inst->isDataPrefetch() ||
|
inst->isDataPrefetch() ||
|
||||||
inst->isInstPrefetch()) {
|
inst->isInstPrefetch()) {
|
||||||
|
removeAddrDependency(inst);
|
||||||
cache_req->setMemStall(false);
|
cache_req->setMemStall(false);
|
||||||
cache_req->done();
|
cache_req->done();
|
||||||
} else {
|
} else {
|
||||||
|
@ -729,6 +747,7 @@ CacheUnit::execute(int slot_num)
|
||||||
if (cache_req->isMemAccComplete() ||
|
if (cache_req->isMemAccComplete() ||
|
||||||
inst->isDataPrefetch() ||
|
inst->isDataPrefetch() ||
|
||||||
inst->isInstPrefetch()) {
|
inst->isInstPrefetch()) {
|
||||||
|
removeAddrDependency(inst);
|
||||||
cache_req->setMemStall(false);
|
cache_req->setMemStall(false);
|
||||||
cache_req->done();
|
cache_req->done();
|
||||||
} else {
|
} else {
|
||||||
|
@ -747,6 +766,7 @@ CacheUnit::execute(int slot_num)
|
||||||
if (cache_req->isMemAccComplete() ||
|
if (cache_req->isMemAccComplete() ||
|
||||||
inst->isDataPrefetch() ||
|
inst->isDataPrefetch() ||
|
||||||
inst->isInstPrefetch()) {
|
inst->isInstPrefetch()) {
|
||||||
|
removeAddrDependency(inst);
|
||||||
cache_req->setMemStall(false);
|
cache_req->setMemStall(false);
|
||||||
cache_req->done();
|
cache_req->done();
|
||||||
} else {
|
} else {
|
||||||
|
@ -911,6 +931,10 @@ CacheUnit::processCacheCompletion(PacketPtr pkt)
|
||||||
"Ignoring completion of squashed access, [tid:%i] [sn:%i]\n",
|
"Ignoring completion of squashed access, [tid:%i] [sn:%i]\n",
|
||||||
cache_pkt->cacheReq->getInst()->readTid(),
|
cache_pkt->cacheReq->getInst()->readTid(),
|
||||||
cache_pkt->cacheReq->getInst()->seqNum);
|
cache_pkt->cacheReq->getInst()->seqNum);
|
||||||
|
DPRINTF(RefCount,
|
||||||
|
"Ignoring completion of squashed access, [tid:%i] [sn:%i]\n",
|
||||||
|
cache_pkt->cacheReq->getTid(),
|
||||||
|
cache_pkt->cacheReq->seqNum);
|
||||||
|
|
||||||
cache_pkt->cacheReq->done();
|
cache_pkt->cacheReq->done();
|
||||||
delete cache_pkt;
|
delete cache_pkt;
|
||||||
|
@ -1154,6 +1178,14 @@ CacheUnit::squash(DynInstPtr inst, int stage_num,
|
||||||
"[tid:%i] Squashing request from [sn:%i]\n",
|
"[tid:%i] Squashing request from [sn:%i]\n",
|
||||||
req_ptr->getInst()->readTid(), req_ptr->getInst()->seqNum);
|
req_ptr->getInst()->readTid(), req_ptr->getInst()->seqNum);
|
||||||
|
|
||||||
|
if (req_ptr->isSquashed()) {
|
||||||
|
DPRINTF(AddrDep, "Request for [tid:%i] [sn:%i] already squashed, ignoring squash process.\n",
|
||||||
|
req_ptr->getInst()->readTid(),
|
||||||
|
req_ptr->getInst()->seqNum);
|
||||||
|
map_it++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
req_ptr->setSquashed();
|
req_ptr->setSquashed();
|
||||||
|
|
||||||
req_ptr->getInst()->setSquashed();
|
req_ptr->getInst()->setSquashed();
|
||||||
|
@ -1178,7 +1210,29 @@ CacheUnit::squash(DynInstPtr inst, int stage_num,
|
||||||
|
|
||||||
// Mark slot for removal from resource
|
// Mark slot for removal from resource
|
||||||
slot_remove_list.push_back(req_ptr->getSlot());
|
slot_remove_list.push_back(req_ptr->getSlot());
|
||||||
|
|
||||||
|
DPRINTF(InOrderCachePort,
|
||||||
|
"[tid:%i] Squashing request from [sn:%i]\n",
|
||||||
|
req_ptr->getInst()->readTid(), req_ptr->getInst()->seqNum);
|
||||||
|
} else {
|
||||||
|
DPRINTF(InOrderCachePort,
|
||||||
|
"[tid:%i] Request from [sn:%i] squashed, but still pending completion.\n",
|
||||||
|
req_ptr->getInst()->readTid(), req_ptr->getInst()->seqNum);
|
||||||
|
DPRINTF(RefCount,
|
||||||
|
"[tid:%i] Request from [sn:%i] squashed (split:%i), but still pending completion.\n",
|
||||||
|
req_ptr->getInst()->readTid(), req_ptr->getInst()->seqNum,
|
||||||
|
req_ptr->getInst()->splitInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req_ptr->getInst()->validMemAddr()) {
|
||||||
|
DPRINTF(AddrDep, "Squash of [tid:%i] [sn:%i], attempting to remove addr. %08p dependencies.\n",
|
||||||
|
req_ptr->getInst()->readTid(),
|
||||||
|
req_ptr->getInst()->seqNum,
|
||||||
|
req_ptr->getInst()->getMemAddr());
|
||||||
|
|
||||||
|
removeAddrDependency(req_ptr->getInst());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
map_it++;
|
map_it++;
|
||||||
|
@ -1320,3 +1374,4 @@ CacheUnit::write(DynInstPtr inst, int32_t data, Addr addr, unsigned flags,
|
||||||
{
|
{
|
||||||
return write(inst, (uint32_t)data, addr, flags, res);
|
return write(inst, (uint32_t)data, addr, flags, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,8 +135,6 @@ class CacheUnit : public Resource
|
||||||
|
|
||||||
int getSlot(DynInstPtr inst);
|
int getSlot(DynInstPtr inst);
|
||||||
|
|
||||||
void freeSlot(int slot_num);
|
|
||||||
|
|
||||||
/** Execute the function of this resource. The Default is action
|
/** Execute the function of this resource. The Default is action
|
||||||
* is to do nothing. More specific models will derive from this
|
* is to do nothing. More specific models will derive from this
|
||||||
* class and define their own execute function.
|
* class and define their own execute function.
|
||||||
|
@ -184,6 +182,9 @@ class CacheUnit : public Resource
|
||||||
|
|
||||||
uint64_t getMemData(Packet *packet);
|
uint64_t getMemData(Packet *packet);
|
||||||
|
|
||||||
|
void setAddrDependency(DynInstPtr inst);
|
||||||
|
void removeAddrDependency(DynInstPtr inst);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Cache interface. */
|
/** Cache interface. */
|
||||||
CachePort *cachePort;
|
CachePort *cachePort;
|
||||||
|
|
|
@ -79,8 +79,6 @@ GraduationUnit::execute(int slot_num)
|
||||||
"[tid:%i] Graduating instruction [sn:%i].\n",
|
"[tid:%i] Graduating instruction [sn:%i].\n",
|
||||||
tid, inst->seqNum);
|
tid, inst->seqNum);
|
||||||
|
|
||||||
DPRINTF(RefCount, "Refcount = %i.\n", 0/*inst->curCount()*/);
|
|
||||||
|
|
||||||
// Release Non-Speculative "Block" on instructions that could not execute
|
// Release Non-Speculative "Block" on instructions that could not execute
|
||||||
// because there was a non-speculative inst. active.
|
// because there was a non-speculative inst. active.
|
||||||
// @TODO: Fix this functionality. Probably too conservative.
|
// @TODO: Fix this functionality. Probably too conservative.
|
||||||
|
|
|
@ -191,6 +191,7 @@ UseDefUnit::execute(int slot_idx)
|
||||||
DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
|
DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
|
||||||
"[sn:%i] to write\n",
|
"[sn:%i] to write\n",
|
||||||
tid, outReadSeqNum[tid]);
|
tid, outReadSeqNum[tid]);
|
||||||
|
ud_req->done(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -249,6 +250,7 @@ UseDefUnit::execute(int slot_idx)
|
||||||
DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
|
DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
|
||||||
"[sn:%i] to forward\n",
|
"[sn:%i] to forward\n",
|
||||||
tid, outReadSeqNum[tid]);
|
tid, outReadSeqNum[tid]);
|
||||||
|
ud_req->done(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DPRINTF(InOrderUseDef, "[tid:%i]: Source register idx: %i"
|
DPRINTF(InOrderUseDef, "[tid:%i]: Source register idx: %i"
|
||||||
|
@ -258,6 +260,7 @@ UseDefUnit::execute(int slot_idx)
|
||||||
"register (idx=%i)\n",
|
"register (idx=%i)\n",
|
||||||
tid, reg_idx);
|
tid, reg_idx);
|
||||||
outReadSeqNum[tid] = inst->seqNum;
|
outReadSeqNum[tid] = inst->seqNum;
|
||||||
|
ud_req->done(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,6 +363,7 @@ UseDefUnit::execute(int slot_idx)
|
||||||
DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
|
DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
|
||||||
"[sn:%i] to read\n",
|
"[sn:%i] to read\n",
|
||||||
tid, outReadSeqNum);
|
tid, outReadSeqNum);
|
||||||
|
ud_req->done(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DPRINTF(InOrderUseDef, "[tid:%i]: Dest. register idx: %i is "
|
DPRINTF(InOrderUseDef, "[tid:%i]: Dest. register idx: %i is "
|
||||||
|
@ -369,6 +373,7 @@ UseDefUnit::execute(int slot_idx)
|
||||||
"register (idx=%i)\n",
|
"register (idx=%i)\n",
|
||||||
tid, reg_idx);
|
tid, reg_idx);
|
||||||
outWriteSeqNum[tid] = inst->seqNum;
|
outWriteSeqNum[tid] = inst->seqNum;
|
||||||
|
ud_req->done(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -402,12 +407,16 @@ UseDefUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
|
||||||
req_ptr->getInst()->readTid(),
|
req_ptr->getInst()->readTid(),
|
||||||
req_ptr->getInst()->seqNum);
|
req_ptr->getInst()->seqNum);
|
||||||
|
|
||||||
regDepMap[tid]->remove(req_ptr->getInst());
|
|
||||||
|
|
||||||
int req_slot_num = req_ptr->getSlot();
|
int req_slot_num = req_ptr->getSlot();
|
||||||
|
|
||||||
if (latency > 0)
|
if (latency > 0) {
|
||||||
|
assert(0);
|
||||||
|
|
||||||
unscheduleEvent(req_slot_num);
|
unscheduleEvent(req_slot_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark request for later removal
|
||||||
|
cpu->reqRemoveList.push(req_ptr);
|
||||||
|
|
||||||
// Mark slot for removal from resource
|
// Mark slot for removal from resource
|
||||||
slot_remove_list.push_back(req_ptr->getSlot());
|
slot_remove_list.push_back(req_ptr->getSlot());
|
||||||
|
|
Loading…
Reference in a new issue