Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cva6_icache: Allow one outstanding killed miss #1497

Closed
wants to merge 2 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 30 additions & 24 deletions core/cache_subsystem/cva6_icache.sv
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ module cva6_icache
cmp_en_d,
cmp_en_q; // enable tag comparison in next cycle. used to cut long path due to NC signal.
logic flush_d, flush_q; // used to register and signal pending flushes
logic outst_miss_d, outst_miss_q; // tracks whether there are any outstanding misses

// replacement strategy
logic update_lfsr; // shift the LFSR
Expand Down Expand Up @@ -187,6 +188,7 @@ module cva6_icache
cache_wren = 1'b0;
inv_en = 1'b0;
flush_d = flush_q | flush_i; // register incoming flush
outst_miss_d = outst_miss_q;

// interfaces
dreq_o.ready = 1'b0;
Expand All @@ -205,6 +207,11 @@ module cva6_icache
inv_en = 1'b1;
end

// kill an outstanding miss
if (mem_rtrn_vld_i && mem_rtrn_i.rtype == ICACHE_IFILL_ACK && outst_miss_q) begin
outst_miss_d = 1'b0;
end

unique case (state_q)
//////////////////////////////////
// this clears all valid bits
Expand All @@ -228,7 +235,7 @@ module cva6_icache
state_d = FLUSH;
// wait for incoming requests
end else begin
// mem requests are for sure invals here
// mem requests are for sure invals here or killed misses here
if (!mem_rtrn_vld_i) begin
dreq_o.ready = 1'b1;
// we have a new request
Expand Down Expand Up @@ -266,8 +273,8 @@ module cva6_icache

// we can accept another request
// and stay here, but only if no inval is coming in
// note: we are not expecting ifill return packets here...
if (!mem_rtrn_vld_i) begin
// note: ifill return packets may arrive here only if killed...
if (!mem_rtrn_vld_i || (mem_rtrn_i.rtype == ICACHE_IFILL_ACK)) begin
dreq_o.ready = 1'b1;
if (dreq_i.req) begin
state_d = READ;
Expand Down Expand Up @@ -302,19 +309,25 @@ module cva6_icache
// returns. do not write to memory
// if the nc bit is set.
MISS: begin
// note: this is mutually exclusive with ICACHE_INV_REQ,
// so we do not have to check for invals here
if (mem_rtrn_vld_i && mem_rtrn_i.rtype == ICACHE_IFILL_ACK) begin
state_d = IDLE;
// only return data if request is not being killed
if (!(dreq_i.kill_s2 || flush_d)) begin
dreq_o.valid = 1'b1;
// only write to cache if this address is cacheable
cache_wren = ~paddr_is_nc;
end
// if there is an outstanding miss we must wait that it is discarded
if (!outst_miss_q) begin
// note: this is mutually exclusive with ICACHE_INV_REQ,
// so we do not have to check for invals here
if (mem_rtrn_vld_i && mem_rtrn_i.rtype == ICACHE_IFILL_ACK) begin
state_d = IDLE;
// only return data if request is not being killed
if (!(dreq_i.kill_s2 || flush_d)) begin
dreq_o.valid = 1'b1;
// only write to cache if this address is cacheable
cache_wren = ~paddr_is_nc;
end
// bail out if this request is being killed
JeanRochCoulon marked this conversation as resolved.
Show resolved Hide resolved
end else if (dreq_i.kill_s2 || flush_d) begin
state_d = KILL_MISS;
end else if (dreq_i.kill_s2 || flush_d) begin
state_d = IDLE;
// track if there is an outstanding miss,
// the next response from memory must be discarded
outst_miss_d = 1'b1;
end
end
end
//////////////////////////////////
Expand All @@ -327,15 +340,6 @@ module cva6_icache
state_d = IDLE;
end
end
//////////////////////////////////
// killed miss,
// wait until memory responds and
// go back to idle
KILL_MISS: begin
if (mem_rtrn_vld_i && mem_rtrn_i.rtype == ICACHE_IFILL_ACK) begin
state_d = IDLE;
end
end
default: begin
// we should never get here
state_d = FLUSH;
Expand Down Expand Up @@ -500,6 +504,7 @@ module cva6_icache
cl_offset_q <= '0;
repl_way_oh_q <= '0;
inv_q <= '0;
outst_miss_q <= '0;
end else begin
cl_tag_q <= cl_tag_d;
flush_cnt_q <= flush_cnt_d;
Expand All @@ -511,6 +516,7 @@ module cva6_icache
cl_offset_q <= cl_offset_d;
repl_way_oh_q <= repl_way_oh_d;
inv_q <= inv_d;
outst_miss_q <= outst_miss_d;
end
end

Expand Down
Loading