From 6aaeb1cbbc32d569a0fd841dc3c9165e79e506d9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 7 Sep 2026 20:24:24 +0000 Subject: [PATCH 1/3] Initial plan From ccb7f8363e6ad50b2d6e237ddd1eda792fb4ddd8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 7 Sep 2026 20:30:29 +0000 Subject: [PATCH 2/3] Fix cache set indexing for non-power-of-two set counts Co-authored-by: ejchung0406 <69669967+ejchung0406@users.noreply.github.com> --- SConscript | 4 +- src/cache.cc | 15 +++++-- src/cache.h | 18 +++++++- src/cache_set_indexing_test.cc | 78 ++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 src/cache_set_indexing_test.cc diff --git a/SConscript b/SConscript index c17a94e5f..f843b0045 100644 --- a/SConscript +++ b/SConscript @@ -349,10 +349,12 @@ env.Program( LIBS=libraries, ) +if ARGUMENTS.get('cache_set_test', '0') == '1': + env.Program('cache_set_indexing_test', ['src/cache_set_indexing_test.cc']) + ######################################################################################### # Clean ######################################################################################### if GetOption('clean'): os.system('rm -f ../bin/macsim') - diff --git a/src/cache.cc b/src/cache.cc index 4a3e5234e..43b57098a 100644 --- a/src/cache.cc +++ b/src/cache.cc @@ -80,6 +80,10 @@ 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; + if (m_num_sets <= 0) { + ASSERTM(0, "cache:%s num_set:%d\n", m_name.c_str(), m_num_sets); + abort(); + } m_line_size = line_size; m_cache_type = cache_type_info; m_num_tiles = (num_tiles > 0) ? num_tiles : 1; @@ -154,9 +158,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 +176,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 +184,10 @@ 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; + cache_line_to_set_and_tag(line_number, m_num_sets, m_set_bits, m_set_mask, + m_tag_mask, tag, set); } // access the cache diff --git a/src/cache.h b/src/cache.h index a68f11730..767666805 100644 --- a/src/cache.h +++ b/src/cache.h @@ -55,6 +55,22 @@ typedef enum Cache_Type_enum { CACHE_BTB } Cache_Type; +inline bool cache_sets_are_power_of_two(int num_sets) { + return (num_sets > 0) && ((num_sets & (num_sets - 1)) == 0); +} + +inline void cache_line_to_set_and_tag(Addr line_number, int num_sets, + int set_bits, Addr set_mask, + Addr tag_mask, Addr *tag, int *set) { + if (cache_sets_are_power_of_two(num_sets)) { + *set = line_number & set_mask; + *tag = line_number & tag_mask; + } else { + *set = line_number % num_sets; + *tag = line_number / num_sets; + } +} + /* set data pointers to this initially */ #define INIT_CACHE_DATA_VALUE ((void *)0x8badbeef) @@ -117,7 +133,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 diff --git a/src/cache_set_indexing_test.cc b/src/cache_set_indexing_test.cc new file mode 100644 index 000000000..a5a2e6fc7 --- /dev/null +++ b/src/cache_set_indexing_test.cc @@ -0,0 +1,78 @@ +#include + +#include "cache.h" + +static int int_log2(int value) { + int bits = 0; + while (value >>= 1) { + ++bits; + } + return bits; +} + +static Addr n_bit_mask(int bits) { + return bits ? ((static_cast(1) << bits) - 1) : 0; +} + +int main() { + const int line_size = 64; + const int line_shift = int_log2(line_size); + + { + const int num_sets = 6; + const int set_bits = int_log2(num_sets); + const Addr set_mask = n_bit_mask(set_bits); + const Addr tag_mask = ~set_mask; + std::set visited_sets; + + for (Addr addr = 0; addr < static_cast(num_sets * 3 * line_size); + addr += line_size) { + Addr line = addr >> line_shift; + Addr tag = 0; + int set = -1; + cache_line_to_set_and_tag(line, num_sets, set_bits, set_mask, tag_mask, + &tag, &set); + visited_sets.insert(set); + } + + if (visited_sets.size() != static_cast(num_sets)) { + return 1; + } + + Addr tag0 = 0; + int set0 = -1; + cache_line_to_set_and_tag(0 >> line_shift, num_sets, set_bits, set_mask, + tag_mask, &tag0, &set0); + Addr tag1 = 0; + int set1 = -1; + cache_line_to_set_and_tag((num_sets * line_size) >> line_shift, num_sets, + set_bits, set_mask, tag_mask, &tag1, &set1); + if (set0 != set1 || tag0 == tag1) { + return 1; + } + } + + { + const int num_sets = 8; + const int set_bits = int_log2(num_sets); + const Addr set_mask = n_bit_mask(set_bits); + const Addr tag_mask = ~set_mask; + + for (Addr addr = 0; addr < 64 * line_size; addr += line_size) { + Addr line = addr >> line_shift; + Addr tag = 0; + int set = -1; + cache_line_to_set_and_tag(line, num_sets, set_bits, set_mask, tag_mask, + &tag, &set); + + if (set != static_cast(line & set_mask)) { + return 1; + } + if (tag != (line & tag_mask)) { + return 1; + } + } + } + + return 0; +} From e76bb4bf7ff12903e885f84227a1c6e6de87b986 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 7 Sep 2026 20:42:44 +0000 Subject: [PATCH 3/3] Apply review cleanup for cache indexing PR Co-authored-by: ejchung0406 <69669967+ejchung0406@users.noreply.github.com> --- SConscript | 3 -- src/cache.cc | 15 ++++--- src/cache.h | 16 ------- src/cache_set_indexing_test.cc | 78 ---------------------------------- 4 files changed, 9 insertions(+), 103 deletions(-) delete mode 100644 src/cache_set_indexing_test.cc diff --git a/SConscript b/SConscript index f843b0045..99471ba0e 100644 --- a/SConscript +++ b/SConscript @@ -349,9 +349,6 @@ env.Program( LIBS=libraries, ) -if ARGUMENTS.get('cache_set_test', '0') == '1': - env.Program('cache_set_indexing_test', ['src/cache_set_indexing_test.cc']) - ######################################################################################### # Clean diff --git a/src/cache.cc b/src/cache.cc index 43b57098a..0bf6dedf3 100644 --- a/src/cache.cc +++ b/src/cache.cc @@ -80,10 +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; - if (m_num_sets <= 0) { - ASSERTM(0, "cache:%s num_set:%d\n", m_name.c_str(), m_num_sets); - abort(); - } + 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; @@ -186,8 +183,14 @@ void cache_c::find_tag_and_set(Addr addr, Addr *tag, int *set) { } Addr line_number = index_addr >> m_shift_bits; - cache_line_to_set_and_tag(line_number, m_num_sets, m_set_bits, m_set_mask, - m_tag_mask, tag, set); + 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 767666805..b02adfcd5 100644 --- a/src/cache.h +++ b/src/cache.h @@ -55,22 +55,6 @@ typedef enum Cache_Type_enum { CACHE_BTB } Cache_Type; -inline bool cache_sets_are_power_of_two(int num_sets) { - return (num_sets > 0) && ((num_sets & (num_sets - 1)) == 0); -} - -inline void cache_line_to_set_and_tag(Addr line_number, int num_sets, - int set_bits, Addr set_mask, - Addr tag_mask, Addr *tag, int *set) { - if (cache_sets_are_power_of_two(num_sets)) { - *set = line_number & set_mask; - *tag = line_number & tag_mask; - } else { - *set = line_number % num_sets; - *tag = line_number / num_sets; - } -} - /* set data pointers to this initially */ #define INIT_CACHE_DATA_VALUE ((void *)0x8badbeef) diff --git a/src/cache_set_indexing_test.cc b/src/cache_set_indexing_test.cc deleted file mode 100644 index a5a2e6fc7..000000000 --- a/src/cache_set_indexing_test.cc +++ /dev/null @@ -1,78 +0,0 @@ -#include - -#include "cache.h" - -static int int_log2(int value) { - int bits = 0; - while (value >>= 1) { - ++bits; - } - return bits; -} - -static Addr n_bit_mask(int bits) { - return bits ? ((static_cast(1) << bits) - 1) : 0; -} - -int main() { - const int line_size = 64; - const int line_shift = int_log2(line_size); - - { - const int num_sets = 6; - const int set_bits = int_log2(num_sets); - const Addr set_mask = n_bit_mask(set_bits); - const Addr tag_mask = ~set_mask; - std::set visited_sets; - - for (Addr addr = 0; addr < static_cast(num_sets * 3 * line_size); - addr += line_size) { - Addr line = addr >> line_shift; - Addr tag = 0; - int set = -1; - cache_line_to_set_and_tag(line, num_sets, set_bits, set_mask, tag_mask, - &tag, &set); - visited_sets.insert(set); - } - - if (visited_sets.size() != static_cast(num_sets)) { - return 1; - } - - Addr tag0 = 0; - int set0 = -1; - cache_line_to_set_and_tag(0 >> line_shift, num_sets, set_bits, set_mask, - tag_mask, &tag0, &set0); - Addr tag1 = 0; - int set1 = -1; - cache_line_to_set_and_tag((num_sets * line_size) >> line_shift, num_sets, - set_bits, set_mask, tag_mask, &tag1, &set1); - if (set0 != set1 || tag0 == tag1) { - return 1; - } - } - - { - const int num_sets = 8; - const int set_bits = int_log2(num_sets); - const Addr set_mask = n_bit_mask(set_bits); - const Addr tag_mask = ~set_mask; - - for (Addr addr = 0; addr < 64 * line_size; addr += line_size) { - Addr line = addr >> line_shift; - Addr tag = 0; - int set = -1; - cache_line_to_set_and_tag(line, num_sets, set_bits, set_mask, tag_mask, - &tag, &set); - - if (set != static_cast(line & set_mask)) { - return 1; - } - if (tag != (line & tag_mask)) { - return 1; - } - } - } - - return 0; -}