Fix ICache caching window test with combination sequences

This fixes several problems. Firstly, the window_reset function was
switching off tracking until it next saw busy_o go low, which is
correct at the start of time, but not what we want after we've
started. This patch splits that behaviour into a new tracking_reset
function (which calls window_reset). This is called on reset or
invalidate.

Secondly, this check was occasionally failing where we'd have an ECC
sequence (which should disable the check) immediately followed by a
caching sequence with similar addresses. If the window ended in the
caching sequence, we'd see a high fetch ratio and conclude that
something had gone wrong.

Now we clear the window completely whenever we fetch an instruction
when the check is disabled, which should avoid the problem (at worst,
you might get 1 instruction overlap, which is unlikely to matter).

Finally, we move the call to tracking_reset up to the end of the reset
sequence. It doesn't usually matter, but if there's a pending item
from the core monitor with busy = 0, we need to make sure that item
comes in before we set not_invalidating = 1. Otherwise, the scoreboard
incorrectly thinks it's seen the end of the invalidation
sequence (before it's even started) and starts tracking fetch ratios
too early.
This commit is contained in:
Rupert Swarbrick 2020-06-18 17:17:05 +01:00 committed by Rupert Swarbrick
parent e7c9b52c36
commit e243ab2617

View file

@ -124,7 +124,7 @@ class ibex_icache_scoreboard
task run_phase(uvm_phase phase);
super.run_phase(phase);
window_reset();
tracking_reset();
fork
process_core_fifo();
process_mem_fifo();
@ -235,10 +235,8 @@ class ibex_icache_scoreboard
end
endtask
// A function called on negedge of rst_n (unlike reset(), from the base class, which is called on
// the following posedge and which we don't use)
// A function called on negedge of rst_n
function void start_reset();
window_reset();
next_addr = 'X;
// Throw away any old seeds
@ -251,6 +249,12 @@ class ibex_icache_scoreboard
mem_trans_count = 0;
endfunction
// Called on the posedge of rst_n which ends the reset period.
function void reset(string kind = "HARD");
super.reset(kind);
tracking_reset();
endfunction
function void check_phase(uvm_phase phase);
super.check_phase(phase);
`DV_EOT_PRINT_TLM_FIFO_CONTENTS(ibex_icache_core_bus_item, core_fifo)
@ -608,11 +612,17 @@ class ibex_icache_scoreboard
end
endtask
// Completely reset cache tracking, waiting for busy to drop to be certain that invalidation is
// done
function automatic void tracking_reset();
not_invalidating = 1'b0;
window_reset();
endfunction
// Reset the caching tracking window
function automatic void window_reset();
insns_in_window = 0;
reads_in_window = 0;
not_invalidating = 1'b0;
window_range_lo = ~(31'b0);
window_range_hi = 0;
endfunction
@ -628,10 +638,13 @@ class ibex_icache_scoreboard
bit [32:0] window_width;
int unsigned fetch_ratio_pc;
// Ignore instructions if this check is disabled in the configuration
if (cfg.disable_caching_ratio_test) return;
if (err) begin
// Ignore instructions and reset the window if this check is disabled in the configuration.
// Resetting the window each time avoids cases where we run an ECC sequence for a while (where
// the check should be disabled), then switch to a normal sequence (where the check should be
// enabled) just before the window finishes.
//
// Similarly, bail on an error since that would significantly lower the cache hit ratio.
if (err || cfg.disable_caching_ratio_test) begin
window_reset();
return;
end