Skip to content

Commit

Permalink
Added Wenqi's MLC fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
aniket-de committed May 4, 2024
1 parent 99142af commit e9445ff
Show file tree
Hide file tree
Showing 7 changed files with 788 additions and 375 deletions.
3 changes: 3 additions & 0 deletions src/globals/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@
#define MIN4(v0, v1, v2, v3) (MIN2(MIN2((v0), (v1)), MIN2((v2), (v3))))
#define MAX4(v0, v1, v2, v3) (MAX2(MAX2((v0), (v1)), MAX2((v2), (v3))))

// a is the original addr, num is the shift amt before interleaving (usually
// the cacheline), int is the interleave factor. The bank idx computed here
// is simply the lower bits
#define BANK(a, num, int) ((a) >> LOG2(int) & N_BIT_MASK(LOG2(num)))
#define CHANNEL(bank, num) ((bank) >> LOG2(num))
#define BANK_IN_CHANNEL(bank, num) ((bank)&N_BIT_MASK(LOG2(num)))
Expand Down
108 changes: 79 additions & 29 deletions src/libs/cache_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,16 @@ char rand_repl_state[31];


/**************************************************************************************/

/**
* @brief Return set index of the addr
* As a side-effect, the tag and line_addr will be populated
* @param cache
* @param addr The access addr (input)
* @param tag The tag of the access (output)
* @param line_addr The base address of the cache blk corresponding to the
* access (output)
* @return uns The set index of the access
*/
static inline uns cache_index(Cache* cache, Addr addr, Addr* tag,
Addr* line_addr) {
*line_addr = addr & ~cache->offset_mask;
Expand Down Expand Up @@ -197,10 +206,15 @@ void init_cache(Cache* cache, const char* name, uns cache_size, uns assoc,
}
}

/**************************************************************************************/
/* cache_access: Does a cache lookup based on the address. Returns a pointer
* to the cache line data if it is found. */

