| 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 |