gem5 v24.0.0.0
Loading...
Searching...
No Matches
CacheMemory.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020-2021 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood
15 * Copyright (c) 2013 Advanced Micro Devices, Inc.
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
43
44#include "base/compiler.hh"
45#include "base/intmath.hh"
46#include "base/logging.hh"
47#include "debug/HtmMem.hh"
48#include "debug/RubyCache.hh"
49#include "debug/RubyCacheTrace.hh"
50#include "debug/RubyResourceStalls.hh"
51#include "debug/RubyStats.hh"
53#include "mem/ruby/protocol/AccessPermission.hh"
55
56namespace gem5
57{
58
59namespace ruby
60{
61
62std::ostream&
63operator<<(std::ostream& out, const CacheMemory& obj)
64{
65 obj.print(out);
66 out << std::flush;
67 return out;
68}
69
71 : SimObject(p),
72 dataArray(p.dataArrayBanks, p.dataAccessLatency,
73 p.start_index_bit, p.ruby_system),
74 tagArray(p.tagArrayBanks, p.tagAccessLatency,
75 p.start_index_bit, p.ruby_system),
76 atomicALUArray(p.atomicALUs, p.atomicLatency *
77 p.ruby_system->clockPeriod()),
78 cacheMemoryStats(this)
79{
80 m_cache_size = p.size;
81 m_cache_assoc = p.assoc;
82 m_replacementPolicy_ptr = p.replacement_policy;
83 m_start_index_bit = p.start_index_bit;
85 m_resource_stalls = p.resourceStalls;
86 m_block_size = p.block_size; // may be 0 at this point. Updated in init()
88 m_replacementPolicy_ptr) ? true : false;
89}
90
91void
93{
94 if (m_block_size == 0) {
96 }
98 assert(m_cache_num_sets > 1);
100 assert(m_cache_num_set_bits > 0);
101
106 // instantiate all the replacement_data here
107 for (int i = 0; i < m_cache_num_sets; i++) {
108 for ( int j = 0; j < m_cache_assoc; j++) {
109 replacement_data[i][j] =
111 }
112 }
113}
114
116{
119 for (int i = 0; i < m_cache_num_sets; i++) {
120 for (int j = 0; j < m_cache_assoc; j++) {
121 delete m_cache[i][j];
122 }
123 }
124}
125
126// convert a Address to its location in the cache
127int64_t
129{
130 assert(address == makeLineAddress(address));
131 return bitSelect(address, m_start_index_bit,
133}
134
135// Given a cache index: returns the index of the tag in a set.
136// returns -1 if the tag is not found.
137int
138CacheMemory::findTagInSet(int64_t cacheSet, Addr tag) const
139{
140 assert(tag == makeLineAddress(tag));
141 // search the set for the tags
142 auto it = m_tag_index.find(tag);
143 if (it != m_tag_index.end())
144 if (m_cache[cacheSet][it->second]->m_Permission !=
145 AccessPermission_NotPresent)
146 return it->second;
147 return -1; // Not found
148}
149
150// Given a cache index: returns the index of the tag in a set.
151// returns -1 if the tag is not found.
152int
154 Addr tag) const
155{
156 assert(tag == makeLineAddress(tag));
157 // search the set for the tags
158 auto it = m_tag_index.find(tag);
159 if (it != m_tag_index.end())
160 return it->second;
161 return -1; // Not found
162}
163
164// Given an unique cache block identifier (idx): return the valid address
165// stored by the cache block. If the block is invalid/notpresent, the
166// function returns the 0 address
167Addr
169{
170 Addr tmp(0);
171
172 int set = idx / m_cache_assoc;
173 assert(set < m_cache_num_sets);
174
175 int way = idx - set * m_cache_assoc;
176 assert (way < m_cache_assoc);
177
178 AbstractCacheEntry* entry = m_cache[set][way];
179 if (entry == NULL ||
180 entry->m_Permission == AccessPermission_Invalid ||
181 entry->m_Permission == AccessPermission_NotPresent) {
182 return tmp;
183 }
184 return entry->m_Address;
185}
186
187bool
188CacheMemory::tryCacheAccess(Addr address, RubyRequestType type,
189 DataBlock*& data_ptr)
190{
191 DPRINTF(RubyCache, "trying to access address: %#x\n", address);
192 AbstractCacheEntry* entry = lookup(address);
193 if (entry != nullptr) {
194 // Do we even have a tag match?
196 entry->setLastAccess(curTick());
197 data_ptr = &(entry->getDataBlk());
198
199 if (entry->m_Permission == AccessPermission_Read_Write) {
200 DPRINTF(RubyCache, "Have permission to access address: %#x\n",
201 address);
202 return true;
203 }
204 if ((entry->m_Permission == AccessPermission_Read_Only) &&
205 (type == RubyRequestType_LD || type == RubyRequestType_IFETCH)) {
206 DPRINTF(RubyCache, "Have permission to access address: %#x\n",
207 address);
208 return true;
209 }
210 // The line must not be accessible
211 }
212 DPRINTF(RubyCache, "Do not have permission to access address: %#x\n",
213 address);
214 data_ptr = NULL;
215 return false;
216}
217
218bool
219CacheMemory::testCacheAccess(Addr address, RubyRequestType type,
220 DataBlock*& data_ptr)
221{
222 DPRINTF(RubyCache, "testing address: %#x\n", address);
223 AbstractCacheEntry* entry = lookup(address);
224 if (entry != nullptr) {
225 // Do we even have a tag match?
227 entry->setLastAccess(curTick());
228 data_ptr = &(entry->getDataBlk());
229
230 DPRINTF(RubyCache, "have permission for address %#x?: %d\n",
231 address,
232 entry->m_Permission != AccessPermission_NotPresent);
233 return entry->m_Permission != AccessPermission_NotPresent;
234 }
235
236 DPRINTF(RubyCache, "do not have permission for address %#x\n",
237 address);
238 data_ptr = NULL;
239 return false;
240}
241
242// tests to see if an address is present in the cache
243bool
245{
246 const AbstractCacheEntry* const entry = lookup(address);
247 if (entry == nullptr) {
248 // We didn't find the tag
249 DPRINTF(RubyCache, "No tag match for address: %#x\n", address);
250 return false;
251 }
252 DPRINTF(RubyCache, "address: %#x found\n", address);
253 return true;
254}
255
256// Returns true if there is:
257// a) a tag match on this address or there is
258// b) an unused line in the same cache "way"
259bool
261{
262 assert(address == makeLineAddress(address));
263
264 int64_t cacheSet = addressToCacheSet(address);
265
266 for (int i = 0; i < m_cache_assoc; i++) {
267 AbstractCacheEntry* entry = m_cache[cacheSet][i];
268 if (entry != NULL) {
269 if (entry->m_Address == address ||
270 entry->m_Permission == AccessPermission_NotPresent) {
271 // Already in the cache or we found an empty entry
272 return true;
273 }
274 } else {
275 return true;
276 }
277 }
278 return false;
279}
280
283{
284 assert(address == makeLineAddress(address));
285 assert(!isTagPresent(address));
286 assert(cacheAvail(address));
287 DPRINTF(RubyCache, "allocating address: %#x\n", address);
288
289 // Find the first open slot
290 int64_t cacheSet = addressToCacheSet(address);
292 for (int i = 0; i < m_cache_assoc; i++) {
293 if (!set[i] || set[i]->m_Permission == AccessPermission_NotPresent) {
294 if (set[i] && (set[i] != entry)) {
295 warn_once("This protocol contains a cache entry handling bug: "
296 "Entries in the cache should never be NotPresent! If\n"
297 "this entry (%#x) is not tracked elsewhere, it will memory "
298 "leak here. Fix your protocol to eliminate these!",
299 address);
300 }
301 set[i] = entry; // Init entry
302 set[i]->m_Address = address;
303 set[i]->m_Permission = AccessPermission_Invalid;
304 DPRINTF(RubyCache, "Allocate clearing lock for addr: 0x%x\n",
305 address);
306 set[i]->m_locked = -1;
307 m_tag_index[address] = i;
308 set[i]->setPosition(cacheSet, i);
309 set[i]->replacementData = replacement_data[cacheSet][i];
310 set[i]->setLastAccess(curTick());
311
312 // Call reset function here to set initial value for different
313 // replacement policies.
315
316 return entry;
317 }
318 }
319 panic("Allocate didn't find an available entry");
320}
321
322void
324{
325 DPRINTF(RubyCache, "deallocating address: %#x\n", address);
326 AbstractCacheEntry* entry = lookup(address);
327 assert(entry != nullptr);
329 uint32_t cache_set = entry->getSet();
330 uint32_t way = entry->getWay();
331 delete entry;
332 m_cache[cache_set][way] = NULL;
333 m_tag_index.erase(address);
334}
335
336// Returns with the physical address of the conflicting cache line
337Addr
339{
340 assert(address == makeLineAddress(address));
341 assert(!cacheAvail(address));
342
343 int64_t cacheSet = addressToCacheSet(address);
345 for (int i = 0; i < m_cache_assoc; i++) {
346 candidates.push_back(static_cast<ReplaceableEntry*>(
347 m_cache[cacheSet][i]));
348 }
349 return m_cache[cacheSet][m_replacementPolicy_ptr->
350 getVictim(candidates)->getWay()]->m_Address;
351}
352
353// looks an address up in the cache
356{
357 assert(address == makeLineAddress(address));
358 int64_t cacheSet = addressToCacheSet(address);
359 int loc = findTagInSet(cacheSet, address);
360 if (loc == -1) return NULL;
361 return m_cache[cacheSet][loc];
362}
363
364// looks an address up in the cache
367{
368 assert(address == makeLineAddress(address));
369 int64_t cacheSet = addressToCacheSet(address);
370 int loc = findTagInSet(cacheSet, address);
371 if (loc == -1) return NULL;
372 return m_cache[cacheSet][loc];
373}
374
375// Sets the most recently used bit for a cache block
376void
378{
379 AbstractCacheEntry* entry = lookup(makeLineAddress(address));
380 if (entry != nullptr) {
382 entry->setLastAccess(curTick());
383 }
384}
385
386void
388{
389 assert(entry != nullptr);
391 entry->setLastAccess(curTick());
392}
393
394void
395CacheMemory::setMRU(Addr address, int occupancy)
396{
397 AbstractCacheEntry* entry = lookup(makeLineAddress(address));
398 if (entry != nullptr) {
399 // m_use_occupancy can decide whether we are using WeightedLRU
400 // replacement policy. Depending on different replacement policies,
401 // use different touch() function.
402 if (m_use_occupancy) {
405 entry->replacementData, occupancy);
406 } else {
408 }
409 entry->setLastAccess(curTick());
410 }
411}
412
413int
415{
416 assert(set < m_cache_num_sets);
417 assert(loc < m_cache_assoc);
418 int ret = 0;
419 if (m_cache[set][loc] != NULL) {
420 ret = m_cache[set][loc]->getNumValidBlocks();
421 assert(ret >= 0);
422 }
423
424 return ret;
425}
426
427void
429{
430 uint64_t warmedUpBlocks = 0;
431 [[maybe_unused]] uint64_t totalBlocks = (uint64_t)m_cache_num_sets *
432 (uint64_t)m_cache_assoc;
433
434 for (int i = 0; i < m_cache_num_sets; i++) {
435 for (int j = 0; j < m_cache_assoc; j++) {
436 if (m_cache[i][j] != NULL) {
437 AccessPermission perm = m_cache[i][j]->m_Permission;
438 RubyRequestType request_type = RubyRequestType_NULL;
439 if (perm == AccessPermission_Read_Only) {
441 request_type = RubyRequestType_IFETCH;
442 } else {
443 request_type = RubyRequestType_LD;
444 }
445 } else if (perm == AccessPermission_Read_Write) {
446 request_type = RubyRequestType_ST;
447 }
448
449 if (request_type != RubyRequestType_NULL) {
450 Tick lastAccessTick;
451 lastAccessTick = m_cache[i][j]->getLastAccess();
452 tr->addRecord(cntrl, m_cache[i][j]->m_Address,
453 0, request_type, lastAccessTick,
454 m_cache[i][j]->getDataBlk());
455 warmedUpBlocks++;
456 }
457 }
458 }
459 }
460
461 DPRINTF(RubyCacheTrace, "%s: %lli blocks of %lli total blocks"
462 "recorded %.2f%% \n", name().c_str(), warmedUpBlocks,
463 totalBlocks, (float(warmedUpBlocks) / float(totalBlocks)) * 100.0);
464}
465
466void
467CacheMemory::print(std::ostream& out) const
468{
469 out << "Cache dump: " << name() << std::endl;
470 for (int i = 0; i < m_cache_num_sets; i++) {
471 for (int j = 0; j < m_cache_assoc; j++) {
472 if (m_cache[i][j] != NULL) {
473 out << " Index: " << i
474 << " way: " << j
475 << " entry: " << *m_cache[i][j] << std::endl;
476 } else {
477 out << " Index: " << i
478 << " way: " << j
479 << " entry: NULL" << std::endl;
480 }
481 }
482 }
483}
484
485void
486CacheMemory::printData(std::ostream& out) const
487{
488 out << "printData() not supported" << std::endl;
489}
490
491void
492CacheMemory::setLocked(Addr address, int context)
493{
494 DPRINTF(RubyCache, "Setting Lock for addr: %#x to %d\n", address, context);
495 AbstractCacheEntry* entry = lookup(address);
496 assert(entry != nullptr);
497 entry->setLocked(context);
498}
499
500void
502{
503 DPRINTF(RubyCache, "Clear Lock for addr: %#x\n", address);
504 AbstractCacheEntry* entry = lookup(address);
505 assert(entry != nullptr);
506 entry->clearLocked();
507}
508
509void
511{
512 // iterate through every set and way to get a cache line
513 for (auto i = m_cache.begin(); i != m_cache.end(); ++i) {
515 for (auto j = set.begin(); j != set.end(); ++j) {
516 AbstractCacheEntry *line = *j;
517 if (line && line->isLocked(context)) {
518 DPRINTF(RubyCache, "Clear Lock for addr: %#x\n",
519 line->m_Address);
520 line->clearLocked();
521 }
522 }
523 }
524}
525
526bool
527CacheMemory::isLocked(Addr address, int context)
528{
529 AbstractCacheEntry* entry = lookup(address);
530 assert(entry != nullptr);
531 DPRINTF(RubyCache, "Testing Lock for addr: %#llx cur %d con %d\n",
532 address, entry->m_locked, context);
533 return entry->isLocked(context);
534}
535
538 : statistics::Group(parent),
539 ADD_STAT(numDataArrayReads, "Number of data array reads"),
540 ADD_STAT(numDataArrayWrites, "Number of data array writes"),
541 ADD_STAT(numTagArrayReads, "Number of tag array reads"),
542 ADD_STAT(numTagArrayWrites, "Number of tag array writes"),
543 ADD_STAT(numTagArrayStalls, "Number of stalls caused by tag array"),
544 ADD_STAT(numDataArrayStalls, "Number of stalls caused by data array"),
545 ADD_STAT(numAtomicALUOperations, "Number of atomic ALU operations"),
546 ADD_STAT(numAtomicALUArrayStalls, "Number of stalls caused by atomic ALU array"),
547 ADD_STAT(htmTransCommitReadSet, "Read set size of a committed "
548 "transaction"),
549 ADD_STAT(htmTransCommitWriteSet, "Write set size of a committed "
550 "transaction"),
551 ADD_STAT(htmTransAbortReadSet, "Read set size of a aborted transaction"),
552 ADD_STAT(htmTransAbortWriteSet, "Write set size of a aborted "
553 "transaction"),
554 ADD_STAT(m_demand_hits, "Number of cache demand hits"),
555 ADD_STAT(m_demand_misses, "Number of cache demand misses"),
556 ADD_STAT(m_demand_accesses, "Number of cache demand accesses",
557 m_demand_hits + m_demand_misses),
558 ADD_STAT(m_prefetch_hits, "Number of cache prefetch hits"),
559 ADD_STAT(m_prefetch_misses, "Number of cache prefetch misses"),
560 ADD_STAT(m_prefetch_accesses, "Number of cache prefetch accesses",
561 m_prefetch_hits + m_prefetch_misses),
562 ADD_STAT(m_accessModeType, "")
563{
566
569
572
575
578
581
584
587
589 .init(8)
592
594 .init(8)
597
599 .init(8)
602
604 .init(8)
607
610
613
616
618 .init(RubyRequestType_NUM)
620
621 for (int i = 0; i < RubyAccessMode_NUM; i++) {
623 .subname(i, RubyAccessMode_to_string(RubyAccessMode(i)))
625 ;
626 }
627}
628
629// assumption: SLICC generated files will only call this function
630// once **all** resources are granted
631void
632CacheMemory::recordRequestType(CacheRequestType requestType, Addr addr)
633{
634 DPRINTF(RubyStats, "Recorded statistic: %s\n",
635 CacheRequestType_to_string(requestType));
636 switch(requestType) {
637 case CacheRequestType_DataArrayRead:
641 return;
642 case CacheRequestType_DataArrayWrite:
646 return;
647 case CacheRequestType_TagArrayRead:
651 return;
652 case CacheRequestType_TagArrayWrite:
656 return;
657 case CacheRequestType_AtomicALUOperation:
661 return;
662 default:
663 warn("CacheMemory access_type not found: %s",
664 CacheRequestType_to_string(requestType));
665 }
666}
667
668bool
670{
671 if (!m_resource_stalls) {
672 return true;
673 }
674
675 if (res == CacheResourceType_TagArray) {
676 if (tagArray.tryAccess(addressToCacheSet(addr))) return true;
677 else {
678 DPRINTF(RubyResourceStalls,
679 "Tag array stall on addr %#x in set %d\n",
682 return false;
683 }
684 } else if (res == CacheResourceType_DataArray) {
685 if (dataArray.tryAccess(addressToCacheSet(addr))) return true;
686 else {
687 DPRINTF(RubyResourceStalls,
688 "Data array stall on addr %#x in set %d\n",
691 return false;
692 }
693 } else if (res == CacheResourceType_AtomicALUArray) {
694 if (atomicALUArray.tryAccess(addr)) return true;
695 else {
696 DPRINTF(RubyResourceStalls,
697 "Atomic ALU array stall on addr %#x in line address %#x\n",
700 return false;
701 }
702 } else {
703 panic("Unrecognized cache resource type.");
704 }
705}
706
707bool
708CacheMemory::isBlockInvalid(int64_t cache_set, int64_t loc)
709{
710 return (m_cache[cache_set][loc]->m_Permission == AccessPermission_Invalid);
711}
712
713bool
714CacheMemory::isBlockNotBusy(int64_t cache_set, int64_t loc)
715{
716 return (m_cache[cache_set][loc]->m_Permission != AccessPermission_Busy);
717}
718
719/* hardware transactional memory */
720
721void
723{
724 uint64_t htmReadSetSize = 0;
725 uint64_t htmWriteSetSize = 0;
726
727 // iterate through every set and way to get a cache line
728 for (auto i = m_cache.begin(); i != m_cache.end(); ++i)
729 {
731
732 for (auto j = set.begin(); j != set.end(); ++j)
733 {
734 AbstractCacheEntry *line = *j;
735
736 if (line != nullptr) {
737 htmReadSetSize += (line->getInHtmReadSet() ? 1 : 0);
738 htmWriteSetSize += (line->getInHtmWriteSet() ? 1 : 0);
739 if (line->getInHtmWriteSet()) {
740 line->invalidateEntry();
741 }
742 line->setInHtmWriteSet(false);
743 line->setInHtmReadSet(false);
744 line->clearLocked();
745 }
746 }
747 }
748
751 DPRINTF(HtmMem, "htmAbortTransaction: read set=%u write set=%u\n",
752 htmReadSetSize, htmWriteSetSize);
753}
754
755void
757{
758 uint64_t htmReadSetSize = 0;
759 uint64_t htmWriteSetSize = 0;
760
761 // iterate through every set and way to get a cache line
762 for (auto i = m_cache.begin(); i != m_cache.end(); ++i)
763 {
765
766 for (auto j = set.begin(); j != set.end(); ++j)
767 {
768 AbstractCacheEntry *line = *j;
769 if (line != nullptr) {
770 htmReadSetSize += (line->getInHtmReadSet() ? 1 : 0);
771 htmWriteSetSize += (line->getInHtmWriteSet() ? 1 : 0);
772 line->setInHtmWriteSet(false);
773 line->setInHtmReadSet(false);
774 line->clearLocked();
775 }
776 }
777 }
778
781 DPRINTF(HtmMem, "htmCommitTransaction: read set=%u write set=%u\n",
782 htmReadSetSize, htmWriteSetSize);
783}
784
785void
790
791void
796
797void
802
803void
808
809} // namespace ruby
810} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
virtual std::string name() const
Definition named.hh:47
A replaceable entry is a basic entry in a 2d table-like structure that needs to have replacement func...
std::shared_ptr< replacement_policy::ReplacementData > replacementData
Replacement data associated to this entry.
uint32_t getWay() const
Get way number.
uint32_t getSet() const
Get set number.
Abstract superclass for simulation objects.
virtual void invalidate(const std::shared_ptr< ReplacementData > &replacement_data)=0
Invalidate replacement data to set it as the next probable victim.
virtual void reset(const std::shared_ptr< ReplacementData > &replacement_data, const PacketPtr pkt)
Reset replacement data.
Definition base.hh:89
virtual void touch(const std::shared_ptr< ReplacementData > &replacement_data, const PacketPtr pkt)
Update replacement data.
Definition base.hh:75
virtual std::shared_ptr< ReplacementData > instantiateEntry()=0
Instantiate a replacement data entry.
bool isLocked(int context) const
void reserve(int64_t idx)
bool tryAccess(int64_t idx)
bool isTagPresent(Addr address) const
Addr getAddressAtIdx(int idx) const
void clearLockedAll(int context)
bool testCacheAccess(Addr address, RubyRequestType type, DataBlock *&data_ptr)
ALUFreeListArray atomicALUArray
bool m_use_occupancy
Set to true when using WeightedLRU replacement policy, otherwise, set to false.
void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
std::vector< std::vector< ReplData > > replacement_data
We store all the ReplacementData in a 2-dimensional array.
void print(std::ostream &out) const
void recordCacheContents(int cntrl, CacheRecorder *tr) const
void setMRU(Addr address)
gem5::ruby::CacheMemory::CacheMemoryStats cacheMemoryStats
void deallocate(Addr address)
int findTagInSet(int64_t line, Addr tag) const
void setLocked(Addr addr, int context)
int findTagInSetIgnorePermissions(int64_t cacheSet, Addr tag) const
bool isBlockInvalid(int64_t cache_set, int64_t loc)
int64_t addressToCacheSet(Addr address) const
bool tryCacheAccess(Addr address, RubyRequestType type, DataBlock *&data_ptr)
RubyCacheParams Params
void clearLocked(Addr addr)
bool isBlockNotBusy(int64_t cache_set, int64_t loc)
Addr cacheProbe(Addr address) const
void recordRequestType(CacheRequestType requestType, Addr addr)
void printData(std::ostream &out) const
bool cacheAvail(Addr address) const
CacheMemory(const Params &p)
replacement_policy::Base * m_replacementPolicy_ptr
We use the replacement policies from the Classic memory system.
std::unordered_map< Addr, int > m_tag_index
AbstractCacheEntry * allocate(Addr address, AbstractCacheEntry *new_entry)
int getReplacementWeight(int64_t set, int64_t loc)
std::vector< std::vector< AbstractCacheEntry * > > m_cache
bool checkResourceAvailable(CacheResourceType res, Addr addr)
AbstractCacheEntry * lookup(Addr address)
bool isLocked(Addr addr, int context)
void addRecord(int cntrl, Addr data_addr, Addr pc_addr, RubyRequestType type, Tick time, DataBlock &data)
static uint32_t getBlockSizeBytes()
Definition RubySystem.hh:72
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.
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Statistics container.
Definition group.hh:93
Histogram & init(size_type size)
Set the parameters of this histogram.
Derived & init(size_type size)
Set this vector to have the given size.
STL vector class.
Definition stl.hh:37
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition group.hh:75
static constexpr std::enable_if_t< std::is_integral_v< T >, int > floorLog2(T x)
Definition intmath.hh:59
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define warn(...)
Definition logging.hh:256
#define warn_once(...)
Definition logging.hh:260
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 12, 11 > set
Bitfield< 0 > p
Bitfield< 3, 1 > perm
Definition pagetable.hh:72
Bitfield< 3 > addr
Definition types.hh:84
Addr makeLineAddress(Addr addr)
Definition Address.cc:60
std::ostream & operator<<(std::ostream &os, const BoolVec &myvector)
Definition BoolVec.cc:49
Addr bitSelect(Addr addr, unsigned int small, unsigned int big)
Definition Address.cc:41
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition info.hh:61
const FlagsType nonan
Don't print if this is NAN.
Definition info.hh:69
const FlagsType nozero
Don't print if this is zero.
Definition info.hh:67
const FlagsType total
Print the total.
Definition info.hh:59
const FlagsType dist
Print the distribution.
Definition info.hh:65
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
uint64_t Tick
Tick count type.
Definition types.hh:58
CacheMemoryStats(statistics::Group *parent)

Generated on Tue Jun 18 2024 16:24:05 for gem5 by doxygen 1.11.0