summaryrefslogtreecommitdiff
path: root/src/cpu/inorder
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/inorder')
-rw-r--r--src/cpu/inorder/pipeline_stage.cc20
-rw-r--r--src/cpu/inorder/resource.cc38
-rw-r--r--src/cpu/inorder/resource.hh4
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc26
-rw-r--r--src/cpu/inorder/resources/fetch_seq_unit.cc2
-rw-r--r--src/cpu/inorder/resources/fetch_unit.cc7
6 files changed, 71 insertions, 26 deletions
diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc
index 610b6f264..15f143251 100644
--- a/src/cpu/inorder/pipeline_stage.cc
+++ b/src/cpu/inorder/pipeline_stage.cc
@@ -940,7 +940,9 @@ PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed)
ResReqPtr req = cpu->resPool->request(res_num, inst);
assert(req->valid);
- if (req->isCompleted()) {
+ bool req_completed = req->isCompleted();
+ bool done_in_pipeline = false;
+ if (req_completed) {
DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s "
"completed.\n", tid, inst->seqNum,
cpu->resPool->name(res_num));
@@ -949,11 +951,10 @@ PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed)
req->stagePasses++;
- bool done_in_pipeline = inst->finishSkedEntry();
+ done_in_pipeline = inst->finishSkedEntry();
if (done_in_pipeline) {
DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] finished "
"in pipeline.\n", tid, inst->seqNum);
- break;
}
} else {
DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s failed."
@@ -990,7 +991,18 @@ PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed)
"thread due to cache miss.\n");
cpu->activateNextReadyContext();
}
-
+ }
+
+ // If this request is no longer needs to take up bandwidth in the
+ // resource, go ahead and free that bandwidth up
+ if (req->doneInResource) {
+ req->freeSlot();
+ }
+
+ // No longer need to process this instruction if the last
+ // request it had wasn't completed or if there is nothing
+ // else for it to do in the pipeline
+ if (done_in_pipeline || !req_completed) {
break;
}
diff --git a/src/cpu/inorder/resource.cc b/src/cpu/inorder/resource.cc
index 757c17e6a..076084d16 100644
--- a/src/cpu/inorder/resource.cc
+++ b/src/cpu/inorder/resource.cc
@@ -44,6 +44,7 @@ Resource::Resource(string res_name, int res_id, int res_width,
// Use to deny a instruction a resource.
deniedReq = new ResourceRequest(this);
+ deniedReq->valid = true;
}
Resource::~Resource()
@@ -97,6 +98,9 @@ Resource::slotsInUse()
void
Resource::freeSlot(int slot_idx)
{
+ DPRINTF(Resource, "Deallocating [slot:%i].\n",
+ slot_idx);
+
// Put slot number on this resource's free list
availSlots.push_back(slot_idx);
@@ -160,6 +164,9 @@ Resource::request(DynInstPtr inst)
slot_num = getSlot(inst);
if (slot_num != -1) {
+ DPRINTF(Resource, "Allocating [slot:%i] for [tid:%i]: [sn:%i]\n",
+ slot_num, inst->readTid(), inst->seqNum);
+
// Get Stage # from Schedule Entry
stage_num = inst->curSkedEntry->stageNum;
unsigned cmd = inst->curSkedEntry->cmd;
@@ -177,10 +184,12 @@ Resource::request(DynInstPtr inst)
inst->readTid());
}
- reqs[slot_num] = inst_req;
-
try_request = true;
+ } else {
+ DPRINTF(Resource, "No slot available for [tid:%i]: [sn:%i]\n",
+ inst->readTid(), inst->seqNum);
}
+
}
if (try_request) {
@@ -352,8 +361,9 @@ int ResourceRequest::resReqID = 0;
int ResourceRequest::maxReqCount = 0;
ResourceRequest::ResourceRequest(Resource *_res)
- : res(_res), inst(NULL), stagePasses(0), valid(false), complSlotNum(-1),
- completed(false), squashed(false), processing(false), memStall(false)
+ : res(_res), inst(NULL), stagePasses(0), valid(false), doneInResource(false),
+ complSlotNum(-1), completed(false), squashed(false), processing(false),
+ memStall(false)
{
}
@@ -384,6 +394,19 @@ ResourceRequest::clearRequest()
valid = false;
inst = NULL;
stagePasses = 0;
+ completed = false;
+ doneInResource = false;
+ squashed = false;
+ memStall = false;
+}
+
+void
+ResourceRequest::freeSlot()
+{
+ assert(res);
+
+ // Free Slot So Another Instruction Can Use This Resource
+ res->freeSlot(slotNum);
}
void
@@ -399,13 +422,8 @@ ResourceRequest::done(bool completed)
if (completed) {
complSlotNum = slotNum;
}
-
- // Free Slot So Another Instruction Can Use This Resource
- res->freeSlot(slotNum);
- // change slot # to -1, since we check slotNum to see if request is
- // still valid
- slotNum = -1;
+ doneInResource = true;
}
ResourceEvent::ResourceEvent()
diff --git a/src/cpu/inorder/resource.hh b/src/cpu/inorder/resource.hh
index c40314c94..fc16df099 100644
--- a/src/cpu/inorder/resource.hh
+++ b/src/cpu/inorder/resource.hh
@@ -318,6 +318,8 @@ class ResourceRequest
*/
void done(bool completed = true);
+ void freeSlot();
+
/////////////////////////////////////////////
//
// GET RESOURCE REQUEST IDENTIFICATION / INFO
@@ -362,6 +364,8 @@ class ResourceRequest
bool valid;
+ bool doneInResource;
+
////////////////////////////////////////
//
// GET RESOURCE REQUEST STATUS FROM VARIABLES
diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc
index 4deb32992..a734f1ebd 100644
--- a/src/cpu/inorder/resources/cache_unit.cc
+++ b/src/cpu/inorder/resources/cache_unit.cc
@@ -667,13 +667,16 @@ CacheUnit::execute(int slot_num)
CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(reqs[slot_num]);
assert(cache_req);
- if (cachePortBlocked) {
+ if (cachePortBlocked &&
+ (cache_req->cmd == InitiateReadData ||
+ cache_req->cmd == InitiateWriteData ||
+ cache_req->cmd == InitSecondSplitRead ||
+ cache_req->cmd == InitSecondSplitWrite)) {
DPRINTF(InOrderCachePort, "Cache Port Blocked. Cannot Access\n");
- cache_req->setCompleted(false);
+ cache_req->done(false);
return;
}
-
DynInstPtr inst = cache_req->inst;
#if TRACING_ON
ThreadID tid = inst->readTid();
@@ -690,7 +693,12 @@ CacheUnit::execute(int slot_num)
acc_type = "read";
#endif
case InitiateWriteData:
-
+ if (cachePortBlocked) {
+ DPRINTF(InOrderCachePort, "Cache Port Blocked. Cannot Access\n");
+ cache_req->done(false);
+ return;
+ }
+
DPRINTF(InOrderCachePort,
"[tid:%u]: [sn:%i] Initiating data %s access to %s for "
"addr. %08p\n", tid, inst->seqNum, acc_type, name(),
@@ -864,7 +872,7 @@ CacheUnit::doCacheAccess(DynInstPtr inst, uint64_t *write_res,
"[tid:%i] [sn:%i] cannot access cache, because port "
"is blocked. now waiting to retry request\n", tid,
inst->seqNum);
- cache_req->setCompleted(false);
+ cache_req->done(false);
cachePortBlocked = true;
} else {
DPRINTF(InOrderCachePort,
@@ -888,7 +896,7 @@ CacheUnit::doCacheAccess(DynInstPtr inst, uint64_t *write_res,
// Make cache request again since access due to
// inability to access
DPRINTF(InOrderStall, "STALL: \n");
- cache_req->setCompleted(false);
+ cache_req->done(false);
}
}
@@ -911,7 +919,7 @@ CacheUnit::processCacheCompletion(PacketPtr pkt)
cache_pkt->cacheReq->getTid(),
cache_pkt->cacheReq->seqNum);
- cache_pkt->cacheReq->done();
+ cache_pkt->cacheReq->freeSlot();
delete cache_pkt;
cpu->wakeCPU();
@@ -1075,8 +1083,10 @@ CacheUnitEvent::process()
req_ptr->tlbStall = false;
if (req_ptr->isSquashed()) {
- req_ptr->done();
+ req_ptr->freeSlot();
}
+
+ tlb_res->cpu->wakeCPU();
}
void
diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc
index 08d162b07..d23ea0a82 100644
--- a/src/cpu/inorder/resources/fetch_seq_unit.cc
+++ b/src/cpu/inorder/resources/fetch_seq_unit.cc
@@ -100,7 +100,7 @@ FetchSeqUnit::execute(int slot_num)
fs_req->done();
} else {
DPRINTF(InOrderStall, "STALL: [tid:%i]: NPC not valid\n", tid);
- fs_req->setCompleted(false);
+ fs_req->done(false);
}
}
break;
diff --git a/src/cpu/inorder/resources/fetch_unit.cc b/src/cpu/inorder/resources/fetch_unit.cc
index dd875efdb..40f2f4ee4 100644
--- a/src/cpu/inorder/resources/fetch_unit.cc
+++ b/src/cpu/inorder/resources/fetch_unit.cc
@@ -208,9 +208,9 @@ FetchUnit::execute(int slot_num)
CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(reqs[slot_num]);
assert(cache_req);
- if (cachePortBlocked) {
+ if (cachePortBlocked && cache_req->cmd == InitiateFetch) {
DPRINTF(InOrderCachePort, "Cache Port Blocked. Cannot Access\n");
- cache_req->setCompleted(false);
+ cache_req->done(false);
return;
}
@@ -261,7 +261,7 @@ FetchUnit::execute(int slot_num)
// If not, block this request.
if (pendingFetch.size() >= fetchBuffSize) {
DPRINTF(InOrderCachePort, "No room available in fetch buffer.\n");
- cache_req->setCompleted(false);
+ cache_req->done();
return;
}
@@ -405,6 +405,7 @@ FetchUnit::processCacheCompletion(PacketPtr pkt)
cache_pkt->cacheReq->seqNum);
cache_pkt->cacheReq->done();
+ cache_pkt->cacheReq->freeSlot();
delete cache_pkt;
cpu->wakeCPU();