summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:38 -0400
committerKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:38 -0400
commitc95fe261abab85bee247737a3d171378689891e0 (patch)
tree75569e5baa06a7bd25870505a48a3ddf24916475
parent4c979f9325f0c82f3284ce0fb0cc118d77268cb5 (diff)
downloadgem5-c95fe261abab85bee247737a3d171378689891e0.tar.xz
inorder: bug in mdu
segfault was caused by squashed multiply thats in the process of an event. use isProcessing flag to handle this and cleanup the MDU code
-rw-r--r--src/cpu/inorder/resource.cc6
-rw-r--r--src/cpu/inorder/resource.hh2
-rw-r--r--src/cpu/inorder/resource_pool.cc5
-rw-r--r--src/cpu/inorder/resources/mult_div_unit.cc123
-rw-r--r--src/cpu/inorder/resources/mult_div_unit.hh7
5 files changed, 83 insertions, 60 deletions
diff --git a/src/cpu/inorder/resource.cc b/src/cpu/inorder/resource.cc
index 8d3f3daac..a21536676 100644
--- a/src/cpu/inorder/resource.cc
+++ b/src/cpu/inorder/resource.cc
@@ -297,16 +297,18 @@ Resource::setupSquash(DynInstPtr inst, int stage_num, ThreadID tid)
cpu->resPool->scheduleEvent(
(InOrderCPU::CPUEventType)ResourcePool::SquashAll, inst, 0);
}
+
void
Resource::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
ThreadID tid)
{
for (int i = 0; i < width; i++) {
ResReqPtr req_ptr = reqs[i];
+ DynInstPtr inst = req_ptr->getInst();
if (req_ptr->valid &&
- req_ptr->getInst()->readTid() == tid &&
- req_ptr->getInst()->seqNum > squash_seq_num) {
+ inst->readTid() == tid &&
+ inst->seqNum > squash_seq_num) {
DPRINTF(Resource, "[tid:%i]: Squashing [sn:%i].\n",
req_ptr->getInst()->readTid(),
diff --git a/src/cpu/inorder/resource.hh b/src/cpu/inorder/resource.hh
index fcf01065a..91d144a64 100644
--- a/src/cpu/inorder/resource.hh
+++ b/src/cpu/inorder/resource.hh
@@ -389,7 +389,7 @@ class ResourceRequest
/** Get/Set IsProcessing variables */
bool isProcessing() { return processing; }
- void setProcessing() { processing = true; }
+ void setProcessing(bool cond = true) { processing = cond; }
/** Get/Set IsWaiting variables */
bool isMemStall() { return memStall; }
diff --git a/src/cpu/inorder/resource_pool.cc b/src/cpu/inorder/resource_pool.cc
index a8a26f51e..0e89a7650 100644
--- a/src/cpu/inorder/resource_pool.cc
+++ b/src/cpu/inorder/resource_pool.cc
@@ -79,7 +79,10 @@ ResourcePool::ResourcePool(InOrderCPU *_cpu, ThePipeline::Params *params)
stage_width, 0, _cpu, params));
resources.push_back(new MultDivUnit("mult_div_unit", MDU,
- stage_width * 2, 0, _cpu, params));
+ stage_width * 2,
+ 0,
+ _cpu,
+ params));
memObjects.push_back(DCache);
resources.push_back(new CacheUnit("dcache_port", DCache,
diff --git a/src/cpu/inorder/resources/mult_div_unit.cc b/src/cpu/inorder/resources/mult_div_unit.cc
index 49df901e3..fc27276d5 100644
--- a/src/cpu/inorder/resources/mult_div_unit.cc
+++ b/src/cpu/inorder/resources/mult_div_unit.cc
@@ -86,25 +86,6 @@ MultDivUnit::init()
initSlots();
}
-int
-MultDivUnit::findSlot(DynInstPtr inst)
-{
- DPRINTF(InOrderMDU, "Finding slot for inst:%i\n | slots-free:%i | "
- "slots-used:%i\n", inst->seqNum, slotsAvail(), slotsInUse());
-
- return Resource::findSlot(inst);
-}
-
-void
-MultDivUnit::freeSlot(int slot_idx)
-{
- DPRINTF(InOrderMDU, "Freeing slot for inst:%i\n | slots-free:%i | "
- "slots-used:%i\n", reqs[slot_idx]->getInst()->seqNum,
- slotsAvail(), slotsInUse());
-
- Resource::freeSlot(slot_idx);
-}
-
//@TODO: Should we push this behavior into base-class to generically
// accomodate all multicyle resources?
void
@@ -124,7 +105,7 @@ MultDivUnit::requestAgain(DynInstPtr inst, bool &service_request)
"[tid:%i]: [sn:%i]: Updating the command for this "
"instruction\n", inst->readTid(), inst->seqNum);
} else {
- // If same command, just check to see if memory access was completed
+ // If same command, just check to see if access was completed
// but dont try to re-execute
DPRINTF(InOrderMDU,
"[tid:%i]: [sn:%i]: requesting this resource again\n",
@@ -212,41 +193,47 @@ MultDivUnit::execute(int slot_num)
ResourceRequest* mult_div_req = reqs[slot_num];
DynInstPtr inst = reqs[slot_num]->inst;
+ DPRINTF(InOrderMDU, "Executing [sn:%i] ...\n", slot_num);
+
switch (mult_div_req->cmd)
{
case StartMultDiv:
- DPRINTF(InOrderMDU, "Start MDU called ...\n");
-
- if (inst->opClass() == IntMultOp) {
- scheduleEvent(slot_num, multLatency);
- } else if (inst->opClass() == IntDivOp) {
- int op_size = getDivOpSize(inst);
-
- switch (op_size)
- {
- case 8:
- scheduleEvent(slot_num, div8Latency);
- break;
-
- case 16:
- scheduleEvent(slot_num, div16Latency);
- break;
-
- case 24:
- scheduleEvent(slot_num, div24Latency);
- break;
-
- case 32:
- scheduleEvent(slot_num, div32Latency);
- break;
+ {
+ DPRINTF(InOrderMDU, "Start MDU called ...\n");
+
+ OpClass op_class = inst->opClass();
+ if (op_class == IntMultOp) {
+ scheduleEvent(slot_num, multLatency);
+ } else if (op_class == IntDivOp) {
+ int op_size = getDivOpSize(inst);
+
+ switch (op_size)
+ {
+ case 8:
+ scheduleEvent(slot_num, div8Latency);
+ break;
+
+ case 16:
+ scheduleEvent(slot_num, div16Latency);
+ break;
+
+ case 24:
+ scheduleEvent(slot_num, div24Latency);
+ break;
+
+ case 32:
+ scheduleEvent(slot_num, div32Latency);
+ break;
+ }
+
+ lastDivSize = op_size;
}
- lastDivSize = op_size;
+ // Allow to pass through to next stage while
+ // event processes
+ mult_div_req->setProcessing();
+ mult_div_req->setCompleted();
}
-
- // Allow to pass through to next stage while
- // event processes
- mult_div_req->setCompleted();
break;
case MultDiv:
@@ -264,7 +251,7 @@ MultDivUnit::execute(int slot_num)
// counting down the time
{
DPRINTF(InOrderMDU, "End MDU called ...\n");
- if (mult_div_req->getInst()->isExecuted()) {
+ if (!mult_div_req->isProcessing()) {
DPRINTF(InOrderMDU, "Mult/Div finished.\n");
mult_div_req->done();
} else {
@@ -295,7 +282,6 @@ MultDivUnit::exeMulDiv(int slot_num)
if (inst->fault == NoFault) {
inst->setExecuted();
- mult_div_req->setCompleted();
DPRINTF(InOrderMDU, "[tid:%i]: The result of execution is 0x%x.\n",
inst->readTid(), inst->readIntResult(0));
@@ -303,8 +289,40 @@ MultDivUnit::exeMulDiv(int slot_num)
DPRINTF(InOrderMDU, "[tid:%i]: [sn:%i]: had a %s "
"fault.\n", inst->readTid(), inst->seqNum, inst->fault->name());
}
+
+ mult_div_req->setProcessing(false);
}
+void
+MultDivUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
+ ThreadID tid)
+{
+ for (int i = 0; i < width; i++) {
+ ResReqPtr req_ptr = reqs[i];
+ DynInstPtr inst = req_ptr->getInst();
+
+ if (req_ptr->valid &&
+ inst->readTid() == tid &&
+ inst->seqNum > squash_seq_num) {
+
+ DPRINTF(InOrderMDU, "[tid:%i]: Squashing [sn:%i].\n",
+ req_ptr->getInst()->readTid(),
+ req_ptr->getInst()->seqNum);
+
+ req_ptr->setSquashed();
+
+ int req_slot_num = req_ptr->getSlot();
+
+ if (req_ptr->isProcessing())
+ DPRINTF(InOrderMDU, "[tid:%i]: Squashed [sn:%i], but "
+ "waiting for MDU operation to complete.\n",
+ req_ptr->getInst()->readTid(),
+ req_ptr->getInst()->seqNum);
+ else
+ freeSlot(req_slot_num);
+ }
+ }
+}
MDUEvent::MDUEvent()
: ResourceEvent()
@@ -319,7 +337,8 @@ MDUEvent::process()
ResourceRequest* mult_div_req = resource->reqs[slotIdx];
- mult_div_req->done();
+ if (mult_div_req->isSquashed())
+ mdu_res->freeSlot(slotIdx);
}
diff --git a/src/cpu/inorder/resources/mult_div_unit.hh b/src/cpu/inorder/resources/mult_div_unit.hh
index 753bc64a6..7d179bdce 100644
--- a/src/cpu/inorder/resources/mult_div_unit.hh
+++ b/src/cpu/inorder/resources/mult_div_unit.hh
@@ -64,10 +64,6 @@ class MultDivUnit : public Resource {
* valid mult/div sequence is being maintained
*/
int getSlot(DynInstPtr inst);
-
- int findSlot(DynInstPtr inst);
-
- void freeSlot(int slot_idx);
void init();
@@ -84,6 +80,9 @@ class MultDivUnit : public Resource {
void requestAgain(DynInstPtr inst, bool &try_request);
+ void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
+ ThreadID tid);
+
protected:
/** Latency & Repeat Rate for Multiply Insts */
unsigned multRepeatRate;