Changes to use siinic:

Changed SimpleCPU to not due functional access until the cache returns
Updated config file to use a simple cpu for second cpu in dual mode.

cpu/simple_cpu/simple_cpu.cc:
cpu/simple_cpu/simple_cpu.hh:
    Update cache completion event to perform the functional read upon completion

--HG--
extra : convert_revision : 7a5b318d2040580fae92c165611425f513b14be9
This commit is contained in:
Ron Dreslinski 2004-11-17 23:26:43 -05:00
parent fed826f6c3
commit 60e88ba7ad
2 changed files with 43 additions and 14 deletions

View file

@ -103,7 +103,7 @@ SimpleCPU::CacheCompletionEvent::CacheCompletionEvent(SimpleCPU *_cpu)
void SimpleCPU::CacheCompletionEvent::process() void SimpleCPU::CacheCompletionEvent::process()
{ {
cpu->processCacheCompletion(); cpu->processCacheCompletion(read);
} }
const char * const char *
@ -414,20 +414,24 @@ template <class T>
Fault Fault
SimpleCPU::read(Addr addr, T &data, unsigned flags) SimpleCPU::read(Addr addr, T &data, unsigned flags)
{ {
Fault fault;
if (status() == DcacheMissStall) {
//Just do the functional access
fault = xc->read(memReq, data);
if (traceData) {
traceData->setAddr(addr);
if (fault == No_Fault)
traceData->setData(data);
}
return fault;
}
memReq->reset(addr, sizeof(T), flags); memReq->reset(addr, sizeof(T), flags);
// translate to physical address // translate to physical address
Fault fault = xc->translateDataReadReq(memReq); fault = xc->translateDataReadReq(memReq);
// do functional access
if (fault == No_Fault)
fault = xc->read(memReq, data);
if (traceData) {
traceData->setAddr(addr);
if (fault == No_Fault)
traceData->setData(data);
}
// if we have a cache, do cache access too // if we have a cache, do cache access too
if (fault == No_Fault && dcacheInterface) { if (fault == No_Fault && dcacheInterface) {
@ -440,11 +444,25 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
// a miss. We really should add first-class support for this // a miss. We really should add first-class support for this
// at some point. // at some point.
if (result != MA_HIT && dcacheInterface->doEvents()) { if (result != MA_HIT && dcacheInterface->doEvents()) {
cacheCompletionEvent.read = true;
memReq->completionEvent = &cacheCompletionEvent; memReq->completionEvent = &cacheCompletionEvent;
//May later want to pass the staticinst as well, so it can call
//it independantly
lastDcacheStall = curTick; lastDcacheStall = curTick;
unscheduleTickEvent(); unscheduleTickEvent();
_status = DcacheMissStall; _status = DcacheMissStall;
} }
else {
// do functional access
if (fault == No_Fault)
fault = xc->read(memReq, data);
if (traceData) {
traceData->setAddr(addr);
if (fault == No_Fault)
traceData->setData(data);
}
}
} }
if (!dcacheInterface && (memReq->flags & UNCACHEABLE)) if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
@ -525,6 +543,7 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
// a miss. We really should add first-class support for this // a miss. We really should add first-class support for this
// at some point. // at some point.
if (result != MA_HIT && dcacheInterface->doEvents()) { if (result != MA_HIT && dcacheInterface->doEvents()) {
cacheCompletionEvent.read = false;
memReq->completionEvent = &cacheCompletionEvent; memReq->completionEvent = &cacheCompletionEvent;
lastDcacheStall = curTick; lastDcacheStall = curTick;
unscheduleTickEvent(); unscheduleTickEvent();
@ -596,7 +615,7 @@ Tick save_cycle = 0;
void void
SimpleCPU::processCacheCompletion() SimpleCPU::processCacheCompletion(bool read)
{ {
switch (status()) { switch (status()) {
case IcacheMissStall: case IcacheMissStall:
@ -606,6 +625,9 @@ SimpleCPU::processCacheCompletion()
break; break;
case DcacheMissStall: case DcacheMissStall:
dcacheStallCycles += curTick - lastDcacheStall; dcacheStallCycles += curTick - lastDcacheStall;
if (read) {
globalsi->execute(this,traceData);
}
_status = Running; _status = Running;
scheduleTickEvent(1); scheduleTickEvent(1);
break; break;
@ -729,6 +751,7 @@ SimpleCPU::tick()
// a miss. We really should add first-class support for this // a miss. We really should add first-class support for this
// at some point. // at some point.
if (result != MA_HIT && icacheInterface->doEvents()) { if (result != MA_HIT && icacheInterface->doEvents()) {
cacheCompletionEvent.read = false;
memReq->completionEvent = &cacheCompletionEvent; memReq->completionEvent = &cacheCompletionEvent;
lastIcacheStall = curTick; lastIcacheStall = curTick;
unscheduleTickEvent(); unscheduleTickEvent();
@ -753,6 +776,8 @@ SimpleCPU::tick()
inst = htoa(inst); inst = htoa(inst);
StaticInstPtr<TheISA> si(inst); StaticInstPtr<TheISA> si(inst);
globalsi = si;
traceData = Trace::getInstRecord(curTick, xc, this, si, traceData = Trace::getInstRecord(curTick, xc, this, si,
xc->regs.pc); xc->regs.pc);

View file

@ -184,6 +184,8 @@ class SimpleCPU : public BaseCPU
// Refcounted pointer to the one memory request. // Refcounted pointer to the one memory request.
MemReqPtr memReq; MemReqPtr memReq;
StaticInstPtr<TheISA> globalsi;
class CacheCompletionEvent : public Event class CacheCompletionEvent : public Event
{ {
private: private:
@ -192,6 +194,8 @@ class SimpleCPU : public BaseCPU
public: public:
CacheCompletionEvent(SimpleCPU *_cpu); CacheCompletionEvent(SimpleCPU *_cpu);
bool read;
virtual void process(); virtual void process();
virtual const char *description(); virtual const char *description();
}; };
@ -238,7 +242,7 @@ class SimpleCPU : public BaseCPU
Stats::Scalar<> dcacheStallCycles; Stats::Scalar<> dcacheStallCycles;
Counter lastDcacheStall; Counter lastDcacheStall;
void processCacheCompletion(); void processCacheCompletion(bool read);
virtual void serialize(std::ostream &os); virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section); virtual void unserialize(Checkpoint *cp, const std::string &section);