blob: 9e17647103a5776574cd46ef704d264b8ec018d0 [file] [log] [blame]
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