/**
* @brief access the address.
*
* @param cache
* @param addr the request addr
* @param line_addr
* @param update_repl
* @return void* data field of the blk or NULL if cache miss
*/
void* cache_access(Cache* cache, Addr addr, Addr* line_addr, Flag update_repl) {
Addr tag;
uns set = cache_index(cache, addr, &tag, line_addr);
Expand All @@ -210,6 +224,7 @@ void* cache_access(Cache* cache, Addr addr, Addr* line_addr, Flag update_repl) {
return access_ideal_storage(cache, set, tag, addr);
}

// search the ways
for(ii = 0; ii < cache->assoc; ii++) {
Cache_Entry* line = &cache->entries[set][ii];

Expand Down Expand Up @@ -249,29 +264,51 @@ void* cache_access(Cache* cache, Addr addr, Addr* line_addr, Flag update_repl) {
return NULL;
}

/**************************************************************************************/
/* cache_insert: returns a pointer to the data section of the new cache line.
Sets line_addr to the address of the first block of the new line. Sets
repl_line_addr to the address of the first block that was replaced
DON'T call this unless you are sure that the line is not in the
cache (call after cache_access returned NULL)
*/

/**
* @brief Insert new addr to the cache
*
* This function is a wrapper of cache_insert_replpos, see below
*
* Note cache_insert is intrusive, for a non-instusive function
* (which only pick out the victim but not doing the insertion),
* see get_next_repl_line, both of these functions calls find_repl_entry
* internally
*
* DON'T call this unless you are sure that the line is not in the
* cache (call after cache_access returned NULL)
*
* @param cache
* @param proc_id
* @param addr
* @param line_addr
* @param repl_line_addr
* @return void* The data field of the inserted blk
*/
void* cache_insert(Cache* cache, uns8 proc_id, Addr addr, Addr* line_addr,
Addr* repl_line_addr) {
return cache_insert_replpos(cache, proc_id, addr, line_addr, repl_line_addr,
INSERT_REPL_DEFAULT, FALSE);
}
/**************************************************************************************/
/* cache_insert_replpos: returns a pointer to the data section of the new cache
line. Sets line_addr to the address of the first block of the new line.
Sets repl_line_addr to the address of the first block that was replaced
DON'T call this unless you are sure that the line is not in the
cache (call after cache_access returned NULL)
*/

/**
* @brief Insert new blk into cache
* returns a pointer to the data section of the new cache line.
* Sets line_addr to the address of the first block of the new line. Sets
* repl_line_addr to the address of the first block that was replaced
*
* Note this func won't do the WB if the victim is dirty, the info of the
* victim blk is returned and WB is handled by the caller of this func
*
* DON'T call this unless you are sure that the line is *not* in the
* cache (call after cache_access returned NULL)
* @param cache
* @param proc_id
* @param addr The addr of the blk to be inserted
* @param line_addr The base addr of the blk to be insert (input)
* @param repl_line_addr The base addr of the blk got evicted (output)
* @return void* The data field of the inserted blk
*/
void* cache_insert_replpos(Cache* cache, uns8 proc_id, Addr addr,
Addr* line_addr, Addr* repl_line_addr,
Cache_Insert_Repl insert_repl_policy,
Expand All @@ -285,16 +322,19 @@ void* cache_insert_replpos(Cache* cache, uns8 proc_id, Addr addr,
new_line = insert_sure_line(cache, set, tag);
*repl_line_addr = 0;
} else {
// new_line points to the victim, repl_index is the way id for the victim
new_line = find_repl_entry(cache, proc_id, set, &repl_index);
/* before insert the data into cache, if the cache has shadow entry */
/* insert that entry to the shadow cache */
if((cache->repl_policy == REPL_SHADOW_IDEAL) && new_line->valid)
shadow_cache_insert(cache, set, new_line->tag, new_line->base);
if(new_line->valid) // bug fixed. 4/26/04 if the entry is not valid,
// repl_line_addr should be set to 0
if(new_line->valid) {
// bug fixed. 4/26/04 if the entry is not valid,
// repl_line_addr should be set to 0
*repl_line_addr = new_line->base;
else
} else {
*repl_line_addr = 0;
}
DEBUG(0,
"Replacing 2.2f(set %u, way %u, tag 0x%s, base 0x%s) in cache '%s' "
"with base 0x%s\n",
Expand All @@ -311,6 +351,7 @@ void* cache_insert_replpos(Cache* cache, uns8 proc_id, Addr addr,

new_line->pref = isPrefetch;

// determine the insert loc (insertion policy)
switch(insert_repl_policy) {
case INSERT_REPL_DEFAULT:
update_repl_policy(cache, new_line, set, repl_index, TRUE);
Expand Down Expand Up @@ -402,10 +443,15 @@ void* cache_insert_replpos(Cache* cache, uns8 proc_id, Addr addr,
}


/**************************************************************************************/
/* invalidate_line: Does a cache lookup based on the address. Returns a pointer
to the cache line data if it is found. */

/**
* @brief Invalidate the blk by address if presented, no wb even the blk
* is dirty
*
* @param cache
* @param addr
* @param line_addr
* @param True on find in cache, False on no present
*/
void cache_invalidate(Cache* cache, Addr addr, Addr* line_addr) {
Addr tag;
uns set = cache_index(cache, addr, &tag, line_addr);
Expand All @@ -426,7 +472,11 @@ void cache_invalidate(Cache* cache, Addr addr, Addr* line_addr) {


/**
* @brief Return a pointer to the lru item in the cache set
* @brief Return a pointer to the victim to be replaced
*
* The caller of this func is supposed to handle the possible
* writeback correctly, otherwise the correctness of simulation
* is compromised
*
* @param cache
* @param proc_id
Expand Down
12 changes: 11 additions & 1 deletion src/memory/mem_req.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct Mem_Queue_struct;
/**************************************************************************************/
/* Types */

// M(em)R(eq)S(tate)
typedef enum Mem_Req_State_enum {
MRS_INV, /* if you change this order or add anything, fix mem_req_state_names
[] and is_final_state() in memory.c and */
Expand All @@ -63,6 +64,7 @@ typedef enum Mem_Req_State_enum {
MRS_FILL_DONE, /* final state */
} Mem_Req_State;

// M(em)R(eq)T(ype)
#define MRT_LIST(elem) \
elem(IFETCH) /* instruction fetch */ \
elem(DFETCH) /* data fetch */ \
Expand Down Expand Up @@ -129,7 +131,15 @@ struct Mem_Req_struct {
uns op_count; /* number of ops that are waiting for the miss */
uns req_count; /* number of requests coalesced into this one */
Flag (*done_func)(struct Mem_Req_struct*); /* pointer to function to call when
the memory request is finished
the memory request is finished,
this is the mechanism scarab
used to implement a "callback".
i.e. when a req is finally
returned from the mem system,
continue with the rest of the
process. This is mostly used by
I$ and D$ to fill the line when
req returned from uncore/mem
*/
Flag mlc_miss; /* did this request miss in MLC */
Flag mlc_miss_satisfied; /* did this request miss in MLC and it is already
Expand Down
Loading

0 comments on commit e9445ff

Please sign in to comment.