diff --git a/SConscript b/SConscript index c17a94e5f..99471ba0e 100644 --- a/SConscript +++ b/SConscript @@ -355,4 +355,3 @@ env.Program( ######################################################################################### if GetOption('clean'): os.system('rm -f ../bin/macsim') - diff --git a/src/cache.cc b/src/cache.cc index 4a3e5234e..0bf6dedf3 100644 --- a/src/cache.cc +++ b/src/cache.cc @@ -80,6 +80,7 @@ cache_c::cache_c(string name, int num_set, int assoc, int line_size, m_data_size = data_size; m_assoc = assoc; m_num_sets = num_set; + ASSERTM(m_num_sets > 0, "cache:%s num_set:%d\n", m_name.c_str(), m_num_sets); m_line_size = line_size; m_cache_type = cache_type_info; m_num_tiles = (num_tiles > 0) ? num_tiles : 1; @@ -154,9 +155,9 @@ cache_c::~cache_c() { // parse tag address and set index from an address void cache_c::find_tag_and_set(Addr addr, Addr *tag, int *set) { + Addr index_addr = addr; if (m_num_tiles == 1) { - *tag = addr >> m_shift_bits & m_tag_mask; - *set = addr >> m_shift_bits & m_set_mask; + index_addr = addr; } else { Addr mod_addr; if (m_tile_bits) { @@ -172,8 +173,7 @@ void cache_c::find_tag_and_set(Addr addr, Addr *tag, int *set) { (((addr >> m_interleave_bits) / m_num_tiles) << m_interleave_bits) | (addr & m_interleave_mask); } - *tag = mod_addr >> m_shift_bits & m_tag_mask; - *set = mod_addr >> m_shift_bits & m_set_mask; + index_addr = mod_addr; // cout << hex << addr << " mod addr " << mod_addr << " imask " << m_interleave_mask << " addr & imask " << (addr & // m_interleave_mask) << " other part short " << ((addr >> m_interleave_bits) / m_num_tiles) << " other part " << // (((addr >> m_interleave_bits) / m_num_tiles) << m_interleave_bits) << " num tiles " << dec << m_num_tiles << " @@ -181,6 +181,16 @@ void cache_c::find_tag_and_set(Addr addr, Addr *tag, int *set) { // : 0) << " tag mask " << hex << m_tag_mask << " tag " << *tag << " set mask " << m_set_mask << " set " << *set << // dec << "\n"; } + + Addr line_number = index_addr >> m_shift_bits; + bool power_of_two_sets = (m_num_sets & (m_num_sets - 1)) == 0; + if (power_of_two_sets) { + *set = line_number & m_set_mask; + *tag = line_number & m_tag_mask; + } else { + *set = line_number % m_num_sets; + *tag = line_number / m_num_sets; + } } // access the cache diff --git a/src/cache.h b/src/cache.h index a68f11730..b02adfcd5 100644 --- a/src/cache.h +++ b/src/cache.h @@ -117,7 +117,7 @@ class cache_c /** * \brief Create a new cache using the configuration sent by the caller. * \param name - Name of the cache - * \param num_set - Cache Size + * \param num_set - Number of cache sets (must be > 0, power-of-two not required) * \param assoc - Cache Associativity * \param line_size - Line Size * \param data_size - Data Size