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:
parent
fed826f6c3
commit
60e88ba7ad
2 changed files with 43 additions and 14 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 §ion);
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
Loading…
Reference in a new issue