take away all instances of reqMap in the code and make all references use the built-in
request vectors inside of each resource. The request map was dynamically allocating
a request per instruction. The request vector just allocates N number of requests
during instantiation and then the surrounding code is fixed up to reuse those N requests
***
setRequest() and clearRequest() are the new accessors needed to define a new
request in a resource
tid,
asid[tid]);
- dummyReq[tid] = new ResourceRequest(resPool->getResource(0),
- dummyInst[tid],
- 0,
- 0,
- 0,
- 0);
+ dummyReq[tid] = new ResourceRequest(resPool->getResource(0));
}
dummyReqInst = new InOrderDynInst(this, NULL, 0, 0, 0);
"\n", tid, inst->seqNum, cpu->resPool->name(res_num));
ResReqPtr req = cpu->resPool->request(res_num, inst);
+ assert(req->valid);
if (req->isCompleted()) {
DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s "
reqs.resize(width);
// Use to deny a instruction a resource.
- deniedReq = new ResourceRequest(this, NULL, 0, 0, 0, 0);
+ deniedReq = new ResourceRequest(this);
}
Resource::~Resource()
resourceEvent = new ResourceEvent[width];
for (int i = 0; i < width; i++) {
- reqs[i] = new ResourceRequest(this, NULL, 0, 0, 0, 0);
+ reqs[i] = new ResourceRequest(this);
}
initSlots();
// 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];
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;
inst->readTid());
}
- reqMap[slot_num] = inst_req;
+ reqs[slot_num] = inst_req;
try_request = true;
}
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
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
Resource::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
ThreadID tid)
{
- 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) {
if (resourceEvent[req_slot_num].scheduled())
unscheduleEvent(req_slot_num);
- // 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]);
}
}
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);
}
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), valid(false), 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), complSlotNum(-1),
+ 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()
#endif
}
+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;
+}
+
void
ResourceRequest::done(bool completed)
{
const int latency;
public:
- /** Mapping of slot-numbers to the resource-request pointers */
- std::map<int, ResReqPtr> reqMap;
-
+ /** List of all Requests the Resource is Servicing. Each request
+ represents part of the resource's bandwidth
+ */
std::vector<ResReqPtr> reqs;
/** A list of all the available execution slots for this resource.
friend class Resource;
public:
- ResourceRequest(Resource *_res, DynInstPtr _inst, int stage_num,
- int res_idx, int slot_num, unsigned _cmd);
+ ResourceRequest(Resource *_res);
virtual ~ResourceRequest();
int reqID;
+ virtual void setRequest(DynInstPtr _inst, int stage_num,
+ int res_idx, int slot_num, unsigned _cmd);
+
+ virtual void clearRequest();
+
/** Acknowledge that this is a request is done and remove
* from resource.
*/
void done(bool completed = true);
-
- short stagePasses;
/////////////////////////////////////////////
//
/** Command For This Resource */
unsigned cmd;
+ short stagePasses;
+
+ bool valid;
+
////////////////////////////////////////
//
// GET RESOURCE REQUEST STATUS FROM VARIABLES
protected:
/** Resource Identification */
- bool valid;
ThreadID tid;
int stageNum;
int resIdx;
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
{
// 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;
CacheUnit::init()
{
for (int i = 0; i < width; i++) {
- reqs[i] = new CacheRequest(this, NULL, 0, 0, 0, 0, 0,
- MemCmd::Command(0), 0, 0, 0);
+ reqs[i] = new CacheRequest(this);
}
// Currently Used to Model TLB Latency. Eventually
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->curSkedEntry->idx) {
return cache_req;
}
- map_it++;
}
return NULL;
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;
int slot_num, unsigned cmd)
{
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");
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->curSkedEntry->idx);
+ cache_req->setRequest(inst, stage_num, id, slot_num,
+ sched_entry->cmd, pkt_cmd,
+ inst->curSkedEntry->idx);
+ return cache_req;
}
void
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) {
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;
}
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);
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;
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) {
"squashed, ignoring squash process.\n",
req_ptr->getInst()->readTid(),
req_ptr->getInst()->seqNum);
- map_it++;
continue;
}
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 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 "
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]);
}
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) {
}
}
+ 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()
+ {
+ 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; }
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)
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;
{
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();
int slot_num, unsigned cmd)
{
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;
+ assert(sched_entry->cmd == InitiateFetch);
- switch (sched_entry->cmd)
- {
- case InitiateFetch:
- pkt_cmd = MemCmd::ReadReq;
-
- 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->curSkedEntry->idx);
+ return cache_req;
}
void
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) {
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->curSkedEntry->stageNum;
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();
// 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();
}
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);
// If we have this instruction's request already then return
if (slot_num != -1 &&
- inst->curSkedEntry->cmd == reqMap[slot_num]->cmd)
+ inst->curSkedEntry->cmd == reqs[slot_num]->cmd)
return slot_num;
unsigned repeat_rate = 0;
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)
{
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();
mdu_res->exeMulDiv(slotIdx);
- ResourceRequest* mult_div_req = resource->reqMap[slotIdx];
+ ResourceRequest* mult_div_req = resource->reqs[slotIdx];
mult_div_req->done();
}
{
resourceEvent = new TLBUnitEvent[width];
+ for (int i = 0; i < width; i++) {
+ reqs[i] = new TLBUnitRequest(this);
+ }
+
initSlots();
}
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
{
// 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;
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",
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->curSkedEntry->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();
+ 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) {
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 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]);
}
}
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;
inst->readTid());
memReq = inst->dataMemReq;
}
+
+ ResourceRequest::setRequest(inst, stage_num, res_idx, slot_num, _cmd);
}
- RequestPtr memReq;
};
resourceEvent = new ResourceEvent[width];
for (int i = 0; i < width; i++) {
- reqs[i] = new UseDefRequest(this, NULL, 0, 0, 0, 0, 0);
+ reqs[i] = new UseDefRequest(this);
}
initSlots();
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->curSkedEntry->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->curSkedEntry->cmd &&
ud_req->useDefIdx == inst->curSkedEntry->idx) {
return ud_req;
}
- map_it++;
}
return NULL;
{
// 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;
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();
-
- 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) {
unscheduleEvent(req_slot_num);
}
-
- // Mark slot for removal from resource
- slot_remove_list.push_back(req_ptr->getSlot());
- }
- map_it++;
- }
-
- // Now Delete Slot Entry from Req. Map
- for (int i = 0; i < slot_remove_list.size(); i++) {
- freeSlot(slot_remove_list[i]);
+ freeSlot(req_slot_num);
+ }
}
if (outReadSeqNum[tid] >= squash_seq_num) {
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: