Update user_proj_example.v
diff --git a/verilog/rtl/user_proj_example.v b/verilog/rtl/user_proj_example.v index 4a14c5e..9504256 100644 --- a/verilog/rtl/user_proj_example.v +++ b/verilog/rtl/user_proj_example.v
@@ -35,974 +35,31 @@ *------------------------------------------------------------- */ -module user_proj_example #( - parameter BITS = 32 -)( +module user_proj_example ( `ifdef USE_POWER_PINS inout vccd1, // User area 1 1.8V supply inout vssd1, // User area 1 digital ground -`endif - - // Wishbone Slave ports (WB MI A) - input wb_clk_i, - input wb_rst_i, - input wbs_stb_i, - input wbs_cyc_i, - input wbs_we_i, - input [3:0] wbs_sel_i, - input [31:0] wbs_dat_i, - input [31:0] wbs_adr_i, - output wbs_ack_o, - output [31:0] wbs_dat_o, - - // Logic Analyzer Signals - input [127:0] la_data_in, - output [127:0] la_data_out, - input [127:0] la_oenb, - - // IOs - input [`MPRJ_IO_PADS-1:0] io_in, - output [`MPRJ_IO_PADS-1:0] io_out, - output [`MPRJ_IO_PADS-1:0] io_oeb, - - // IRQ - output [2:0] irq -); - wire clk; - wire rst; - - wire [`MPRJ_IO_PADS-1:0] io_in; - wire [`MPRJ_IO_PADS-1:0] io_out; - wire [`MPRJ_IO_PADS-1:0] io_oeb; - - wire [31:0] rdata; - wire [31:0] wdata; - wire [BITS-1:0] count; - - wire valid; - wire [3:0] wstrb; - wire [31:0] la_write; - - // WB MI A - assign valid = wbs_cyc_i && wbs_stb_i; - assign wstrb = wbs_sel_i & {4{wbs_we_i}}; - assign wbs_dat_o = rdata; - assign wdata = wbs_dat_i; - - // IO - assign io_out = count; - assign io_oeb = {(`MPRJ_IO_PADS-1){rst}}; - - // IRQ - assign irq = 3'b000; // Unused - - // LA - assign la_data_out = {{(127-BITS){1'b0}}, count}; - // Assuming LA probes [63:32] are for controlling the count register - assign la_write = ~la_oenb[63:32] & ~{BITS{valid}}; - // Assuming LA probes [65:64] are for controlling the count clk & reset - assign clk = (~la_oenb[64]) ? la_data_in[64]: wb_clk_i; - assign rst = (~la_oenb[65]) ? la_data_in[65]: wb_rst_i; - - counter #( - .BITS(BITS) - ) counter( - .clk(clk), - .reset(la_data_in[0]), - .trace_ready(la_data_in[1]), - .mem_addr(la_data_in[33:2]), - .L1_hit_count(la_data_out[9:0]), - .L2_hit_count4(la_data_out[19:10]), - .L2_hit_count8(la_data_out[29:20]), - .L2_hit_count16(la_data_out[39:30]), - .L2_ss1_count4(la_data_out[49:40]), - .L2_ss1_count8(la_data_out[59:50]), - .L2_ss1_count16(la_data_out[69:60]), - .L2_ss2_count4(la_data_out[79:70]), - .L2_ss2_count8(la_data_out[89:80]), - .L2_ss2_count16(la_data_out[99:90]) - ); - -endmodule - -module main(clk,reset,trace_ready,mem_addr,L1_hit_count,L2_hit_count4,L2_hit_count8,L2_hit_count16,L2_ss1_count4,L2_ss1_count8,L2_ss1_count16,L2_ss2_count4,L2_ss2_count8,L2_ss2_count16); - - parameter L1_way = 4; - parameter L1_block_size_byte = 16; - parameter L1_cache_size_byte = 1*1024; +`endif - parameter L2_way = 16; - parameter L2_block_size_byte = 16; - parameter L2_set_size = 64; - - parameter L1_block_offset_index = $rtoi($ln(L1_block_size_byte)/$ln(2)); - parameter L1_set = L1_cache_size_byte/(L1_block_size_byte*L1_way); - parameter L1_set_index = $rtoi($ln(L1_set)/$ln(2)); - parameter L1_way_width = $rtoi($ln(L1_way)/$ln(2)); - - parameter L2_block_offset_index = $rtoi($ln(L2_block_size_byte)/$ln(2)); - parameter L2_set_index = $rtoi($ln(L2_set_size)/$ln(2)); - parameter L2_way_width = $rtoi($ln(L2_way)/$ln(2)); - - input clk,trace_ready,reset; - input [31:0] mem_addr; - + input clk,reset,trace_ready; + input [31:0] mem_addr; output [19:0] L1_hit_count,L2_hit_count4,L2_hit_count8,L2_hit_count16,L2_ss1_count4,L2_ss1_count8,L2_ss1_count16,L2_ss2_count4,L2_ss2_count8,L2_ss2_count16; - wire updated; - // variables to divide address in tag, index and offset for L1 cache - wire [31-L1_set_index-L1_block_offset_index:0] L1_tag; - wire [L1_set_index-1:0] L1_index; - wire [L1_block_offset_index-1:0] L1_block_offset; - - // variables to divide address in tag, index and offset for L2 cache - wire [31-L2_set_index-L2_block_offset_index:0] L2_tag; - wire [L2_set_index-1:0] L2_index; - wire [L2_block_offset_index-1:0] L2_block_offset; - - //L1 cache - wire L1_done,L1_found_in_cache,L1_updated; - - //L2 cache - wire L2_done,L2_found_in_cache,L2_updated ; - wire [L2_way_width:0] L2_hit_way; - - //Subset cache1 - wire ss1_found_in_cache,ss1_updated; - wire [L2_way_width:0] ss1_hit_way; - - //Subset cache2 - wire ss2_found_in_cache,ss2_updated; - wire [L2_way_width:0] ss2_hit_way; - wire [L2_set_index-2:0] ss1_index; - - //prefetcher - wire prefetch_hit,prefetch_done; - + main cache ( + .clk(clk), + .reset(reset), + .trace_ready(trace_ready), + .mem_addr(mem_addr), + .L1_hit_count(L1_hit_count), + .L2_hit_count4(L2_hit_count4), + .L2_hit_count8(L2_hit_count8), + .L2_hit_count16(L2_hit_count16), + .L2_ss1_count4(L2_ss1_count4), + .L2_ss1_count8(L2_ss1_count8), + .L2_ss1_count16(L2_ss1_count16), + .L2_ss2_count4(L2_ss2_count4), + .L2_ss2_count8(L2_ss2_count8), + .L2_ss2_count16(L2_ss2_count16) + ); - assign L1_block_offset = mem_addr[L1_block_offset_index-1:0]; - assign L1_index = mem_addr[L1_set_index+L1_block_offset_index-1:L1_block_offset_index]; - assign L1_tag = mem_addr[31:L1_set_index+L1_block_offset_index]; - - assign L2_block_offset = mem_addr[L2_block_offset_index-1:0]; - assign L2_index = mem_addr[L2_set_index+L2_block_offset_index-1:L2_block_offset_index]; - assign L2_tag = mem_addr[31:L2_set_index+L2_block_offset_index]; - - assign ss1_index = L2_index[L2_set_index-2:0]; - assign updated = !prefetch_hit&&ss1_updated ? 1'b1 : L1_updated&&(prefetch_hit||L1_found_in_cache) ? 1'b1 : 1'b0; - - L1_cache #(.way(L1_way),.block_size_byte(L1_block_size_byte),.cache_size_byte(L1_cache_size_byte)) i1 (clk,reset,L1_tag,L1_index,L1_block_offset,trace_ready,prefetch_hit,L2_found_in_cache,L1_hit_count,L1_found_in_cache,L1_updated,L1_done,prefetch_done); - L2_cache #(.way(L2_way),.block_size_byte(L2_block_size_byte),.set_size(L2_set_size)) i2 (clk,reset,L2_tag,L2_index,L2_block_offset,(prefetch_done && !prefetch_hit),L2_hit_count4,L2_hit_count8,L2_hit_count16,L2_found_in_cache,L2_hit_way,L2_done,L2_updated); - L2_cache_subset #(.way(L2_way),.block_size_byte(L2_block_size_byte),.set_size(L2_set_size/2)) i3 (clk,reset,L2_index,L2_updated,L2_found_in_cache,L2_hit_way,ss1_found_in_cache,L2_ss1_count4,L2_ss1_count8,L2_ss1_count16,ss1_hit_way,ss1_updated); - L2_cache_subset #(.way(L2_way),.block_size_byte(L2_block_size_byte),.set_size(L2_set_size/4)) i4 (clk,reset,ss1_index,ss1_updated,ss1_found_in_cache,ss1_hit_way,ss2_found_in_cache,L2_ss2_count4,L2_ss2_count8,L2_ss2_count16,ss2_hit_way,ss2_updated); - prefetcher #(.way(L1_way),.block_size_byte(L1_block_size_byte),.cache_size_byte(L1_cache_size_byte)) i5(clk,mem_addr,(L1_done && !L1_found_in_cache),prefetch_hit); - -endmodule - -module L1_cache(clk,reset,tag,index,block_offset,find_start,prefetch_hit,L2_cache_hit,cache_hit_count,found_in_cache,updated,done_L1,done_prefetch); - - parameter way = 4; - parameter block_size_byte = 16; - parameter cache_size_byte = 32*1024; - - parameter block_offset_index = $rtoi($ln(block_size_byte)/$ln(2)); - parameter set = cache_size_byte/(block_size_byte*way); - parameter set_index = $rtoi($ln(set)/$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,L2_cache_hit,prefetch_hit,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; - output reg [19:0] cache_hit_count; - output reg updated,done_L1,done_prefetch; - - reg [1:0]find_state; - reg [1:0]flag; - reg bi_flag; - reg [way_width:0] way_index; - reg [way_width-1:0] hit_way; - reg [cache_line_width-1:0] cache [0:set-1][0:way-1]; - reg [cache_line_width-1:0] temp_content; - reg [cache_line_width-1:0] temp_content1 [0:way-1]; - - integer i,j; - - initial - begin - found_in_cache = 0; - cache_hit_count = 0; - find_state = 0; - flag = 0; - bi_flag = 0; - updated = 0; - done_prefetch = 0; - for (i=0;i<set;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_count = 0; - //cache_miss_count = 0; - find_state = 0; - flag = 0; - bi_flag = 0; - updated = 0; - done_prefetch = 0; - for (i=0;i<set;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_L1 = 1'b0; - end - end - - 2'b01: begin - - if (done_L1 && !found_in_cache) - begin - find_state = 2'b10; - done_L1 = 1'b0; - end - else if (done_L1 && found_in_cache) - begin - find_state = 2'b11; - done_L1 = 1'b0; - 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]; - cache_hit_count = cache_hit_count + 1'b1; - done_L1 = 1'b1; - end - end - end - if (way_index==way&&!found_in_cache) - begin - //cache_miss_count = cache_miss_count + 1'b1; - found_in_cache = 1'b0; - done_L1 = 1'b1; - end - end - end - - 2'b10: begin - if(done_prefetch) - begin - find_state= 2'b11; - done_prefetch = 1'b0; - flag = 1'b0; - end - else - begin - if(!flag) - flag = 1'b1; - else - begin - if(prefetch_hit&flag) - begin - flag = 1'b0; - cache_hit_count = cache_hit_count + 1'b1; - end - //else - //cache_miss_count = cache_miss_count + 1'b1; - done_prefetch = 1'b1; - end - end - end - - 2'b11: begin - if(updated) - begin - find_state = 2'b00; - updated = 1'b0; - end - - else - begin - if(found_in_cache) // hit - begin - if(hit_way != 0) - begin - cache[index][hit_way] = cache[index][hit_way-1]; - hit_way = hit_way - 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 - -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 - -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 - - -module prefetcher (clk,address,cache_miss,prefetch_hit); - - parameter way = 4; - parameter block_size_byte = 16; - parameter cache_size_byte = 1024; - - parameter block_offset_index = $rtoi($ln(block_size_byte)/$ln(2)); //2 - parameter set = cache_size_byte/(block_size_byte*way); - parameter set_index = $rtoi($ln(set)/$ln(2)); - - parameter prefetch_width = 32-block_offset_index + 1; // without data (tag+index+valid) - - input clk,cache_miss; - input [31:0]address; - output reg prefetch_hit; - - - wire [31-set_index-block_offset_index:0] tag; // 23 bits..22:0 - wire [set_index-1:0] index; //7 bits...6:0 - wire [block_offset_index-1:0] block_offset; //2 bits...1:0 - - - wire [set_index-1:0]temp_index; - wire [5:0]prefetch_fill_index; - wire valid_buffer_check, valid_fill_check; - - reg [prefetch_width-1:0]prefetch_buffer[0:7]; - wire [2:0] hit_index; - reg [2:0] way_index; - reg [1:0] find_state; - reg done,updated; - reg [prefetch_width-1:0] temp_data; - integer k; - - assign block_offset = address[block_offset_index-1:0]; - assign index = address[set_index+block_offset_index-1:block_offset_index]; - assign tag =address[31:set_index+block_offset_index]; - assign temp_index = index + 1; - - assign valid_buffer_check = (prefetch_buffer[0][prefetch_width-1] && (prefetch_buffer[0][prefetch_width-2:0]==address[31:block_offset_index])) || (prefetch_buffer[1][prefetch_width-1] && (prefetch_buffer[1][prefetch_width-2:0]==address[31:block_offset_index])) || (prefetch_buffer[2][prefetch_width-1] && (prefetch_buffer[2][prefetch_width-2:0]==address[31:block_offset_index])) || (prefetch_buffer[3][prefetch_width-1] && (prefetch_buffer[3][prefetch_width-2:0]==address[31:block_offset_index])) || (prefetch_buffer[4][prefetch_width-1] && (prefetch_buffer[4][prefetch_width-2:0]==address[31:block_offset_index])) || (prefetch_buffer[5][prefetch_width-1] && (prefetch_buffer[5][prefetch_width-2:0]==address[31:block_offset_index])) || (prefetch_buffer[6][prefetch_width-1] && (prefetch_buffer[6][prefetch_width-2:0]==address[31:block_offset_index])) || (prefetch_buffer[7][prefetch_width-1] && (prefetch_buffer[7][prefetch_width-2:0]==address[31:block_offset_index])); - - assign hit_index = (prefetch_buffer[0][prefetch_width-1] && (prefetch_buffer[0][prefetch_width-2:0]==address[31:block_offset_index])) ? 3'b000 : - (prefetch_buffer[1][prefetch_width-1] && (prefetch_buffer[1][prefetch_width-2:0]==address[31:block_offset_index])) ? 3'b001 : - (prefetch_buffer[2][prefetch_width-1] && (prefetch_buffer[2][prefetch_width-2:0]==address[31:block_offset_index])) ? 3'b010 : - (prefetch_buffer[3][prefetch_width-1] && (prefetch_buffer[3][prefetch_width-2:0]==address[31:block_offset_index])) ? 3'b011 : - (prefetch_buffer[4][prefetch_width-1] && (prefetch_buffer[4][prefetch_width-2:0]==address[31:block_offset_index])) ? 3'b100 : - (prefetch_buffer[5][prefetch_width-1] && (prefetch_buffer[5][prefetch_width-2:0]==address[31:block_offset_index])) ? 3'b101 : - (prefetch_buffer[6][prefetch_width-1] && (prefetch_buffer[6][prefetch_width-2:0]==address[31:block_offset_index])) ? 3'b110 : 3'b111; - - - assign valid_fill_check = (prefetch_buffer[0][prefetch_width-1] && (prefetch_buffer[0][prefetch_width-2:0]=={tag,temp_index})) || (prefetch_buffer[1][prefetch_width-1] && (prefetch_buffer[1][prefetch_width-2:0]=={tag,temp_index})) || (prefetch_buffer[2][prefetch_width-1] && (prefetch_buffer[2][prefetch_width-2:0]=={tag,temp_index})) || (prefetch_buffer[3][prefetch_width-1] && (prefetch_buffer[3][prefetch_width-2:0]=={tag,temp_index})) || (prefetch_buffer[4][prefetch_width-1] && (prefetch_buffer[4][prefetch_width-2:0]=={tag,temp_index})) || (prefetch_buffer[5][prefetch_width-1] && (prefetch_buffer[5][prefetch_width-2:0]=={tag,temp_index})) || (prefetch_buffer[6][prefetch_width-1] && (prefetch_buffer[6][prefetch_width-2:0]=={tag,temp_index})) || (prefetch_buffer[7][prefetch_width-1] && (prefetch_buffer[7][prefetch_width-2:0]=={tag,temp_index})); - initial - begin - for (k=0;k<8;k=k+1) - prefetch_buffer[k] = 0; - done = 0; - updated = 0; - prefetch_hit = 0; - find_state = 0; - end - - always @ (posedge clk) - begin - case(find_state) - 2'b00: begin - done = 1'b0; - prefetch_hit = 1'b0; - if(cache_miss) - begin - find_state = 2'b01; - end - end - - 2'b01: begin - if(done) - find_state = 2'b10; - else - begin - if(valid_buffer_check) - begin - prefetch_hit = 1'b1; - done = 1'b1; - end - else - begin - done =1'b1; - prefetch_hit=1'b0; - end - end - end - - 2'b10: begin - if(updated) - begin - find_state = 2'b00; - updated = 1'b0; - end - else - begin - if(!prefetch_hit) - begin - if(valid_fill_check) - updated = 1'b1; - else - begin - prefetch_buffer[7] = prefetch_buffer[6]; - prefetch_buffer[6] = prefetch_buffer[5]; - prefetch_buffer[5] = prefetch_buffer[4]; - prefetch_buffer[4] = prefetch_buffer[3]; - prefetch_buffer[3] = prefetch_buffer[2]; - prefetch_buffer[2] = prefetch_buffer[1]; - prefetch_buffer[1] = prefetch_buffer[0]; - prefetch_buffer[0] = {1'b1,tag,temp_index}; - updated = 1'b1; - end - end - - if(prefetch_hit) - begin - temp_data = prefetch_buffer[hit_index]; - for (way_index=0;way_index<hit_index;way_index=way_index+1) - prefetch_buffer[hit_index-way_index]= prefetch_buffer[hit_index-way_index-1]; - prefetch_buffer[0] = temp_data; - - updated = 1'b1; - end - - end - end - endcase - end endmodule