inorder: remove request map, use request vector
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
This commit is contained in:
parent
c883729025
commit
d64226750e
|
@ -324,12 +324,7 @@ InOrderCPU::InOrderCPU(Params *params)
|
|||
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);
|
||||
|
|
|
@ -938,6 +938,7 @@ PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed)
|
|||
"\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 "
|
||||
|
|
|
@ -43,7 +43,7 @@ Resource::Resource(string res_name, int res_id, int res_width,
|
|||
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()
|
||||
|
@ -60,7 +60,7 @@ Resource::init()
|
|||
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();
|
||||
|
@ -100,39 +100,28 @@ Resource::freeSlot(int 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];
|
||||
|
@ -142,24 +131,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;
|
||||
|
@ -206,7 +177,7 @@ Resource::request(DynInstPtr inst)
|
|||
inst->readTid());
|
||||
}
|
||||
|
||||
reqMap[slot_num] = inst_req;
|
||||
reqs[slot_num] = inst_req;
|
||||
|
||||
try_request = true;
|
||||
}
|
||||
|
@ -242,32 +213,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
|
||||
|
@ -281,9 +241,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
|
||||
|
@ -299,15 +259,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) {
|
||||
|
||||
|
@ -322,16 +277,8 @@ Resource::squash(DynInstPtr inst, int stage_num, InstSeqNum 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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,8 +313,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);
|
||||
}
|
||||
|
@ -404,32 +351,10 @@ 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), 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()
|
||||
|
@ -441,6 +366,26 @@ 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)
|
||||
{
|
||||
|
|
|
@ -221,9 +221,9 @@ class Resource {
|
|||
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.
|
||||
|
@ -302,19 +302,21 @@ class ResourceRequest
|
|||
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;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
|
@ -356,6 +358,10 @@ class ResourceRequest
|
|||
/** Command For This Resource */
|
||||
unsigned cmd;
|
||||
|
||||
short stagePasses;
|
||||
|
||||
bool valid;
|
||||
|
||||
////////////////////////////////////////
|
||||
//
|
||||
// GET RESOURCE REQUEST STATUS FROM VARIABLES
|
||||
|
@ -379,7 +385,6 @@ class ResourceRequest
|
|||
|
||||
protected:
|
||||
/** Resource Identification */
|
||||
bool valid;
|
||||
ThreadID tid;
|
||||
int stageNum;
|
||||
int resIdx;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -134,8 +134,7 @@ void
|
|||
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
|
||||
|
@ -255,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->curSkedEntry->idx) {
|
||||
return cache_req;
|
||||
}
|
||||
map_it++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -277,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;
|
||||
|
@ -302,6 +293,7 @@ CacheUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
|
|||
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");
|
||||
|
@ -348,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->curSkedEntry->idx);
|
||||
cache_req->setRequest(inst, stage_num, id, slot_num,
|
||||
sched_entry->cmd, pkt_cmd,
|
||||
inst->curSkedEntry->idx);
|
||||
return cache_req;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -672,7 +664,7 @@ 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) {
|
||||
|
@ -813,7 +805,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;
|
||||
}
|
||||
|
@ -1064,10 +1056,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);
|
||||
|
@ -1078,7 +1070,7 @@ 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;
|
||||
|
||||
|
@ -1129,15 +1121,10 @@ void
|
|||
CacheUnit::squash(DynInstPtr inst, int stage_num,
|
||||
InstSeqNum squash_seq_num, ThreadID tid)
|
||||
{
|
||||
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) {
|
||||
|
||||
|
@ -1150,7 +1137,6 @@ CacheUnit::squash(DynInstPtr inst, int stage_num,
|
|||
"squashed, ignoring squash process.\n",
|
||||
req_ptr->getInst()->readTid(),
|
||||
req_ptr->getInst()->seqNum);
|
||||
map_it++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1164,15 +1150,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 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 "
|
||||
|
@ -1184,14 +1169,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]);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,33 @@ 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()
|
||||
{
|
||||
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; }
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ 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)
|
||||
|
|
|
@ -82,8 +82,8 @@ 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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -119,32 +119,23 @@ FetchUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
|
|||
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());
|
||||
|
||||
DPRINTF(InOrderCachePort,
|
||||
"[tid:%i]: Fetch request from [sn:%i] for addr %08p\n",
|
||||
inst->readTid(), inst->seqNum, inst->getMemAddr());
|
||||
break;
|
||||
cache_req->setRequest(inst, stage_num, id, slot_num,
|
||||
sched_entry->cmd, MemCmd::ReadReq,
|
||||
inst->curSkedEntry->idx);
|
||||
|
||||
default:
|
||||
panic("%i: Unexpected request type (%i) to %s", curTick(),
|
||||
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);
|
||||
return cache_req;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -214,7 +205,7 @@ 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) {
|
||||
|
|
|
@ -49,8 +49,8 @@ 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->curSkedEntry->stageNum;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
@ -132,7 +136,7 @@ MultDivUnit::getSlot(DynInstPtr inst)
|
|||
|
||||
// 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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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->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;
|
||||
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) {
|
||||
|
||||
|
@ -250,23 +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 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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ UseDefUnit::init()
|
|||
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();
|
||||
|
@ -105,29 +105,27 @@ 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->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;
|
||||
|
@ -138,7 +136,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;
|
||||
|
@ -421,15 +419,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;
|
||||
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) {
|
||||
|
||||
|
@ -444,17 +437,9 @@ UseDefUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
|
|||
|
||||
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]);
|
||||
}
|
||||
|
||||
if (outReadSeqNum[tid] >= squash_seq_num) {
|
||||
|
|
|
@ -98,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:
|
||||
|
|
Loading…
Reference in a new issue