summaryrefslogtreecommitdiff
path: root/src/cpu/inorder/resources
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/inorder/resources')
-rw-r--r--src/cpu/inorder/resources/agen_unit.cc4
-rw-r--r--src/cpu/inorder/resources/branch_predictor.cc2
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc161
-rw-r--r--src/cpu/inorder/resources/cache_unit.hh47
-rw-r--r--src/cpu/inorder/resources/decode_unit.cc11
-rw-r--r--src/cpu/inorder/resources/execution_unit.cc47
-rw-r--r--src/cpu/inorder/resources/execution_unit.hh1
-rw-r--r--src/cpu/inorder/resources/fetch_seq_unit.cc8
-rw-r--r--src/cpu/inorder/resources/fetch_unit.cc71
-rw-r--r--src/cpu/inorder/resources/fetch_unit.hh2
-rw-r--r--src/cpu/inorder/resources/graduation_unit.cc22
-rw-r--r--src/cpu/inorder/resources/graduation_unit.hh4
-rw-r--r--src/cpu/inorder/resources/inst_buffer.cc15
-rw-r--r--src/cpu/inorder/resources/inst_buffer_new.cc158
-rw-r--r--src/cpu/inorder/resources/inst_buffer_new.hh109
-rw-r--r--src/cpu/inorder/resources/mult_div_unit.cc22
-rw-r--r--src/cpu/inorder/resources/tlb_unit.cc56
-rw-r--r--src/cpu/inorder/resources/tlb_unit.hh15
-rw-r--r--src/cpu/inorder/resources/use_def.cc65
-rw-r--r--src/cpu/inorder/resources/use_def.hh18
20 files changed, 332 insertions, 506 deletions
diff --git a/src/cpu/inorder/resources/agen_unit.cc b/src/cpu/inorder/resources/agen_unit.cc
index f1862b94a..764cd9446 100644
--- a/src/cpu/inorder/resources/agen_unit.cc
+++ b/src/cpu/inorder/resources/agen_unit.cc
@@ -50,8 +50,8 @@ AGENUnit::regStats()
void
AGENUnit::execute(int slot_num)
{
- ResourceRequest* agen_req = reqMap[slot_num];
- DynInstPtr inst = reqMap[slot_num]->inst;
+ ResourceRequest* agen_req = reqs[slot_num];
+ DynInstPtr inst = reqs[slot_num]->inst;
#if TRACING_ON
ThreadID tid = inst->readTid();
#endif
diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc
index 8ca5a9718..5a22e40eb 100644
--- a/src/cpu/inorder/resources/branch_predictor.cc
+++ b/src/cpu/inorder/resources/branch_predictor.cc
@@ -66,7 +66,7 @@ BranchPredictor::execute(int slot_num)
{
// After this is working, change this to a reinterpret cast
// for performance considerations
- ResourceRequest* bpred_req = reqMap[slot_num];
+ ResourceRequest* bpred_req = reqs[slot_num];
DynInstPtr inst = bpred_req->inst;
ThreadID tid = inst->readTid();
int seq_num = inst->seqNum;
diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc
index 8b4dd4402..b17e5b3da 100644
--- a/src/cpu/inorder/resources/cache_unit.cc
+++ b/src/cpu/inorder/resources/cache_unit.cc
@@ -133,6 +133,10 @@ CacheUnit::getPort(const string &if_name, int idx)
void
CacheUnit::init()
{
+ for (int i = 0; i < width; i++) {
+ reqs[i] = new CacheRequest(this);
+ }
+
// Currently Used to Model TLB Latency. Eventually
// Switch to Timing TLB translations.
resourceEvent = new CacheUnitEvent[width];
@@ -250,20 +254,16 @@ CacheUnit::removeAddrDependency(DynInstPtr inst)
ResReqPtr
CacheUnit::findRequest(DynInstPtr inst)
{
- map<int, ResReqPtr>::iterator map_it = reqMap.begin();
- map<int, ResReqPtr>::iterator map_end = reqMap.end();
-
- while (map_it != map_end) {
+ for (int i = 0; i < width; i++) {
CacheRequest* cache_req =
- dynamic_cast<CacheRequest*>((*map_it).second);
+ dynamic_cast<CacheRequest*>(reqs[i]);
assert(cache_req);
- if (cache_req &&
+ if (cache_req->valid &&
cache_req->getInst() == inst &&
- cache_req->instIdx == inst->resSched.top()->idx) {
+ cache_req->instIdx == inst->curSkedEntry->idx) {
return cache_req;
}
- map_it++;
}
return NULL;
@@ -272,20 +272,16 @@ CacheUnit::findRequest(DynInstPtr inst)
ResReqPtr
CacheUnit::findRequest(DynInstPtr inst, int idx)
{
- map<int, ResReqPtr>::iterator map_it = reqMap.begin();
- map<int, ResReqPtr>::iterator map_end = reqMap.end();
-
- while (map_it != map_end) {
+ for (int i = 0; i < width; i++) {
CacheRequest* cache_req =
- dynamic_cast<CacheRequest*>((*map_it).second);
+ dynamic_cast<CacheRequest*>(reqs[i]);
assert(cache_req);
- if (cache_req &&
+ if (cache_req->valid &&
cache_req->getInst() == inst &&
cache_req->instIdx == idx) {
return cache_req;
}
- map_it++;
}
return NULL;
@@ -296,7 +292,8 @@ ResReqPtr
CacheUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
int slot_num, unsigned cmd)
{
- ScheduleEntry* sched_entry = inst->resSched.top();
+ ScheduleEntry* sched_entry = *inst->curSkedEntry;
+ CacheRequest* cache_req = dynamic_cast<CacheRequest*>(reqs[slot_num]);
if (!inst->validMemAddr()) {
panic("Mem. Addr. must be set before requesting cache access\n");
@@ -343,10 +340,10 @@ CacheUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
sched_entry->cmd, name());
}
- return new CacheRequest(this, inst, stage_num, id, slot_num,
- sched_entry->cmd, 0, pkt_cmd,
- 0/*flags*/, this->cpu->readCpuId(),
- inst->resSched.top()->idx);
+ cache_req->setRequest(inst, stage_num, id, slot_num,
+ sched_entry->cmd, pkt_cmd,
+ inst->curSkedEntry->idx);
+ return cache_req;
}
void
@@ -357,17 +354,17 @@ CacheUnit::requestAgain(DynInstPtr inst, bool &service_request)
// Check to see if this instruction is requesting the same command
// or a different one
- if (cache_req->cmd != inst->resSched.top()->cmd &&
- cache_req->instIdx == inst->resSched.top()->idx) {
+ if (cache_req->cmd != inst->curSkedEntry->cmd &&
+ cache_req->instIdx == inst->curSkedEntry->idx) {
// If different, then update command in the request
- cache_req->cmd = inst->resSched.top()->cmd;
+ cache_req->cmd = inst->curSkedEntry->cmd;
DPRINTF(InOrderCachePort,
"[tid:%i]: [sn:%i]: Updating the command for this "
"instruction\n ", inst->readTid(), inst->seqNum);
service_request = true;
- } else if (inst->resSched.top()->idx != CacheUnit::InitSecondSplitRead &&
- inst->resSched.top()->idx != CacheUnit::InitSecondSplitWrite) {
+ } else if (inst->curSkedEntry->idx != CacheUnit::InitSecondSplitRead &&
+ inst->curSkedEntry->idx != CacheUnit::InitSecondSplitWrite) {
// If same command, just check to see if memory access was completed
// but dont try to re-execute
DPRINTF(InOrderCachePort,
@@ -487,14 +484,20 @@ CacheUnit::read(DynInstPtr inst, Addr addr,
inst->splitMemData = new uint8_t[size];
if (!inst->splitInstSked) {
+ assert(0 && "Split Requests Not Supported for Now...");
+
// Schedule Split Read/Complete for Instruction
// ==============================
int stage_num = cache_req->getStageNum();
-
- int stage_pri = ThePipeline::getNextPriority(inst, stage_num);
+ RSkedPtr inst_sked = (stage_num >= ThePipeline::BackEndStartStage) ?
+ inst->backSked : inst->frontSked;
+
+ // this is just an arbitrarily high priority to ensure that this
+ // gets pushed to the back of the list
+ int stage_pri = 20;
int isplit_cmd = CacheUnit::InitSecondSplitRead;
- inst->resSched.push(new
+ inst_sked->push(new
ScheduleEntry(stage_num,
stage_pri,
cpu->resPool->getResIdx(DCache),
@@ -502,7 +505,7 @@ CacheUnit::read(DynInstPtr inst, Addr addr,
1));
int csplit_cmd = CacheUnit::CompleteSecondSplitRead;
- inst->resSched.push(new
+ inst_sked->push(new
ScheduleEntry(stage_num + 1,
1/*stage_pri*/,
cpu->resPool->getResIdx(DCache),
@@ -590,27 +593,33 @@ CacheUnit::write(DynInstPtr inst, uint8_t *data, unsigned size,
inst->splitInst = true;
if (!inst->splitInstSked) {
+ assert(0 && "Split Requests Not Supported for Now...");
+
// Schedule Split Read/Complete for Instruction
// ==============================
int stage_num = cache_req->getStageNum();
+ RSkedPtr inst_sked = (stage_num >= ThePipeline::BackEndStartStage) ?
+ inst->backSked : inst->frontSked;
- int stage_pri = ThePipeline::getNextPriority(inst, stage_num);
+ // this is just an arbitrarily high priority to ensure that this
+ // gets pushed to the back of the list
+ int stage_pri = 20;
int isplit_cmd = CacheUnit::InitSecondSplitWrite;
- inst->resSched.push(new
- ScheduleEntry(stage_num,
- stage_pri,
- cpu->resPool->getResIdx(DCache),
- isplit_cmd,
- 1));
+ inst_sked->push(new
+ ScheduleEntry(stage_num,
+ stage_pri,
+ cpu->resPool->getResIdx(DCache),
+ isplit_cmd,
+ 1));
int csplit_cmd = CacheUnit::CompleteSecondSplitWrite;
- inst->resSched.push(new
- ScheduleEntry(stage_num + 1,
- 1/*stage_pri*/,
- cpu->resPool->getResIdx(DCache),
- csplit_cmd,
- 1));
+ inst_sked->push(new
+ ScheduleEntry(stage_num + 1,
+ 1/*stage_pri*/,
+ cpu->resPool->getResIdx(DCache),
+ csplit_cmd,
+ 1));
inst->splitInstSked = true;
} else {
DPRINTF(InOrderCachePort, "[tid:%i] sn:%i] Retrying Split Read "
@@ -639,8 +648,6 @@ CacheUnit::write(DynInstPtr inst, uint8_t *data, unsigned size,
if (inst->fault == NoFault) {
if (!cache_req->splitAccess) {
- // Remove this line since storeData is saved in INST?
- cache_req->reqData = new uint8_t[size];
doCacheAccess(inst, write_res);
} else {
doCacheAccess(inst, write_res, cache_req);
@@ -655,16 +662,19 @@ CacheUnit::write(DynInstPtr inst, uint8_t *data, unsigned size,
void
CacheUnit::execute(int slot_num)
{
- CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(reqMap[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();
@@ -681,7 +691,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(),
@@ -796,7 +811,7 @@ CacheUnit::doCacheAccess(DynInstPtr inst, uint64_t *write_res,
CacheReqPtr cache_req;
if (split_req == NULL) {
- cache_req = dynamic_cast<CacheReqPtr>(reqMap[inst->getCurResSlot()]);
+ cache_req = dynamic_cast<CacheReqPtr>(reqs[inst->getCurResSlot()]);
} else{
cache_req = split_req;
}
@@ -855,7 +870,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,
@@ -879,7 +894,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);
}
}
@@ -902,7 +917,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();
@@ -1047,10 +1062,10 @@ CacheUnitEvent::CacheUnitEvent()
void
CacheUnitEvent::process()
{
- DynInstPtr inst = resource->reqMap[slotIdx]->inst;
- int stage_num = resource->reqMap[slotIdx]->getStageNum();
+ DynInstPtr inst = resource->reqs[slotIdx]->inst;
+ int stage_num = resource->reqs[slotIdx]->getStageNum();
ThreadID tid = inst->threadNumber;
- CacheReqPtr req_ptr = dynamic_cast<CacheReqPtr>(resource->reqMap[slotIdx]);
+ CacheReqPtr req_ptr = dynamic_cast<CacheReqPtr>(resource->reqs[slotIdx]);
DPRINTF(InOrderTLB, "Waking up from TLB Miss caused by [sn:%i].\n",
inst->seqNum);
@@ -1061,13 +1076,15 @@ CacheUnitEvent::process()
tlb_res->tlbBlocked[tid] = false;
tlb_res->cpu->pipelineStage[stage_num]->
- unsetResStall(tlb_res->reqMap[slotIdx], tid);
+ unsetResStall(tlb_res->reqs[slotIdx], tid);
req_ptr->tlbStall = false;
if (req_ptr->isSquashed()) {
- req_ptr->done();
+ req_ptr->freeSlot();
}
+
+ tlb_res->cpu->wakeCPU();
}
void
@@ -1112,15 +1129,10 @@ void
CacheUnit::squash(DynInstPtr inst, int stage_num,
InstSeqNum squash_seq_num, ThreadID tid)
{
- vector<int> slot_remove_list;
-
- map<int, ResReqPtr>::iterator map_it = reqMap.begin();
- map<int, ResReqPtr>::iterator map_end = reqMap.end();
-
- while (map_it != map_end) {
- ResReqPtr req_ptr = (*map_it).second;
+ for (int i = 0; i < width; i++) {
+ ResReqPtr req_ptr = reqs[i];
- if (req_ptr &&
+ if (req_ptr->valid &&
req_ptr->getInst()->readTid() == tid &&
req_ptr->getInst()->seqNum > squash_seq_num) {
@@ -1133,7 +1145,6 @@ CacheUnit::squash(DynInstPtr inst, int stage_num,
"squashed, ignoring squash process.\n",
req_ptr->getInst()->readTid(),
req_ptr->getInst()->seqNum);
- map_it++;
continue;
}
@@ -1147,18 +1158,14 @@ CacheUnit::squash(DynInstPtr inst, int stage_num,
if (cache_req->tlbStall) {
tlbBlocked[tid] = false;
- int stall_stage = reqMap[req_slot_num]->getStageNum();
+ int stall_stage = reqs[req_slot_num]->getStageNum();
cpu->pipelineStage[stall_stage]->
- unsetResStall(reqMap[req_slot_num], tid);
+ unsetResStall(reqs[req_slot_num], tid);
}
if (!cache_req->tlbStall && !cache_req->isMemAccPending()) {
- // Mark request for later removal
- cpu->reqRemoveList.push(req_ptr);
-
- // Mark slot for removal from resource
- slot_remove_list.push_back(req_ptr->getSlot());
+ freeSlot(req_slot_num);
} else {
DPRINTF(InOrderCachePort,
"[tid:%i] Request from [sn:%i] squashed, but still "
@@ -1170,14 +1177,8 @@ CacheUnit::squash(DynInstPtr inst, int stage_num,
req_ptr->getInst()->readTid(), req_ptr->getInst()->seqNum,
req_ptr->getInst()->splitInst);
}
-
}
-
- map_it++;
}
- // Now Delete Slot Entry from Req. Map
- for (int i = 0; i < slot_remove_list.size(); i++)
- freeSlot(slot_remove_list[i]);
}
diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh
index afcb36a24..097b6fa7a 100644
--- a/src/cpu/inorder/resources/cache_unit.hh
+++ b/src/cpu/inorder/resources/cache_unit.hh
@@ -219,20 +219,18 @@ class CacheUnitEvent : public ResourceEvent {
void process();
};
+//@todo: Move into CacheUnit Class for private access to "valid" field
class CacheRequest : public ResourceRequest
{
public:
- CacheRequest(CacheUnit *cres, DynInstPtr inst, int stage_num, int res_idx,
- int slot_num, unsigned cmd, int req_size,
- MemCmd::Command pkt_cmd, unsigned flags, int cpu_id, int idx)
- : ResourceRequest(cres, inst, stage_num, res_idx, slot_num, cmd),
- pktCmd(pkt_cmd), memReq(NULL), reqData(NULL), dataPkt(NULL),
- retryPkt(NULL), memAccComplete(false), memAccPending(false),
- tlbStall(false), splitAccess(false), splitAccessNum(-1),
- split2ndAccess(false), instIdx(idx), fetchBufferFill(false)
+ CacheRequest(CacheUnit *cres)
+ : ResourceRequest(cres), memReq(NULL), reqData(NULL),
+ dataPkt(NULL), retryPkt(NULL), memAccComplete(false),
+ memAccPending(false), tlbStall(false), splitAccess(false),
+ splitAccessNum(-1), split2ndAccess(false),
+ fetchBufferFill(false)
{ }
-
virtual ~CacheRequest()
{
if (reqData && !splitAccess) {
@@ -240,6 +238,37 @@ class CacheRequest : public ResourceRequest
}
}
+ void setRequest(DynInstPtr _inst, int stage_num, int res_idx, int slot_num,
+ unsigned _cmd, MemCmd::Command pkt_cmd, int idx)
+ {
+ pktCmd = pkt_cmd;
+ instIdx = idx;
+
+ ResourceRequest::setRequest(_inst, stage_num, res_idx, slot_num, _cmd);
+ }
+
+ void clearRequest()
+ {
+ if (reqData && !splitAccess) {
+ delete [] reqData;
+ }
+
+ memReq = NULL;
+ reqData = NULL;
+ dataPkt = NULL;
+ retryPkt = NULL;
+ memAccComplete = false;
+ memAccPending = false;
+ tlbStall = false;
+ splitAccess = false;
+ splitAccessNum = -1;
+ split2ndAccess = false;
+ instIdx = 0;
+ fetchBufferFill = false;
+
+ ResourceRequest::clearRequest();
+ }
+
virtual PacketDataPtr getData()
{ return reqData; }
diff --git a/src/cpu/inorder/resources/decode_unit.cc b/src/cpu/inorder/resources/decode_unit.cc
index c2f7ae22d..71d33ab90 100644
--- a/src/cpu/inorder/resources/decode_unit.cc
+++ b/src/cpu/inorder/resources/decode_unit.cc
@@ -49,21 +49,24 @@ DecodeUnit::DecodeUnit(std::string res_name, int res_id, int res_width,
void
DecodeUnit::execute(int slot_num)
{
- ResourceRequest* decode_req = reqMap[slot_num];
- DynInstPtr inst = reqMap[slot_num]->inst;
+ ResourceRequest* decode_req = reqs[slot_num];
+ DynInstPtr inst = reqs[slot_num]->inst;
ThreadID tid = inst->readTid();
switch (decode_req->cmd)
{
case DecodeInst:
{
- bool done_sked = ThePipeline::createBackEndSchedule(inst);
+ inst->setBackSked(cpu->createBackEndSked(inst));
- if (done_sked) {
+ if (inst->backSked != NULL) {
DPRINTF(InOrderDecode,
"[tid:%i]: Setting Destination Register(s) for [sn:%i].\n",
tid, inst->seqNum);
regDepMap[tid]->insert(inst);
+
+ //inst->printSked();
+
decode_req->done();
} else {
DPRINTF(Resource,
diff --git a/src/cpu/inorder/resources/execution_unit.cc b/src/cpu/inorder/resources/execution_unit.cc
index 36bf2a4dc..b2540cff8 100644
--- a/src/cpu/inorder/resources/execution_unit.cc
+++ b/src/cpu/inorder/resources/execution_unit.cc
@@ -42,7 +42,7 @@ ExecutionUnit::ExecutionUnit(string res_name, int res_id, int res_width,
int res_latency, InOrderCPU *_cpu,
ThePipeline::Params *params)
: Resource(res_name, res_id, res_width, res_latency, _cpu),
- lastExecuteTick(0), lastControlTick(0)
+ lastExecuteTick(0), lastControlTick(0), serializeTick(0)
{ }
void
@@ -82,27 +82,52 @@ ExecutionUnit::regStats()
void
ExecutionUnit::execute(int slot_num)
{
- ResourceRequest* exec_req = reqMap[slot_num];
- DynInstPtr inst = reqMap[slot_num]->inst;
+ ResourceRequest* exec_req = reqs[slot_num];
+ DynInstPtr inst = reqs[slot_num]->inst;
Fault fault = NoFault;
int seq_num = inst->seqNum;
+ Tick cur_tick = curTick();
+
+ if (cur_tick == serializeTick) {
+ DPRINTF(InOrderExecute, "Can not execute [tid:%i][sn:%i][PC:%s] %s. "
+ "All instructions are being serialized this cycle\n",
+ inst->readTid(), seq_num, inst->pcState(), inst->instName());
+ exec_req->done(false);
+ return;
+ }
- DPRINTF(InOrderExecute, "[tid:%i] Executing [sn:%i] [PC:%s] %s.\n",
- inst->readTid(), seq_num, inst->pcState(), inst->instName());
switch (exec_req->cmd)
{
case ExecuteInst:
{
- if (curTick() != lastExecuteTick) {
- lastExecuteTick = curTick();
+ if (inst->isNop()) {
+ DPRINTF(InOrderExecute, "[tid:%i] [sn:%i] [PC:%s] Ignoring execution"
+ "of %s.\n", inst->readTid(), seq_num, inst->pcState(),
+ inst->instName());
+ inst->setExecuted();
+ exec_req->done();
+ return;
+ } else {
+ DPRINTF(InOrderExecute, "[tid:%i] Executing [sn:%i] [PC:%s] %s.\n",
+ inst->readTid(), seq_num, inst->pcState(), inst->instName());
}
+ if (cur_tick != lastExecuteTick) {
+ lastExecuteTick = cur_tick;
+ }
+
+ assert(!inst->isMemRef());
+
+ if (inst->isSerializeAfter()) {
+ serializeTick = cur_tick;
+ DPRINTF(InOrderExecute, "Serializing execution after [tid:%i] "
+ "[sn:%i] [PC:%s] %s.\n", inst->readTid(), seq_num,
+ inst->pcState(), inst->instName());
+ }
- if (inst->isMemRef()) {
- panic("%s not configured to handle memory ops.\n", resName);
- } else if (inst->isControl()) {
- if (lastControlTick == curTick()) {
+ if (inst->isControl()) {
+ if (lastControlTick == cur_tick) {
DPRINTF(InOrderExecute, "Can not Execute More than One Control "
"Inst Per Cycle. Blocking Request.\n");
exec_req->done(false);
diff --git a/src/cpu/inorder/resources/execution_unit.hh b/src/cpu/inorder/resources/execution_unit.hh
index a6694ddb5..b03a6655e 100644
--- a/src/cpu/inorder/resources/execution_unit.hh
+++ b/src/cpu/inorder/resources/execution_unit.hh
@@ -76,6 +76,7 @@ class ExecutionUnit : public Resource {
Stats::Scalar executions;
Tick lastExecuteTick;
Tick lastControlTick;
+ Tick serializeTick;
};
diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc
index 6f84a333d..d23ea0a82 100644
--- a/src/cpu/inorder/resources/fetch_seq_unit.cc
+++ b/src/cpu/inorder/resources/fetch_seq_unit.cc
@@ -62,13 +62,17 @@ FetchSeqUnit::init()
{
resourceEvent = new FetchSeqEvent[width];
+ for (int i = 0; i < width; i++) {
+ reqs[i] = new ResourceRequest(this);
+ }
+
initSlots();
}
void
FetchSeqUnit::execute(int slot_num)
{
- ResourceRequest* fs_req = reqMap[slot_num];
+ ResourceRequest* fs_req = reqs[slot_num];
DynInstPtr inst = fs_req->inst;
ThreadID tid = inst->readTid();
int stage_num = fs_req->getStageNum();
@@ -96,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 0e9866708..a0d830ecf 100644
--- a/src/cpu/inorder/resources/fetch_unit.cc
+++ b/src/cpu/inorder/resources/fetch_unit.cc
@@ -56,6 +56,31 @@ FetchUnit::FetchUnit(string res_name, int res_id, int res_width,
predecoder(NULL)
{ }
+FetchUnit::~FetchUnit()
+{
+ std::list<FetchBlock*>::iterator fetch_it = fetchBuffer.begin();
+ std::list<FetchBlock*>::iterator end_it = fetchBuffer.end();
+ while (fetch_it != end_it) {
+ delete (*fetch_it)->block;
+ delete *fetch_it;
+ fetch_it++;
+ }
+ fetchBuffer.clear();
+
+
+ std::list<FetchBlock*>::iterator pend_it = pendingFetch.begin();
+ std::list<FetchBlock*>::iterator pend_end = pendingFetch.end();
+ while (pend_it != pend_end) {
+ if ((*pend_it)->block) {
+ delete (*pend_it)->block;
+ }
+
+ delete *pend_it;
+ pend_it++;
+ }
+ pendingFetch.clear();
+}
+
void
FetchUnit::createMachInst(std::list<FetchBlock*>::iterator fetch_it,
DynInstPtr inst)
@@ -118,33 +143,24 @@ ResReqPtr
FetchUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
int slot_num, unsigned cmd)
{
- ScheduleEntry* sched_entry = inst->resSched.top();
+ ScheduleEntry* sched_entry = *inst->curSkedEntry;
+ CacheRequest* cache_req = dynamic_cast<CacheRequest*>(reqs[slot_num]);
if (!inst->validMemAddr()) {
panic("Mem. Addr. must be set before requesting cache access\n");
}
- MemCmd::Command pkt_cmd;
-
- switch (sched_entry->cmd)
- {
- case InitiateFetch:
- pkt_cmd = MemCmd::ReadReq;
+ assert(sched_entry->cmd == InitiateFetch);
- DPRINTF(InOrderCachePort,
- "[tid:%i]: Fetch request from [sn:%i] for addr %08p\n",
- inst->readTid(), inst->seqNum, inst->getMemAddr());
- break;
+ DPRINTF(InOrderCachePort,
+ "[tid:%i]: Fetch request from [sn:%i] for addr %08p\n",
+ inst->readTid(), inst->seqNum, inst->getMemAddr());
- default:
- panic("%i: Unexpected request type (%i) to %s", curTick(),
- sched_entry->cmd, name());
- }
+ cache_req->setRequest(inst, stage_num, id, slot_num,
+ sched_entry->cmd, MemCmd::ReadReq,
+ inst->curSkedEntry->idx);
- return new CacheRequest(this, inst, stage_num, id, slot_num,
- sched_entry->cmd, 0, pkt_cmd,
- 0/*flags*/, this->cpu->readCpuId(),
- inst->resSched.top()->idx);
+ return cache_req;
}
void
@@ -214,12 +230,12 @@ FetchUnit::markBlockUsed(std::list<FetchBlock*>::iterator block_it)
void
FetchUnit::execute(int slot_num)
{
- CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(reqMap[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;
}
@@ -270,7 +286,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;
}
@@ -337,6 +353,8 @@ FetchUnit::execute(int slot_num)
return;
}
+ delete [] (*repl_it)->block;
+ delete *repl_it;
fetchBuffer.erase(repl_it);
}
@@ -414,6 +432,7 @@ FetchUnit::processCacheCompletion(PacketPtr pkt)
cache_pkt->cacheReq->seqNum);
cache_pkt->cacheReq->done();
+ cache_pkt->cacheReq->freeSlot();
delete cache_pkt;
cpu->wakeCPU();
@@ -447,7 +466,7 @@ FetchUnit::processCacheCompletion(PacketPtr pkt)
short asid = cpu->asid[tid];
assert(!cache_req->isSquashed());
- assert(inst->resSched.top()->cmd == CompleteFetch);
+ assert(inst->curSkedEntry->cmd == CompleteFetch);
DPRINTF(InOrderCachePort,
"[tid:%u]: [sn:%i]: Processing fetch access for block %#x\n",
@@ -514,6 +533,10 @@ FetchUnit::squashCacheRequest(CacheReqPtr req_ptr)
DPRINTF(InOrderCachePort, "[sn:%i] Removing Pending Fetch "
"for block %08p (cnt=%i)\n", inst->seqNum,
block_addr, (*block_it)->cnt);
+ if ((*block_it)->block) {
+ delete [] (*block_it)->block;
+ }
+ delete *block_it;
pendingFetch.erase(block_it);
}
}
diff --git a/src/cpu/inorder/resources/fetch_unit.hh b/src/cpu/inorder/resources/fetch_unit.hh
index 035f3f4a1..fa133b9eb 100644
--- a/src/cpu/inorder/resources/fetch_unit.hh
+++ b/src/cpu/inorder/resources/fetch_unit.hh
@@ -55,6 +55,8 @@ class FetchUnit : public CacheUnit
FetchUnit(std::string res_name, int res_id, int res_width,
int res_latency, InOrderCPU *_cpu, ThePipeline::Params *params);
+ virtual ~FetchUnit();
+
typedef ThePipeline::DynInstPtr DynInstPtr;
typedef TheISA::ExtMachInst ExtMachInst;
diff --git a/src/cpu/inorder/resources/graduation_unit.cc b/src/cpu/inorder/resources/graduation_unit.cc
index 8ccdaa36a..edc2fb3ff 100644
--- a/src/cpu/inorder/resources/graduation_unit.cc
+++ b/src/cpu/inorder/resources/graduation_unit.cc
@@ -37,8 +37,7 @@ GraduationUnit::GraduationUnit(std::string res_name, int res_id, int res_width,
int res_latency, InOrderCPU *_cpu,
ThePipeline::Params *params)
: Resource(res_name, res_id, res_width, res_latency, _cpu),
- lastCycleGrad(0), numCycleGrad(0)
-
+ lastNonSpecTick(0)
{
for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
nonSpecInstActive[tid] = &cpu->nonSpecInstActive[tid];
@@ -49,23 +48,27 @@ GraduationUnit::GraduationUnit(std::string res_name, int res_id, int res_width,
void
GraduationUnit::execute(int slot_num)
{
- ResourceRequest* grad_req = reqMap[slot_num];
- DynInstPtr inst = reqMap[slot_num]->inst;
+ ResourceRequest* grad_req = reqs[slot_num];
+ DynInstPtr inst = reqs[slot_num]->inst;
ThreadID tid = inst->readTid();
- int stage_num = inst->resSched.top()->stageNum;
+ int stage_num = inst->curSkedEntry->stageNum;
switch (grad_req->cmd)
{
case GraduateInst:
{
- // Make sure this is the last thing on the resource schedule
- assert(inst->resSched.size() == 1);
+ if (lastNonSpecTick == curTick()) {
+ DPRINTF(InOrderGraduation, "Unable to graduate [sn:%i]. "
+ "Only 1 nonspec inst. per cycle can graduate.\n");
+ grad_req->done(false);
+ return;
+ }
- // Handle Any Faults Before Graduating Instruction
+ // Handle Any Faults Before Graduating Instruction
if (inst->fault != NoFault) {
cpu->trap(inst->fault, tid, inst);
grad_req->setCompleted(false);
- return;
+ return;
}
DPRINTF(InOrderGraduation,
@@ -80,6 +83,7 @@ GraduationUnit::execute(int slot_num)
DPRINTF(InOrderGraduation,
"[tid:%i] Non-speculative inst [sn:%i] graduated\n",
tid, inst->seqNum);
+ lastNonSpecTick = curTick();
}
if (inst->traceData) {
diff --git a/src/cpu/inorder/resources/graduation_unit.hh b/src/cpu/inorder/resources/graduation_unit.hh
index aae41993f..59631bfcb 100644
--- a/src/cpu/inorder/resources/graduation_unit.hh
+++ b/src/cpu/inorder/resources/graduation_unit.hh
@@ -57,9 +57,7 @@ class GraduationUnit : public Resource {
void execute(int slot_num);
protected:
- Tick lastCycleGrad;
- int numCycleGrad;
-
+ Tick lastNonSpecTick;
bool *nonSpecInstActive[ThePipeline::MaxThreads];
InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
diff --git a/src/cpu/inorder/resources/inst_buffer.cc b/src/cpu/inorder/resources/inst_buffer.cc
index 18dd26a78..46f5cce72 100644
--- a/src/cpu/inorder/resources/inst_buffer.cc
+++ b/src/cpu/inorder/resources/inst_buffer.cc
@@ -62,7 +62,7 @@ InstBuffer::regStats()
void
InstBuffer::execute(int slot_idx)
{
- ResReqPtr ib_req = reqMap[slot_idx];
+ ResReqPtr ib_req = reqs[slot_idx];
DynInstPtr inst = ib_req->inst;
ThreadID tid = inst->readTid();
int stage_num = ib_req->getStageNum();
@@ -99,19 +99,22 @@ InstBuffer::execute(int slot_idx)
inst->seqNum, next_stage);
// Add to schedule: Insert into buffer in next stage
- int stage_pri = ThePipeline::getNextPriority(inst,
- next_stage);
+ int stage_pri = 20;
+ RSkedPtr insert_sked = (stage_num >= ThePipeline::BackEndStartStage) ?
+ inst->backSked : inst->frontSked;
- inst->resSched.push(new ScheduleEntry(next_stage,
+ insert_sked->push(new ScheduleEntry(next_stage,
stage_pri,
id,
InstBuffer::InsertInst));
// Add to schedule: Remove from buffer in next next (bypass)
// stage
- stage_pri = ThePipeline::getNextPriority(inst, bypass_stage);
+ stage_pri = 20;
+ RSkedPtr bypass_sked = (stage_num >= ThePipeline::BackEndStartStage) ?
+ inst->backSked : inst->frontSked;
- inst->resSched.push(new ScheduleEntry(bypass_stage,
+ bypass_sked->push(new ScheduleEntry(bypass_stage,
stage_pri,
id,
InstBuffer::RemoveInst));
diff --git a/src/cpu/inorder/resources/inst_buffer_new.cc b/src/cpu/inorder/resources/inst_buffer_new.cc
deleted file mode 100644
index 2e5a9666a..000000000
--- a/src/cpu/inorder/resources/inst_buffer_new.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2007 MIPS Technologies, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Korey Sewell
- *
- */
-
-#include <vector>
-#include <list>
-
-#include "arch/isa_traits.hh"
-#include "config/the_isa.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/resources/inst_buffer.hh"
-#include "cpu/inorder/cpu.hh"
-
-using namespace std;
-using namespace TheISA;
-using namespace ThePipeline;
-
-InstBuffer::InstBuffer(string res_name, int res_id, int res_width,
- int res_latency, InOrderCPU *_cpu)
- : Resource(res_name, res_id, res_width, res_latency, _cpu)
-{ }
-
-ResReqPtr
-InstBuffer::getRequest(DynInstPtr inst, int stage_num, int res_idx,
- int slot_num)
-{
- // After this is working, change this to a reinterpret cast
- // for performance considerations
- InstBufferEntry* ib_entry = dynamic_cast<InstBufferEntry*>(inst->resSched.top());
- assert(ib_entry);
-
- return new InstBufferRequest(this, inst, stage_num, id, slot_num,
- ib_entry->cmd);
-}
-
-void
-InstBuffer::execute(int slot_idx)
-{
- // After this is working, change this to a reinterpret cast
- // for performance considerations
- InstBufferRequest* ib_req = dynamic_cast<InstBufferRequest*>(reqMap[slot_idx]);
- assert(ib_req);
-
- DynInstPtr inst = ib_req->inst;
- ThreadID tid = inst->readTid();
- int seq_num = inst->seqNum;
- ib_req->fault = NoFault;
-
- switch (ib_req->cmd)
- {
- case InsertInst:
- {
- DPRINTF(Resource, "[tid:%i]: Inserting [sn:%i] into buffer.\n",
- tid, seq_num);
- insert(inst);
- ib_req->done();
- }
- break;
-
- case RemoveInst:
- {
- DPRINTF(Resource, "[tid:%i]: Removing [sn:%i] from buffer.\n",
- tid, seq_num);
- remove(inst);
- ib_req->done();
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-
- DPRINTF(Resource, "Buffer now contains %i insts.\n", instList.size());
-}
-
-void
-InstBuffer::insert(DynInstPtr inst)
-{
- instList.push_back(inst);
-}
-
-void
-InstBuffer::remove(DynInstPtr inst)
-{
- std::list<DynInstPtr>::iterator list_it = instList.begin();
- std::list<DynInstPtr>::iterator list_end = instList.end();
-
- while (list_it != list_end) {
- if((*list_it) == inst) {
- instList.erase(list_it);
- break;
- }
- list_it++;
- }
-}
-
-void
-InstBuffer::pop()
-{ instList.pop_front(); }
-
-ThePipeline::DynInstPtr
-InstBuffer::top()
-{ return instList.front(); }
-
-void
-InstBuffer::squash(InstSeqNum squash_seq_num, ThreadID tid)
-{
- list<DynInstPtr>::iterator list_it = instList.begin();
- list<DynInstPtr>::iterator list_end = instList.end();
- queue<list<DynInstPtr>::iterator> remove_list;
-
- // Collect All Instructions to be Removed in Remove List
- while (list_it != list_end) {
- if((*list_it)->seqNum > squash_seq_num) {
- DPRINTF(Resource, "[tid:%i]: Squashing [sn:%i] in resource.\n",
- tid, (*list_it)->seqNum);
- (*list_it)->setSquashed();
- remove_list.push(list_it);
- }
-
- list_it++;
- }
-
- // Removed Instructions from InstList & Clear Remove List
- while (!remove_list.empty()) {
- instList.erase(remove_list.front());
- remove_list.pop();
- }
-
- Resource::squash(squash_seq_num, tid);
-}
diff --git a/src/cpu/inorder/resources/inst_buffer_new.hh b/src/cpu/inorder/resources/inst_buffer_new.hh
deleted file mode 100644
index b1d5a7b09..000000000
--- a/src/cpu/inorder/resources/inst_buffer_new.hh
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2007 MIPS Technologies, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Korey Sewell
- *
- */
-
-#ifndef __CPU_INORDER_INST_BUFF_UNIT_HH__
-#define __CPU_INORDER_INST_BUFF_UNIT_HH__
-
-#include <vector>
-#include <list>
-#include <string>
-
-#include "cpu/inorder/resource.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/cpu.hh"
-
-class InstBuffer : public Resource {
- public:
- typedef InOrderDynInst::DynInstPtr DynInstPtr;
-
- public:
- enum Command {
- InsertInst,
- InsertAddr,
- RemoveInst,
- RemoveAddr
- };
-
- public:
- InstBuffer(std::string res_name, int res_id, int res_width,
- int res_latency, InOrderCPU *_cpu);
- virtual ~InstBuffer() {}
-
- virtual ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
- int res_idx, int slot_num);
-
- virtual void execute(int slot_num);
-
- virtual void insert(DynInstPtr inst);
-
- virtual void remove(DynInstPtr inst);
-
- virtual void pop();
-
- virtual DynInstPtr top();
-
- virtual void squash(InstSeqNum squash_seq_num, ThreadID tid);
-
- protected:
- /** List of instructions this resource is currently
- * processing.
- */
- std::list<DynInstPtr> instList;
-
- /** @todo: Add Resource Stats Here */
-
-};
-
-struct InstBufferEntry : public ThePipeline::ScheduleEntry {
- InstBufferEntry(int stage_num, int res_num, InstBuffer::Command _cmd) :
- ScheduleEntry(stage_num, res_num), cmd(_cmd)
- { }
-
- InstBuffer::Command cmd;
-};
-
-class InstBufferRequest : public ResourceRequest {
- public:
- typedef InOrderDynInst::DynInstPtr DynInstPtr;
-
- public:
- InstBufferRequest(InstBuffer *res, DynInstPtr inst, int stage_num, int res_idx, int slot_num,
- InstBuffer::Command _cmd)
- : ResourceRequest(res, inst, stage_num, res_idx, slot_num),
- cmd(_cmd)
- { }
-
- InstBuffer::Command cmd;
-};
-
-
-#endif //__CPU_INORDER_INST_BUFF_UNIT_HH__
diff --git a/src/cpu/inorder/resources/mult_div_unit.cc b/src/cpu/inorder/resources/mult_div_unit.cc
index 5aa0b0aa1..ad8b2b47b 100644
--- a/src/cpu/inorder/resources/mult_div_unit.cc
+++ b/src/cpu/inorder/resources/mult_div_unit.cc
@@ -76,6 +76,10 @@ MultDivUnit::init()
// Set Up Resource Events to Appropriate Resource BandWidth
resourceEvent = new MDUEvent[width];
+ for (int i = 0; i < width; i++) {
+ reqs[i] = new ResourceRequest(this);
+ }
+
initSlots();
}
@@ -92,7 +96,7 @@ void
MultDivUnit::freeSlot(int slot_idx)
{
DPRINTF(InOrderMDU, "Freeing slot for inst:%i\n | slots-free:%i | "
- "slots-used:%i\n", reqMap[slot_idx]->getInst()->seqNum,
+ "slots-used:%i\n", reqs[slot_idx]->getInst()->seqNum,
slotsAvail(), slotsInUse());
Resource::freeSlot(slot_idx);
@@ -110,9 +114,9 @@ MultDivUnit::requestAgain(DynInstPtr inst, bool &service_request)
// 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 (mult_div_req->cmd != inst->curSkedEntry->cmd) {
// If different, then update command in the request
- mult_div_req->cmd = inst->resSched.top()->cmd;
+ mult_div_req->cmd = inst->curSkedEntry->cmd;
DPRINTF(InOrderMDU,
"[tid:%i]: [sn:%i]: Updating the command for this "
"instruction\n", inst->readTid(), inst->seqNum);
@@ -132,7 +136,7 @@ MultDivUnit::getSlot(DynInstPtr inst)
// If we have this instruction's request already then return
if (slot_num != -1 &&
- inst->resSched.top()->cmd == reqMap[slot_num]->cmd)
+ inst->curSkedEntry->cmd == reqs[slot_num]->cmd)
return slot_num;
unsigned repeat_rate = 0;
@@ -202,8 +206,8 @@ MultDivUnit::getDivOpSize(DynInstPtr inst)
void
MultDivUnit::execute(int slot_num)
{
- ResourceRequest* mult_div_req = reqMap[slot_num];
- DynInstPtr inst = reqMap[slot_num]->inst;
+ ResourceRequest* mult_div_req = reqs[slot_num];
+ DynInstPtr inst = reqs[slot_num]->inst;
switch (mult_div_req->cmd)
{
@@ -275,8 +279,8 @@ MultDivUnit::execute(int slot_num)
void
MultDivUnit::exeMulDiv(int slot_num)
{
- ResourceRequest* mult_div_req = reqMap[slot_num];
- DynInstPtr inst = reqMap[slot_num]->inst;
+ ResourceRequest* mult_div_req = reqs[slot_num];
+ DynInstPtr inst = reqs[slot_num]->inst;
inst->fault = inst->execute();
@@ -310,7 +314,7 @@ MDUEvent::process()
mdu_res->exeMulDiv(slotIdx);
- ResourceRequest* mult_div_req = resource->reqMap[slotIdx];
+ ResourceRequest* mult_div_req = resource->reqs[slotIdx];
mult_div_req->done();
}
diff --git a/src/cpu/inorder/resources/tlb_unit.cc b/src/cpu/inorder/resources/tlb_unit.cc
index 59840d15b..37aec2209 100644
--- a/src/cpu/inorder/resources/tlb_unit.cc
+++ b/src/cpu/inorder/resources/tlb_unit.cc
@@ -72,6 +72,10 @@ TLBUnit::init()
{
resourceEvent = new TLBUnitEvent[width];
+ for (int i = 0; i < width; i++) {
+ reqs[i] = new TLBUnitRequest(this);
+ }
+
initSlots();
}
@@ -90,8 +94,9 @@ TLBUnit::getRequest(DynInstPtr _inst, int stage_num,
int res_idx, int slot_num,
unsigned cmd)
{
- return new TLBUnitRequest(this, _inst, stage_num, res_idx, slot_num,
- cmd);
+ TLBUnitRequest *tlb_req = dynamic_cast<TLBUnitRequest*>(reqs[slot_num]);
+ tlb_req->setRequest(inst, stage_num, id, slot_num, cmd);
+ return ud_req;
}
void
@@ -99,7 +104,7 @@ TLBUnit::execute(int slot_idx)
{
// After this is working, change this to a reinterpret cast
// for performance considerations
- TLBUnitRequest* tlb_req = dynamic_cast<TLBUnitRequest*>(reqMap[slot_idx]);
+ TLBUnitRequest* tlb_req = dynamic_cast<TLBUnitRequest*>(reqs[slot_idx]);
assert(tlb_req != 0x0);
DynInstPtr inst = tlb_req->inst;
@@ -200,8 +205,8 @@ TLBUnitEvent::TLBUnitEvent()
void
TLBUnitEvent::process()
{
- DynInstPtr inst = resource->reqMap[slotIdx]->inst;
- int stage_num = resource->reqMap[slotIdx]->getStageNum();
+ DynInstPtr inst = resource->reqs[slotIdx]->inst;
+ int stage_num = resource->reqs[slotIdx]->getStageNum();
ThreadID tid = inst->threadNumber;
DPRINTF(InOrderTLB, "Waking up from TLB Miss caused by [sn:%i].\n",
@@ -212,31 +217,18 @@ TLBUnitEvent::process()
tlb_res->tlbBlocked[tid] = false;
- tlb_res->cpu->pipelineStage[stage_num]->unsetResStall(tlb_res->reqMap[slotIdx], tid);
-
- // Effectively NOP the instruction but still allow it
- // to commit
- //while (!inst->resSched.empty() &&
- // inst->resSched.top()->stageNum != ThePipeline::NumStages - 1) {
- //inst->resSched.pop();
- //}
+ tlb_res->cpu->pipelineStage[stage_num]->
+ unsetResStall(tlb_res->reqs[slotIdx], tid);
}
void
TLBUnit::squash(DynInstPtr inst, int stage_num,
InstSeqNum squash_seq_num, ThreadID tid)
{
- //@TODO: Figure out a way to consolidate common parts
- // of this squash code
- std::vector<int> slot_remove_list;
-
- map<int, ResReqPtr>::iterator map_it = reqMap.begin();
- map<int, ResReqPtr>::iterator map_end = reqMap.end();
-
- while (map_it != map_end) {
- ResReqPtr req_ptr = (*map_it).second;
+ for (int i = 0; i < width; i++) {
+ ResReqPtr req_ptr = reqs[i];
- if (req_ptr &&
+ if (req_ptr->valid &&
req_ptr->getInst()->readTid() == tid &&
req_ptr->getInst()->seqNum > squash_seq_num) {
@@ -250,26 +242,16 @@ TLBUnit::squash(DynInstPtr inst, int stage_num,
tlbBlocked[tid] = false;
- int stall_stage = reqMap[req_slot_num]->getStageNum();
+ int stall_stage = reqs[req_slot_num]->getStageNum();
- cpu->pipelineStage[stall_stage]->unsetResStall(reqMap[req_slot_num], tid);
+ cpu->pipelineStage[stall_stage]->
+ unsetResStall(reqs[req_slot_num], tid);
if (resourceEvent[req_slot_num].scheduled())
unscheduleEvent(req_slot_num);
- // Mark request for later removal
- cpu->reqRemoveList.push(req_ptr);
-
- // Mark slot for removal from resource
- slot_remove_list.push_back(req_ptr->getSlot());
+ freeSlot(req_slot_num);
}
-
- map_it++;
- }
-
- // Now Delete Slot Entry from Req. Map
- for (int i = 0; i < slot_remove_list.size(); i++) {
- freeSlot(slot_remove_list[i]);
}
}
diff --git a/src/cpu/inorder/resources/tlb_unit.hh b/src/cpu/inorder/resources/tlb_unit.hh
index eb1bf55f0..904ac3eba 100644
--- a/src/cpu/inorder/resources/tlb_unit.hh
+++ b/src/cpu/inorder/resources/tlb_unit.hh
@@ -99,9 +99,15 @@ class TLBUnitRequest : public ResourceRequest {
typedef ThePipeline::DynInstPtr DynInstPtr;
public:
- TLBUnitRequest(TLBUnit *res, DynInstPtr inst, int stage_num, int res_idx, int slot_num,
- unsigned _cmd)
- : ResourceRequest(res, inst, stage_num, res_idx, slot_num, _cmd)
+ TLBUnitRequest(TLBUnit *res)
+ : ResourceRequest(res), memReq(NULL)
+ {
+ }
+
+ RequestPtr memReq;
+
+ void setRequest(DynInstPtr inst, int stage_num, int res_idx, int slot_num,
+ unsigned _cmd)
{
Addr aligned_addr;
int req_size;
@@ -131,9 +137,10 @@ class TLBUnitRequest : public ResourceRequest {
inst->readTid());
memReq = inst->dataMemReq;
}
+
+ ResourceRequest::setRequest(inst, stage_num, res_idx, slot_num, _cmd);
}
- RequestPtr memReq;
};
diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc
index 743011573..19246a30b 100644
--- a/src/cpu/inorder/resources/use_def.cc
+++ b/src/cpu/inorder/resources/use_def.cc
@@ -88,33 +88,48 @@ UseDefUnit::regStats()
Resource::regStats();
}
+void
+UseDefUnit::init()
+{
+ // Set Up Resource Events to Appropriate Resource BandWidth
+ if (latency > 0) {
+ resourceEvent = new ResourceEvent[width];
+ } else {
+ resourceEvent = NULL;
+ }
+
+ for (int i = 0; i < width; i++) {
+ reqs[i] = new UseDefRequest(this);
+ }
+
+ initSlots();
+}
+
ResReqPtr
UseDefUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
int slot_num, unsigned cmd)
{
- return new UseDefRequest(this, inst, stage_num, id, slot_num, cmd,
- inst->resSched.top()->idx);
+ UseDefRequest *ud_req = dynamic_cast<UseDefRequest*>(reqs[slot_num]);
+ ud_req->setRequest(inst, stage_num, id, slot_num, cmd,
+ inst->curSkedEntry->idx);
+ return ud_req;
}
ResReqPtr
UseDefUnit::findRequest(DynInstPtr inst)
{
- map<int, ResReqPtr>::iterator map_it = reqMap.begin();
- map<int, ResReqPtr>::iterator map_end = reqMap.end();
-
- while (map_it != map_end) {
- UseDefRequest* ud_req =
- dynamic_cast<UseDefRequest*>((*map_it).second);
+ for (int i = 0; i < width; i++) {
+ UseDefRequest* ud_req =
+ dynamic_cast<UseDefRequest*>(reqs[i]);
assert(ud_req);
- if (ud_req &&
+ if (ud_req->valid &&
ud_req->getInst() == inst &&
- ud_req->cmd == inst->resSched.top()->cmd &&
- ud_req->useDefIdx == inst->resSched.top()->idx) {
+ ud_req->cmd == inst->curSkedEntry->cmd &&
+ ud_req->useDefIdx == inst->curSkedEntry->idx) {
return ud_req;
}
- map_it++;
}
return NULL;
@@ -125,7 +140,7 @@ UseDefUnit::execute(int slot_idx)
{
// After this is working, change this to a reinterpret cast
// for performance considerations
- UseDefRequest* ud_req = dynamic_cast<UseDefRequest*>(reqMap[slot_idx]);
+ UseDefRequest* ud_req = dynamic_cast<UseDefRequest*>(reqs[slot_idx]);
assert(ud_req);
DynInstPtr inst = ud_req->inst;
@@ -408,15 +423,10 @@ UseDefUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
DPRINTF(InOrderUseDef, "[tid:%i]: Updating Due To Squash After [sn:%i].\n",
tid, squash_seq_num);
- std::vector<int> slot_remove_list;
-
- map<int, ResReqPtr>::iterator map_it = reqMap.begin();
- map<int, ResReqPtr>::iterator map_end = reqMap.end();
+ for (int i = 0; i < width; i++) {
+ ResReqPtr req_ptr = reqs[i];
- while (map_it != map_end) {
- ResReqPtr req_ptr = (*map_it).second;
-
- if (req_ptr &&
+ if (req_ptr->valid &&
req_ptr->getInst()->readTid() == tid &&
req_ptr->getInst()->seqNum > squash_seq_num) {
@@ -431,20 +441,9 @@ UseDefUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
unscheduleEvent(req_slot_num);
}
-
- // Mark request for later removal
- cpu->reqRemoveList.push(req_ptr);
- // Mark slot for removal from resource
- slot_remove_list.push_back(req_ptr->getSlot());
+ freeSlot(req_slot_num);
}
-
- map_it++;
- }
-
- // Now Delete Slot Entry from Req. Map
- for (int i = 0; i < slot_remove_list.size(); i++) {
- freeSlot(slot_remove_list[i]);
}
if (outReadSeqNum[tid] >= squash_seq_num) {
diff --git a/src/cpu/inorder/resources/use_def.hh b/src/cpu/inorder/resources/use_def.hh
index d2cc55315..21770cec6 100644
--- a/src/cpu/inorder/resources/use_def.hh
+++ b/src/cpu/inorder/resources/use_def.hh
@@ -56,6 +56,8 @@ class UseDefUnit : public Resource {
UseDefUnit(std::string res_name, int res_id, int res_width,
int res_latency, InOrderCPU *_cpu, ThePipeline::Params *params);
+ void init();
+
ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
int res_idx, int slot_num,
unsigned cmd);
@@ -96,14 +98,20 @@ class UseDefUnit : public Resource {
typedef ThePipeline::DynInstPtr DynInstPtr;
public:
- UseDefRequest(UseDefUnit *res, DynInstPtr inst, int stage_num,
- int res_idx, int slot_num, unsigned cmd,
- int use_def_idx)
- : ResourceRequest(res, inst, stage_num, res_idx, slot_num, cmd),
- useDefIdx(use_def_idx)
+ UseDefRequest(UseDefUnit *res)
+ : ResourceRequest(res)
{ }
int useDefIdx;
+
+ void setRequest(DynInstPtr _inst, int stage_num, int res_idx,
+ int slot_num, unsigned _cmd, int idx)
+ {
+ useDefIdx = idx;
+
+ ResourceRequest::setRequest(_inst, stage_num, res_idx, slot_num,
+ _cmd);
+ }
};
protected: