diff options
author | Ron Dreslinski <rdreslin@umich.edu> | 2006-06-28 14:35:00 -0400 |
---|---|---|
committer | Ron Dreslinski <rdreslin@umich.edu> | 2006-06-28 14:35:00 -0400 |
commit | fc281d0b64fca8d2809ec462148acb7cf0461ea5 (patch) | |
tree | ef772f136f4e1bad0e9de6282201aa6611329fc7 | |
parent | ed8564a6b9f0702a40995d95cc4da54de3d35462 (diff) | |
download | gem5-fc281d0b64fca8d2809ec462148acb7cf0461ea5.tar.xz |
Backing in more changsets, getting closer to compile
base_cache.cc compiles, continuing on
src/SConscript:
Add in compilation flags for cache files
src/mem/cache/base_cache.cc:
src/mem/cache/base_cache.hh:
Back in more fixes, now base_cache compiles
src/mem/cache/cache.hh:
src/mem/cache/cache_blk.hh:
src/mem/cache/cache_impl.hh:
src/mem/cache/coherence/coherence_protocol.cc:
src/mem/cache/miss/blocking_buffer.cc:
src/mem/cache/miss/blocking_buffer.hh:
src/mem/cache/miss/miss_queue.cc:
src/mem/cache/miss/miss_queue.hh:
src/mem/cache/miss/mshr.cc:
src/mem/cache/miss/mshr.hh:
src/mem/cache/miss/mshr_queue.cc:
src/mem/cache/miss/mshr_queue.hh:
src/mem/cache/prefetch/base_prefetcher.cc:
src/mem/cache/tags/fa_lru.cc:
src/mem/cache/tags/iic.cc:
src/mem/cache/tags/lru.cc:
src/mem/cache/tags/split_lifo.cc:
src/mem/cache/tags/split_lru.cc:
src/mem/packet.cc:
src/mem/packet.hh:
src/mem/request.hh:
Backing in more changsets, getting closer to compile
--HG--
extra : convert_revision : ac2dcda39f8d27baffc4db1df17b9a1fcce5b6ed
25 files changed, 225 insertions, 118 deletions
diff --git a/src/SConscript b/src/SConscript index 124f88708..ff41e5931 100644 --- a/src/SConscript +++ b/src/SConscript @@ -101,6 +101,31 @@ base_sources = Split(''' mem/physical.cc mem/port.cc + mem/cache/base_cache.cc + mem/cache/cache.cc + mem/cache/cache_builder.cc + mem/cache/coherence/coherence_protocol.cc + mem/cache/coherence/uni_coherence.cc + mem/cache/miss/blocking_buffer.cc + mem/cache/miss/miss_queue.cc + mem/cache/miss/mshr.cc + mem/cache/miss/mshr_queue.cc + mem/cache/prefetch/base_prefetcher.cc + mem/cache/prefetch/ghb_prefetcher.cc + mem/cache/prefetch/prefetcher.cc + mem/cache/prefetch/stride_prefetcher.cc + mem/cache/prefetch/tagged_prefetcher.cc + mem/cache/tags/base_tags.cc + mem/cache/tags/cache_tags.cc + mem/cache/tags/fa_lru.cc + mem/cache/tags/iic/cc + mem/cache/tags/lru.cc + mem/cache/tags/repl/gen.cc + mem/cache/tags/repl/repl.cc + mem/cache/tags/split.cc + mem/cache/tags/split_lifo.cc + mem/cache/tags/split_lru.cc + sim/builder.cc sim/debug.cc sim/eventq.cc diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 10a49edb1..89e23ce31 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -45,11 +45,11 @@ BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache, { blocked = false; //Start ports at null if more than one is created we should panic - cpuSidePort = NULL; - memSidePort = NULL; + //cpuSidePort = NULL; + //memSidePort = NULL; } -bool +void BaseCache::CachePort::recvStatusChange(Port::Status status) { cache->recvStatusChange(status, isCpuSide); @@ -121,12 +121,16 @@ BaseCache::getPort(const std::string &if_name) void BaseCache::regStats() { + Request temp_req; + Packet::Command temp_cmd = Packet::ReadReq; + Packet temp_pkt(&temp_req, temp_cmd, 0); //@todo FIx command strings so this isn't neccessary + using namespace Stats; // Hit statistics for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { - Packet::Command cmd = (Packet::CommandEnum)access_idx; - const string &cstr = cmd.toString(); + Packet::Command cmd = (Packet::Command)access_idx; + const string &cstr = temp_pkt.cmdIdxToString(cmd); hits[access_idx] .init(maxThreadsPerCPU) @@ -141,20 +145,20 @@ BaseCache::regStats() .desc("number of demand (read+write) hits") .flags(total) ; - demandHits = hits[Read] + hits[Write]; + demandHits = hits[Packet::ReadReq] + hits[Packet::WriteReq]; overallHits .name(name() + ".overall_hits") .desc("number of overall hits") .flags(total) ; - overallHits = demandHits + hits[Soft_Prefetch] + hits[Hard_Prefetch] - + hits[Writeback]; + overallHits = demandHits + hits[Packet::SoftPFReq] + hits[Packet::HardPFReq] + + hits[Packet::Writeback]; // Miss statistics for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { - Packet::Command cmd = (Packet::CommandEnum)access_idx; - const string &cstr = cmd.toString(); + Packet::Command cmd = (Packet::Command)access_idx; + const string &cstr = temp_pkt.cmdIdxToString(cmd); misses[access_idx] .init(maxThreadsPerCPU) @@ -169,20 +173,20 @@ BaseCache::regStats() .desc("number of demand (read+write) misses") .flags(total) ; - demandMisses = misses[Read] + misses[Write]; + demandMisses = misses[Packet::ReadReq] + misses[Packet::WriteReq]; overallMisses .name(name() + ".overall_misses") .desc("number of overall misses") .flags(total) ; - overallMisses = demandMisses + misses[Soft_Prefetch] + - misses[Hard_Prefetch] + misses[Writeback]; + overallMisses = demandMisses + misses[Packet::SoftPFReq] + + misses[Packet::HardPFReq] + misses[Packet::Writeback]; // Miss latency statistics for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { - Packet::Command cmd = (Packet::CommandEnum)access_idx; - const string &cstr = cmd.toString(); + Packet::Command cmd = (Packet::Command)access_idx; + const string &cstr = temp_pkt.cmdIdxToString(cmd); missLatency[access_idx] .init(maxThreadsPerCPU) @@ -197,20 +201,20 @@ BaseCache::regStats() .desc("number of demand (read+write) miss cycles") .flags(total) ; - demandMissLatency = missLatency[Read] + missLatency[Write]; + demandMissLatency = missLatency[Packet::ReadReq] + missLatency[Packet::WriteReq]; overallMissLatency .name(name() + ".overall_miss_latency") .desc("number of overall miss cycles") .flags(total) ; - overallMissLatency = demandMissLatency + missLatency[Soft_Prefetch] + - missLatency[Hard_Prefetch]; + overallMissLatency = demandMissLatency + missLatency[Packet::SoftPFReq] + + missLatency[Packet::HardPFReq]; // access formulas for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { - Packet::Command cmd = (Packet::CommandEnum)access_idx; - const string &cstr = cmd.toString(); + Packet::Command cmd = (Packet::Command)access_idx; + const string &cstr = temp_pkt.cmdIdxToString(cmd); accesses[access_idx] .name(name() + "." + cstr + "_accesses") @@ -237,8 +241,8 @@ BaseCache::regStats() // miss rate formulas for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { - Packet::Command cmd = (Packet::CommandEnum)access_idx; - const string &cstr = cmd.toString(); + Packet::Command cmd = (Packet::Command)access_idx; + const string &cstr = temp_pkt.cmdIdxToString(cmd); missRate[access_idx] .name(name() + "." + cstr + "_miss_rate") @@ -265,8 +269,8 @@ BaseCache::regStats() // miss latency formulas for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { - Packet::Command cmd = (Packet::CommandEnum)access_idx; - const string &cstr = cmd.toString(); + Packet::Command cmd = (Packet::Command)access_idx; + const string &cstr = temp_pkt.cmdIdxToString(cmd); avgMissLatency[access_idx] .name(name() + "." + cstr + "_avg_miss_latency") diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index 0170b0249..977e0ae29 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -47,6 +47,7 @@ #include "mem/packet.hh" #include "mem/port.hh" #include "mem/request.hh" +#include "sim/eventq.hh" /** * Reasons for Caches to be Blocked. @@ -82,7 +83,7 @@ class BaseCache : public MemObject public: CachePort(const std::string &_name, BaseCache *_cache, bool _isCpuSide); - private: + protected: virtual bool recvTiming(Packet *pkt); virtual Tick recvAtomic(Packet *pkt); @@ -96,6 +97,7 @@ class BaseCache : public MemObject virtual int deviceBlockSize(); + public: void setBlocked(); void clearBlocked(); @@ -110,10 +112,10 @@ class BaseCache : public MemObject Packet *pkt; CachePort *cachePort; - CacheResponseEvent(Packet *pkt, CachePort *cachePort); + CacheEvent(Packet *pkt, CachePort *cachePort); void process(); const char *description(); - } + }; protected: CachePort *cpuSidePort; @@ -124,7 +126,7 @@ class BaseCache : public MemObject private: //To be defined in cache_impl.hh not in base class - virtual bool doTimingAccess(Packet *pkt, MemoryPort *memoryPort, bool isCpuSide); + virtual bool doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide); virtual Tick doAtomicAccess(Packet *pkt, bool isCpuSide); virtual void doFunctionalAccess(Packet *pkt, bool isCpuSide); virtual void recvStatusChange(Port::Status status, bool isCpuSide); @@ -275,12 +277,14 @@ class BaseCache : public MemObject * of this cache. * @param params The parameter object for this BaseCache. */ - BaseCache(const std::string &name, HierParams *hier_params, Params ¶ms) - : BaseMem(name, hier_params, params.hitLatency, params.addrRange), - blocked(0), blockedSnoop(0), masterRequests(0), slaveRequests(0), - topLevelCache(false), blkSize(params.blkSize), + BaseCache(const std::string &name, Params ¶ms) + : MemObject(name), blocked(0), blockedSnoop(0), masterRequests(0), + slaveRequests(0), topLevelCache(false), blkSize(params.blkSize), missCount(params.maxMisses) { + //Start ports at null if more than one is created we should panic + cpuSidePort = NULL; + memSidePort = NULL; } /** @@ -453,8 +457,8 @@ class BaseCache : public MemObject */ void respondToMiss(Packet *pkt, Tick time) { - if (!pkt->isUncacheable()) { - missLatency[pkt->cmd.toIndex()][pkt->thread_num] += time - pkt->time; + if (!pkt->req->isUncacheable()) { + missLatency[pkt->cmdToIndex()][pkt->req->getThreadNum()] += time - pkt->time; } assert("Implement\n" && 0); // si->respond(pkt,time); @@ -475,6 +479,11 @@ class BaseCache : public MemObject * to do for a cache. */ void rangeChange() {} + + void getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) + { + panic("Unimplimented\n"); + } }; #endif //__BASE_CACHE_HH__ diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index dcb22a99c..78e87479b 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -46,7 +46,6 @@ // forward declarations class Bus; -class ExecContext; /** * A template-policy based cache. The behavior of the cache can be altered by @@ -209,11 +208,11 @@ class Cache : public BaseCache /** * Aquash all requests associated with specified thread. * intended for use by I-cache. - * @param thread_number The thread to squash. + * @param req->getThreadNum()ber The thread to squash. */ - void squash(int thread_number) + void squash(int threadNum) { - missQueue->squash(thread_number); + missQueue->squash(threadNum); } /** diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index cf1bd20e2..02fdd7a51 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -37,7 +37,6 @@ #include "sim/root.hh" // for Tick #include "arch/isa_traits.hh" // for Addr -#include "cpu/exec_context.hh" /** * Cache block status bit assignments @@ -88,9 +87,6 @@ class CacheBlk /** Which curTick will this block be accessable */ Tick whenReady; - /** Save the exec context so that writebacks can use them. */ - ExecContext *xc; - /** * The set this block belongs to. * @todo Move this into subclasses when we fix CacheTags to use them. diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 3dd8d74cd..3dc95af68 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -175,7 +175,7 @@ Cache<TagStore,Buffering,Coherence>::access(Packet &pkt) //We are determining prefetches on access stream, call prefetcher prefetcher->handleMiss(pkt, curTick); } - if (!pkt->isUncacheable()) { + if (!pkt->req->isUncacheable()) { if (pkt->cmd.isInvalidate() && !pkt->cmd.isRead() && !pkt->cmd.isWrite()) { //Upgrade or Invalidate @@ -220,7 +220,7 @@ Cache<TagStore,Buffering,Coherence>::access(Packet &pkt) pkt->paddr & ~((Addr)blkSize - 1), pkt->pc); if (blk) { // Hit - hits[pkt->cmd.toIndex()][pkt->thread_num]++; + hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; // clear dirty bit if write through if (!pkt->cmd.isNoResponse()) respond(pkt, curTick+lat); @@ -228,8 +228,8 @@ Cache<TagStore,Buffering,Coherence>::access(Packet &pkt) } // Miss - if (!pkt->isUncacheable()) { - misses[pkt->cmd.toIndex()][pkt->thread_num]++; + if (!pkt->req->isUncacheable()) { + misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; /** @todo Move miss count code into BaseCache */ if (missCount) { --missCount; @@ -248,8 +248,8 @@ Cache<TagStore,Buffering,Coherence>::getPacket() { Packet * pkt = missQueue->getPacket(); if (pkt) { - if (!pkt->isUncacheable()) { - if (pkt->cmd == Hard_Prefetch) misses[Hard_Prefetch][pkt->thread_num]++; + if (!pkt->req->isUncacheable()) { + if (pkt->cmd == Hard_Prefetch) misses[Hard_Prefetch][pkt->req->getThreadNum()]++; BlkType *blk = tags->findBlock(pkt); Packet::Command cmd = coherence->getBusCmd(pkt->cmd, (blk)? blk->status : 0); @@ -272,7 +272,7 @@ Cache<TagStore,Buffering,Coherence>::sendResult(MemPktPtr &pkt, bool success) if (pkt->cmd == Upgrade) { handleResponse(pkt); } - } else if (pkt && !pkt->isUncacheable()) { + } else if (pkt && !pkt->req->isUncacheable()) { missQueue->restoreOrigCmd(pkt); } } @@ -394,7 +394,7 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt) for (int i=0; i<writebacks.size(); i++) { mshr = writebacks[i]; - if (!mshr->pkt->isUncacheable()) { + if (!mshr->pkt->req->isUncacheable()) { if (pkt->cmd.isRead()) { //Only Upgrades don't get here //Supply the data @@ -469,7 +469,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update) { MemDebug::cacheProbe(pkt); - if (!pkt->isUncacheable()) { + if (!pkt->req->isUncacheable()) { if (pkt->cmd.isInvalidate() && !pkt->cmd.isRead() && !pkt->cmd.isWrite()) { //Upgrade or Invalidate, satisfy it, don't forward @@ -583,7 +583,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update) // Can't handle it, return pktuest unsatisfied. return 0; } - if (!pkt->isUncacheable()) { + if (!pkt->req->isUncacheable()) { // Fetch the cache block to fill Packet * busPkt = new MemPkt(); busPkt->paddr = blk_addr; @@ -596,7 +596,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update) busPkt->req->asid = pkt->req->asid; busPkt->xc = pkt->xc; - busPkt->thread_num = pkt->thread_num; + busPkt->req->setThreadNum() = pkt->req->getThreadNum(); busPkt->time = curTick; lat = mi->sendProbe(busPkt, update); @@ -606,7 +606,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update) return 0; } - misses[pkt->cmd.toIndex()][pkt->thread_num]++; + misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; CacheBlk::State old_state = (blk) ? blk->status : 0; tags->handleFill(blk, busPkt, @@ -631,7 +631,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update) } if (update) { - hits[pkt->cmd.toIndex()][pkt->thread_num]++; + hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; } else if (pkt->cmd.isWrite()) { // Still need to change data in all locations. return mi->sendProbe(pkt, update); diff --git a/src/mem/cache/coherence/coherence_protocol.cc b/src/mem/cache/coherence/coherence_protocol.cc index 107fd2502..9d5b8ef54 100644 --- a/src/mem/cache/coherence/coherence_protocol.cc +++ b/src/mem/cache/coherence/coherence_protocol.cc @@ -465,7 +465,7 @@ CacheBlk::State CoherenceProtocol::getNewState(const Packet * &pkt, CacheBlk::State oldState) { CacheBlk::State state = oldState & stateMask; - int cmd_idx = pkt->cmd.toIndex(); + int cmd_idx = pkt->cmdToIndex(); assert(0 <= state && state <= stateMax); assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS); @@ -498,7 +498,7 @@ CoherenceProtocol::handleBusRequest(BaseCache *cache, Packet * &pkt, } CacheBlk::State state = blk->status & stateMask; - int cmd_idx = pkt->cmd.toIndex(); + int cmd_idx = pkt->cmdToIndex(); assert(0 <= state && state <= stateMax); assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS); diff --git a/src/mem/cache/miss/blocking_buffer.cc b/src/mem/cache/miss/blocking_buffer.cc index 621855c3d..912a0f5bd 100644 --- a/src/mem/cache/miss/blocking_buffer.cc +++ b/src/mem/cache/miss/blocking_buffer.cc @@ -73,7 +73,7 @@ void BlockingBuffer::handleMiss(Packet * &pkt, int blk_size, Tick time) { Addr blk_addr = pkt->paddr & ~(Addr)(blk_size - 1); - if (pkt->cmd.isWrite() && (pkt->isUncacheable() || !writeAllocate || + if (pkt->cmd.isWrite() && (pkt->req->isUncacheable() || !writeAllocate || pkt->cmd.isNoResponse())) { if (pkt->cmd.isNoResponse()) { wb.allocateAsBuffer(pkt); @@ -93,7 +93,7 @@ BlockingBuffer::handleMiss(Packet * &pkt, int blk_size, Tick time) } else { miss.allocate(pkt->cmd, blk_addr, pkt->req->asid, blk_size, pkt); } - if (!pkt->isUncacheable()) { + if (!pkt->req->isUncacheable()) { miss.pkt->flags |= CACHE_LINE_FILL; } cache->setBlocked(Blocked_NoMSHRs); @@ -186,12 +186,12 @@ BlockingBuffer::handleResponse(Packet * &pkt, Tick time) } void -BlockingBuffer::squash(int thread_number) +BlockingBuffer::squash(int req->getThreadNum()ber) { - if (miss.threadNum == thread_number) { + if (miss.setThreadNum() == req->getThreadNum()ber) { Packet * target = miss.getTarget(); miss.popTarget(); - assert(target->thread_num == thread_number); + assert(target->req->setThreadNum() == req->getThreadNum()ber); if (target->completionEvent != NULL) { delete target->completionEvent; } @@ -207,7 +207,7 @@ BlockingBuffer::squash(int thread_number) } void -BlockingBuffer::doWriteback(Addr addr, int asid, ExecContext *xc, +BlockingBuffer::doWriteback(Addr addr, int asid, int size, uint8_t *data, bool compressed) { @@ -224,18 +224,14 @@ BlockingBuffer::doWriteback(Addr addr, int asid, ExecContext *xc, * @todo Need to find a way to charge the writeback to the "correct" * thread. */ - pkt->xc = xc; - if (xc) - pkt->thread_num = xc->getThreadNum(); - else - pkt->thread_num = 0; + pkt->req->setThreadNum() = 0; pkt->cmd = Writeback; if (compressed) { pkt->flags |= COMPRESSED; } - writebacks[pkt->thread_num]++; + writebacks[pkt->req->getThreadNum()]++; wb.allocateAsBuffer(pkt); cache->setMasterRequest(Request_WB, curTick); @@ -247,7 +243,7 @@ BlockingBuffer::doWriteback(Addr addr, int asid, ExecContext *xc, void BlockingBuffer::doWriteback(Packet * &pkt) { - writebacks[pkt->thread_num]++; + writebacks[pkt->req->getThreadNum()]++; wb.allocateAsBuffer(pkt); diff --git a/src/mem/cache/miss/blocking_buffer.hh b/src/mem/cache/miss/blocking_buffer.hh index 52256be74..08814b43e 100644 --- a/src/mem/cache/miss/blocking_buffer.hh +++ b/src/mem/cache/miss/blocking_buffer.hh @@ -164,9 +164,9 @@ public: /** * Removes all outstanding requests for a given thread number. If a request * has been sent to the bus, this function removes all of its targets. - * @param thread_number The thread number of the requests to squash. + * @param req->getThreadNum()ber The thread number of the requests to squash. */ - void squash(int thread_number); + void squash(int req->getThreadNum()ber); /** * Return the current number of outstanding misses. @@ -212,12 +212,11 @@ public: * Perform a writeback of dirty data to the given address. * @param addr The address to write to. * @param asid The address space id. - * @param xc The execution context of the address space. * @param size The number of bytes to write. * @param data The data to write, can be NULL. * @param compressed True if the data is compressed. */ - void doWriteback(Addr addr, int asid, ExecContext *xc, + void doWriteback(Addr addr, int asid, int size, uint8_t *data, bool compressed); /** diff --git a/src/mem/cache/miss/miss_queue.cc b/src/mem/cache/miss/miss_queue.cc index 7902fbcee..d02f27d52 100644 --- a/src/mem/cache/miss/miss_queue.cc +++ b/src/mem/cache/miss/miss_queue.cc @@ -347,7 +347,7 @@ MissQueue::allocateMiss(Packet * &pkt, int size, Tick time) { MSHR* mshr = mq.allocate(pkt, size); mshr->order = order++; - if (!pkt->isUncacheable() ){//&& !pkt->isNoAllocate()) { + if (!pkt->req->isUncacheable() ){//&& !pkt->isNoAllocate()) { // Mark this as a cache line fill mshr->pkt->flags |= CACHE_LINE_FILL; } @@ -399,13 +399,13 @@ MissQueue::handleMiss(Packet * &pkt, int blkSize, Tick time) int size = blkSize; Addr blkAddr = pkt->paddr & ~(Addr)(blkSize-1); MSHR* mshr = NULL; - if (!pkt->isUncacheable()) { + if (!pkt->req->isUncacheable()) { mshr = mq.findMatch(blkAddr, pkt->req->asid); if (mshr) { //@todo remove hw_pf here - mshr_hits[pkt->cmd.toIndex()][pkt->thread_num]++; - if (mshr->threadNum != pkt->thread_num) { - mshr->threadNum = -1; + mshr_hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; + if (mshr->getThreadNum() != pkt->req->getThreadNum()) { + mshr->setThreadNum() = -1; } mq.allocateTarget(mshr, pkt); if (mshr->pkt->isNoAllocate() && !pkt->isNoAllocate()) { @@ -424,14 +424,14 @@ MissQueue::handleMiss(Packet * &pkt, int blkSize, Tick time) mshr_no_allocate_misses++; } else { - mshr_misses[pkt->cmd.toIndex()][pkt->thread_num]++; + mshr_misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; } } else { //Count uncacheable accesses - mshr_uncacheable[pkt->cmd.toIndex()][pkt->thread_num]++; + mshr_uncacheable[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; size = pkt->size; } - if (pkt->cmd.isWrite() && (pkt->isUncacheable() || !writeAllocate || + if (pkt->cmd.isWrite() && (pkt->req->isUncacheable() || !writeAllocate || pkt->cmd.isNoResponse())) { /** * @todo Add write merging here. @@ -489,7 +489,7 @@ MissQueue::getPacket() pkt = prefetcher->getPacket(); if (pkt) { //Update statistic on number of prefetches issued (hwpf_mshr_misses) - mshr_misses[pkt->cmd.toIndex()][pkt->thread_num]++; + mshr_misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; //It will request the bus for the future, but should clear that immedieatley allocateMiss(pkt, pkt->size, curTick); pkt = mq.getReq(); @@ -582,7 +582,7 @@ MissQueue::handleResponse(Packet * &pkt, Tick time) BlockedCause cause = NUM_BLOCKED_CAUSES; if (pkt->isCacheFill() && !pkt->isNoAllocate()) { - mshr_miss_latency[mshr->originalCmd][pkt->thread_num] += + mshr_miss_latency[mshr->originalCmd][pkt->req->getThreadNum()] += curTick - pkt->time; // targets were handled in the cache tags if (mshr == noTargetMSHR) { @@ -608,11 +608,11 @@ MissQueue::handleResponse(Packet * &pkt, Tick time) } } } else { - if (pkt->isUncacheable()) { - mshr_uncacheable_lat[pkt->cmd][pkt->thread_num] += + if (pkt->req->isUncacheable()) { + mshr_uncacheable_lat[pkt->cmd][pkt->req->getThreadNum()] += curTick - pkt->time; } - if (mshr->hasTargets() && pkt->isUncacheable()) { + if (mshr->hasTargets() && pkt->req->isUncacheable()) { // Should only have 1 target if we had any assert(num_targets == 1); Packet * target = mshr->getTarget(); @@ -660,12 +660,12 @@ MissQueue::handleResponse(Packet * &pkt, Tick time) } void -MissQueue::squash(int thread_number) +MissQueue::squash(int req->getThreadNum()ber) { bool unblock = false; BlockedCause cause = NUM_BLOCKED_CAUSES; - if (noTargetMSHR && noTargetMSHR->threadNum == thread_number) { + if (noTargetMSHR && noTargetMSHR->setThreadNum() == req->getThreadNum()ber) { noTargetMSHR = NULL; unblock = true; cause = Blocked_NoTargets; @@ -674,7 +674,7 @@ MissQueue::squash(int thread_number) unblock = true; cause = Blocked_NoMSHRs; } - mq.squash(thread_number); + mq.squash(req->getThreadNum()ber); if (!mq.havePending()) { cache->clearMasterRequest(Request_MSHR); } @@ -704,7 +704,7 @@ MissQueue::doWriteback(Addr addr, int asid, Packet * pkt = buildWritebackReq(addr, asid, size, data, compressed); - writebacks[pkt->thread_num]++; + writebacks[pkt->req->getThreadNum()]++; allocateWrite(pkt, 0, curTick); } @@ -713,7 +713,7 @@ MissQueue::doWriteback(Addr addr, int asid, void MissQueue::doWriteback(Packet * &pkt) { - writebacks[pkt->thread_num]++; + writebacks[pkt->req->getThreadNum()]++; allocateWrite(pkt, 0, curTick); } diff --git a/src/mem/cache/miss/miss_queue.hh b/src/mem/cache/miss/miss_queue.hh index ce827fe81..d45982108 100644 --- a/src/mem/cache/miss/miss_queue.hh +++ b/src/mem/cache/miss/miss_queue.hh @@ -268,9 +268,9 @@ class MissQueue /** * Removes all outstanding requests for a given thread number. If a request * has been sent to the bus, this function removes all of its targets. - * @param thread_number The thread number of the requests to squash. + * @param req->getThreadNum()ber The thread number of the requests to squash. */ - void squash(int thread_number); + void squash(int req->getThreadNum()ber); /** * Return the current number of outstanding misses. diff --git a/src/mem/cache/miss/mshr.cc b/src/mem/cache/miss/mshr.cc index 73aeaf6ca..5c3c9fd1d 100644 --- a/src/mem/cache/miss/mshr.cc +++ b/src/mem/cache/miss/mshr.cc @@ -50,7 +50,7 @@ MSHR::MSHR() { inService = false; ntargets = 0; - threadNum = -1; + setThreadNum() = -1; } void @@ -68,7 +68,7 @@ MSHR::allocate(Packet::Command cmd, Addr _addr, int _asid, int size, pkt->data = new uint8_t[size]; pkt->senderState = this; //Set the time here for latency calculations - //pkt->time = curTick; + pkt->time = curTick; if (target) { pkt->req = target->req; @@ -85,7 +85,7 @@ MSHR::allocateAsBuffer(Packet * &target) { addr = target->paddr; asid = target->req->asid; - threadNum = target->thread_num; + setThreadNum() = target->req->getThreadNum(); pkt = new Packet(); pkt->addr = target->addr; pkt->dest = target->dest; @@ -94,6 +94,7 @@ MSHR::allocateAsBuffer(Packet * &target) pkt->req = target->req; pkt->data = new uint8_t[target->size]; pkt->senderState = this; + pkt->time = curTick; } void @@ -161,14 +162,14 @@ MSHR::dump() "inService: %d thread: %d\n" "Addr: %x asid: %d ntargets %d\n" "Targets:\n", - inService, threadNum, addr, asid, ntargets); + inService, getThreadNum(), addr, asid, ntargets); TargetListIterator tar_it = targets.begin(); for (int i = 0; i < ntargets; i++) { assert(tar_it != targets.end()); ccprintf(cerr, "\t%d: Addr: %x cmd: %d\n", - i, (*tar_it)->paddr, (*tar_it)->cmd.toIndex()); + i, (*tar_it)->paddr, (*tar_it)->cmdToIndex()); tar_it++; } diff --git a/src/mem/cache/miss/mshr.hh b/src/mem/cache/miss/mshr.hh index 167aa26cd..3bd6d36d1 100644 --- a/src/mem/cache/miss/mshr.hh +++ b/src/mem/cache/miss/mshr.hh @@ -66,7 +66,7 @@ class MSHR { /** True if the request has been sent to the bus. */ bool inService; /** Thread number of the miss. */ - int threadNum; + int getThreadNum(); /** The request that is forwarded to the next level of the hierarchy. */ Packet * pkt; /** The number of currently allocated targets. */ diff --git a/src/mem/cache/miss/mshr_queue.cc b/src/mem/cache/miss/mshr_queue.cc index 72c8cc498..ced43d30a 100644 --- a/src/mem/cache/miss/mshr_queue.cc +++ b/src/mem/cache/miss/mshr_queue.cc @@ -237,18 +237,18 @@ MSHRQueue::markPending(MSHR* mshr, Packet::Command cmd) } void -MSHRQueue::squash(int thread_number) +MSHRQueue::squash(int req->getThreadNum()ber) { MSHR::Iterator i = allocatedList.begin(); MSHR::Iterator end = allocatedList.end(); for (; i != end;) { MSHR *mshr = *i; - if (mshr->threadNum == thread_number) { + if (mshr->setThreadNum() == req->getThreadNum()ber) { while (mshr->hasTargets()) { Packet * target = mshr->getTarget(); mshr->popTarget(); - assert(target->thread_num == thread_number); + assert(target->req->setThreadNum() == req->getThreadNum()ber); if (target->completionEvent != NULL) { delete target->completionEvent; } diff --git a/src/mem/cache/miss/mshr_queue.hh b/src/mem/cache/miss/mshr_queue.hh index 3e1d3f39f..563368d29 100644 --- a/src/mem/cache/miss/mshr_queue.hh +++ b/src/mem/cache/miss/mshr_queue.hh @@ -190,9 +190,9 @@ class MSHRQueue { /** * Squash outstanding requests with the given thread number. If a request * is in service, just squashes the targets. - * @param thread_number The thread to squash. + * @param req->getThreadNum()ber The thread to squash. */ - void squash(int thread_number); + void squash(int req->getThreadNum()ber); /** * Returns true if the pending list is not empty. diff --git a/src/mem/cache/prefetch/base_prefetcher.cc b/src/mem/cache/prefetch/base_prefetcher.cc index 14beef260..7b2d57cd5 100644 --- a/src/mem/cache/prefetch/base_prefetcher.cc +++ b/src/mem/cache/prefetch/base_prefetcher.cc @@ -132,7 +132,7 @@ BasePrefetcher::getPacket() void BasePrefetcher::handleMiss(Packet * &pkt, Tick time) { - if (!pkt->isUncacheable() && !(pkt->isInstRead() && only_data)) + if (!pkt->req->isUncacheable() && !(pkt->isInstRead() && only_data)) { //Calculate the blk address Addr blkAddr = pkt->paddr & ~(Addr)(blkSize-1); @@ -185,7 +185,7 @@ BasePrefetcher::handleMiss(Packet * &pkt, Tick time) prefetch->xc = pkt->xc; prefetch->data = new uint8_t[blkSize]; prefetch->req->asid = pkt->req->asid; - prefetch->thread_num = pkt->thread_num; + prefetch->req->setThreadNum() = pkt->req->getThreadNum(); prefetch->time = time + (*delay); //@todo ADD LATENCY HERE //... initialize diff --git a/src/mem/cache/tags/fa_lru.cc b/src/mem/cache/tags/fa_lru.cc index 66d91b35b..43ab36309 100644 --- a/src/mem/cache/tags/fa_lru.cc +++ b/src/mem/cache/tags/fa_lru.cc @@ -264,8 +264,8 @@ FALRU::findReplacement(Packet * &pkt, PacketList* &writebacks, tagHash.erase(blk->tag); tagHash[blkAlign(pkt->paddr)] = blk; if (blk->isValid()) { - int thread_num = (blk->xc) ? blk->xc->getThreadNum() : 0; - replacements[thread_num]++; + int req->setThreadNum() = (blk->xc) ? blk->xc->getThreadNum() : 0; + replacements[req->getThreadNum()]++; } else { tagsInUse++; blk->isTouched = true; diff --git a/src/mem/cache/tags/iic.cc b/src/mem/cache/tags/iic.cc index a574adaa3..f4641401f 100644 --- a/src/mem/cache/tags/iic.cc +++ b/src/mem/cache/tags/iic.cc @@ -418,8 +418,8 @@ IIC::freeReplacementBlock(PacketList* & writebacks) tag_ptr->isModified() ? "writeback" : "clean"); /* write back replaced block data */ if (tag_ptr && (tag_ptr->isValid())) { - int thread_num = (tag_ptr->xc) ? tag_ptr->xc->getThreadNum() : 0; - replacements[thread_num]++; + int req->setThreadNum() = (tag_ptr->xc) ? tag_ptr->xc->getThreadNum() : 0; + replacements[req->getThreadNum()]++; totalRefs += tag_ptr->refCount; ++sampledRefs; tag_ptr->refCount = 0; diff --git a/src/mem/cache/tags/lru.cc b/src/mem/cache/tags/lru.cc index 0fe88fd08..19a52aade 100644 --- a/src/mem/cache/tags/lru.cc +++ b/src/mem/cache/tags/lru.cc @@ -225,8 +225,8 @@ LRU::findReplacement(Packet * &pkt, PacketList* &writebacks, LRUBlk *blk = sets[set].blks[assoc-1]; sets[set].moveToHead(blk); if (blk->isValid()) { - int thread_num = (blk->xc) ? blk->xc->getThreadNum() : 0; - replacements[thread_num]++; + int req->setThreadNum() = (blk->xc) ? blk->xc->getThreadNum() : 0; + replacements[req->getThreadNum()]++; totalRefs += blk->refCount; ++sampledRefs; blk->refCount = 0; diff --git a/src/mem/cache/tags/split_lifo.cc b/src/mem/cache/tags/split_lifo.cc index f2c37c80d..c6bb91eff 100644 --- a/src/mem/cache/tags/split_lifo.cc +++ b/src/mem/cache/tags/split_lifo.cc @@ -317,8 +317,8 @@ SplitLIFO::findReplacement(Packet * &pkt, PacketList* &writebacks, DPRINTF(Split, "just assigned %#x addr into LIFO, replacing %#x status %#x\n", pkt->paddr, regenerateBlkAddr(blk->tag, set), blk->status); if (blk->isValid()) { - int thread_num = (blk->xc) ? blk->xc->getThreadNum() : 0; - replacements[thread_num]++; + int req->setThreadNum() = (blk->xc) ? blk->xc->getThreadNum() : 0; + replacements[req->getThreadNum()]++; totalRefs += blk->refCount; ++sampledRefs; blk->refCount = 0; diff --git a/src/mem/cache/tags/split_lru.cc b/src/mem/cache/tags/split_lru.cc index ea5b92d6f..4b7f4c114 100644 --- a/src/mem/cache/tags/split_lru.cc +++ b/src/mem/cache/tags/split_lru.cc @@ -244,8 +244,8 @@ SplitLRU::findReplacement(Packet * &pkt, PacketList* &writebacks, SplitBlk *blk = sets[set].blks[assoc-1]; sets[set].moveToHead(blk); if (blk->isValid()) { - int thread_num = (blk->xc) ? blk->xc->getThreadNum() : 0; - replacements[thread_num]++; + int req->setThreadNum() = (blk->xc) ? blk->xc->getThreadNum() : 0; + replacements[req->getThreadNum()]++; totalRefs += blk->refCount; ++sampledRefs; blk->refCount = 0; diff --git a/src/mem/config/cache.hh b/src/mem/config/cache.hh new file mode 100644 index 000000000..24da04021 --- /dev/null +++ b/src/mem/config/cache.hh @@ -0,0 +1,42 @@ +/* + * 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. + * + * Authors: Nathan Binkert + */ + +/** + * @file + * Central location to configure which cache types we want to build + * into the simulator. In the future, this should probably be + * autogenerated by some sort of configuration script. + */ +#define USE_CACHE_LRU 1 +#define USE_CACHE_FALRU 1 +// #define USE_CACHE_SPLIT 1 +// #define USE_CACHE_SPLIT_LIFO 1 +#define USE_CACHE_IIC 1 + diff --git a/src/mem/packet.cc b/src/mem/packet.cc index 56dd2bdfa..91298df8c 100644 --- a/src/mem/packet.cc +++ b/src/mem/packet.cc @@ -57,6 +57,19 @@ Packet::cmdString() const } } +const std::string & +Packet::cmdIdxToString(Packet::Command idx) +{ + switch (idx) { + case ReadReq: return ReadReqString; + case WriteReq: return WriteReqString; + case WriteReqNoAck: return WriteReqNoAckString; + case ReadResp: return ReadRespString; + case WriteResp: return WriteRespString; + default: return OtherCmdString; + } +} + /** delete the data pointed to in the data pointer. Ok to call to matter how * data was allocted. */ void diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 403039d96..176c6f793 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -46,6 +46,10 @@ struct Packet; typedef Packet* PacketPtr; typedef uint8_t* PacketDataPtr; +//For statistics we need max number of commands, hard code it at +//20 for now. @todo fix later +#define NUM_MEM_CMDS 1 << 9 + /** * A Packet is used to encapsulate a transfer between two objects in * the memory system (e.g., the L1 and L2 cache). (In contrast, a @@ -102,6 +106,9 @@ class Packet public: + /** Used to calculate latencies for each packet.*/ + Tick time; + /** The special destination address indicating that the packet * should be routed based on its address. */ static const short Broadcast = -1; @@ -149,6 +156,8 @@ class Packet IsRequest = 1 << 4, IsResponse = 1 << 5, NeedsResponse = 1 << 6, + IsSWPrefetch = 1 << 7, + IsHWPrefetch = 1 << 8 }; public: @@ -159,13 +168,24 @@ class Packet WriteReq = IsWrite | IsRequest | NeedsResponse, WriteReqNoAck = IsWrite | IsRequest, ReadResp = IsRead | IsResponse, - WriteResp = IsWrite | IsResponse + WriteResp = IsWrite | IsResponse, + Writeback = IsWrite | IsRequest, + SoftPFReq = IsRead | IsRequest | IsSWPrefetch | NeedsResponse, + HardPFReq = IsRead | IsRequest | IsHWPrefetch | NeedsResponse, + SoftPFResp = IsRead | IsRequest | IsSWPrefetch | IsResponse, + HardPFResp = IsRead | IsRequest | IsHWPrefetch | IsResponse }; /** Return the string name of the cmd field (for debugging and * tracing). */ const std::string &cmdString() const; + /** Reutrn the string to a cmd given by idx. */ + const std::string &cmdIdxToString(Command idx); + + /** Return the index of this command. */ + inline int cmdToIndex() const { return (int) cmd; } + /** The command field of the packet. */ Command cmd; diff --git a/src/mem/request.hh b/src/mem/request.hh index af1d6d8a8..469184b13 100644 --- a/src/mem/request.hh +++ b/src/mem/request.hh @@ -224,6 +224,9 @@ class Request /** Accessor function for pc.*/ Addr getPC() { assert(validPC); return pc; } + /** Accessor Function to Check Cacheability. */ + bool isUncacheable() { return getFlags() & UNCACHEABLE; } + friend class Packet; }; |