summaryrefslogtreecommitdiff
path: root/src/cpu/inorder/resource.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/inorder/resource.cc')
-rw-r--r--src/cpu/inorder/resource.cc253
1 files changed, 115 insertions, 138 deletions
diff --git a/src/cpu/inorder/resource.cc b/src/cpu/inorder/resource.cc
index 51beb5aa0..24211532e 100644
--- a/src/cpu/inorder/resource.cc
+++ b/src/cpu/inorder/resource.cc
@@ -31,6 +31,8 @@
#include <vector>
#include <list>
+
+#include "base/str.hh"
#include "cpu/inorder/resource.hh"
#include "cpu/inorder/cpu.hh"
using namespace std;
@@ -40,22 +42,42 @@ Resource::Resource(string res_name, int res_id, int res_width,
: resName(res_name), id(res_id),
width(res_width), latency(res_latency), cpu(_cpu)
{
+ reqs.resize(width);
+
// Use to deny a instruction a resource.
- deniedReq = new ResourceRequest(this, NULL, 0, 0, 0, 0);
+ deniedReq = new ResourceRequest(this);
+ deniedReq->valid = true;
}
Resource::~Resource()
{
- delete [] resourceEvent;
- delete deniedReq;
+ if (resourceEvent) {
+ delete [] resourceEvent;
+ }
+
+ delete deniedReq;
+
+ for (int i = 0; i < width; i++) {
+ delete reqs[i];
+ }
}
void
Resource::init()
{
- // Set Up Resource Events to Appropriate Resource BandWidth
- resourceEvent = new ResourceEvent[width];
+ // If the resource has a zero-cycle (no latency)
+ // function, then no reason to have events
+ // that will process them for the right tick
+ if (latency > 0) {
+ resourceEvent = new ResourceEvent[width];
+ } else {
+ resourceEvent = NULL;
+ }
+
+ for (int i = 0; i < width; i++) {
+ reqs[i] = new ResourceRequest(this);
+ }
initSlots();
}
@@ -66,7 +88,10 @@ Resource::initSlots()
// Add available slot numbers for resource
for (int slot_idx = 0; slot_idx < width; slot_idx++) {
availSlots.push_back(slot_idx);
- resourceEvent[slot_idx].init(this, slot_idx);
+
+ if (resourceEvent) {
+ resourceEvent[slot_idx].init(this, slot_idx);
+ }
}
}
@@ -91,42 +116,34 @@ 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);
- // Erase Request Pointer From Request Map
- std::map<int, ResReqPtr>::iterator req_it = reqMap.find(slot_idx);
-
- assert(req_it != reqMap.end());
- reqMap.erase(req_it);
-
+ // Invalidate Request & Reset it's flags
+ reqs[slot_idx]->clearRequest();
}
-// TODO: More efficiently search for instruction's slot within
-// resource.
int
Resource::findSlot(DynInstPtr inst)
{
- map<int, ResReqPtr>::iterator map_it = reqMap.begin();
- map<int, ResReqPtr>::iterator map_end = reqMap.end();
-
int slot_num = -1;
- while (map_it != map_end) {
- if ((*map_it).second->getInst()->seqNum ==
- inst->seqNum) {
- slot_num = (*map_it).second->getSlot();
+ for (int i = 0; i < width; i++) {
+ if (reqs[i]->valid &&
+ reqs[i]->getInst()->seqNum == inst->seqNum) {
+ slot_num = reqs[i]->getSlot();
}
- map_it++;
}
-
return slot_num;
}
int
Resource::getSlot(DynInstPtr inst)
{
- int slot_num;
+ int slot_num = -1;
if (slotsAvail() != 0) {
slot_num = availSlots[0];
@@ -136,24 +153,6 @@ Resource::getSlot(DynInstPtr inst)
assert(slot_num == *vect_it);
availSlots.erase(vect_it);
- } else {
- DPRINTF(Resource, "[tid:%i]: No slots in resource "
- "available to service [sn:%i].\n", inst->readTid(),
- inst->seqNum);
- slot_num = -1;
-
- map<int, ResReqPtr>::iterator map_it = reqMap.begin();
- map<int, ResReqPtr>::iterator map_end = reqMap.end();
-
- while (map_it != map_end) {
- if ((*map_it).second) {
- DPRINTF(Resource, "Currently Serving request from: "
- "[tid:%i] [sn:%i].\n",
- (*map_it).second->getInst()->readTid(),
- (*map_it).second->getInst()->seqNum);
- }
- map_it++;
- }
}
return slot_num;
@@ -183,9 +182,12 @@ 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->resSched.top()->stageNum;
- unsigned cmd = inst->resSched.top()->cmd;
+ stage_num = inst->curSkedEntry->stageNum;
+ unsigned cmd = inst->curSkedEntry->cmd;
// Generate Resource Request
inst_req = getRequest(inst, stage_num, id, slot_num, cmd);
@@ -200,10 +202,12 @@ Resource::request(DynInstPtr inst)
inst->readTid());
}
- reqMap[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) {
@@ -236,32 +240,21 @@ ResReqPtr
Resource::getRequest(DynInstPtr inst, int stage_num, int res_idx,
int slot_num, unsigned cmd)
{
- return new ResourceRequest(this, inst, stage_num, id, slot_num,
- cmd);
+ reqs[slot_num]->setRequest(inst, stage_num, id, slot_num, cmd);
+ return reqs[slot_num];
}
ResReqPtr
Resource::findRequest(DynInstPtr inst)
{
- map<int, ResReqPtr>::iterator map_it = reqMap.begin();
- map<int, ResReqPtr>::iterator map_end = reqMap.end();
-
- bool found = false;
- ResReqPtr req = NULL;
-
- while (map_it != map_end) {
- if ((*map_it).second &&
- (*map_it).second->getInst() == inst) {
- req = (*map_it).second;
- //return (*map_it).second;
- assert(found == false);
- found = true;
+ for (int i = 0; i < width; i++) {
+ if (reqs[i]->valid &&
+ reqs[i]->getInst() == inst) {
+ return reqs[i];
}
- map_it++;
}
- return req;
- //return NULL;
+ return NULL;
}
void
@@ -275,9 +268,9 @@ void
Resource::execute(int slot_idx)
{
DPRINTF(Resource, "[tid:%i]: Executing %s resource.\n",
- reqMap[slot_idx]->getTid(), name());
- reqMap[slot_idx]->setCompleted(true);
- reqMap[slot_idx]->done();
+ reqs[slot_idx]->getTid(), name());
+ reqs[slot_idx]->setCompleted(true);
+ reqs[slot_idx]->done();
}
void
@@ -293,15 +286,10 @@ void
Resource::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
ThreadID tid)
{
- std::vector<int> slot_remove_list;
+ for (int i = 0; i < width; i++) {
+ ResReqPtr req_ptr = reqs[i];
- 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;
-
- if (req_ptr &&
+ if (req_ptr->valid &&
req_ptr->getInst()->readTid() == tid &&
req_ptr->getInst()->seqNum > squash_seq_num) {
@@ -316,19 +304,8 @@ Resource::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
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]);
}
}
@@ -350,10 +327,8 @@ Resource::ticks(int num_cycles)
void
Resource::scheduleExecution(int slot_num)
{
- int res_latency = getLatency(slot_num);
-
- if (res_latency >= 1) {
- scheduleEvent(slot_num, res_latency);
+ if (latency >= 1) {
+ scheduleEvent(slot_num, latency);
} else {
execute(slot_num);
}
@@ -363,8 +338,8 @@ void
Resource::scheduleEvent(int slot_idx, int delay)
{
DPRINTF(Resource, "[tid:%i]: Scheduling event for [sn:%i] on tick %i.\n",
- reqMap[slot_idx]->inst->readTid(),
- reqMap[slot_idx]->inst->seqNum,
+ reqs[slot_idx]->inst->readTid(),
+ reqs[slot_idx]->inst->seqNum,
cpu->ticks(delay) + curTick());
resourceEvent[slot_idx].scheduleEvent(delay);
}
@@ -401,32 +376,11 @@ int ResourceRequest::resReqID = 0;
int ResourceRequest::maxReqCount = 0;
-ResourceRequest::ResourceRequest(Resource *_res, DynInstPtr _inst,
- int stage_num, int res_idx, int slot_num,
- unsigned _cmd)
- : res(_res), inst(_inst), cmd(_cmd), stageNum(stage_num),
- resIdx(res_idx), slotNum(slot_num), completed(false),
- squashed(false), processing(false), memStall(false)
+ResourceRequest::ResourceRequest(Resource *_res)
+ : res(_res), inst(NULL), stagePasses(0), valid(false), doneInResource(false),
+ completed(false), squashed(false), processing(false),
+ memStall(false)
{
-#ifdef DEBUG
- reqID = resReqID++;
- res->cpu->resReqCount++;
- DPRINTF(ResReqCount, "Res. Req %i created. resReqCount=%i.\n", reqID,
- res->cpu->resReqCount);
-
- if (res->cpu->resReqCount > 100) {
- fatal("Too many undeleted resource requests. Memory leak?\n");
- }
-
- if (res->cpu->resReqCount > maxReqCount) {
- maxReqCount = res->cpu->resReqCount;
- }
-
-#endif
-
- stagePasses = 0;
- complSlotNum = -1;
-
}
ResourceRequest::~ResourceRequest()
@@ -436,6 +390,46 @@ ResourceRequest::~ResourceRequest()
DPRINTF(ResReqCount, "Res. Req %i deleted. resReqCount=%i.\n", reqID,
res->cpu->resReqCount);
#endif
+ inst = NULL;
+}
+
+std::string
+ResourceRequest::name()
+{
+ return res->name() + "." + to_string(slotNum);
+}
+
+void
+ResourceRequest::setRequest(DynInstPtr _inst, int stage_num,
+ int res_idx, int slot_num, unsigned _cmd)
+{
+ valid = true;
+ inst = _inst;
+ stageNum = stage_num;
+ resIdx = res_idx;
+ slotNum = slot_num;
+ cmd = _cmd;
+}
+
+void
+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
@@ -447,25 +441,7 @@ ResourceRequest::done(bool completed)
setCompleted(completed);
- // Used for debugging purposes
- 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
- res->freeSlot(slotNum);
-
- // change slot # to -1, since we check slotNum to see if request is
- // still valid
- slotNum = -1;
+ doneInResource = true;
}
ResourceEvent::ResourceEvent()
@@ -493,7 +469,8 @@ ResourceEvent::process()
const char *
ResourceEvent::description()
{
- string desc = resource->name() + " event";
+ string desc = resource->name() + "-event:slot[" + to_string(slotIdx)
+ + "]";
return desc.c_str();
}