diff --git a/src/mem/ruby/structures/CacheMemory.hh b/src/mem/ruby/structures/CacheMemory.hh --- a/src/mem/ruby/structures/CacheMemory.hh +++ b/src/mem/ruby/structures/CacheMemory.hh @@ -114,7 +114,7 @@ void regStats(); bool checkResourceAvailable(CacheResourceType res, Address addr); - void recordRequestType(CacheRequestType requestType); + void recordRequestType(CacheRequestType requestType, Address addr); public: Stats::Scalar m_demand_hits; diff --git a/src/mem/ruby/structures/CacheMemory.cc b/src/mem/ruby/structures/CacheMemory.cc --- a/src/mem/ruby/structures/CacheMemory.cc +++ b/src/mem/ruby/structures/CacheMemory.cc @@ -549,22 +549,32 @@ ; } +// 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: # Node ID afeee121918e8b0b1821763f8d0db077d8610ac4 # Parent 91c1912ec60e96d8156e9eec29bdf52f0d3dba09 diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm --- a/src/mem/protocol/RubySlicc_Types.sm +++ b/src/mem/protocol/RubySlicc_Types.sm @@ -154,7 +154,7 @@ 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.hh b/src/mem/ruby/structures/BankedArray.hh --- a/src/mem/ruby/structures/BankedArray.hh +++ b/src/mem/ruby/structures/BankedArray.hh @@ -67,6 +67,8 @@ // 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/BankedArray.cc b/src/mem/ruby/structures/BankedArray.cc --- a/src/mem/ruby/structures/BankedArray.cc +++ b/src/mem/ruby/structures/BankedArray.cc @@ -57,13 +57,29 @@ 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"); } } @@ -71,8 +87,6 @@ busyBanks[bank].startAccess = curTick(); busyBanks[bank].endAccess = curTick() + (accessLatency-1) * g_system_ptr->clockPeriod(); - - return true; } unsigned int