blob: 046d0997eec23d6369a5e90899c65a0e5f474968 [file] [log] [blame]
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;
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;
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;
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