From fb15894731c1bb39469a568df6a023ba9a513f22 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sun, 26 Jun 2022 15:28:06 +0100 Subject: [PATCH] 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. --- hdl/hazard3_core.v | 2 +- hdl/hazard3_frontend.v | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/hdl/hazard3_core.v b/hdl/hazard3_core.v index e88fed2..ecf6320 100644 --- a/hdl/hazard3_core.v +++ b/hdl/hazard3_core.v @@ -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 diff --git a/hdl/hazard3_frontend.v b/hdl/hazard3_frontend.v index b470321..1dd9c30 100644 --- a/hdl/hazard3_frontend.v +++ b/hdl/hazard3_frontend.v @@ -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;