diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm index 6c3c4168d..11159fd6c 100644 --- a/src/mem/protocol/RubySlicc_Types.sm +++ b/src/mem/protocol/RubySlicc_Types.sm @@ -154,7 +154,7 @@ structure (CacheMemory, external = "yes") { Cycles getTagLatency(); Cycles getDataLatency(); void setMRU(Address); - void recordRequestType(CacheRequestType); + void recordRequestType(CacheRequestType, Address); bool checkResourceAvailable(CacheResourceType, Address); int getCacheSize(); diff --git a/src/mem/ruby/structures/BankedArray.cc b/src/mem/ruby/structures/BankedArray.cc index dbde2ab9a..8bc3cf584 100644 --- a/src/mem/ruby/structures/BankedArray.cc +++ b/src/mem/ruby/structures/BankedArray.cc @@ -58,13 +58,29 @@ BankedArray::tryAccess(int64 idx) assert(bank < banks); if (busyBanks[bank].endAccess >= curTick()) { - if (!(busyBanks[bank].startAccess == curTick() && - busyBanks[bank].idx == idx)) { return false; + } + + return true; +} + +void +BankedArray::reserve(int64 idx) +{ + if (accessLatency == 0) + return; + + unsigned int bank = mapIndexToBank(idx); + assert(bank < banks); + + if(busyBanks[bank].endAccess >= curTick()) { + if (busyBanks[bank].startAccess == curTick() && + busyBanks[bank].idx == idx) { + // this is the same reservation (can happen when + // e.g., reserve the same resource for read and write) + return; // OK } else { - // We tried to allocate resources twice - // in the same cycle for the same addr - return true; + panic("BankedArray reservation error"); } } @@ -72,8 +88,6 @@ BankedArray::tryAccess(int64 idx) busyBanks[bank].startAccess = curTick(); busyBanks[bank].endAccess = curTick() + (accessLatency-1) * m_ruby_system->clockPeriod(); - - return true; } unsigned int diff --git a/src/mem/ruby/structures/BankedArray.hh b/src/mem/ruby/structures/BankedArray.hh index dbfee9994..438186944 100644 --- a/src/mem/ruby/structures/BankedArray.hh +++ b/src/mem/ruby/structures/BankedArray.hh @@ -70,6 +70,8 @@ class BankedArray // This is so we don't get aliasing on blocks being replaced bool tryAccess(int64 idx); + void reserve(int64 idx); + Cycles getLatency() const { return accessLatency; } }; diff --git a/src/mem/ruby/structures/CacheMemory.cc b/src/mem/ruby/structures/CacheMemory.cc index c802d8fb6..d08724cff 100644 --- a/src/mem/ruby/structures/CacheMemory.cc +++ b/src/mem/ruby/structures/CacheMemory.cc @@ -528,22 +528,32 @@ CacheMemory::regStats() ; } +// assumption: SLICC generated files will only call this function +// once **all** resources are granted void -CacheMemory::recordRequestType(CacheRequestType requestType) +CacheMemory::recordRequestType(CacheRequestType requestType, Address addr) { DPRINTF(RubyStats, "Recorded statistic: %s\n", CacheRequestType_to_string(requestType)); switch(requestType) { case CacheRequestType_DataArrayRead: + if (m_resource_stalls) + dataArray.reserve(addressToCacheSet(addr)); numDataArrayReads++; return; case CacheRequestType_DataArrayWrite: + if (m_resource_stalls) + dataArray.reserve(addressToCacheSet(addr)); numDataArrayWrites++; return; case CacheRequestType_TagArrayRead: + if (m_resource_stalls) + tagArray.reserve(addressToCacheSet(addr)); numTagArrayReads++; return; case CacheRequestType_TagArrayWrite: + if (m_resource_stalls) + tagArray.reserve(addressToCacheSet(addr)); numTagArrayWrites++; return; default: diff --git a/src/mem/ruby/structures/CacheMemory.hh b/src/mem/ruby/structures/CacheMemory.hh index c9c20d8b8..af5e680d8 100644 --- a/src/mem/ruby/structures/CacheMemory.hh +++ b/src/mem/ruby/structures/CacheMemory.hh @@ -117,7 +117,7 @@ class CacheMemory : public SimObject void regStats(); bool checkResourceAvailable(CacheResourceType res, Address addr); - void recordRequestType(CacheRequestType requestType); + void recordRequestType(CacheRequestType requestType, Address addr); public: Stats::Scalar m_demand_hits;