Merge zizzer:/z/m5/Bitkeeper/m5

into zazzer.eecs.umich.edu:/z/rdreslin/m5bk/clean

--HG--
extra : convert_revision : 09f035c902eedbf665cf7df8f72abdede4d8bea5
This commit is contained in:
Ron Dreslinski 2004-11-18 06:15:59 -05:00
commit 9061301b48
4 changed files with 97 additions and 25 deletions

View file

@ -28,9 +28,10 @@
// FIX ME: make trackBlkAddr use blocksize from actual cache, not hard coded // FIX ME: make trackBlkAddr use blocksize from actual cache, not hard coded
#include <string>
#include <sstream>
#include <iomanip> #include <iomanip>
#include <set>
#include <sstream>
#include <string>
#include <vector> #include <vector>
#include "base/misc.hh" #include "base/misc.hh"
@ -44,6 +45,8 @@
using namespace std; using namespace std;
int TESTER_ALLOCATOR=0;
MemTest::MemTest(const string &name, MemTest::MemTest(const string &name,
MemInterface *_cache_interface, MemInterface *_cache_interface,
FunctionalMemory *main_mem, FunctionalMemory *main_mem,
@ -111,6 +114,8 @@ MemTest::MemTest(const string &name,
noResponseCycles = 0; noResponseCycles = 0;
numReads = 0; numReads = 0;
tickEvent.schedule(0); tickEvent.schedule(0);
id = TESTER_ALLOCATOR++;
} }
static void static void
@ -127,6 +132,11 @@ printData(ostream &os, uint8_t *data, int nbytes)
void void
MemTest::completeRequest(MemReqPtr &req, uint8_t *data) MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
{ {
//Remove the address from the list of outstanding
std::set<unsigned>::iterator removeAddr = outstandingAddrs.find(req->paddr);
assert(removeAddr != outstandingAddrs.end());
outstandingAddrs.erase(removeAddr);
switch (req->cmd) { switch (req->cmd) {
case Read: case Read:
if (memcmp(req->data, data, req->size) != 0) { if (memcmp(req->data, data, req->size) != 0) {
@ -158,6 +168,10 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
break; break;
case Copy: case Copy:
//Also remove dest from outstanding list
removeAddr = outstandingAddrs.find(req->dest);
assert(removeAddr != outstandingAddrs.end());
outstandingAddrs.erase(removeAddr);
numCopiesStat++; numCopiesStat++;
break; break;
@ -212,7 +226,7 @@ MemTest::tick()
if (!tickEvent.scheduled()) if (!tickEvent.scheduled())
tickEvent.schedule(curTick + 1); tickEvent.schedule(curTick + 1);
if (++noResponseCycles >= 5000) { if (++noResponseCycles >= 500000) {
cerr << name() << ": deadlocked at cycle " << curTick << endl; cerr << name() << ": deadlocked at cycle " << curTick << endl;
fatal(""); fatal("");
} }
@ -232,6 +246,16 @@ MemTest::tick()
unsigned source_align = rand() % 100; unsigned source_align = rand() % 100;
unsigned dest_align = rand() % 100; unsigned dest_align = rand() % 100;
//If we aren't doing copies, use id as offset, and do a false sharing
//mem tester
if (percentCopies == 0) {
//We can eliminate the lower bits of the offset, and then use the id
//to offset within the blks
offset1 &= ~63; //Not the low order bits
offset1 += id;
access_size = 0;
}
MemReqPtr req = new MemReq(); MemReqPtr req = new MemReq();
if (cacheable < percentUncacheable) { if (cacheable < percentUncacheable) {
@ -251,6 +275,13 @@ MemTest::tick()
if (cmd < percentReads) { if (cmd < percentReads) {
// read // read
//For now we only allow one outstanding request per addreess per tester
//This means we assume CPU does write forwarding to reads that alias something
//in the cpu store buffer.
if (outstandingAddrs.find(req->paddr) != outstandingAddrs.end()) return;
else outstandingAddrs.insert(req->paddr);
req->cmd = Read; req->cmd = Read;
uint8_t *result = new uint8_t[8]; uint8_t *result = new uint8_t[8];
checkMem->access(Read, req->paddr, result, req->size); checkMem->access(Read, req->paddr, result, req->size);
@ -273,6 +304,13 @@ MemTest::tick()
} }
} else if (cmd < (100 - percentCopies)){ } else if (cmd < (100 - percentCopies)){
// write // write
//For now we only allow one outstanding request per addreess per tester
//This means we assume CPU does write forwarding to reads that alias something
//in the cpu store buffer.
if (outstandingAddrs.find(req->paddr) != outstandingAddrs.end()) return;
else outstandingAddrs.insert(req->paddr);
req->cmd = Write; req->cmd = Write;
memcpy(req->data, &data, req->size); memcpy(req->data, &data, req->size);
checkMem->access(Write, req->paddr, req->data, req->size); checkMem->access(Write, req->paddr, req->data, req->size);
@ -298,6 +336,11 @@ MemTest::tick()
// copy // copy
Addr source = ((base) ? baseAddr1 : baseAddr2) + offset1; Addr source = ((base) ? baseAddr1 : baseAddr2) + offset1;
Addr dest = ((base) ? baseAddr2 : baseAddr1) + offset2; Addr dest = ((base) ? baseAddr2 : baseAddr1) + offset2;
if (outstandingAddrs.find(source) != outstandingAddrs.end()) return;
else outstandingAddrs.insert(source);
if (outstandingAddrs.find(dest) != outstandingAddrs.end()) return;
else outstandingAddrs.insert(dest);
if (source_align >= percentSourceUnaligned) { if (source_align >= percentSourceUnaligned) {
source = blockAddr(source); source = blockAddr(source);
} }

View file

@ -29,13 +29,14 @@
#ifndef __MEMTEST_HH__ #ifndef __MEMTEST_HH__
#define __MEMTEST_HH__ #define __MEMTEST_HH__
#include "sim/sim_object.hh" #include <set>
#include "mem/mem_interface.hh"
#include "mem/functional_mem/functional_memory.hh"
#include "cpu/base_cpu.hh"
#include "cpu/exec_context.hh"
#include "base/statistics.hh" #include "base/statistics.hh"
#include "cpu/base_cpu.hh"
#include "cpu/exec_context.hh"
#include "mem/functional_mem/functional_memory.hh"
#include "mem/mem_interface.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh" #include "sim/stats.hh"
class MemTest : public BaseCPU class MemTest : public BaseCPU
@ -87,6 +88,10 @@ class MemTest : public BaseCPU
unsigned percentCopies; // target percentage of copy accesses unsigned percentCopies; // target percentage of copy accesses
unsigned percentUncacheable; unsigned percentUncacheable;
int id;
std::set<unsigned> outstandingAddrs;
unsigned blockSize; unsigned blockSize;
Addr blockAddrMask; Addr blockAddrMask;

View file

@ -414,21 +414,22 @@ template <class T>
Fault Fault
SimpleCPU::read(Addr addr, T &data, unsigned flags) SimpleCPU::read(Addr addr, T &data, unsigned flags)
{ {
if (status() == DcacheMissStall) {
Fault 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 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) {
memReq->cmd = Read; memReq->cmd = Read;
@ -444,6 +445,24 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
lastDcacheStall = curTick; lastDcacheStall = curTick;
unscheduleTickEvent(); unscheduleTickEvent();
_status = DcacheMissStall; _status = DcacheMissStall;
} else {
// do functional access
fault = xc->read(memReq, data);
if (traceData) {
traceData->setAddr(addr);
if (fault == No_Fault)
traceData->setData(data);
}
}
} else if(fault == No_Fault) {
// do functional access
fault = xc->read(memReq, data);
if (traceData) {
traceData->setAddr(addr);
if (fault == No_Fault)
traceData->setData(data);
} }
} }
@ -605,6 +624,9 @@ SimpleCPU::processCacheCompletion()
scheduleTickEvent(1); scheduleTickEvent(1);
break; break;
case DcacheMissStall: case DcacheMissStall:
if (memReq->cmd.isRead()) {
curStaticInst->execute(this,traceData);
}
dcacheStallCycles += curTick - lastDcacheStall; dcacheStallCycles += curTick - lastDcacheStall;
_status = Running; _status = Running;
scheduleTickEvent(1); scheduleTickEvent(1);
@ -750,10 +772,10 @@ SimpleCPU::tick()
comInstEventQueue[0]->serviceEvents(numInst); comInstEventQueue[0]->serviceEvents(numInst);
// decode the instruction // decode the instruction
inst = htoa(inst); inst = htoa(inst);
StaticInstPtr<TheISA> si(inst); curStaticInst = StaticInst<TheISA>::decode(inst);
traceData = Trace::getInstRecord(curTick, xc, this, si, traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst,
xc->regs.pc); xc->regs.pc);
#ifdef FULL_SYSTEM #ifdef FULL_SYSTEM
@ -762,18 +784,18 @@ SimpleCPU::tick()
xc->func_exe_inst++; xc->func_exe_inst++;
fault = si->execute(this, traceData); fault = curStaticInst->execute(this, traceData);
#ifdef FULL_SYSTEM #ifdef FULL_SYSTEM
if (xc->fnbin) if (xc->fnbin)
xc->execute(si.get()); xc->execute(curStaticInst.get());
#endif #endif
if (si->isMemRef()) { if (curStaticInst->isMemRef()) {
numMemRefs++; numMemRefs++;
} }
if (si->isLoad()) { if (curStaticInst->isLoad()) {
++numLoad; ++numLoad;
comLoadEventQueue[0]->serviceEvents(numLoad); comLoadEventQueue[0]->serviceEvents(numLoad);
} }

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> curStaticInst;
class CacheCompletionEvent : public Event class CacheCompletionEvent : public Event
{ {
private: private: