memtest.cc revision 3348
11689SN/A/* 22325SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Erik Hallnor 292756Sksewell@umich.edu * Steve Reinhardt 301689SN/A */ 311689SN/A 321858SN/A// FIX ME: make trackBlkAddr use blocksize from actual cache, not hard coded 332733Sktlim@umich.edu 341858SN/A#include <iomanip> 351858SN/A#include <set> 362356SN/A#include <string> 371060SN/A#include <vector> 381060SN/A 391060SN/A#include "base/misc.hh" 401060SN/A#include "base/statistics.hh" 411060SN/A#include "cpu/memtest/memtest.hh" 422325SN/A//#include "cpu/simple_thread.hh" 432683Sktlim@umich.edu//#include "mem/cache/base_cache.hh" 442680Sktlim@umich.edu#include "mem/mem_object.hh" 452817Sksewell@umich.edu#include "mem/port.hh" 461717SN/A#include "mem/packet.hh" 471060SN/A//#include "mem/physical.hh" 484167Sbinkertn@umich.edu#include "mem/request.hh" 492292SN/A#include "sim/builder.hh" 502292SN/A#include "sim/sim_events.hh" 512794Sktlim@umich.edu#include "sim/stats.hh" 522794Sktlim@umich.edu 532794Sktlim@umich.eduusing namespace std; 542794Sktlim@umich.edu 551060SN/Aint TESTER_ALLOCATOR=0; 562669Sktlim@umich.edu 571060SN/Abool 582733Sktlim@umich.eduMemTest::CpuPort::recvTiming(Packet *pkt) 592292SN/A{ 601060SN/A memtest->completeRequest(pkt); 611060SN/A return true; 621060SN/A} 632292SN/A 642733Sktlim@umich.eduTick 652292SN/AMemTest::CpuPort::recvAtomic(Packet *pkt) 662292SN/A{ 672292SN/A panic("MemTest doesn't expect recvAtomic callback!"); 682292SN/A return curTick; 691060SN/A} 701755SN/A 711060SN/Avoid 721060SN/AMemTest::CpuPort::recvFunctional(Packet *pkt) 731060SN/A{ 741060SN/A //Do nothing if we see one come through 751060SN/A// if (curTick != 0)//Supress warning durring initialization 761060SN/A// warn("Functional Writes not implemented in MemTester\n"); 771755SN/A //Need to find any response values that intersect and update 781060SN/A return; 791060SN/A} 801060SN/A 811060SN/Avoid 821060SN/AMemTest::CpuPort::recvStatusChange(Status status) 831060SN/A{ 841755SN/A if (status == RangeChange) 851060SN/A return; 861755SN/A 871060SN/A panic("MemTest doesn't expect recvStatusChange callback!"); 881060SN/A} 891060SN/A 902829Sksewell@umich.eduvoid 913221Sktlim@umich.eduMemTest::CpuPort::recvRetry() 922829Sksewell@umich.edu{ 932829Sksewell@umich.edu memtest->doRetry(); 942829Sksewell@umich.edu} 952829Sksewell@umich.edu 962829Sksewell@umich.eduvoid 972829Sksewell@umich.eduMemTest::sendPkt(Packet *pkt) { 982829Sksewell@umich.edu if (atomic) { 992829Sksewell@umich.edu cachePort.sendAtomic(pkt); 1002829Sksewell@umich.edu pkt->makeAtomicResponse(); 1012829Sksewell@umich.edu completeRequest(pkt); 1022829Sksewell@umich.edu } 1032829Sksewell@umich.edu else if (!cachePort.sendTiming(pkt)) { 1042829Sksewell@umich.edu accessRetry = true; 1052829Sksewell@umich.edu retryPkt = pkt; 1062829Sksewell@umich.edu } 1072829Sksewell@umich.edu 1082829Sksewell@umich.edu} 1092829Sksewell@umich.edu 1102829Sksewell@umich.eduMemTest::MemTest(const string &name, 1112829Sksewell@umich.edu// MemInterface *_cache_interface, 1122829Sksewell@umich.edu// PhysicalMemory *main_mem, 1132829Sksewell@umich.edu// PhysicalMemory *check_mem, 1142829Sksewell@umich.edu unsigned _memorySize, 1152829Sksewell@umich.edu unsigned _percentReads, 1162829Sksewell@umich.edu// unsigned _percentCopies, 1172829Sksewell@umich.edu unsigned _percentUncacheable, 1182829Sksewell@umich.edu unsigned _progressInterval, 1192875Sksewell@umich.edu unsigned _percentSourceUnaligned, 1203859Sbinkertn@umich.edu unsigned _percentDestUnaligned, 1212875Sksewell@umich.edu Addr _traceAddr, 1222875Sksewell@umich.edu Counter _max_loads, 1232875Sksewell@umich.edu bool _atomic) 1242875Sksewell@umich.edu : MemObject(name), 1252875Sksewell@umich.edu tickEvent(this), 1262875Sksewell@umich.edu cachePort("test", this), 1273859Sbinkertn@umich.edu funcPort("functional", this), 1282875Sksewell@umich.edu retryPkt(NULL), 1292875Sksewell@umich.edu// mainMem(main_mem), 1302875Sksewell@umich.edu// checkMem(check_mem), 1313859Sbinkertn@umich.edu size(_memorySize), 1322875Sksewell@umich.edu percentReads(_percentReads), 1332875Sksewell@umich.edu// percentCopies(_percentCopies), 1342875Sksewell@umich.edu percentUncacheable(_percentUncacheable), 1352875Sksewell@umich.edu progressInterval(_progressInterval), 1362875Sksewell@umich.edu nextProgressMessage(_progressInterval), 1372875Sksewell@umich.edu percentSourceUnaligned(_percentSourceUnaligned), 1382875Sksewell@umich.edu percentDestUnaligned(percentDestUnaligned), 1393221Sktlim@umich.edu maxLoads(_max_loads), 1403221Sktlim@umich.edu atomic(_atomic) 1412875Sksewell@umich.edu{ 1422875Sksewell@umich.edu vector<string> cmd; 1432875Sksewell@umich.edu cmd.push_back("/bin/ls"); 1442875Sksewell@umich.edu vector<string> null_vec; 1452875Sksewell@umich.edu // thread = new SimpleThread(NULL, 0, NULL, 0, mainMem); 1462875Sksewell@umich.edu curTick = 0; 1472875Sksewell@umich.edu 1482875Sksewell@umich.edu // Needs to be masked off once we know the block size. 1492875Sksewell@umich.edu traceBlockAddr = _traceAddr; 1502875Sksewell@umich.edu baseAddr1 = 0x100000; 1514329Sktlim@umich.edu baseAddr2 = 0x400000; 1522733Sktlim@umich.edu uncacheAddr = 0x800000; 1533781Sgblack@eecs.umich.edu 1543781Sgblack@eecs.umich.edu // set up counters 1553781Sgblack@eecs.umich.edu noResponseCycles = 0; 1563781Sgblack@eecs.umich.edu numReads = 0; 1571060SN/A tickEvent.schedule(0); 1582292SN/A 1594329Sktlim@umich.edu id = TESTER_ALLOCATOR++; 1604329Sktlim@umich.edu if (TESTER_ALLOCATOR > 8) 1614329Sktlim@umich.edu panic("False sharing memtester only allows up to 8 testers"); 1624329Sktlim@umich.edu 1634329Sktlim@umich.edu accessRetry = false; 1641060SN/A} 1654329Sktlim@umich.edu 1664329Sktlim@umich.eduPort * 1671060SN/AMemTest::getPort(const std::string &if_name, int idx) 1682831Sksewell@umich.edu{ 1692292SN/A if (if_name == "functional") 1702292SN/A return &funcPort; 1711060SN/A else if (if_name == "test") 1724329Sktlim@umich.edu return &cachePort; 1734329Sktlim@umich.edu else 1742292SN/A panic("No Such Port\n"); 1752292SN/A} 1761060SN/A 1772831Sksewell@umich.eduvoid 1782292SN/AMemTest::init() 1792292SN/A{ 1802292SN/A // By the time init() is called, the ports should be hooked up. 1812292SN/A blockSize = cachePort.peerBlockSize(); 1821060SN/A blockAddrMask = blockSize - 1; 1832873Sktlim@umich.edu traceBlockAddr = blockAddr(traceBlockAddr); 1842873Sktlim@umich.edu 1852873Sktlim@umich.edu // set up intial memory contents here 1862873Sktlim@umich.edu 1872873Sktlim@umich.edu cachePort.memsetBlob(baseAddr1, 1, size); 1882873Sktlim@umich.edu funcPort.memsetBlob(baseAddr1, 1, size); 1892873Sktlim@umich.edu cachePort.memsetBlob(baseAddr2, 2, size); 1902873Sktlim@umich.edu funcPort.memsetBlob(baseAddr2, 2, size); 1911060SN/A cachePort.memsetBlob(uncacheAddr, 3, size); 1921060SN/A funcPort.memsetBlob(uncacheAddr, 3, size); 1931858SN/A} 1942292SN/A 1951060SN/Astatic void 1961060SN/AprintData(ostream &os, uint8_t *data, int nbytes) 1972843Sktlim@umich.edu{ 1982316SN/A os << hex << setfill('0'); 1992316SN/A // assume little-endian: print bytes from highest address to lowest 2001060SN/A for (uint8_t *dp = data + nbytes - 1; dp >= data; --dp) { 2013221Sktlim@umich.edu os << setw(2) << (unsigned)*dp; 2023221Sktlim@umich.edu } 2033221Sktlim@umich.edu os << dec; 2043221Sktlim@umich.edu} 2053221Sktlim@umich.edu 2061681SN/Avoid 2072733Sktlim@umich.eduMemTest::completeRequest(Packet *pkt) 2082733Sktlim@umich.edu{ 2092794Sktlim@umich.edu MemTestSenderState *state = 2102733Sktlim@umich.edu dynamic_cast<MemTestSenderState *>(pkt->senderState); 2112316SN/A 2122316SN/A uint8_t *data = state->data; 2132316SN/A uint8_t *pkt_data = pkt->getPtr<uint8_t>(); 2142316SN/A Request *req = pkt->req; 2152316SN/A 2162794Sktlim@umich.edu //Remove the address from the list of outstanding 2172794Sktlim@umich.edu std::set<unsigned>::iterator removeAddr = outstandingAddrs.find(req->getPaddr()); 2182794Sktlim@umich.edu assert(removeAddr != outstandingAddrs.end()); 2192316SN/A outstandingAddrs.erase(removeAddr); 2202316SN/A 2211858SN/A switch (pkt->cmd) { 2222292SN/A case Packet::ReadResp: 2232292SN/A 2241681SN/A if (memcmp(pkt_data, data, pkt->getSize()) != 0) { 2251681SN/A cerr << name() << ": on read of 0x" << hex << req->getPaddr() 2262325SN/A << " (0x" << hex << blockAddr(req->getPaddr()) << ")" 2272325SN/A << "@ cycle " << dec << curTick 2282325SN/A << ", cache returns 0x"; 2291060SN/A printData(cerr, pkt_data, pkt->getSize()); 2302292SN/A cerr << ", expected 0x"; 2312292SN/A printData(cerr, data, pkt->getSize()); 2322292SN/A cerr << endl; 2332292SN/A fatal(""); 2342292SN/A } 2352292SN/A 2361060SN/A numReads++; 2371060SN/A numReadsStat++; 2381060SN/A 2391060SN/A if (numReads == nextProgressMessage) { 2401060SN/A ccprintf(cerr, "%s: completed %d read accesses @%d\n", 2411060SN/A name(), numReads, curTick); 2421060SN/A nextProgressMessage += progressInterval; 2431060SN/A } 2441060SN/A 2451060SN/A if (numReads >= maxLoads) 2461060SN/A exitSimLoop("Maximum number of loads reached!"); 2472292SN/A break; 2481060SN/A 2491060SN/A case Packet::WriteResp: 2501060SN/A numWritesStat++; 2511060SN/A break; 2521060SN/A/* 2531060SN/A case Copy: 2541060SN/A //Also remove dest from outstanding list 2551060SN/A removeAddr = outstandingAddrs.find(req->dest); 2562292SN/A assert(removeAddr != outstandingAddrs.end()); 2572292SN/A outstandingAddrs.erase(removeAddr); 2582292SN/A numCopiesStat++; 2592292SN/A break; 2602292SN/A*/ 2612307SN/A default: 2622831Sksewell@umich.edu panic("invalid command"); 2632831Sksewell@umich.edu } 2642831Sksewell@umich.edu 2652831Sksewell@umich.edu if (blockAddr(req->getPaddr()) == traceBlockAddr) { 2662831Sksewell@umich.edu cerr << name() << ": completed " 2672831Sksewell@umich.edu << (pkt->isWrite() ? "write" : "read") 2682292SN/A << " access of " 2692307SN/A << dec << pkt->getSize() << " bytes at address 0x" 2702292SN/A << hex << req->getPaddr() 2712292SN/A << " (0x" << hex << blockAddr(req->getPaddr()) << ")" 2722316SN/A << ", value = 0x"; 2732292SN/A printData(cerr, pkt_data, pkt->getSize()); 2742292SN/A cerr << " @ cycle " << dec << curTick; 2752292SN/A 2762292SN/A cerr << endl; 2772292SN/A } 2782292SN/A 2791060SN/A noResponseCycles = 0; 2802292SN/A delete state; 2812292SN/A delete [] data; 2821060SN/A delete pkt->req; 2832292SN/A delete pkt; 2842307SN/A} 2852292SN/A 2862292SN/Avoid 2872292SN/AMemTest::regStats() 2882325SN/A{ 2892292SN/A using namespace Stats; 2902292SN/A 2912292SN/A numReadsStat 2922325SN/A .name(name() + ".num_reads") 2932292SN/A .desc("number of read accesses completed") 2942292SN/A ; 2952292SN/A 2962292SN/A numWritesStat 2972292SN/A .name(name() + ".num_writes") 2982292SN/A .desc("number of write accesses completed") 2992292SN/A ; 3002292SN/A 3012292SN/A numCopiesStat 3022292SN/A .name(name() + ".num_copies") 3032292SN/A .desc("number of copy accesses completed") 3042325SN/A ; 3052292SN/A} 3062292SN/A 3072292SN/Avoid 3082325SN/AMemTest::tick() 3092292SN/A{ 3102292SN/A if (!tickEvent.scheduled()) 3112292SN/A tickEvent.schedule(curTick + cycles(1)); 3122292SN/A 3132292SN/A if (++noResponseCycles >= 500000) { 3142292SN/A cerr << name() << ": deadlocked at cycle " << curTick << endl; 3152292SN/A fatal(""); 3162292SN/A } 3173221Sktlim@umich.edu 3183221Sktlim@umich.edu if (accessRetry) { 3193221Sktlim@umich.edu return; 3202292SN/A } 3212292SN/A 3222292SN/A //make new request 3232292SN/A unsigned cmd = random() % 100; 3242292SN/A unsigned offset = random() % size; 3252292SN/A unsigned base = random() % 2; 3262292SN/A uint64_t data = random(); 3272292SN/A unsigned access_size = random() % 4; 3282292SN/A unsigned cacheable = random() % 100; 3291060SN/A 3302292SN/A //If we aren't doing copies, use id as offset, and do a false sharing 3311060SN/A //mem tester 3321060SN/A //We can eliminate the lower bits of the offset, and then use the id 3332292SN/A //to offset within the blks 3342292SN/A offset &= ~63; //Not the low order bits 3352292SN/A offset += id; 3362829Sksewell@umich.edu access_size = 0; 3372829Sksewell@umich.edu 3383093Sksewell@umich.edu Request *req = new Request(); 3393093Sksewell@umich.edu uint32_t flags = 0; 3403093Sksewell@umich.edu Addr paddr; 3413093Sksewell@umich.edu 3423093Sksewell@umich.edu if (cacheable < percentUncacheable) { 3432292SN/A flags |= UNCACHEABLE; 3441060SN/A paddr = uncacheAddr + offset; 3451060SN/A } else { 3461060SN/A paddr = ((base) ? baseAddr1 : baseAddr2) + offset; 3471755SN/A } 3481060SN/A bool probe = (random() % 2 == 1) && !(flags & UNCACHEABLE); 3491060SN/A //bool probe = false; 3501060SN/A 3511060SN/A paddr &= ~((1 << access_size) - 1); 3521060SN/A req->setPhys(paddr, 1 << access_size, flags); 3531755SN/A req->setThreadContext(id,0); 3541062SN/A 3552733Sktlim@umich.edu uint8_t *result = new uint8_t[8]; 3562292SN/A 3572733Sktlim@umich.edu if (cmd < percentReads) { 3582292SN/A // read 3592292SN/A 3602292SN/A //For now we only allow one outstanding request per addreess per tester 3612292SN/A //This means we assume CPU does write forwarding to reads that alias something 3622292SN/A //in the cpu store buffer. 3632292SN/A if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) { 3642292SN/A delete result; 3652292SN/A delete req; 3662292SN/A return; 3672292SN/A } 3682292SN/A else outstandingAddrs.insert(paddr); 3692292SN/A 3702292SN/A // ***** NOTE FOR RON: I'm not sure how to access checkMem. - Kevin 3712292SN/A funcPort.readBlob(req->getPaddr(), result, req->getSize()); 3722292SN/A 3732292SN/A if (blockAddr(paddr) == traceBlockAddr) { 3742292SN/A cerr << name() 3752292SN/A << ": initiating read " 3762292SN/A << ((probe) ? "probe of " : "access of ") 3772292SN/A << dec << req->getSize() << " bytes from addr 0x" 3782292SN/A << hex << paddr 3792292SN/A << " (0x" << hex << blockAddr(paddr) << ")" 3802292SN/A << " at cycle " 3812292SN/A << dec << curTick << endl; 3822292SN/A } 3832292SN/A 3842292SN/A Packet *pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast); 3852292SN/A pkt->dataDynamicArray(new uint8_t[req->getSize()]); 3862292SN/A MemTestSenderState *state = new MemTestSenderState(result); 3872292SN/A pkt->senderState = state; 3882292SN/A 3892292SN/A if (probe) { 3902292SN/A cachePort.sendFunctional(pkt); 3912292SN/A pkt->makeAtomicResponse(); 3922292SN/A completeRequest(pkt); 3932292SN/A } else { 3942292SN/A// req->completionEvent = new MemCompleteEvent(req, result, this); 3952292SN/A sendPkt(pkt); 3962292SN/A } 3972292SN/A } else { 3982292SN/A // write 3992292SN/A 4002292SN/A //For now we only allow one outstanding request per addreess per tester 4012292SN/A //This means we assume CPU does write forwarding to reads that alias something 4022292SN/A //in the cpu store buffer. 4032292SN/A if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) { 4042292SN/A delete [] result; 4052292SN/A delete req; 4062292SN/A return; 4071062SN/A } 4081062SN/A 4091062SN/A else outstandingAddrs.insert(paddr); 4102871Sktlim@umich.edu 4112871Sktlim@umich.edu/* 4122871Sktlim@umich.edu if (blockAddr(req->getPaddr()) == traceBlockAddr) { 4132871Sktlim@umich.edu cerr << name() << ": initiating write " 4142871Sktlim@umich.edu << ((probe)?"probe of ":"access of ") 4152871Sktlim@umich.edu << dec << req->getSize() << " bytes (value = 0x"; 4162871Sktlim@umich.edu printData(cerr, data_pkt->getPtr(), req->getSize()); 4172871Sktlim@umich.edu cerr << ") to addr 0x" 4182871Sktlim@umich.edu << hex << req->getPaddr() 4192871Sktlim@umich.edu << " (0x" << hex << blockAddr(req->getPaddr()) << ")" 4202871Sktlim@umich.edu << " at cycle " 4212871Sktlim@umich.edu << dec << curTick << endl; 4221062SN/A } 4231755SN/A*/ 4241060SN/A Packet *pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast); 4252733Sktlim@umich.edu uint8_t *pkt_data = new uint8_t[req->getSize()]; 4261060SN/A pkt->dataDynamicArray(pkt_data); 4272292SN/A memcpy(pkt_data, &data, req->getSize()); 4282292SN/A MemTestSenderState *state = new MemTestSenderState(result); 4292325SN/A pkt->senderState = state; 4302292SN/A 4312292SN/A funcPort.writeBlob(req->getPaddr(), pkt_data, req->getSize()); 4321060SN/A 4331060SN/A if (probe) { 4341060SN/A cachePort.sendFunctional(pkt); 4351060SN/A pkt->makeAtomicResponse(); 4361060SN/A completeRequest(pkt); 4371060SN/A } else { 4381060SN/A// req->completionEvent = new MemCompleteEvent(req, NULL, this); 4391060SN/A sendPkt(pkt); 4401060SN/A } 4411060SN/A } 4422292SN/A/* else { 4432292SN/A // copy 4442292SN/A unsigned source_align = random() % 100; 4452292SN/A unsigned dest_align = random() % 100; 4462292SN/A unsigned offset2 = random() % size; 4471060SN/A 4481060SN/A Addr source = ((base) ? baseAddr1 : baseAddr2) + offset; 4491060SN/A Addr dest = ((base) ? baseAddr2 : baseAddr1) + offset2; 4501060SN/A if (outstandingAddrs.find(source) != outstandingAddrs.end()) return; 4511060SN/A else outstandingAddrs.insert(source); 4521060SN/A if (outstandingAddrs.find(dest) != outstandingAddrs.end()) return; 4531060SN/A else outstandingAddrs.insert(dest); 4542325SN/A 4552292SN/A if (source_align >= percentSourceUnaligned) { 4562292SN/A source = blockAddr(source); 4572292SN/A } 4582292SN/A if (dest_align >= percentDestUnaligned) { 4592292SN/A dest = blockAddr(dest); 4602325SN/A } 4612867Sktlim@umich.edu req->cmd = Copy; 4622905Sktlim@umich.edu req->flags &= ~UNCACHEABLE; 4633226Sktlim@umich.edu req->paddr = source; 4642325SN/A req->dest = dest; 4652325SN/A delete [] req->data; 4663221Sktlim@umich.edu req->data = new uint8_t[blockSize]; 4673226Sktlim@umich.edu req->size = blockSize; 4682325SN/A if (source == traceBlockAddr || dest == traceBlockAddr) { 4692325SN/A cerr << name() 4702325SN/A << ": initiating copy of " 4714030Sktlim@umich.edu << dec << req->size << " bytes from addr 0x" 4723226Sktlim@umich.edu << hex << source 4732325SN/A << " (0x" << hex << blockAddr(source) << ")" 4742292SN/A << " to addr 0x" 4752292SN/A << hex << dest 4762292SN/A << " (0x" << hex << blockAddr(dest) << ")" 4772292SN/A << " at cycle " 4782292SN/A << dec << curTick << endl; 4792292SN/A }* 4801060SN/A cacheInterface->access(req); 4811060SN/A uint8_t result[blockSize]; 4821060SN/A checkMem->access(Read, source, &result, blockSize); 4831060SN/A checkMem->access(Write, dest, &result, blockSize); 4841755SN/A } 4851060SN/A*/ 4862307SN/A} 4872680Sktlim@umich.edu 4882292SN/Avoid 4891060SN/AMemTest::doRetry() 4902292SN/A{ 4912292SN/A if (cachePort.sendTiming(retryPkt)) { 4922292SN/A accessRetry = false; 4932292SN/A retryPkt = NULL; 4942292SN/A } 4952292SN/A} 4961858SN/A 4972680Sktlim@umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest) 4981681SN/A 4992680Sktlim@umich.edu// SimObjectParam<BaseCache *> cache; 5001681SN/A// SimObjectParam<PhysicalMemory *> main_mem; 5012292SN/A// SimObjectParam<PhysicalMemory *> check_mem; 5022680Sktlim@umich.edu Param<unsigned> memory_size; 5032292SN/A Param<unsigned> percent_reads; 5041060SN/A// Param<unsigned> percent_copies; 5051060SN/A Param<unsigned> percent_uncacheable; 5062292SN/A Param<unsigned> progress_interval; 5072680Sktlim@umich.edu Param<unsigned> percent_source_unaligned; 5082292SN/A Param<unsigned> percent_dest_unaligned; 5092292SN/A Param<Addr> trace_addr; 5102292SN/A Param<Counter> max_loads; 5112292SN/A Param<bool> atomic; 5122292SN/A 5132292SN/AEND_DECLARE_SIM_OBJECT_PARAMS(MemTest) 5142292SN/A 5152316SN/A 5162292SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(MemTest) 5172292SN/A 5182292SN/A// INIT_PARAM(cache, "L1 cache"), 5192292SN/A// INIT_PARAM(main_mem, "hierarchical memory"), 5202292SN/A// INIT_PARAM(check_mem, "check memory"), 5212292SN/A INIT_PARAM(memory_size, "memory size"), 5222292SN/A INIT_PARAM(percent_reads, "target read percentage"), 5232292SN/A// INIT_PARAM(percent_copies, "target copy percentage"), 5242292SN/A INIT_PARAM(percent_uncacheable, "target uncacheable percentage"), 5252292SN/A INIT_PARAM(progress_interval, "progress report interval (in accesses)"), 5262875Sksewell@umich.edu INIT_PARAM(percent_source_unaligned, 5272875Sksewell@umich.edu "percent of copy source address that are unaligned"), 5282875Sksewell@umich.edu INIT_PARAM(percent_dest_unaligned, 5292875Sksewell@umich.edu "percent of copy dest address that are unaligned"), 5302875Sksewell@umich.edu INIT_PARAM(trace_addr, "address to trace"), 5313226Sktlim@umich.edu INIT_PARAM(max_loads, "terminate when we have reached this load count"), 5323226Sktlim@umich.edu INIT_PARAM(atomic, "Is the tester testing atomic mode (or timing)") 5332875Sksewell@umich.edu 5342875Sksewell@umich.eduEND_INIT_SIM_OBJECT_PARAMS(MemTest) 5352875Sksewell@umich.edu 5362875Sksewell@umich.edu 5372875Sksewell@umich.eduCREATE_SIM_OBJECT(MemTest) 5382875Sksewell@umich.edu{ 5392875Sksewell@umich.edu return new MemTest(getInstanceName(), /*cache->getInterface(),*/ /*main_mem,*/ 5402875Sksewell@umich.edu /*check_mem,*/ memory_size, percent_reads, /*percent_copies,*/ 5412875Sksewell@umich.edu percent_uncacheable, progress_interval, 5422875Sksewell@umich.edu percent_source_unaligned, percent_dest_unaligned, 5432875Sksewell@umich.edu trace_addr, max_loads, atomic); 5442875Sksewell@umich.edu} 5452875Sksewell@umich.edu 5462875Sksewell@umich.eduREGISTER_SIM_OBJECT("MemTest", MemTest) 5472875Sksewell@umich.edu