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:
Korey Sewell 2011-02-18 14:28:30 -05:00
parent c883729025
commit d64226750e
19 changed files with 214 additions and 282 deletions

View file

@ -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);

View file

@ -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 "

View file

@ -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)
{

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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]);
}

View file

@ -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; }

View file

@ -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)

View file

@ -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;

View file

@ -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();

View file

@ -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) {

View file

@ -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;

View file

@ -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();

View file

@ -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();
}

View file

@ -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]);
}
}

View file

@ -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;
};

View file

@ -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) {

View file

@ -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: