diff --git a/dv/uvm/icache/dv/tb/tb.sv b/dv/uvm/icache/dv/tb/tb.sv index c4925c42..753c97e1 100644 --- a/dv/uvm/icache/dv/tb/tb.sv +++ b/dv/uvm/icache/dv/tb/tb.sv @@ -25,32 +25,34 @@ module tb #(parameter bit ICacheECC = 1'b0); ibex_icache #( .ICacheECC (ICacheECC) ) dut ( - .clk_i (clk), - .rst_ni (rst_n), + .clk_i (clk), + .rst_ni (rst_n), // Connect icache <-> core interface - .req_i (core_if.req), - .branch_i (core_if.branch), - .branch_spec_i (core_if.branch_spec), - .addr_i (core_if.branch_addr), - .ready_i (core_if.ready), - .valid_o (core_if.valid), - .rdata_o (core_if.rdata), - .addr_o (core_if.addr), - .err_o (core_if.err), - .err_plus2_o (core_if.err_plus2), - .icache_enable_i (core_if.enable), - .icache_inval_i (core_if.invalidate), - .busy_o (core_if.busy), + .req_i (core_if.req), + .branch_i (core_if.branch), + .branch_spec_i (core_if.branch_spec), + .predicted_branch_i (1'b0), + .branch_mispredict_i (1'b0), + .addr_i (core_if.branch_addr), + .ready_i (core_if.ready), + .valid_o (core_if.valid), + .rdata_o (core_if.rdata), + .addr_o (core_if.addr), + .err_o (core_if.err), + .err_plus2_o (core_if.err_plus2), + .icache_enable_i (core_if.enable), + .icache_inval_i (core_if.invalidate), + .busy_o (core_if.busy), // Connect icache <-> instruction bus interface - .instr_req_o (mem_if.req), - .instr_gnt_i (mem_if.gnt), - .instr_addr_o (mem_if.addr), - .instr_rdata_i (mem_if.rdata), - .instr_err_i (mem_if.err), - .instr_pmp_err_i (mem_if.pmp_err), - .instr_rvalid_i (mem_if.rvalid) + .instr_req_o (mem_if.req), + .instr_gnt_i (mem_if.gnt), + .instr_addr_o (mem_if.addr), + .instr_rdata_i (mem_if.rdata), + .instr_err_i (mem_if.err), + .instr_pmp_err_i (mem_if.pmp_err), + .instr_rvalid_i (mem_if.rvalid) ); // If the ICacheECC parameter is set in the DUT, generate another interface for each tag ram and diff --git a/formal/icache/formal_tb.sv b/formal/icache/formal_tb.sv index 158aec48..107db246 100644 --- a/formal/icache/formal_tb.sv +++ b/formal/icache/formal_tb.sv @@ -17,21 +17,22 @@ module formal_tb #( // DUT parameters - parameter int unsigned BusWidth = 32, - parameter int unsigned CacheSizeBytes = 4*1024, - parameter bit ICacheECC = 1'b0, - parameter int unsigned LineSize = 64, - parameter int unsigned NumWays = 2, - parameter bit BranchCache = 1'b0, + parameter bit BranchPredictor = 1'b0, + parameter int unsigned BusWidth = 32, + parameter int unsigned CacheSizeBytes = 4*1024, + parameter bit ICacheECC = 1'b0, + parameter int unsigned LineSize = 64, + parameter int unsigned NumWays = 2, + parameter bit BranchCache = 1'b0, // Internal parameters / localparams - parameter int unsigned ADDR_W = 32, - parameter int unsigned NUM_FB = 4, - parameter int unsigned LINE_W = 3, - parameter int unsigned BUS_BYTES = BusWidth/8, - parameter int unsigned BUS_W = $clog2(BUS_BYTES), - parameter int unsigned LINE_BEATS = 2, - parameter int unsigned LINE_BEATS_W = 1 + parameter int unsigned ADDR_W = 32, + parameter int unsigned NUM_FB = 4, + parameter int unsigned LINE_W = 3, + parameter int unsigned BUS_BYTES = BusWidth/8, + parameter int unsigned BUS_W = $clog2(BUS_BYTES), + parameter int unsigned LINE_BEATS = 2, + parameter int unsigned LINE_BEATS_W = 1 ) ( // Top-level ports input logic clk_i, @@ -39,6 +40,8 @@ module formal_tb #( input logic req_i, input logic branch_i, input logic branch_spec_i, + input logic predicted_branch_i, + input logic branch_mispredict_i, input logic [31:0] addr_i, input logic ready_i, input logic valid_o, @@ -65,7 +68,8 @@ module formal_tb #( input logic [NUM_FB-1:0] fill_hit_q, input logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_ext_cnt_q, input logic [NUM_FB-1:0] fill_ext_hold_q, - input logic [NUM_FB-1:0] fill_ext_done, + input logic [NUM_FB-1:0] fill_ext_done_d, + input logic [NUM_FB-1:0] fill_ext_done_q, input logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_rvd_cnt_q, input logic [NUM_FB-1:0] fill_rvd_done, input logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_out_cnt_q, @@ -122,6 +126,17 @@ module formal_tb #( end end + // Reset assumptions + // + // We assume that req_i isn't asserted to the block when in reset (which avoids it making requests + // on the external bus). + `ASSUME_ZERO_IN_RESET(req_i) + + // Parameter assumptions + // + // If BranchPredictor = 1'b0, the branch_mispredict_i signal will never go high + `ASSUME(no_mispred_without_branch_pred, `IMPLIES(branch_mispredict_i, BranchPredictor)) + // Protocol assumptions // // These are assumptions based on the top-level ports. They somewhat mirror the assertions in the @@ -346,7 +361,7 @@ module formal_tb #( (fill_ext_cnt_q[fb] != '0) && fill_older_q[fb][fb2] && fill_busy_q[fb2]), - fill_ext_done[fb2])) + fill_ext_done_q[fb2])) // Similarly, if J is older than I then we should see fill_rvd_done[J] before // fill_rvd_cnt_q[I] is nonzero. @@ -656,7 +671,7 @@ module formal_tb #( // for beat b and the memory request was squashed by a PMP error. // // The former case is easy (bit b should be set in f_fill_rvd_mask). In the latter case, - // fill_ext_done will be true, fill_ext_cnt_q will be less than LINE_BEATS, and fill_ext_off (the + // fill_ext_done_d will be true, fill_ext_cnt_q will be less than LINE_BEATS, and fill_ext_off (the // next beat to fetch) will equal b. We define explicit masks for the bits allowed in each case. logic [NUM_FB-1:0][LINE_BEATS-1:0] f_rvd_err_mask, f_pmp_err_mask, f_err_mask; always_comb begin @@ -665,7 +680,7 @@ module formal_tb #( for (int i = 0; i < NUM_FB; i++) begin f_rvd_err_mask[i] = f_fill_rvd_mask[i]; for (int b = 0; b < LINE_BEATS; b++) begin - f_pmp_err_mask[i][b] = (fill_ext_done[i] && + f_pmp_err_mask[i][b] = (fill_ext_done_d[i] && !fill_ext_cnt_q[i][LINE_BEATS_W] && (fill_ext_off[i] == b[LINE_BEATS_W-1:0])); end diff --git a/formal/icache/formal_tb_frag.svh b/formal/icache/formal_tb_frag.svh index 855bfe23..74d85be0 100644 --- a/formal/icache/formal_tb_frag.svh +++ b/formal/icache/formal_tb_frag.svh @@ -8,18 +8,19 @@ // Using a wildcard (.*) for ports allows the testbench to inspect internal signals of the cache. formal_tb #( - .BusWidth (BusWidth), - .CacheSizeBytes (CacheSizeBytes), - .ICacheECC (ICacheECC), - .LineSize (LineSize), - .NumWays (NumWays), - .BranchCache (BranchCache), + .BranchPredictor (BranchPredictor), + .BusWidth (BusWidth), + .CacheSizeBytes (CacheSizeBytes), + .ICacheECC (ICacheECC), + .LineSize (LineSize), + .NumWays (NumWays), + .BranchCache (BranchCache), - .ADDR_W (ADDR_W), - .NUM_FB (NUM_FB), - .LINE_W (LINE_W), - .BUS_BYTES (BUS_BYTES), - .BUS_W (BUS_W), - .LINE_BEATS (LINE_BEATS), - .LINE_BEATS_W (LINE_BEATS_W) + .ADDR_W (ADDR_W), + .NUM_FB (NUM_FB), + .LINE_W (LINE_W), + .BUS_BYTES (BUS_BYTES), + .BUS_W (BUS_W), + .LINE_BEATS (LINE_BEATS), + .LINE_BEATS_W (LINE_BEATS_W) ) tb_i (.*); diff --git a/rtl/ibex_icache.sv b/rtl/ibex_icache.sv index 70637e4a..346e6a28 100644 --- a/rtl/ibex_icache.sv +++ b/rtl/ibex_icache.sv @@ -11,14 +11,15 @@ `include "prim_assert.sv" module ibex_icache #( + parameter bit BranchPredictor = 1'b0, // Cache arrangement parameters - parameter int unsigned BusWidth = 32, - parameter int unsigned CacheSizeBytes = 4*1024, - parameter bit ICacheECC = 1'b0, - parameter int unsigned LineSize = 64, - parameter int unsigned NumWays = 2, + parameter int unsigned BusWidth = 32, + parameter int unsigned CacheSizeBytes = 4*1024, + parameter bit ICacheECC = 1'b0, + parameter int unsigned LineSize = 64, + parameter int unsigned NumWays = 2, // Only cache branch targets - parameter bit BranchCache = 1'b0 + parameter bit BranchCache = 1'b0 ) ( // Clock and reset input logic clk_i, @@ -30,6 +31,8 @@ module ibex_icache #( // Set the cache's address counter input logic branch_i, input logic branch_spec_i, + input logic predicted_branch_i, + input logic branch_mispredict_i, input logic [31:0] addr_i, // IF stage interface: Pass fetched instructions to the core @@ -77,8 +80,10 @@ module ibex_icache #( // Prefetch signals logic [ADDR_W-1:0] lookup_addr_aligned; + logic [ADDR_W-1:0] branch_mispredict_addr; logic [ADDR_W-1:0] prefetch_addr_d, prefetch_addr_q; logic prefetch_addr_en; + logic branch_or_mispredict; // Cache pipelipe IC0 signals logic branch_suppress; logic lookup_throttle; @@ -134,7 +139,7 @@ module ibex_icache #( logic [NUM_FB-1:0] fill_hit_ic1, fill_hit_d, fill_hit_q; logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_ext_cnt_d, fill_ext_cnt_q; logic [NUM_FB-1:0] fill_ext_hold_d, fill_ext_hold_q; - logic [NUM_FB-1:0] fill_ext_done; + logic [NUM_FB-1:0] fill_ext_done_d, fill_ext_done_q; logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_rvd_cnt_d, fill_rvd_cnt_q; logic [NUM_FB-1:0] fill_rvd_done; logic [NUM_FB-1:0] fill_ram_done_d, fill_ram_done_q; @@ -175,6 +180,7 @@ module ibex_icache #( logic output_valid; logic addr_incr_two; logic output_addr_en; + logic [ADDR_W-1:1] output_addr_incr; logic [ADDR_W-1:1] output_addr_d, output_addr_q; logic [15:0] output_data_lo, output_data_hi; logic data_valid, output_ready; @@ -194,6 +200,33 @@ module ibex_icache #( // Instruction prefetch // ////////////////////////// + if (BranchPredictor) begin : g_branch_predictor + // Where the branch predictor is present record what address followed a predicted branch. If + // that branch is predicted taken but mispredicted (so not-taken) this is used to resume on + // the not-taken code path. + logic [31:0] branch_mispredict_addr_q; + logic branch_mispredict_addr_en; + + assign branch_mispredict_addr_en = branch_i & predicted_branch_i; + + always_ff @(posedge clk_i) begin + if (branch_mispredict_addr_en) begin + branch_mispredict_addr_q <= {output_addr_incr, 1'b0}; + end + end + + assign branch_mispredict_addr = branch_mispredict_addr_q; + + end else begin : g_no_branch_predictor + logic unused_predicted_branch; + + assign unused_predicted_branch = predicted_branch_i; + + assign branch_mispredict_addr = '0; + end + + assign branch_or_mispredict = branch_i | branch_mispredict_i; + assign lookup_addr_aligned = {lookup_addr_ic0[ADDR_W-1:LINE_W],{LINE_W{1'b0}}}; // The prefetch address increments by one cache line for each granted request. @@ -204,9 +237,10 @@ module ibex_icache #( // line must also be recorded for later use by the fill buffers. assign prefetch_addr_d = lookup_grant_ic0 ? (lookup_addr_aligned + {{ADDR_W-LINE_W-1{1'b0}},1'b1,{LINE_W{1'b0}}}) : - addr_i; + branch_i ? addr_i : + branch_mispredict_addr; - assign prefetch_addr_en = branch_i | lookup_grant_ic0; + assign prefetch_addr_en = branch_or_mispredict | lookup_grant_ic0; always_ff @(posedge clk_i) begin if (prefetch_addr_en) begin @@ -221,9 +255,11 @@ module ibex_icache #( // Cache lookup assign lookup_throttle = (fb_fill_level > FB_THRESHOLD[$clog2(NUM_FB)-1:0]); - assign lookup_req_ic0 = req_i & ~&fill_busy_q & (branch_i | ~lookup_throttle) & ~ecc_write_req; - assign lookup_addr_ic0 = branch_spec_i ? addr_i : - prefetch_addr_q; + assign lookup_req_ic0 = req_i & ~&fill_busy_q & (branch_or_mispredict | ~lookup_throttle) & + ~ecc_write_req; + assign lookup_addr_ic0 = branch_spec_i ? addr_i : + branch_mispredict_i ? branch_mispredict_addr : + prefetch_addr_q; assign lookup_index_ic0 = lookup_addr_ic0[INDEX_HI:LINE_W]; // Cache write @@ -516,7 +552,7 @@ module ibex_icache #( assign fill_new_alloc = lookup_grant_ic0; // Track whether a speculative external request was made from IC0, and whether it was granted // 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_req = (~icache_enable_i | branch_or_mispredict) & ~|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; @@ -545,7 +581,7 @@ module ibex_icache #( assign fill_done[fb] = (fill_ram_done_q[fb] | fill_hit_q[fb] | ~fill_cache_q[fb] | (|fill_err_q[fb])) & // all data output unless stale due to intervening branch - (fill_out_done[fb] | fill_stale_q[fb] | branch_i) & + (fill_out_done[fb] | fill_stale_q[fb] | branch_or_mispredict) & // all external requests completed fill_rvd_done[fb]; @@ -554,7 +590,7 @@ module ibex_icache #( ///////////////////////////////// // Track staleness (requests become stale when a branch intervenes) - assign fill_stale_d[fb] = fill_busy_q[fb] & (branch_i | fill_stale_q[fb]); + assign fill_stale_d[fb] = fill_busy_q[fb] & (branch_or_mispredict | fill_stale_q[fb]); // Track whether or not this request should allocate to the cache // Any invalidation or disabling of the cache while the buffer is busy will stop allocation assign fill_cache_d[fb] = (fill_alloc[fb] & fill_cache_new) | @@ -569,7 +605,7 @@ module ibex_icache #( /////////////////////////////////////////// // Make an external request - assign fill_ext_req[fb] = fill_busy_q[fb] & ~fill_ext_done[fb]; + assign fill_ext_req[fb] = fill_busy_q[fb] & ~fill_ext_done_d[fb]; // Count the number of completed external requests (each line requires LINE_BEATS requests) // Don't count fake PMP error grants here since they will never receive an rvalid response @@ -581,17 +617,17 @@ module ibex_icache #( assign fill_ext_hold_d[fb] = (fill_alloc[fb] & fill_spec_hold) | (fill_ext_arb[fb] & ~gnt_or_pmp_err); // External requests are completed when the counter is filled or when the request is cancelled - assign fill_ext_done[fb] = (fill_ext_cnt_q[fb][LINE_BEATS_W] | + assign fill_ext_done_d[fb] = (fill_ext_cnt_q[fb][LINE_BEATS_W] | // external requests are considered complete if the request hit 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 won't be cached and, it is stale - (~fill_cache_q[fb] & (branch_i | fill_stale_q[fb] | + (~fill_cache_q[fb] & (branch_or_mispredict | 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]; + ~fill_ext_hold_q[fb] & fill_busy_q[fb]; // Track whether this fill buffer expects to receive beats of data assign fill_rvd_exp[fb] = fill_busy_q[fb] & ~fill_rvd_done[fb]; // Count the number of rvalid beats received @@ -599,7 +635,8 @@ module ibex_icache #( (fill_rvd_cnt_q[fb] + {{LINE_BEATS_W{1'b0}},fill_rvd_arb[fb]}); // External data is complete when all issued external requests have received their data - assign fill_rvd_done[fb] = fill_ext_done[fb] & (fill_rvd_cnt_q[fb] == fill_ext_cnt_q[fb]); + assign fill_rvd_done[fb] = (fill_ext_done_q[fb] & ~fill_ext_hold_q[fb]) & + (fill_rvd_cnt_q[fb] == fill_ext_cnt_q[fb]); ////////////////////////////////////// // Fill buffer data output tracking // @@ -705,6 +742,7 @@ module ibex_icache #( fill_hit_q[fb] <= 1'b0; fill_ext_cnt_q[fb] <= '0; fill_ext_hold_q[fb] <= 1'b0; + fill_ext_done_q[fb] <= 1'b0; fill_rvd_cnt_q[fb] <= '0; fill_ram_done_q[fb] <= 1'b0; fill_out_cnt_q[fb] <= '0; @@ -716,6 +754,7 @@ module ibex_icache #( fill_hit_q[fb] <= fill_hit_d[fb]; fill_ext_cnt_q[fb] <= fill_ext_cnt_d[fb]; fill_ext_hold_q[fb] <= fill_ext_hold_d[fb]; + fill_ext_done_q[fb] <= fill_ext_done_d[fb]; fill_rvd_cnt_q[fb] <= fill_rvd_cnt_d[fb]; fill_ram_done_q[fb] <= fill_ram_done_d[fb]; fill_out_cnt_q[fb] <= fill_out_cnt_d[fb]; @@ -828,7 +867,7 @@ module ibex_icache #( // External requests // /////////////////////// - assign instr_req = ((~icache_enable_i | branch_i) & lookup_grant_ic0) | + assign instr_req = ((~icache_enable_i | branch_or_mispredict) & lookup_grant_ic0) | (|fill_ext_req); assign instr_addr = |fill_ext_req ? fill_ext_req_addr : @@ -893,7 +932,7 @@ module ibex_icache #( assign skid_valid_d = // Branches invalidate the skid buffer - branch_i ? 1'b0 : + branch_or_mispredict ? 1'b0 : // Once valid, the skid buffer stays valid until a compressed instruction realigns the stream (skid_valid_q ? ~(ready_i & ((skid_data_q[1:0] != 2'b11) | skid_err_q)) : // The skid buffer becomes valid when: @@ -921,15 +960,20 @@ module ibex_icache #( output_err | (output_data[17:16] != 2'b11))); // Update the address on branches and every time an instruction is driven - assign output_addr_en = branch_i | (ready_i & valid_o); + assign output_addr_en = branch_or_mispredict | (ready_i & valid_o); // Increment the address by two every time a compressed instruction is popped assign addr_incr_two = output_compressed & ~err_o; - assign output_addr_d = branch_i ? addr_i[31:1] : - (output_addr_q[31:1] + - // Increment address by 4 or 2 - {29'd0, ~addr_incr_two, addr_incr_two}); + // Next IF stage PC + assign output_addr_incr = (output_addr_q[31:1] + + // Increment address by 4 or 2 + {29'd0, ~addr_incr_two, addr_incr_two}); + + // Redirect the address on branches or mispredicts + assign output_addr_d = branch_i ? addr_i[31:1] : + branch_mispredict_i ? branch_mispredict_addr[31:1] : + output_addr_incr; always_ff @(posedge clk_i) begin if (output_addr_en) begin @@ -963,7 +1007,7 @@ module ibex_icache #( end end - assign valid_o = output_valid; + assign valid_o = output_valid & ~branch_mispredict_i; assign rdata_o = {output_data_hi, (skid_valid_q ? skid_data_q : output_data_lo)}; assign addr_o = {output_addr_q, 1'b0}; assign err_o = (skid_valid_q & skid_err_q) | (~skid_complete_instr & output_err); diff --git a/rtl/ibex_if_stage.sv b/rtl/ibex_if_stage.sv index ee217a8c..33911e46 100644 --- a/rtl/ibex_if_stage.sv +++ b/rtl/ibex_if_stage.sv @@ -184,40 +184,39 @@ module ibex_if_stage #( if (ICache) begin : gen_icache // Full I-Cache option ibex_icache #( - .ICacheECC (ICacheECC) + .BranchPredictor (BranchPredictor), + .ICacheECC (ICacheECC) ) icache_i ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), - .req_i ( req_i ), + .req_i ( req_i ), - .branch_i ( branch_req ), - .branch_spec_i ( branch_spec ), - .addr_i ( {fetch_addr_n[31:1], 1'b0} ), + .branch_i ( branch_req ), + .branch_spec_i ( branch_spec ), + .predicted_branch_i ( predicted_branch ), + .branch_mispredict_i ( nt_branch_mispredict_i ), + .addr_i ( {fetch_addr_n[31:1], 1'b0} ), - .ready_i ( fetch_ready ), - .valid_o ( fetch_valid ), - .rdata_o ( fetch_rdata ), - .addr_o ( fetch_addr ), - .err_o ( fetch_err ), - .err_plus2_o ( fetch_err_plus2 ), + .ready_i ( fetch_ready ), + .valid_o ( fetch_valid ), + .rdata_o ( fetch_rdata ), + .addr_o ( fetch_addr ), + .err_o ( fetch_err ), + .err_plus2_o ( fetch_err_plus2 ), - .instr_req_o ( instr_req_o ), - .instr_addr_o ( instr_addr_o ), - .instr_gnt_i ( instr_gnt_i ), - .instr_rvalid_i ( instr_rvalid_i ), - .instr_rdata_i ( instr_rdata_i ), - .instr_err_i ( instr_err_i ), - .instr_pmp_err_i ( instr_pmp_err_i ), + .instr_req_o ( instr_req_o ), + .instr_addr_o ( instr_addr_o ), + .instr_gnt_i ( instr_gnt_i ), + .instr_rvalid_i ( instr_rvalid_i ), + .instr_rdata_i ( instr_rdata_i ), + .instr_err_i ( instr_err_i ), + .instr_pmp_err_i ( instr_pmp_err_i ), - .icache_enable_i ( icache_enable_i ), - .icache_inval_i ( icache_inval_i ), - .busy_o ( prefetch_busy ) + .icache_enable_i ( icache_enable_i ), + .icache_inval_i ( icache_inval_i ), + .busy_o ( prefetch_busy ) ); - // Branch predictor tie-offs (which are unused when the instruction cache is enabled) - logic unused_nt_branch_mispredict, unused_predicted_branch; - assign unused_nt_branch_mispredict = nt_branch_mispredict_i; - assign unused_predicted_branch = predicted_branch; end else begin : gen_prefetch_buffer // prefetch buffer, caches a fixed number of instructions ibex_prefetch_buffer #( @@ -590,6 +589,9 @@ module ibex_if_stage #( // following cycle core signal that that branch has mispredicted). `ASSERT(MispredictSingleCycle, nt_branch_mispredict_i & ~(fetch_valid & fetch_ready) |=> ~nt_branch_mispredict_i) + // Note that we should never see a mispredict and an incoming branch on the same cycle. + // The mispredict also cancels any predicted branch so overall branch_req must be low. + `ASSERT(NoMispredBranch, nt_branch_mispredict_i |-> ~branch_req) `endif end else begin : g_no_branch_predictor_asserts diff --git a/rtl/ibex_prefetch_buffer.sv b/rtl/ibex_prefetch_buffer.sv index f206b2ad..1eae0b7c 100644 --- a/rtl/ibex_prefetch_buffer.sv +++ b/rtl/ibex_prefetch_buffer.sv @@ -286,7 +286,7 @@ module ibex_prefetch_buffer #( // Push a new entry to the FIFO once complete (and not cancelled by a branch) assign fifo_valid = rvalid_or_pmp_err & ~branch_discard_q[0]; - assign fifo_addr = branch_mispredict_i ? branch_mispredict_addr : addr_i; + assign fifo_addr = branch_i ? addr_i : branch_mispredict_addr; /////////////// // Registers //