module L2_cache_subset(clk,reset,msb_index,find_start,L2_found_in_cache,hit_way,found_in_cache,cache_hit_count4,cache_hit_count8,cache_hit_count16,hit_source,updated); | |
parameter way = 16; | |
parameter block_size_byte = 16; | |
parameter set_size = 512; | |
parameter set_index = $rtoi($ln(set_size)/$ln(2)); | |
parameter way_width = $rtoi($ln(way)/$ln(2)); | |
input clk,find_start,reset,L2_found_in_cache; | |
input [way_width:0] hit_way; | |
input [set_index:0] msb_index; | |
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 updated; | |
output reg [way_width:0] hit_source; | |
reg msb_indexbit,msb_update,mask_update; | |
reg [set_index-1:0] index; | |
reg [way_width:0] way_index; | |
reg mask0 [0:set_size-1][0:way-1]; | |
reg mask1 [0:set_size-1][0:way-1]; | |
reg [1:0] source [0:set_size-1][0:way-1]; | |
reg [1:0] temp_data; | |
reg temp_source; | |
reg [way_width:0] count; | |
//reg [19:0] hit_count [way-1:0]; | |
reg [1:0]find_state; | |
reg done; | |
integer i,j; | |
initial | |
begin | |
found_in_cache = 0; | |
cache_hit_count4 = 0; | |
cache_hit_count8 = 0; | |
cache_hit_count16 = 0; | |
//cache_miss_count = 0; | |
find_state = 0; | |
temp_data = 0; | |
msb_update = 0; | |
mask_update = 0; | |
for (i=0;i<set_size;i=i+1) | |
begin | |
for (j=0;j<way;j=j+1) | |
begin | |
source[i][j] = 0; | |
mask0[i][j] = 0; | |
mask1[i][j] = 0; | |
end | |
end | |
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; | |
temp_data = 0; | |
for (i=0;i<set_size;i=i+1) | |
begin | |
for (j=0;j<way;j=j+1) | |
begin | |
source[i][j] = 0; | |
mask0[i][j] = 0; | |
mask1[i][j] = 0; | |
end | |
end | |
end | |
else | |
begin | |
case (find_state) | |
2'b00: begin | |
if(find_start) | |
begin | |
found_in_cache = 1'b0; | |
find_state = 2'b01; | |
done = 1'b0; | |
end | |
end | |
2'b01: begin | |
if (done) | |
begin | |
find_state = 2'b10; | |
count = 0; | |
end | |
else | |
begin | |
// to check if there is hit in cache | |
msb_indexbit = msb_index[set_index]; | |
index[set_index-1:0] = msb_index[set_index-1:0]; | |
if (L2_found_in_cache) | |
begin | |
if (msb_indexbit) | |
begin | |
if(mask1[index][hit_way]) | |
begin | |
temp_source = 1'b1; | |
found_in_cache = 1'b1; | |
end | |
end | |
else if (!msb_indexbit) | |
begin | |
if(mask0[index][hit_way]) // mask0[0][16] | |
begin | |
temp_source = 1'b0; | |
found_in_cache = 1'b1; | |
end | |
end | |
if (found_in_cache) | |
begin | |
way_index = 0; | |
if(temp_source) | |
begin | |
for(way_index=0;way_index<way;way_index=way_index+1) | |
begin | |
if(source[index][way_index]==2'b11&&count<hit_way+1) | |
count = count + 1; | |
if(count==hit_way+1) | |
begin | |
temp_data = source[index][way_index]; | |
hit_source = way_index; | |
count = count + 1; | |
end | |
end | |
end | |
else if (!temp_source) | |
begin | |
for(way_index=0;way_index<way;way_index=way_index+1) | |
begin | |
if(source[index][way_index]==2'b10&&count<hit_way+1) | |
count = count + 1; | |
if(count==hit_way+1) | |
begin | |
temp_data = source[index][way_index]; | |
hit_source = way_index; | |
count = count + 1; | |
end | |
end | |
end | |
if (hit_source>=0 && hit_source<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_source>=4 && hit_source<8) | |
begin | |
cache_hit_count8 = cache_hit_count8 + 1; | |
cache_hit_count16 = cache_hit_count16 + 1; | |
end | |
else if (hit_source>=8 && hit_source<16) | |
begin | |
cache_hit_count16 = cache_hit_count16 + 1; | |
end | |
way_index = hit_source; | |
done = 1'b1; | |
end | |
else | |
begin | |
hit_source = way; | |
done = 1'b1; | |
end | |
end | |
else | |
begin | |
hit_source = way; | |
done = 1'b1; | |
end | |
end | |
end | |
2'b10: begin | |
if(updated) | |
begin | |
find_state = 2'b00; | |
updated = 1'b0; | |
count = 0; | |
end | |
else | |
begin | |
if(found_in_cache) | |
begin | |
if(msb_indexbit && !msb_update && !mask_update) | |
begin | |
if(way_index != 0) | |
begin | |
mask1[index][way_index] = mask1[index][way_index-1]; | |
way_index = way_index - 1; | |
end | |
else | |
begin | |
mask1[index][0] = 1'b1; | |
msb_update = 1'b1; | |
end | |
end | |
else if (!msb_indexbit && !msb_update && !mask_update) | |
begin | |
if(way_index != 0) | |
begin | |
mask0[index][way_index] = mask0[index][way_index-1]; | |
way_index = way_index - 1; | |
end | |
else | |
begin | |
mask0[index][0] = 1'b1; | |
msb_update = 1'b1; | |
end | |
end | |
if (msb_update && !mask_update) | |
begin | |
for(way_index=0;way_index<way;way_index=way_index+1) | |
begin | |
if(mask0[index][way_index]) | |
count = count + 1; | |
if(mask1[index][way_index]) | |
count = count + 1; | |
end | |
// if count>way then we have to change one of mask from 1 to 0 based on LRU | |
if(count>way) | |
begin | |
if(source[index][way-1] == 2'b11) | |
begin | |
way_index = way-1; | |
while(way_index>0 && !mask1[index][way_index]) | |
way_index = way_index - 1; | |
mask1[index][way_index] = 1'b0; | |
end | |
else if (source[index][way-1] == 2'b10) | |
begin | |
way_index = way-1; | |
while(way_index>0 && !mask0[index][way_index]) | |
way_index = way_index - 1; | |
mask0[index][way_index] = 1'b0; | |
end | |
end | |
mask_update = 1'b1; | |
way_index = hit_source; | |
msb_update = 1'b0; | |
end | |
if(mask_update) | |
begin | |
if(way_index != 0) | |
begin | |
source[index][way_index] = source[index][way_index-1]; | |
way_index = way_index - 1; | |
end | |
else | |
begin | |
mask_update = 1'b0; | |
source[index][0] = temp_data; | |
updated = 1'b1; | |
end | |
end | |
end | |
else // cache miss | |
begin | |
// update mask register | |
if(msb_indexbit) | |
begin | |
for(way_index=way-2;way_index>0;way_index=way_index-1) | |
mask1[index][way_index+1] = mask1[index][way_index]; | |
mask1[index][1] = mask1[index][0]; | |
mask1[index][0] = 1'b1; | |
end | |
else | |
begin | |
for(way_index=way-2;way_index>0;way_index=way_index-1) | |
mask0[index][way_index+1] = mask0[index][way_index]; | |
mask0[index][1] = mask0[index][0]; | |
mask0[index][0] = 1'b1; | |
end | |
// after updating the mask registers check count of 1's in both mask 0 and 1 | |
for(way_index=0;way_index<way;way_index=way_index+1) | |
begin | |
if(mask0[index][way_index]) | |
count = count + 1; | |
if(mask1[index][way_index]) | |
count = count + 1; | |
end | |
// if count>way then we have to change one of mask from 1 to 0 based on LRU | |
if(count>way) | |
begin | |
if(source[index][way-1] == 2'b11) | |
begin | |
way_index = way-1; | |
while(way_index>0 && !mask1[index][way_index]) | |
way_index = way_index - 1; | |
mask1[index][way_index] = 1'b0; | |
end | |
else if (source[index][way-1] == 2'b10) | |
begin | |
way_index = way-1; | |
while(way_index>0 && !mask0[index][way_index]) | |
way_index = way_index - 1; | |
mask0[index][way_index] = 1'b0; | |
end | |
end | |
// update source register | |
for(way_index=way-2;way_index>0;way_index=way_index-1) | |
source[index][way_index+1] = source[index][way_index]; | |
source[index][1] = source[index][0]; | |
source[index][0] = {1'b1,msb_indexbit}; | |
updated = 1'b1; | |
end | |
end | |
end | |
endcase | |
end | |
end | |
endmodule |