diff options
Diffstat (limited to 'src/cpu/inorder/resource.cc')
-rw-r--r-- | src/cpu/inorder/resource.cc | 249 |
1 files changed, 113 insertions, 136 deletions
diff --git a/src/cpu/inorder/resource.cc b/src/cpu/inorder/resource.cc index 72b45dda8..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,6 +182,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; @@ -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(); } |