summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2009-09-17 15:45:27 -0400
committerKorey Sewell <ksewell@umich.edu>2009-09-17 15:45:27 -0400
commit6f7e1961131250817f6b73f5ee8cf7902bb4bba0 (patch)
treede2498210293d075b11cafb5bd9fd535f360a067 /src
parent931405da2f8828c23463d83f0b77b551d633565c (diff)
downloadgem5-6f7e1961131250817f6b73f5ee8cf7902bb4bba0.tar.xz
inorder-mdu: multiplier latency fix
mdu was workign incorrectly for 4+ latency due to incorrectly assuming multiply was finished the next stage
Diffstat (limited to 'src')
-rw-r--r--src/cpu/inorder/resources/mult_div_unit.cc34
-rw-r--r--src/cpu/inorder/resources/mult_div_unit.hh2
2 files changed, 34 insertions, 2 deletions
diff --git a/src/cpu/inorder/resources/mult_div_unit.cc b/src/cpu/inorder/resources/mult_div_unit.cc
index 7592c0260..e7bd6750f 100644
--- a/src/cpu/inorder/resources/mult_div_unit.cc
+++ b/src/cpu/inorder/resources/mult_div_unit.cc
@@ -91,7 +91,32 @@ MultDivUnit::freeSlot(int slot_idx)
Resource::freeSlot(slot_idx);
}
-
+//@TODO: Should we push this behavior into base-class to generically
+// accomodate all multicyle resources?
+void
+MultDivUnit::requestAgain(DynInstPtr inst, bool &service_request)
+{
+ ResReqPtr mult_div_req = findRequest(inst);
+ assert(mult_div_req);
+
+ service_request = true;
+
+ // Check to see if this instruction is requesting the same command
+ // or a different one
+ if (mult_div_req->cmd != inst->resSched.top()->cmd) {
+ // If different, then update command in the request
+ mult_div_req->cmd = inst->resSched.top()->cmd;
+ DPRINTF(InOrderMDU,
+ "[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
+ // but dont try to re-execute
+ DPRINTF(InOrderMDU,
+ "[tid:%i]: [sn:%i]: requesting this resource again\n",
+ inst->readTid(), inst->seqNum);
+ }
+}
int
MultDivUnit::getSlot(DynInstPtr inst)
{
@@ -232,8 +257,13 @@ 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->getInst()->isExecuted()) {
+ DPRINTF(InOrderMDU, "Mult/Div finished.\n");
mult_div_req->done();
+ } else {
+ mult_div_req->setCompleted(false);
+ }
+
}
break;
diff --git a/src/cpu/inorder/resources/mult_div_unit.hh b/src/cpu/inorder/resources/mult_div_unit.hh
index 76180714c..d3dd0260d 100644
--- a/src/cpu/inorder/resources/mult_div_unit.hh
+++ b/src/cpu/inorder/resources/mult_div_unit.hh
@@ -82,6 +82,8 @@ class MultDivUnit : public Resource {
/** Register extra resource stats */
virtual void regStats();
+ void requestAgain(DynInstPtr inst, bool &try_request);
+
protected:
/** Latency & Repeat Rate for Multiply Insts */
unsigned multRepeatRate;