trace_cpu.cc revision 7823:dac01f14f20f
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Erik Hallnor 29 */ 30 31/** 32 * @file 33 * Declaration of a memory trace CPU object. Uses a memory trace to drive the 34 * provided memory hierarchy. 35 */ 36 37#include <algorithm> // For min 38 39#include "cpu/trace/trace_cpu.hh" 40#include "cpu/trace/reader/mem_trace_reader.hh" 41#include "mem/base_mem.hh" // For PARAM constructor 42#include "mem/mem_interface.hh" 43#include "params/TraceCPU.hh" 44#include "sim/sim_events.hh" 45 46using namespace std; 47 48TraceCPU::TraceCPU(const string &name, 49 MemInterface *icache_interface, 50 MemInterface *dcache_interface, 51 MemTraceReader *data_trace) 52 : SimObject(name), icacheInterface(icache_interface), 53 dcacheInterface(dcache_interface), 54 dataTrace(data_trace), outstandingRequests(0), tickEvent(this) 55{ 56 assert(dcacheInterface); 57 nextCycle = dataTrace->getNextReq(nextReq); 58 tickEvent.schedule(0); 59} 60 61void 62TraceCPU::tick() 63{ 64 assert(outstandingRequests >= 0); 65 assert(outstandingRequests < 1000); 66 int instReqs = 0; 67 int dataReqs = 0; 68 69 while (nextReq && curTick() >= nextCycle) { 70 assert(nextReq->thread_num < 4 && "Not enough threads"); 71 if (nextReq->isInstFetch() && icacheInterface) { 72 if (icacheInterface->isBlocked()) 73 break; 74 75 nextReq->time = curTick(); 76 if (nextReq->cmd == Squash) { 77 icacheInterface->squash(nextReq->asid); 78 } else { 79 ++instReqs; 80 if (icacheInterface->doEvents()) { 81 nextReq->completionEvent = 82 new TraceCompleteEvent(nextReq, this); 83 icacheInterface->access(nextReq); 84 } else { 85 icacheInterface->access(nextReq); 86 completeRequest(nextReq); 87 } 88 } 89 } else { 90 if (dcacheInterface->isBlocked()) 91 break; 92 93 ++dataReqs; 94 nextReq->time = curTick(); 95 if (dcacheInterface->doEvents()) { 96 nextReq->completionEvent = 97 new TraceCompleteEvent(nextReq, this); 98 dcacheInterface->access(nextReq); 99 } else { 100 dcacheInterface->access(nextReq); 101 completeRequest(nextReq); 102 } 103 104 } 105 nextCycle = dataTrace->getNextReq(nextReq); 106 } 107 108 if (!nextReq) { 109 // No more requests to send. Finish trailing events and exit. 110 if (mainEventQueue.empty()) { 111 exitSimLoop("end of memory trace reached"); 112 } else { 113 tickEvent.schedule(mainEventQueue.nextEventTime() + ticks(1)); 114 } 115 } else { 116 tickEvent.schedule(max(curTick() + ticks(1), nextCycle)); 117 } 118} 119 120void 121TraceCPU::completeRequest(MemReqPtr& req) 122{ 123} 124 125void 126TraceCompleteEvent::process() 127{ 128 tester->completeRequest(req); 129} 130 131const char * 132TraceCompleteEvent::description() const 133{ 134 return "trace access complete"; 135} 136 137TraceCPU::TickEvent::TickEvent(TraceCPU *c) 138 : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) 139{ 140} 141 142void 143TraceCPU::TickEvent::process() 144{ 145 cpu->tick(); 146} 147 148const char * 149TraceCPU::TickEvent::description() const 150{ 151 return "TraceCPU tick"; 152} 153 154TraceCPU * 155TraceCPUParams::create() 156{ 157 return new TraceCPU(name, 158 (icache) ? icache->getInterface() : NULL, 159 (dcache) ? dcache->getInterface() : NULL, 160 data_trace); 161} 162