[rtl] icache performance updates

Remove the SpeculativeRequest parameter, and replace it with a
policy. If the cache is disabled, make the request on the basis that we
definitely won't hit in the cache and so should make the bus request
asap.

Stop fill buffers from fetching complete cache lines when the cache is
disabled. When the core branches into the middle of a line, the lower
words would normally be fetched to complete the line. This is
unnecessary when the cache is disabled since those words will just be
thrown away and the core will stall while they are being fetched.

These two changes make the performance using the disabled icache the
same as using non-icache prefetch buffer.

Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This commit is contained in:
Tom Roberts 2020-11-11 17:41:09 +00:00 committed by Tom Roberts
parent 38a6b59e0b
commit 64ee9a930d
4 changed files with 11 additions and 19 deletions

View file

@ -52,14 +52,6 @@ The following table describes the available configuration parameters.
+-------------------------+-----------+-----------------------------------------------+
| ``NumWays`` | ``2`` | The number of ways. |
+-------------------------+-----------+-----------------------------------------------+
| ``SpecRequest`` | ``1'b0`` | When set, the system will attempt to |
| | | speculatively request data from memory in |
| | | parallel with the cache lookup. This can give |
| | | improved performance for workloads which |
| | | cache poorly (at the expense of power). |
| | | When not set, only branches will make |
| | | speculative requests. |
+-------------------------+-----------+-----------------------------------------------+
| ``BranchCache`` | ``1'b0`` | When set, the cache will only allocate the |
| | | targets of branches + two subsequent cache |
| | | lines. This gives improved performance in |

View file

@ -22,7 +22,6 @@ module formal_tb #(
parameter bit ICacheECC = 1'b0,
parameter int unsigned LineSize = 64,
parameter int unsigned NumWays = 2,
parameter bit SpecRequest = 1'b0,
parameter bit BranchCache = 1'b0,
// Internal parameters / localparams

View file

@ -13,7 +13,6 @@ formal_tb #(
.ICacheECC (ICacheECC),
.LineSize (LineSize),
.NumWays (NumWays),
.SpecRequest (SpecRequest),
.BranchCache (BranchCache),
.ADDR_W (ADDR_W),

View file

@ -17,8 +17,6 @@ module ibex_icache #(
parameter bit ICacheECC = 1'b0,
parameter int unsigned LineSize = 64,
parameter int unsigned NumWays = 2,
// Always make speculative bus requests in parallel with lookups
parameter bit SpecRequest = 1'b0,
// Only cache branch targets
parameter bit BranchCache = 1'b0
) (
@ -146,7 +144,7 @@ module ibex_icache #(
logic [NUM_FB-1:0] fill_ext_req, fill_rvd_exp, fill_ram_req, fill_out_req;
logic [NUM_FB-1:0] fill_data_sel, fill_data_reg, fill_data_hit, fill_data_rvd;
logic [NUM_FB-1:0][LINE_BEATS_W-1:0] fill_ext_off, fill_rvd_off;
logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_rvd_beat;
logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_ext_beat, fill_rvd_beat;
logic [NUM_FB-1:0] fill_ext_arb, fill_ram_arb, fill_out_arb;
logic [NUM_FB-1:0] fill_rvd_arb;
logic [NUM_FB-1:0] fill_entry_en;
@ -517,7 +515,8 @@ module ibex_icache #(
// Allocate a new buffer for every granted lookup
assign fill_new_alloc = lookup_grant_ic0;
// Track whether a speculative external request was made from IC0, and whether it was granted
assign fill_spec_req = (SpecRequest | branch_i) & ~|fill_ext_req;
// Speculative requests are only made for branches, or if the cache is disabled
assign fill_spec_req = (~icache_enable_i | branch_i) & ~|fill_ext_req;
assign fill_spec_done = fill_spec_req & gnt_not_pmp_err;
assign fill_spec_hold = fill_spec_req & ~gnt_or_pmp_err;
@ -587,8 +586,10 @@ module ibex_icache #(
fill_hit_ic1[fb] | fill_hit_q[fb] |
// external requests will stop once any PMP error is received
fill_err_q[fb][fill_ext_off[fb]] |
// cancel if the line is stale and won't be cached
(~fill_cache_q[fb] & (branch_i | fill_stale_q[fb]))) &
// cancel if the line won't be cached and, it is stale
(~fill_cache_q[fb] & (branch_i | fill_stale_q[fb] |
// or we're already at the end of the line
fill_ext_beat[fb][LINE_BEATS_W]))) &
// can't cancel while we are waiting for a grant on the bus
~fill_ext_hold_q[fb];
// Track whether this fill buffer expects to receive beats of data
@ -646,10 +647,11 @@ module ibex_icache #(
// When we branch into the middle of a line, the output count will not start from zero. This
// beat count is used to know which incoming rdata beats are relevant.
assign fill_ext_beat[fb] = {1'b0,fill_addr_q[fb][LINE_W-1:BUS_W]} +
fill_ext_cnt_q[fb][LINE_BEATS_W:0];
assign fill_ext_off[fb] = fill_ext_beat[fb][LINE_BEATS_W-1:0];
assign fill_rvd_beat[fb] = {1'b0,fill_addr_q[fb][LINE_W-1:BUS_W]} +
fill_rvd_cnt_q[fb][LINE_BEATS_W:0];
assign fill_ext_off[fb] = fill_addr_q[fb][LINE_W-1:BUS_W] +
fill_ext_cnt_q[fb][LINE_BEATS_W-1:0];
assign fill_rvd_off[fb] = fill_rvd_beat[fb][LINE_BEATS_W-1:0];
/////////////////////////////
@ -826,7 +828,7 @@ module ibex_icache #(
// External requests //
///////////////////////
assign instr_req = ((SpecRequest | branch_i) & lookup_grant_ic0) |
assign instr_req = ((~icache_enable_i | branch_i) & lookup_grant_ic0) |
(|fill_ext_req);
assign instr_addr = |fill_ext_req ? fill_ext_req_addr :