diff options
Diffstat (limited to 'cpu/memtest/memtest.cc')
-rw-r--r-- | cpu/memtest/memtest.cc | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc index b55af332a..e967c79da 100644 --- a/cpu/memtest/memtest.cc +++ b/cpu/memtest/memtest.cc @@ -28,9 +28,10 @@ // FIX ME: make trackBlkAddr use blocksize from actual cache, not hard coded -#include <string> -#include <sstream> #include <iomanip> +#include <set> +#include <sstream> +#include <string> #include <vector> #include "base/misc.hh" @@ -44,6 +45,8 @@ using namespace std; +int TESTER_ALLOCATOR=0; + MemTest::MemTest(const string &name, MemInterface *_cache_interface, FunctionalMemory *main_mem, @@ -58,7 +61,8 @@ MemTest::MemTest(const string &name, Addr _traceAddr, Counter max_loads_any_thread, Counter max_loads_all_threads) - : BaseCPU(name, 1, 0, 0, max_loads_any_thread, max_loads_all_threads), + : BaseCPU(name, 1, true, 0, 0, max_loads_any_thread, + max_loads_all_threads), tickEvent(this), cacheInterface(_cache_interface), mainMem(main_mem), @@ -110,6 +114,8 @@ MemTest::MemTest(const string &name, noResponseCycles = 0; numReads = 0; tickEvent.schedule(0); + + id = TESTER_ALLOCATOR++; } static void @@ -126,6 +132,11 @@ printData(ostream &os, uint8_t *data, int nbytes) void 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) { case Read: if (memcmp(req->data, data, req->size) != 0) { @@ -157,6 +168,10 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data) break; case Copy: + //Also remove dest from outstanding list + removeAddr = outstandingAddrs.find(req->dest); + assert(removeAddr != outstandingAddrs.end()); + outstandingAddrs.erase(removeAddr); numCopiesStat++; break; @@ -211,7 +226,7 @@ MemTest::tick() if (!tickEvent.scheduled()) tickEvent.schedule(curTick + 1); - if (++noResponseCycles >= 5000) { + if (++noResponseCycles >= 500000) { cerr << name() << ": deadlocked at cycle " << curTick << endl; fatal(""); } @@ -231,6 +246,16 @@ MemTest::tick() unsigned source_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(); if (cacheable < percentUncacheable) { @@ -250,6 +275,13 @@ MemTest::tick() if (cmd < percentReads) { // 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; uint8_t *result = new uint8_t[8]; checkMem->access(Read, req->paddr, result, req->size); @@ -272,6 +304,13 @@ MemTest::tick() } } else if (cmd < (100 - percentCopies)){ // 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; memcpy(req->data, &data, req->size); checkMem->access(Write, req->paddr, req->data, req->size); @@ -297,6 +336,11 @@ MemTest::tick() // copy Addr source = ((base) ? baseAddr1 : baseAddr2) + offset1; 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) { source = blockAddr(source); } |