diff --git a/exc_controller.sv b/exc_controller.sv index c1807fd6..e48e16fa 100644 --- a/exc_controller.sv +++ b/exc_controller.sv @@ -32,8 +32,10 @@ module exc_controller input logic fetch_enable_i, // to IF stage - output logic exc_pc_sel_o, // influences next PC, if set exception PC is used - output logic [1:0] exc_pc_mux_o, // Selector in the Fetch stage to select the rigth exception PC + output logic exc_pc_sel_o, // influences next PC, if set exception PC is used + output logic [1:0] exc_pc_mux_o, // Selector in the Fetch stage to select the rigth exception PC + + input logic branch_done_i, // Did we already perform a branch while waiting for the next instruction? // hwloop signals output logic hwloop_enable_o, // '1' if pc is valid (interrupt related signal) @@ -167,9 +169,9 @@ module exc_controller // to the ISR without flushing the pipeline ExcIR: begin - if (((jump_in_id_i == `BRANCH_JALR || jump_in_id_i == `BRANCH_JAL) && new_instr_id_q == 1'b0) || jump_in_ex_i == `BRANCH_COND) + if (((jump_in_id_i == `BRANCH_JALR || jump_in_id_i == `BRANCH_JAL) && new_instr_id_q == 1'b0) || jump_in_ex_i == `BRANCH_COND || branch_done_i) begin - //wait one cycle + // wait one cycle if (~stall_id_i) exc_reason_n = ExcIRDeferred; end @@ -177,7 +179,6 @@ module exc_controller begin exc_pc_sel_o = 1'b1; - if (irq_nm_i == 1'b1) // emergency IRQ has higher priority exc_pc_mux_o = `EXC_PC_IRQ_NM; else // irq_i == 1'b1 diff --git a/id_stage.sv b/id_stage.sv index af44cb8a..619277f2 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -57,6 +57,8 @@ module id_stage output logic [2:0] pc_mux_sel_o, output logic [1:0] exc_pc_mux_o, + input logic branch_done_i, + input logic illegal_c_insn_i, input logic is_compressed_i, @@ -725,6 +727,8 @@ module id_stage .exc_pc_sel_o ( exc_pc_sel ), .exc_pc_mux_o ( exc_pc_mux_o ), + .branch_done_i ( branch_done_i ), + // hwloop signals .hwloop_enable_o ( hwloop_enable ), diff --git a/if_stage.sv b/if_stage.sv index 705edad4..f9c33c43 100644 --- a/if_stage.sv +++ b/if_stage.sv @@ -67,6 +67,8 @@ module if_stage input logic [2:0] pc_mux_sel_i, // sel for pc multiplexer input logic [1:0] exc_pc_mux_i, // select which exception to execute + output logic branch_done_o, // we already performed a branch + // jump and branch target and decision input logic [1:0] jump_in_id_i, input logic [1:0] jump_in_ex_i, // jump in EX -> get PC from jump target (could also be branch) @@ -422,4 +424,6 @@ module if_stage assign if_ready_o = valid & id_ready_i; assign if_valid_o = (~halt_if_i) & if_ready_o & (jump_in_id_i != `BRANCH_COND); + assign branch_done_o = branch_req_Q; + endmodule diff --git a/riscv_core.sv b/riscv_core.sv index 0f8d2821..b7c2517f 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -92,6 +92,8 @@ module riscv_core logic [2:0] pc_mux_sel_id; // Mux selector for next PC logic [1:0] exc_pc_mux_id; // Mux selector for exception PC + logic branch_done; // Branch already done + // ID performance counter signals logic is_decoding; @@ -263,6 +265,8 @@ module riscv_core .pc_mux_sel_i ( pc_mux_sel_id ), // sel for pc multiplexer .exc_pc_mux_i ( exc_pc_mux_id ), // selector for exception multiplexer + .branch_done_o ( branch_done ), + // from hwloop controller .hwloop_jump_i ( hwloop_jump ), .hwloop_target_i ( hwloop_target ), // pc from hwloop start address @@ -320,6 +324,8 @@ module riscv_core .pc_mux_sel_o ( pc_mux_sel_id ), .exc_pc_mux_o ( exc_pc_mux_id ), + .branch_done_i ( branch_done ), + .illegal_c_insn_i ( illegal_c_insn_id ), .is_compressed_i ( is_compressed_id ),