Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patch for MLC fix and exclusive L1 support #134

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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