33 #include "debug/RubyCache.hh"
34 #include "debug/RubyCacheTrace.hh"
35 #include "debug/RubyResourceStalls.hh"
36 #include "debug/RubyStats.hh"
37 #include "mem/protocol/AccessPermission.hh"
52 RubyCacheParams::create()
59 dataArray(p->dataArrayBanks, p->dataAccessLatency,
60 p->start_index_bit, p->ruby_system),
61 tagArray(p->tagArrayBanks, p->tagAccessLatency,
62 p->start_index_bit, p->ruby_system)
118 if (
m_cache[cacheSet][it->second]->m_Permission !=
119 AccessPermission_NotPresent)
150 assert (way < m_cache_assoc);
166 DPRINTF(RubyCache,
"address: %#x\n", address);
175 if (entry->
m_Permission == AccessPermission_Read_Write) {
178 if ((entry->
m_Permission == AccessPermission_Read_Only) &&
179 (type == RubyRequestType_LD || type == RubyRequestType_IFETCH)) {
193 DPRINTF(RubyCache,
"address: %#x\n", address);
203 return m_cache[cacheSet][loc]->m_Permission !=
204 AccessPermission_NotPresent;
221 DPRINTF(RubyCache,
"No tag match for address: %#x\n", address);
224 DPRINTF(RubyCache,
"address: %#x found\n", address);
259 DPRINTF(RubyCache,
"address: %#x\n", address);
265 if (!set[
i] || set[
i]->m_Permission == AccessPermission_NotPresent) {
266 if (set[
i] && (set[
i] != entry)) {
267 warn_once(
"This protocol contains a cache entry handling bug: "
268 "Entries in the cache should never be NotPresent! If\n"
269 "this entry (%#x) is not tracked elsewhere, it will memory "
270 "leak here. Fix your protocol to eliminate these!",
274 set[
i]->m_Address = address;
275 set[
i]->m_Permission = AccessPermission_Invalid;
276 DPRINTF(RubyCache,
"Allocate clearing lock for addr: %x\n",
278 set[
i]->m_locked = -1;
290 panic(
"Allocate didn't find an available entry");
298 DPRINTF(RubyCache,
"address: %#x\n", address);
327 if (loc == -1)
return NULL;
338 if (loc == -1)
return NULL;
370 touch(cacheSet, loc,
curTick(), occupancy);
373 touch(cacheSet, loc,
curTick());
384 if (
m_cache[set][loc] != NULL) {
385 ret =
m_cache[set][loc]->getNumValidBlocks();
395 uint64_t warmedUpBlocks = 0;
402 AccessPermission perm =
m_cache[
i][
j]->m_Permission;
403 RubyRequestType request_type = RubyRequestType_NULL;
404 if (perm == AccessPermission_Read_Only) {
406 request_type = RubyRequestType_IFETCH;
408 request_type = RubyRequestType_LD;
410 }
else if (perm == AccessPermission_Read_Write) {
411 request_type = RubyRequestType_ST;
414 if (request_type != RubyRequestType_NULL) {
425 DPRINTF(RubyCacheTrace,
"%s: %lli blocks of %lli total blocks"
426 "recorded %.2f%% \n",
name().c_str(), warmedUpBlocks,
427 totalBlocks, (
float(warmedUpBlocks) /
float(totalBlocks)) * 100.0);
433 out <<
"Cache dump: " <<
name() << endl;
437 out <<
" Index: " <<
i
441 out <<
" Index: " <<
i
443 <<
" entry: NULL" << endl;
452 out <<
"printData() not supported" << endl;
458 DPRINTF(RubyCache,
"Setting Lock for addr: %#x to %d\n", address, context);
463 m_cache[cacheSet][loc]->setLocked(context);
469 DPRINTF(RubyCache,
"Clear Lock for addr: %#x\n", address);
474 m_cache[cacheSet][loc]->clearLocked();
484 DPRINTF(RubyCache,
"Testing Lock for addr: %#llx cur %d con %d\n",
485 address,
m_cache[cacheSet][loc]->m_locked, context);
486 return m_cache[cacheSet][loc]->isLocked(context);
496 .
desc(
"Number of cache demand hits")
501 .
desc(
"Number of cache demand misses")
506 .
desc(
"Number of cache demand accesses")
512 .
name(
name() +
".total_sw_prefetches")
513 .
desc(
"Number of software prefetches")
518 .
name(
name() +
".total_hw_prefetches")
519 .
desc(
"Number of hardware prefetches")
525 .
desc(
"Number of prefetches")
532 .
init(RubyRequestType_NUM)
536 for (
int i = 0;
i < RubyAccessMode_NUM;
i++) {
538 .
subname(
i, RubyAccessMode_to_string(RubyAccessMode(
i)))
544 .
name(
name() +
".num_data_array_reads")
545 .
desc(
"number of data array reads")
550 .
name(
name() +
".num_data_array_writes")
551 .
desc(
"number of data array writes")
556 .
name(
name() +
".num_tag_array_reads")
557 .
desc(
"number of tag array reads")
562 .
name(
name() +
".num_tag_array_writes")
563 .
desc(
"number of tag array writes")
568 .
name(
name() +
".num_tag_array_stalls")
569 .
desc(
"number of stalls caused by tag array")
574 .
name(
name() +
".num_data_array_stalls")
575 .
desc(
"number of stalls caused by data array")
585 DPRINTF(RubyStats,
"Recorded statistic: %s\n",
586 CacheRequestType_to_string(requestType));
587 switch(requestType) {
588 case CacheRequestType_DataArrayRead:
593 case CacheRequestType_DataArrayWrite:
598 case CacheRequestType_TagArrayRead:
603 case CacheRequestType_TagArrayWrite:
609 warn(
"CacheMemory access_type not found: %s",
610 CacheRequestType_to_string(requestType));
621 if (res == CacheResourceType_TagArray) {
625 "Tag array stall on addr %#x in set %d\n",
630 }
else if (res == CacheResourceType_DataArray) {
634 "Data array stall on addr %#x in set %d\n",
648 return (
m_cache[cache_set][loc]->m_Permission == AccessPermission_Invalid);
654 return (
m_cache[cache_set][loc]->m_Permission != AccessPermission_Busy);
Stats::Scalar m_demand_misses
const FlagsType pdf
Print the percent of the total that this entry represents.
virtual bool useOccupancy() const
void setSetIndex(uint32_t s)
void setWayIndex(uint32_t s)
void recordCacheContents(int cntrl, CacheRecorder *tr) const
Stats::Vector m_accessModeType
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation...
Addr bitSelect(Addr addr, unsigned int small, unsigned int big)
void recordRequestType(CacheRequestType requestType, Addr addr)
Stats::Formula m_demand_accesses
uint32_t getSetIndex() const
int findTagInSet(int64_t line, Addr tag) const
bool tryAccess(int64_t idx)
virtual DataBlock & getDataBlk()
bool cacheAvail(Addr address) const
bool isBlockNotBusy(int64_t cache_set, int64_t loc)
bool testCacheAccess(Addr address, RubyRequestType type, DataBlock *&data_ptr)
Stats::Scalar m_hw_prefetches
void addRecord(int cntrl, Addr data_addr, Addr pc_addr, RubyRequestType type, Tick time, DataBlock &data)
void clearLocked(Addr addr)
bool isLocked(Addr addr, int context)
Addr getAddressAtIdx(int idx) const
void regStats()
Register statistics for this object.
virtual void regStats()
Register statistics for this object.
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Stats::Scalar numTagArrayStalls
Derived & init(size_type size)
Set this vector to have the given size.
void deallocate(Addr address)
void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
std::unordered_map< Addr, int > m_tag_index
Tick curTick()
The current simulated tick.
void setMRU(Addr address)
virtual void touch(int64_t set, int64_t way, Tick time)=0
CacheMemory(const Params *p)
bool isBlockInvalid(int64_t cache_set, int64_t loc)
uint32_t getWayIndex() const
Addr cacheProbe(Addr address) const
bool tryCacheAccess(Addr address, RubyRequestType type, DataBlock *&data_ptr)
Stats::Scalar m_demand_hits
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Addr makeLineAddress(Addr addr)
Stats::Scalar numDataArrayWrites
AbstractReplacementPolicy * m_replacementPolicy_ptr
const FlagsType total
Print the total.
Tick getLastAccess(int64_t set, int64_t way)
bool m_is_instruction_only_cache
static const int NumArgumentRegs M5_VAR_USED
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
int floorLog2(unsigned x)
virtual const std::string name() const
int findTagInSetIgnorePermissions(int64_t cacheSet, Addr tag) const
void reserve(int64_t idx)
void setCache(CacheMemory *pCache)
AbstractCacheEntry * allocate(Addr address, AbstractCacheEntry *new_entry, bool touch)
Stats::Scalar m_sw_prefetches
int getReplacementWeight(int64_t set, int64_t loc)
void setLocked(Addr addr, int context)
ostream & operator<<(ostream &out, const CacheMemory &obj)
Stats::Scalar numTagArrayWrites
void print(std::ostream &out) const
Stats::Scalar numDataArrayStalls
Stats::Scalar numDataArrayReads
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
void printData(std::ostream &out) const
Stats::Scalar numTagArrayReads
int64_t addressToCacheSet(Addr address) const
AccessPermission m_Permission
Stats::Formula m_prefetches
const FlagsType nozero
Don't print if this is zero.
bool checkResourceAvailable(CacheResourceType res, Addr addr)
AbstractCacheEntry * lookup(Addr address)
static uint32_t getBlockSizeBytes()
Abstract superclass for simulation objects.
std::vector< std::vector< AbstractCacheEntry * > > m_cache
bool isTagPresent(Addr address) const
virtual int64_t getVictim(int64_t set) const =0