Cycles getTagLatency();
Cycles getDataLatency();
void setMRU(Address);
- void recordRequestType(CacheRequestType);
+ void recordRequestType(CacheRequestType, Address);
bool checkResourceAvailable(CacheResourceType, Address);
int getCacheSize();
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");
}
}
busyBanks[bank].startAccess = curTick();
busyBanks[bank].endAccess = curTick() +
(accessLatency-1) * m_ruby_system->clockPeriod();
-
- return true;
}
unsigned int
// 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; }
};
;
}
+// 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:
void regStats();
bool checkResourceAvailable(CacheResourceType res, Address addr);
- void recordRequestType(CacheRequestType requestType);
+ void recordRequestType(CacheRequestType requestType, Address addr);
public:
Stats::Scalar m_demand_hits;