@@ -22,6 +22,8 @@ CachePolicy::get_policy_instance(const CacheConfig *config) {
2222 config->associativity (), config->set_count ());
2323 case CacheConfig::RP_PLRU:
2424 return std::make_unique<CachePolicyPLRU>(config->associativity (), config->set_count ());
25+ case CacheConfig::RP_NMRU:
26+ return std::make_unique<CachePolicyNMRU>(config->associativity (), config->set_count ());
2527 }
2628 } else {
2729 // Disabled cache will never use it.
@@ -172,4 +174,29 @@ size_t CachePolicyPLRU::select_way_to_evict(size_t row) const {
172174 }
173175 return (idx >= associativity) ? (associativity - 1 ) : idx;
174176}
177+
178+ CachePolicyNMRU::CachePolicyNMRU (size_t associativity, size_t set_count)
179+ : associativity(associativity) {
180+ mru_ptr.resize (set_count);
181+ for (auto &row : mru_ptr) {
182+ row = 0 ; // Initially point to block 0
183+ }
184+ std::srand (1 ); // NOLINT(cert-msc51-cpp)
185+ }
186+
187+ void CachePolicyNMRU::update_stats (size_t way, size_t row, bool is_valid) {
188+ UNUSED (is_valid)
189+ auto &row_ptr = mru_ptr.at (row); // Set currently accessed block to most recently used
190+ row_ptr = way;
191+ }
192+
193+ size_t CachePolicyNMRU::select_way_to_evict (size_t row) const {
194+ if (associativity == 1 ) {
195+ return 0 ;
196+ }
197+ uint32_t idx = std::rand () % (associativity - 1 );
198+ auto &row_ptr = mru_ptr.at (row);
199+ idx = (idx < row_ptr) ? idx : idx + 1 ;
200+ return idx;
201+ }
175202} // namespace machine
0 commit comments