Hopefully fix case where we jump to the address immediately after a

halfword-sized word-aligned predicted-taken branch, and an
address-phase hold causes the jump target to go to the fetch address
counter, causing a spurious BTB match on the branch.
This commit is contained in:
Luke Wren 2022-06-26 15:28:06 +01:00
parent 33cec49952
commit fb15894731
2 changed files with 10 additions and 4 deletions

View File

@ -712,7 +712,7 @@ wire [W_ADDR-1:0] x_jump_target = x_addr_sum & ~32'h1;
wire x_jump_misaligned = ~|EXTENSION_C && x_addr_sum[1];
wire x_branch_cmp_noinvert;
wire x_branch_was_predicted = |BRANCH_PREDICTOR && fd_cir_predbranch[fd_cir[1:0] == 2'b11];
wire x_branch_was_predicted = |BRANCH_PREDICTOR && fd_cir_predbranch[0];
wire x_branch_cmp = x_branch_cmp_noinvert ^ x_branch_was_predicted;
generate

View File

@ -95,6 +95,7 @@ localparam FIFO_DEPTH = 2;
wire jump_now = jump_target_vld && jump_target_rdy;
reg [1:0] mem_data_hwvld;
// Mark data as containing a predicted-taken branch instruction so that
// mispredicts can be recovered -- need to track both halfwords so that we
// can mark the entire instruction, and nothing but the instruction:
@ -225,13 +226,20 @@ assign btb_target_addr_out = btb_target_addr;
reg [W_ADDR-1:0] fetch_addr;
reg fetch_priv;
reg btb_prev_start_of_overhanging;
reg [1:0] mem_aph_hwvld;
wire btb_match_word = |BRANCH_PREDICTOR && btb_valid && (
fetch_addr[W_ADDR-1:2] == btb_src_addr[W_ADDR-1:2]
);
// Catch case where predicted-taken branch instruction extends into next word:
wire btb_src_overhanging = btb_src_size && btb_src_addr[1];
wire btb_match_current_addr = btb_match_word && !btb_src_overhanging;
// Suppress case where we have jumped immediately after a word-aligned halfword-sized
// branch, and the jump target went into fetch_addr due to an address-phase hold:
wire btb_jumped_beyond = !btb_src_size && !btb_src_addr[1] && !mem_aph_hwvld[0];
wire btb_match_current_addr = btb_match_word && !btb_src_overhanging && !btb_jumped_beyond;
wire btb_match_next_addr = btb_match_word && btb_src_overhanging;
wire btb_match_now = btb_match_current_addr || btb_prev_start_of_overhanging;
@ -353,8 +361,6 @@ always @ (posedge clk or negedge rst_n) begin
end
end
reg [1:0] mem_aph_hwvld;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
mem_data_hwvld <= 2'b11;