diff options
Diffstat (limited to 'src/cpu/trace')
-rw-r--r-- | src/cpu/trace/opt_cpu.cc | 239 | ||||
-rw-r--r-- | src/cpu/trace/opt_cpu.hh | 223 | ||||
-rw-r--r-- | src/cpu/trace/reader/ibm_reader.cc | 120 | ||||
-rw-r--r-- | src/cpu/trace/reader/ibm_reader.hh | 73 | ||||
-rw-r--r-- | src/cpu/trace/reader/itx_reader.cc | 206 | ||||
-rw-r--r-- | src/cpu/trace/reader/itx_reader.hh | 84 | ||||
-rw-r--r-- | src/cpu/trace/reader/m5_reader.cc | 97 | ||||
-rw-r--r-- | src/cpu/trace/reader/m5_reader.hh | 67 | ||||
-rw-r--r-- | src/cpu/trace/reader/mem_trace_reader.cc | 37 | ||||
-rw-r--r-- | src/cpu/trace/reader/mem_trace_reader.hh | 57 | ||||
-rw-r--r-- | src/cpu/trace/trace_cpu.cc | 179 | ||||
-rw-r--r-- | src/cpu/trace/trace_cpu.hh | 140 |
12 files changed, 1522 insertions, 0 deletions
diff --git a/src/cpu/trace/opt_cpu.cc b/src/cpu/trace/opt_cpu.cc new file mode 100644 index 000000000..6cd23b0dd --- /dev/null +++ b/src/cpu/trace/opt_cpu.cc @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Definition of a memory trace CPU object for optimal caches. Uses a memory + * trace to access a fully associative cache with optimal replacement. + */ + +#include <algorithm> // For heap functions. + +#include "cpu/trace/opt_cpu.hh" +#include "cpu/trace/reader/mem_trace_reader.hh" + +#include "sim/builder.hh" +#include "sim/sim_events.hh" + +using namespace std; + +OptCPU::OptCPU(const string &name, + MemTraceReader *_trace, + int block_size, + int cache_size, + int _assoc) + : SimObject(name), tickEvent(this), trace(_trace), + numBlks(cache_size/block_size), assoc(_assoc), numSets(numBlks/assoc), + setMask(numSets - 1) +{ + int log_block_size = 0; + int tmp_block_size = block_size; + while (tmp_block_size > 1) { + ++log_block_size; + tmp_block_size = tmp_block_size >> 1; + } + assert(1<<log_block_size == block_size); + MemReqPtr req; + trace->getNextReq(req); + refInfo.resize(numSets); + while (req) { + RefInfo temp; + temp.addr = req->paddr >> log_block_size; + int set = temp.addr & setMask; + refInfo[set].push_back(temp); + trace->getNextReq(req); + } + + // Initialize top level of lookup table. + lookupTable.resize(16); + + // Annotate references with next ref time. + for (int k = 0; k < numSets; ++k) { + for (RefIndex i = refInfo[k].size() - 1; i >= 0; --i) { + Addr addr = refInfo[k][i].addr; + initTable(addr, InfiniteRef); + refInfo[k][i].nextRefTime = lookupValue(addr); + setValue(addr, i); + } + } + + // Reset the lookup table + for (int j = 0; j < 16; ++j) { + if (lookupTable[j].size() == (1<<16)) { + for (int k = 0; k < (1<<16); ++k) { + if (lookupTable[j][k].size() == (1<<16)) { + for (int l = 0; l < (1<<16); ++l) { + lookupTable[j][k][l] = -1; + } + } + } + } + } + + tickEvent.schedule(0); + + hits = 0; + misses = 0; +} + +void +OptCPU::processSet(int set) +{ + // Initialize cache + int blks_in_cache = 0; + RefIndex i = 0; + cacheHeap.clear(); + cacheHeap.resize(assoc); + + while (blks_in_cache < assoc) { + RefIndex cache_index = lookupValue(refInfo[set][i].addr); + if (cache_index == -1) { + // First reference to this block + misses++; + cache_index = blks_in_cache++; + setValue(refInfo[set][i].addr, cache_index); + } else { + hits++; + } + // update cache heap to most recent reference + cacheHeap[cache_index] = i; + if (++i >= refInfo[set].size()) { + return; + } + } + for (int start = assoc/2; start >= 0; --start) { + heapify(set,start); + } + //verifyHeap(set,0); + + for (; i < refInfo[set].size(); ++i) { + RefIndex cache_index = lookupValue(refInfo[set][i].addr); + if (cache_index == -1) { + // miss + misses++; + // replace from cacheHeap[0] + // mark replaced block as absent + setValue(refInfo[set][cacheHeap[0]].addr, -1); + setValue(refInfo[set][i].addr, 0); + cacheHeap[0] = i; + heapify(set, 0); + // Make sure its in the cache + assert(lookupValue(refInfo[set][i].addr) != -1); + } else { + // hit + hits++; + assert(refInfo[set][cacheHeap[cache_index]].addr == + refInfo[set][i].addr); + assert(refInfo[set][cacheHeap[cache_index]].nextRefTime == i); + assert(heapLeft(cache_index) >= assoc); + + cacheHeap[cache_index] = i; + processRankIncrease(set, cache_index); + assert(lookupValue(refInfo[set][i].addr) != -1); + } + } +} +void +OptCPU::tick() +{ + // Do opt simulation + + int references = 0; + for (int set = 0; set < numSets; ++set) { + if (!refInfo[set].empty()) { + processSet(set); + } + references += refInfo[set].size(); + } + // exit; + fprintf(stderr,"sys.cpu.misses %d #opt cache misses\n",misses); + fprintf(stderr,"sys.cpu.hits %d #opt cache hits\n", hits); + fprintf(stderr,"sys.cpu.accesses %d #opt cache acceses\n", references); + new SimExitEvent("Finshed Memory Trace"); +} + +void +OptCPU::initTable(Addr addr, RefIndex index) +{ + int l1_index = (addr >> 32) & 0x0f; + int l2_index = (addr >> 16) & 0xffff; + assert(l1_index == addr >> 32); + if (lookupTable[l1_index].size() != (1<<16)) { + lookupTable[l1_index].resize(1<<16); + } + if (lookupTable[l1_index][l2_index].size() != (1<<16)) { + lookupTable[l1_index][l2_index].resize(1<<16, index); + } +} + +OptCPU::TickEvent::TickEvent(OptCPU *c) + : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) +{ +} + +void +OptCPU::TickEvent::process() +{ + cpu->tick(); +} + +const char * +OptCPU::TickEvent::description() +{ + return "OptCPU tick event"; +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(OptCPU) + + SimObjectParam<MemTraceReader *> data_trace; + Param<int> size; + Param<int> block_size; +Param<int> assoc; + +END_DECLARE_SIM_OBJECT_PARAMS(OptCPU) + +BEGIN_INIT_SIM_OBJECT_PARAMS(OptCPU) + + INIT_PARAM_DFLT(data_trace, "memory trace", NULL), + INIT_PARAM(size, "cache size"), + INIT_PARAM(block_size, "block size"), + INIT_PARAM(assoc,"associativity") + +END_INIT_SIM_OBJECT_PARAMS(OptCPU) + +CREATE_SIM_OBJECT(OptCPU) +{ + return new OptCPU(getInstanceName(), + data_trace, + block_size, + size, + assoc); +} + +REGISTER_SIM_OBJECT("OptCPU", OptCPU) diff --git a/src/cpu/trace/opt_cpu.hh b/src/cpu/trace/opt_cpu.hh new file mode 100644 index 000000000..f81691733 --- /dev/null +++ b/src/cpu/trace/opt_cpu.hh @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Declaration of a memory trace CPU object for optimal caches. Uses a memory + * trace to access a fully associative cache with optimal replacement. + */ + +#ifndef __CPU_TRACE_OPT_CPU_HH__ +#define __CPU_TRACE_OPT_CPU_HH__ + +#include <vector> + +#include "mem/mem_req.hh" // for MemReqPtr +#include "sim/eventq.hh" // for Event +#include "sim/sim_object.hh" + +// Forward Declaration +class MemTraceReader; + +/** + * A CPU object to simulate a fully-associative cache with optimal replacement. + */ +class OptCPU : public SimObject +{ + private: + typedef int RefIndex; + + typedef std::vector<RefIndex> L3Table; + typedef std::vector<L3Table> L2Table; + typedef std::vector<L2Table> L1Table; + + /** + * Event to call OptCPU::tick + */ + class TickEvent : public Event + { + private: + /** The associated CPU */ + OptCPU *cpu; + + public: + /** + * Construct this event; + */ + TickEvent(OptCPU *c); + + /** + * Call the tick function. + */ + void process(); + + /** + * Return a string description of this event. + */ + const char *description(); + }; + + TickEvent tickEvent; + + class RefInfo + { + public: + RefIndex nextRefTime; + Addr addr; + }; + + /** Reference Information, per set. */ + std::vector<std::vector<RefInfo> > refInfo; + + /** Lookup table to track blocks in the cache heap */ + L1Table lookupTable; + + /** + * Return the correct value in the lookup table. + */ + RefIndex lookupValue(Addr addr) + { + int l1_index = (addr >> 32) & 0x0f; + int l2_index = (addr >> 16) & 0xffff; + int l3_index = addr & 0xffff; + assert(l1_index == addr >> 32); + return lookupTable[l1_index][l2_index][l3_index]; + } + + /** + * Set the value in the lookup table. + */ + void setValue(Addr addr, RefIndex index) + { + int l1_index = (addr >> 32) & 0x0f; + int l2_index = (addr >> 16) & 0xffff; + int l3_index = addr & 0xffff; + assert(l1_index == addr >> 32); + lookupTable[l1_index][l2_index][l3_index]=index; + } + + /** + * Initialize the lookup table to the given value. + */ + void initTable(Addr addr, RefIndex index); + + void heapSwap(int set, int a, int b) { + RefIndex tmp = cacheHeap[a]; + cacheHeap[a] = cacheHeap[b]; + cacheHeap[b] = tmp; + + setValue(refInfo[set][cacheHeap[a]].addr, a); + setValue(refInfo[set][cacheHeap[b]].addr, b); + } + + int heapLeft(int index) { return index + index + 1; } + int heapRight(int index) { return index + index + 2; } + int heapParent(int index) { return (index - 1) >> 1; } + + RefIndex heapRank(int set, int index) { + return refInfo[set][cacheHeap[index]].nextRefTime; + } + + void heapify(int set, int start){ + int left = heapLeft(start); + int right = heapRight(start); + int max = start; + if (left < assoc && heapRank(set, left) > heapRank(set, start)) { + max = left; + } + if (right < assoc && heapRank(set, right) > heapRank(set, max)) { + max = right; + } + + if (max != start) { + heapSwap(set, start, max); + heapify(set, max); + } + } + + void verifyHeap(int set, int start) { + int left = heapLeft(start); + int right = heapRight(start); + + if (left < assoc) { + assert(heapRank(set, start) >= heapRank(set, left)); + verifyHeap(set, left); + } + if (right < assoc) { + assert(heapRank(set, start) >= heapRank(set, right)); + verifyHeap(set, right); + } + } + + void processRankIncrease(int set, int start) { + int parent = heapParent(start); + while (start > 0 && heapRank(set,parent) < heapRank(set,start)) { + heapSwap(set, parent, start); + start = parent; + parent = heapParent(start); + } + } + + void processSet(int set); + + static const RefIndex InfiniteRef = 0x7fffffff; + + /** Memory reference trace. */ + MemTraceReader *trace; + + /** Cache heap for replacement. */ + std::vector<RefIndex> cacheHeap; + + /** The number of blocks in the cache. */ + const int numBlks; + + const int assoc; + const int numSets; + const int setMask; + + + int misses; + int hits; + + public: + /** + * Construct a OptCPU object. + */ + OptCPU(const std::string &name, + MemTraceReader *_trace, + int block_size, + int cache_size, + int assoc); + + /** + * Perform the optimal replacement simulation. + */ + void tick(); +}; + +#endif // __CPU_TRACE_OPT_CPU_HH__ diff --git a/src/cpu/trace/reader/ibm_reader.cc b/src/cpu/trace/reader/ibm_reader.cc new file mode 100644 index 000000000..420101b63 --- /dev/null +++ b/src/cpu/trace/reader/ibm_reader.cc @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Declaration of a IBM memory trace format reader. + */ +#include <sstream> + +#include "cpu/trace/reader/ibm_reader.hh" +#include "sim/builder.hh" +#include "base/misc.hh" // for fatal + +using namespace std; + +IBMReader::IBMReader(const string &name, const string &filename) + : MemTraceReader(name) +{ + if (strcmp((filename.c_str() + filename.length() -3), ".gz") == 0) { + // Compressed file, need to use a pipe to gzip. + stringstream buf; + buf << "gzip -d -c " << filename << endl; + trace = popen(buf.str().c_str(), "r"); + } else { + trace = fopen(filename.c_str(), "rb"); + } + if (!trace) { + fatal("Can't open file %s", filename); + } +} + +Tick +IBMReader::getNextReq(MemReqPtr &req) +{ + MemReqPtr tmp_req; + + int c = getc(trace); + if (c != EOF) { + tmp_req = new MemReq(); + //int cpu_id = (c & 0xf0) >> 4; + int type = c & 0x0f; + // We have L1 miss traces, so all accesses are 128 bytes + tmp_req->size = 128; + + tmp_req->paddr = 0; + for (int i = 2; i >= 0; --i) { + c = getc(trace); + if (c == EOF) { + fatal("Unexpected end of file"); + } + tmp_req->paddr |= ((c & 0xff) << (8 * i)); + } + tmp_req->paddr = tmp_req->paddr << 7; + + switch(type) { + case IBM_COND_EXCLUSIVE_FETCH: + case IBM_READ_ONLY_FETCH: + tmp_req->cmd = Read; + break; + case IBM_EXCLUSIVE_FETCH: + case IBM_FETCH_NO_DATA: + tmp_req->cmd = Write; + break; + case IBM_INST_FETCH: + tmp_req->cmd = Read; + break; + default: + fatal("Unknown trace entry type."); + } + + } + req = tmp_req; + return 0; +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(IBMReader) + + Param<string> filename; + +END_DECLARE_SIM_OBJECT_PARAMS(IBMReader) + + +BEGIN_INIT_SIM_OBJECT_PARAMS(IBMReader) + + INIT_PARAM(filename, "trace file") + +END_INIT_SIM_OBJECT_PARAMS(IBMReader) + + +CREATE_SIM_OBJECT(IBMReader) +{ + return new IBMReader(getInstanceName(), filename); +} + +REGISTER_SIM_OBJECT("IBMReader", IBMReader) diff --git a/src/cpu/trace/reader/ibm_reader.hh b/src/cpu/trace/reader/ibm_reader.hh new file mode 100644 index 000000000..ce29206a2 --- /dev/null +++ b/src/cpu/trace/reader/ibm_reader.hh @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Definition of a IBM memory trace format reader. + */ + +#ifndef __IBM_READER_HH__ +#define __IBM_READER_HH__ + +#include <stdio.h> +#include "cpu/trace/reader/mem_trace_reader.hh" +#include "mem/mem_req.hh" + +/** + * A memory trace reader for the IBM memory trace format. + */ +class IBMReader : public MemTraceReader +{ + /** IBM trace file. */ + FILE* trace; + + enum IBMType { + IBM_INST_FETCH, + IBM_READ_ONLY_FETCH, + IBM_COND_EXCLUSIVE_FETCH, + IBM_EXCLUSIVE_FETCH, + IBM_FETCH_NO_DATA + }; + + public: + /** + * Construct an IBMReader. + */ + IBMReader(const std::string &name, const std::string &filename); + + /** + * Read the next request from the trace. Returns the request in the + * provided MemReqPtr and the cycle of the request in the return value. + * @param req Return the next request from the trace. + * @return IBM traces don't store timing information, return 0 + */ + virtual Tick getNextReq(MemReqPtr &req); +}; + +#endif //__IBM_READER_HH__ + diff --git a/src/cpu/trace/reader/itx_reader.cc b/src/cpu/trace/reader/itx_reader.cc new file mode 100644 index 000000000..39ba27393 --- /dev/null +++ b/src/cpu/trace/reader/itx_reader.cc @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Declaration of a Intel ITX memory trace format reader. + */ +#include <sstream> + +#include "cpu/trace/reader/itx_reader.hh" +#include "sim/builder.hh" +#include "base/misc.hh" // for fatal + +using namespace std; + +ITXReader::ITXReader(const string &name, const string &filename) + : MemTraceReader(name) +{ + if (strcmp((filename.c_str() + filename.length() -3), ".gz") == 0) { + // Compressed file, need to use a pipe to gzip. + stringstream buf; + buf << "gzip -d -c " << filename << endl; + trace = popen(buf.str().c_str(), "r"); + } else { + trace = fopen(filename.c_str(), "rb"); + } + if (!trace) { + fatal("Can't open file %s", filename); + } + traceFormat = 0; + int c; + for (int i = 0; i < 4; ++i) { + c = getc(trace); + if (c == EOF) { + fatal("Unexpected end of trace file."); + } + traceFormat |= (c & 0xff) << (8 * i); + } + if (traceFormat > 2) + fatal("Invalid trace format."); +} + +Tick +ITXReader::getNextReq(MemReqPtr &req) +{ + MemReqPtr tmp_req = new MemReq(); + bool phys_val; + do { + int c = getc(trace); + if (c != EOF) { + // Decode first byte + // phys_val<1> | type <2:0> | size <3:0> + phys_val = c & 0x80; + tmp_req->size = (c & 0x0f) + 1; + int type = (c & 0x70) >> 4; + + // Could be a compressed instruction entry, expand if necessary + if (type == ITXCodeComp) { + if (traceFormat != 2) { + fatal("Compressed code entry in non CompCode trace."); + } + if (!codeVirtValid) { + fatal("Corrupt CodeComp entry."); + } + + tmp_req->vaddr = codeVirtAddr; + codeVirtAddr += tmp_req->size; + if (phys_val) { + if (!codePhysValid) { + fatal("Corrupt CodeComp entry."); + } + tmp_req->paddr = codePhysAddr; + if (((tmp_req->paddr & 0xfff) + tmp_req->size) & ~0xfff) { + // Crossed page boundary, next physical address is + // invalid + codePhysValid = false; + } else { + codePhysAddr += tmp_req->size; + } + assert(tmp_req->paddr >> 36 == 0); + } else { + codePhysValid = false; + } + type = ITXCode; + tmp_req->cmd = Read; + } else { + // Normal entry + tmp_req->vaddr = 0; + for (int i = 0; i < 4; ++i) { + c = getc(trace); + if (c == EOF) { + fatal("Unexpected end of trace file."); + } + tmp_req->vaddr |= (c & 0xff) << (8 * i); + } + if (type == ITXCode) { + codeVirtAddr = tmp_req->vaddr + tmp_req->size; + codeVirtValid = true; + } + tmp_req->paddr = 0; + if (phys_val) { + c = getc(trace); + if (c == EOF) { + fatal("Unexpected end of trace file."); + } + // Get the page offset from the virtual address. + tmp_req->paddr = tmp_req->vaddr & 0xfff; + tmp_req->paddr |= (c & 0xf0) << 8; + tmp_req->paddr |= (Addr)(c & 0x0f) << 32; + for (int i = 2; i < 4; ++i) { + c = getc(trace); + if (c == EOF) { + fatal("Unexpected end of trace file."); + } + tmp_req->paddr |= (Addr)(c & 0xff) << (8 * i); + } + if (type == ITXCode) { + if (((tmp_req->paddr & 0xfff) + tmp_req->size) + & ~0xfff) { + // Crossing the page boundary, next physical + // address isn't valid + codePhysValid = false; + } else { + codePhysAddr = tmp_req->paddr + tmp_req->size; + codePhysValid = true; + } + } + assert(tmp_req->paddr >> 36 == 0); + } else if (type == ITXCode) { + codePhysValid = false; + } + switch(type) { + case ITXRead: + tmp_req->cmd = Read; + break; + case ITXWrite: + tmp_req->cmd = Write; + break; + case ITXWriteback: + tmp_req->cmd = Writeback; + break; + case ITXCode: + tmp_req->cmd = Read; + tmp_req->flags |= INST_READ; + break; + default: + fatal("Unknown ITX type"); + } + } + } else { + // EOF need to return a null request + MemReqPtr null_req; + req = null_req; + return 0; + } + } while (!phys_val); + req = tmp_req; + assert(!req || (req->paddr >> 36) == 0); + return 0; +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITXReader) + + Param<string> filename; + +END_DECLARE_SIM_OBJECT_PARAMS(ITXReader) + + +BEGIN_INIT_SIM_OBJECT_PARAMS(ITXReader) + + INIT_PARAM(filename, "trace file") + +END_INIT_SIM_OBJECT_PARAMS(ITXReader) + + +CREATE_SIM_OBJECT(ITXReader) +{ + return new ITXReader(getInstanceName(), filename); +} + +REGISTER_SIM_OBJECT("ITXReader", ITXReader) diff --git a/src/cpu/trace/reader/itx_reader.hh b/src/cpu/trace/reader/itx_reader.hh new file mode 100644 index 000000000..a16a08085 --- /dev/null +++ b/src/cpu/trace/reader/itx_reader.hh @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Definition of a Intel ITX memory trace format reader. + */ + +#ifndef __ITX_READER_HH__ +#define __ITX_READER_HH__ + +#include <stdio.h> +#include <string> + +#include "cpu/trace/reader/mem_trace_reader.hh" +#include "mem/mem_req.hh" + + +/** + * A memory trace reader for the Intel ITX memory trace format. + */ +class ITXReader : public MemTraceReader +{ + private: + /** Trace file. */ + FILE *trace; + + bool codeVirtValid; + Addr codeVirtAddr; + bool codePhysValid; + Addr codePhysAddr; + + int traceFormat; + + enum ITXType { + ITXRead, + ITXWrite, + ITXWriteback, + ITXCode, + ITXCodeComp + }; + + public: + /** + * Construct an ITXReader. + */ + ITXReader(const std::string &name, const std::string &filename); + + /** + * Read the next request from the trace. Returns the request in the + * provided MemReqPtr and the cycle of the request in the return value. + * @param req Return the next request from the trace. + * @return ITX traces don't store timing information, return 0 + */ + virtual Tick getNextReq(MemReqPtr &req); +}; + +#endif //__ITX_READER_HH__ + diff --git a/src/cpu/trace/reader/m5_reader.cc b/src/cpu/trace/reader/m5_reader.cc new file mode 100644 index 000000000..ce44672f2 --- /dev/null +++ b/src/cpu/trace/reader/m5_reader.cc @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Declaration of a memory trace reader for a M5 memory trace. + */ + +#include "cpu/trace/reader/m5_reader.hh" +#include "mem/trace/m5_format.hh" +#include "mem/mem_cmd.hh" +#include "sim/builder.hh" + +using namespace std; + +M5Reader::M5Reader(const string &name, const string &filename) + : MemTraceReader(name) +{ + traceFile.open(filename.c_str(), ios::binary); +} + +Tick +M5Reader::getNextReq(MemReqPtr &req) +{ + M5Format ref; + + MemReqPtr tmp_req; + // Need to read EOF char before eof() will return true. + traceFile.read((char*) &ref, sizeof(ref)); + if (!traceFile.eof()) { + //traceFile.read((char*) &ref, sizeof(ref)); +#ifndef NDEBUG + int gcount = traceFile.gcount(); + assert(gcount != 0 || traceFile.eof()); + assert(gcount == sizeof(ref)); + assert(ref.cmd < 12); +#endif + tmp_req = new MemReq(); + tmp_req->paddr = ref.paddr; + tmp_req->asid = ref.asid; + // Assume asid == thread_num + tmp_req->thread_num = ref.asid; + tmp_req->cmd = (MemCmdEnum)ref.cmd; + tmp_req->size = ref.size; + tmp_req->dest = ref.dest; + } else { + ref.cycle = 0; + } + req = tmp_req; + return ref.cycle; +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(M5Reader) + + Param<string> filename; + +END_DECLARE_SIM_OBJECT_PARAMS(M5Reader) + + +BEGIN_INIT_SIM_OBJECT_PARAMS(M5Reader) + + INIT_PARAM(filename, "trace file") + +END_INIT_SIM_OBJECT_PARAMS(M5Reader) + + +CREATE_SIM_OBJECT(M5Reader) +{ + return new M5Reader(getInstanceName(), filename); +} + +REGISTER_SIM_OBJECT("M5Reader", M5Reader) diff --git a/src/cpu/trace/reader/m5_reader.hh b/src/cpu/trace/reader/m5_reader.hh new file mode 100644 index 000000000..974a83ffa --- /dev/null +++ b/src/cpu/trace/reader/m5_reader.hh @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Definition of a memory trace reader for a M5 memory trace. + */ + +#ifndef __M5_READER_HH__ +#define __M5_READER_HH__ + +#include <fstream> + +#include "cpu/trace/reader/mem_trace_reader.hh" + +/** + * A memory trace reader for an M5 memory trace. @sa M5Writer. + */ +class M5Reader : public MemTraceReader +{ + /** The traceFile. */ + std::ifstream traceFile; + + std::string fn; + + public: + /** + * Construct an M5 memory trace reader. + */ + M5Reader(const std::string &name, const std::string &filename); + + + /** + * Read the next request from the trace. Returns the request in the + * provided MemReqPtr and the cycle of the request in the return value. + * @param req Return the next request from the trace. + * @return The cycle the reference was started. + */ + virtual Tick getNextReq(MemReqPtr &req); +}; + +#endif // __M5_READER_HH__ diff --git a/src/cpu/trace/reader/mem_trace_reader.cc b/src/cpu/trace/reader/mem_trace_reader.cc new file mode 100644 index 000000000..769f0be27 --- /dev/null +++ b/src/cpu/trace/reader/mem_trace_reader.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * SimObject Declaration of pure virtual MemTraceReader class. + */ + +#include "cpu/trace/reader/mem_trace_reader.hh" +#include "sim/param.hh" + +DEFINE_SIM_OBJECT_CLASS_NAME("MemTraceReader", MemTraceReader); diff --git a/src/cpu/trace/reader/mem_trace_reader.hh b/src/cpu/trace/reader/mem_trace_reader.hh new file mode 100644 index 000000000..b433cdbdd --- /dev/null +++ b/src/cpu/trace/reader/mem_trace_reader.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Definitions for a pure virtual interface to a memory trace reader. + */ + +#ifndef __MEM_TRACE_READER_HH__ +#define __MEM_TRACE_READER_HH__ + +#include "sim/sim_object.hh" +#include "mem/mem_req.hh" // For MemReqPtr + +/** + * Pure virtual base class for memory trace readers. + */ +class MemTraceReader : public SimObject +{ + public: + /** Construct this MemoryTrace reader. */ + MemTraceReader(const std::string &name) : SimObject(name) {} + + /** + * Read the next request from the trace. Returns the request in the + * provided MemReqPtr and the cycle of the request in the return value. + * @param req Return the next request from the trace. + * @return The cycle of the request, 0 if none in trace. + */ + virtual Tick getNextReq(MemReqPtr &req) = 0; +}; + +#endif //__MEM_TRACE_READER_HH__ diff --git a/src/cpu/trace/trace_cpu.cc b/src/cpu/trace/trace_cpu.cc new file mode 100644 index 000000000..20d0a567f --- /dev/null +++ b/src/cpu/trace/trace_cpu.cc @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Declaration of a memory trace CPU object. Uses a memory trace to drive the + * provided memory hierarchy. + */ + +#include <algorithm> // For min + +#include "cpu/trace/trace_cpu.hh" +#include "cpu/trace/reader/mem_trace_reader.hh" +#include "mem/base_mem.hh" // For PARAM constructor +#include "mem/mem_interface.hh" +#include "sim/builder.hh" +#include "sim/sim_events.hh" + +using namespace std; + +TraceCPU::TraceCPU(const string &name, + MemInterface *icache_interface, + MemInterface *dcache_interface, + MemTraceReader *data_trace) + : SimObject(name), icacheInterface(icache_interface), + dcacheInterface(dcache_interface), + dataTrace(data_trace), outstandingRequests(0), tickEvent(this) +{ + assert(dcacheInterface); + nextCycle = dataTrace->getNextReq(nextReq); + tickEvent.schedule(0); +} + +void +TraceCPU::tick() +{ + assert(outstandingRequests >= 0); + assert(outstandingRequests < 1000); + int instReqs = 0; + int dataReqs = 0; + + while (nextReq && curTick >= nextCycle) { + assert(nextReq->thread_num < 4 && "Not enough threads"); + if (nextReq->isInstRead() && icacheInterface) { + if (icacheInterface->isBlocked()) + break; + + nextReq->time = curTick; + if (nextReq->cmd == Squash) { + icacheInterface->squash(nextReq->asid); + } else { + ++instReqs; + if (icacheInterface->doEvents()) { + nextReq->completionEvent = + new TraceCompleteEvent(nextReq, this); + icacheInterface->access(nextReq); + } else { + icacheInterface->access(nextReq); + completeRequest(nextReq); + } + } + } else { + if (dcacheInterface->isBlocked()) + break; + + ++dataReqs; + nextReq->time = curTick; + if (dcacheInterface->doEvents()) { + nextReq->completionEvent = + new TraceCompleteEvent(nextReq, this); + dcacheInterface->access(nextReq); + } else { + dcacheInterface->access(nextReq); + completeRequest(nextReq); + } + + } + nextCycle = dataTrace->getNextReq(nextReq); + } + + if (!nextReq) { + // No more requests to send. Finish trailing events and exit. + if (mainEventQueue.empty()) { + new SimExitEvent("Finshed Memory Trace"); + } else { + tickEvent.schedule(mainEventQueue.nextEventTime() + cycles(1)); + } + } else { + tickEvent.schedule(max(curTick + cycles(1), nextCycle)); + } +} + +void +TraceCPU::completeRequest(MemReqPtr& req) +{ +} + +void +TraceCompleteEvent::process() +{ + tester->completeRequest(req); +} + +const char * +TraceCompleteEvent::description() +{ + return "trace access complete"; +} + +TraceCPU::TickEvent::TickEvent(TraceCPU *c) + : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) +{ +} + +void +TraceCPU::TickEvent::process() +{ + cpu->tick(); +} + +const char * +TraceCPU::TickEvent::description() +{ + return "TraceCPU tick event"; +} + + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(TraceCPU) + + SimObjectParam<BaseMem *> icache; + SimObjectParam<BaseMem *> dcache; + SimObjectParam<MemTraceReader *> data_trace; + +END_DECLARE_SIM_OBJECT_PARAMS(TraceCPU) + +BEGIN_INIT_SIM_OBJECT_PARAMS(TraceCPU) + + INIT_PARAM_DFLT(icache, "instruction cache", NULL), + INIT_PARAM_DFLT(dcache, "data cache", NULL), + INIT_PARAM_DFLT(data_trace, "data trace", NULL) + +END_INIT_SIM_OBJECT_PARAMS(TraceCPU) + +CREATE_SIM_OBJECT(TraceCPU) +{ + return new TraceCPU(getInstanceName(), + (icache) ? icache->getInterface() : NULL, + (dcache) ? dcache->getInterface() : NULL, + data_trace); +} + +REGISTER_SIM_OBJECT("TraceCPU", TraceCPU) + diff --git a/src/cpu/trace/trace_cpu.hh b/src/cpu/trace/trace_cpu.hh new file mode 100644 index 000000000..69ca35321 --- /dev/null +++ b/src/cpu/trace/trace_cpu.hh @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Declaration of a memory trace CPU object. Uses a memory trace to drive the + * provided memory hierarchy. + */ + +#ifndef __CPU_TRACE_TRACE_CPU_HH__ +#define __CPU_TRACE_TRACE_CPU_HH__ + +#include <string> + +#include "mem/mem_req.hh" // for MemReqPtr +#include "sim/eventq.hh" // for Event +#include "sim/sim_object.hh" + +// Forward declaration. +class MemInterface; +class MemTraceReader; + +/** + * A cpu object for running memory traces through a memory hierarchy. + */ +class TraceCPU : public SimObject +{ + private: + /** Interface for instruction trace requests, if any. */ + MemInterface *icacheInterface; + /** Interface for data trace requests, if any. */ + MemInterface *dcacheInterface; + + /** Data reference trace. */ + MemTraceReader *dataTrace; + + /** Number of outstanding requests. */ + int outstandingRequests; + + /** Cycle of the next request, 0 if not available. */ + Tick nextCycle; + + /** Next request. */ + MemReqPtr nextReq; + + /** + * Event to call the TraceCPU::tick + */ + class TickEvent : public Event + { + private: + /** The associated CPU */ + TraceCPU *cpu; + + public: + /** + * Construct this event; + */ + TickEvent(TraceCPU *c); + + /** + * Call the tick function. + */ + void process(); + + /** + * Return a string description of this event. + */ + const char *description(); + }; + + TickEvent tickEvent; + + public: + /** + * Construct a TraceCPU object. + */ + TraceCPU(const std::string &name, + MemInterface *icache_interface, + MemInterface *dcache_interface, + MemTraceReader *data_trace); + + inline Tick cycles(int numCycles) { return numCycles; } + + /** + * Perform all the accesses for one cycle. + */ + void tick(); + + /** + * Handle a completed memory request. + */ + void completeRequest(MemReqPtr &req); +}; + +class TraceCompleteEvent : public Event +{ + MemReqPtr req; + TraceCPU *tester; + + public: + + TraceCompleteEvent(MemReqPtr &_req, TraceCPU *_tester) + : Event(&mainEventQueue), req(_req), tester(_tester) + { + setFlags(AutoDelete); + } + + void process(); + + virtual const char *description(); +}; + +#endif // __CPU_TRACE_TRACE_CPU_HH__ + |