|
|
|
@ -73,6 +73,7 @@ void print_set(linked_line* line);
@@ -73,6 +73,7 @@ void print_set(linked_line* line);
|
|
|
|
|
/* Cache access functions */ |
|
|
|
|
char cache_access(linked_line** cache, long address, int set_bits, int block_offset_bits, long num_lines); |
|
|
|
|
linked_line* find_line(linked_line* set_head, long tag); |
|
|
|
|
linked_line* update_set(linked_line* old_head, linked_line* new_head); |
|
|
|
|
//linked_line* move_to_head(linked_line* new_head, linked_line* old_head);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -396,37 +397,28 @@ void print_set(linked_line* line)
@@ -396,37 +397,28 @@ void print_set(linked_line* line)
|
|
|
|
|
char cache_access(linked_line** cache, long address, |
|
|
|
|
int set_bits, int block_offset_bits, long num_lines) |
|
|
|
|
{ |
|
|
|
|
char out; |
|
|
|
|
char operation; |
|
|
|
|
long tag = address >> set_bits >> block_offset_bits; |
|
|
|
|
long set = (address >> block_offset_bits) & ((1 << set_bits) - 1); |
|
|
|
|
linked_line* set_head = cache[set]; |
|
|
|
|
linked_line* line = find_line(set_head, tag); |
|
|
|
|
|
|
|
|
|
if (!line->validity) { |
|
|
|
|
out = 'M'; |
|
|
|
|
operation = 'M'; |
|
|
|
|
} |
|
|
|
|
else if (line->tag == tag) { |
|
|
|
|
out = 'H'; |
|
|
|
|
operation = 'H'; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
out = 'E'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(!(line == set_head)) { |
|
|
|
|
line->newer->older = line->older; |
|
|
|
|
if(line->older) { |
|
|
|
|
line->older->newer = line->newer; |
|
|
|
|
} |
|
|
|
|
line->newer = NULL; |
|
|
|
|
line->older = set_head; |
|
|
|
|
set_head->newer = line; |
|
|
|
|
cache[set] = line; |
|
|
|
|
operation = 'E'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
line->tag = tag; |
|
|
|
|
line->validity = 1; |
|
|
|
|
|
|
|
|
|
return out; |
|
|
|
|
cache[set] = update_set(set_head, line); |
|
|
|
|
|
|
|
|
|
return operation; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -448,4 +440,24 @@ linked_line* find_line(linked_line* line, long tag)
@@ -448,4 +440,24 @@ linked_line* find_line(linked_line* line, long tag)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
Updates the use order of a set by moving the line being accessed in front of |
|
|
|
|
the previously-accessed line and linking the neighbors of the new head. |
|
|
|
|
@param old_head The previous most-recently modified line of the set. |
|
|
|
|
@param new_head The line of the set being accessed. |
|
|
|
|
@return new_head |
|
|
|
|
*/ |
|
|
|
|
linked_line* update_set(linked_line* old_head, linked_line* new_head) { |
|
|
|
|
if(!(new_head == old_head)) { |
|
|
|
|
new_head->newer->older = new_head->older; |
|
|
|
|
if(new_head->older) { |
|
|
|
|
new_head->older->newer = new_head->newer; |
|
|
|
|
} |
|
|
|
|
new_head->newer = NULL; |
|
|
|
|
new_head->older = old_head; |
|
|
|
|
old_head->newer = new_head; |
|
|
|
|
} |
|
|
|
|
return new_head; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|