Create L2_cache_subset.v
diff --git a/verilog/rtl/L2_cache_subset.v b/verilog/rtl/L2_cache_subset.v
new file mode 100644
index 0000000..a2bd67e
--- /dev/null
+++ b/verilog/rtl/L2_cache_subset.v
@@ -0,0 +1,339 @@
+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