module L2_cache(clk,reset,tag,index,block_offset,find_start,cache_hit_count4,cache_hit_count8,cache_hit_count16,found_in_cache,hit_way,done,updated); | |
parameter way = 16; | |
parameter block_size_byte = 16; | |
parameter set_size = 64; | |
parameter block_offset_index = $rtoi($ln(block_size_byte)/$ln(2)); | |
parameter set_index = $rtoi($ln(set_size)/$ln(2)); | |
parameter way_width = $rtoi($ln(way)/$ln(2)); | |
parameter cache_line_width = 32-set_index-block_offset_index+1; | |
input clk,find_start,reset; | |
input [31-set_index-block_offset_index:0] tag; | |
input [set_index-1:0] index; | |
input [block_offset_index-1:0] block_offset; | |
output reg found_in_cache; | |
// this needs to get parameterized based on number of max associativity | |
output reg [19:0] cache_hit_count4; | |
output reg [19:0] cache_hit_count8; | |
output reg [19:0] cache_hit_count16; | |
output reg [way_width:0] hit_way; | |
output reg updated,done; | |
reg [1:0]find_state; | |
reg [way_width:0] way_index; | |
reg [cache_line_width-1:0] cache [0:set_size-1][0:way-1]; | |
reg [cache_line_width-1:0] temp_content; | |
//reg [19:0] hit_count [way-1:0]; | |
integer i,j; | |
initial | |
begin | |
found_in_cache = 0; | |
cache_hit_count4 = 0; | |
cache_hit_count8 = 0; | |
cache_hit_count16 = 0; | |
find_state = 0; | |
updated = 0; | |
for (i=0;i<set_size;i=i+1) | |
for (j=0;j<way;j=j+1) | |
cache[i][j] = 0; | |
end | |
always @ (posedge clk) | |
begin | |
if (reset) | |
begin | |
found_in_cache = 0; | |
cache_hit_count4 = 0; | |
cache_hit_count8 = 0; | |
cache_hit_count16 = 0; | |
find_state = 0; | |
updated = 0; | |
for (i=0;i<set_size;i=i+1) | |
for (j=0;j<way;j=j+1) | |
cache[i][j] = 0; | |
end | |
else | |
begin | |
case (find_state) | |
2'b00: begin | |
found_in_cache = 1'b0; | |
if(find_start) | |
begin | |
find_state = 2'b01; | |
done = 1'b0; | |
end | |
end | |
// Find cache state (to check if particular memory address data is present in cache or not) | |
2'b01: begin | |
if (done) | |
begin | |
find_state = 2'b10; | |
end | |
else | |
begin | |
for (way_index=0;way_index<way;way_index=way_index+1'b1) | |
begin | |
if(cache[index][way_index][cache_line_width-1]) // valid bit | |
begin | |
if(cache[index][way_index][cache_line_width-2:0]==tag) // tag comparison | |
begin | |
found_in_cache = 1'b1; | |
hit_way = way_index; | |
temp_content = cache[index][way_index]; | |
end | |
end | |
end | |
if (found_in_cache) | |
begin | |
if (hit_way>=0 && hit_way<4) | |
begin | |
cache_hit_count4 = cache_hit_count4 + 1; | |
cache_hit_count8 = cache_hit_count8 + 1; | |
cache_hit_count16 = cache_hit_count16 + 1; | |
end | |
else if (hit_way>=4 && hit_way<8) | |
begin | |
cache_hit_count8 = cache_hit_count8 + 1; | |
cache_hit_count16 = cache_hit_count16 + 1; | |
end | |
else if (hit_way>=8 && hit_way<16) | |
begin | |
cache_hit_count16 = cache_hit_count16 + 1; | |
end | |
done = 1'b1; | |
way_index = hit_way; | |
end | |
else | |
begin | |
hit_way = way; | |
done = 1'b1; | |
end | |
end | |
end | |
// Updation of cache according LRU shift register policy | |
2'b10: begin | |
if(updated) | |
begin | |
find_state = 2'b00; | |
updated = 1'b0; | |
end | |
else | |
begin | |
if(found_in_cache) // hit | |
begin | |
if(way_index != 0) | |
begin | |
cache[index][way_index] = cache[index][way_index-1]; | |
way_index = way_index - 1; | |
end | |
else | |
begin | |
cache[index][0] = temp_content; | |
updated = 1'b1; | |
end | |
end | |
else // miss | |
begin | |
for(way_index=way-2;way_index>0;way_index=way_index-1) | |
cache[index][way_index+1] = cache[index][way_index]; | |
cache[index][1] = cache[index][0]; | |
cache[index][0] = {1'b1,tag}; | |
updated = 1'b1; | |
end | |
end | |
end | |
endcase | |
end | |
end | |
endmodule |