diff --git a/controller.sv b/controller.sv index 015602b6..a38ffe31 100644 --- a/controller.sv +++ b/controller.sv @@ -70,12 +70,10 @@ module riscv_controller input logic hwloop_jump_i, // modify pc_mux_sel to select the hwloop addr // jump/branch signals - input logic [1:0] jump_in_ex_i, // jump is being calculated in ALU + input logic branch_taken_ex_i, // branch taken signal from EX ALU input logic [1:0] jump_in_id_i, // jump is being calculated in ALU input logic [1:0] jump_in_dec_i, // jump is being calculated in ALU - input logic branch_decision_i, // branch decision is available in EX stage - // Exception Controller Signals input logic exc_req_i, output logic exc_ack_o, @@ -261,8 +259,7 @@ module riscv_controller // decode and execute instructions only if the current conditional // branch in the EX stage is either not taken, or there is no // conditional branch in the EX stage - if ((jump_in_ex_i == `BRANCH_COND && ~branch_decision_i) || - (jump_in_ex_i != `BRANCH_COND)) + if (~branch_taken_ex_i) begin // now analyze the current instruction in the ID stage is_decoding_o = 1'b1; @@ -348,7 +345,7 @@ module riscv_controller // TODO: make sure this is not done multiple times in a row!!! // maybe with an assertion? // handle conditional branches - if (jump_in_ex_i == `BRANCH_COND && branch_decision_i) begin + if (branch_taken_ex_i) begin // there is a branch in the EX stage that is taken pc_mux_sel_o = `PC_BRANCH; pc_set_o = 1'b1; @@ -370,7 +367,7 @@ module riscv_controller begin halt_if_o = 1'b1; - if (branch_decision_i) begin + if (branch_taken_ex_i) begin // there is a branch in the EX stage that is taken pc_mux_sel_o = `PC_BRANCH; pc_set_o = 1'b1; @@ -575,9 +572,4 @@ module riscv_controller assign perf_jr_stall_o = jr_stall_o; assign perf_ld_stall_o = load_stall_o; - - // Assertions - assert property ( - @(posedge clk) (pc_mux_sel_o == `PC_BRANCH) |-> (branch_decision_i !== 1'bx) ); - endmodule // controller diff --git a/debug_unit.sv b/debug_unit.sv index d797268a..89637fda 100644 --- a/debug_unit.sv +++ b/debug_unit.sv @@ -63,7 +63,7 @@ module riscv_debug_unit input logic [31:0] curr_pc_id_i, input logic [31:0] branch_pc_i, - input logic [1:0] jump_in_ex_i, + input logic branch_in_ex_i, input logic branch_taken_i, output logic [31:0] npc_o, @@ -254,7 +254,7 @@ module riscv_debug_unit if (stall_core_o && (bp_fsm_cs != StallCore)) begin pc_tracking_fsm_ns = IFID; - if (jump_in_ex_i == `BRANCH_COND) begin + if (branch_in_ex_i) begin if (branch_taken_i) pc_tracking_fsm_ns = IFEX; else diff --git a/id_stage.sv b/id_stage.sv index 6a5ecdc1..f5e59e45 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -51,8 +51,7 @@ module riscv_id_stage // Jumps and branches - output logic [1:0] jump_in_id_o, - output logic [1:0] jump_in_ex_o, + output logic branch_in_ex_o, input logic branch_decision_i, output logic [31:0] jump_target_o, @@ -63,8 +62,6 @@ module riscv_id_stage output logic [1:0] exc_pc_mux_o, output logic [4:0] exc_vec_pc_mux_o, - input logic branch_done_i, - input logic illegal_c_insn_i, input logic is_compressed_i, @@ -183,6 +180,8 @@ module riscv_id_stage logic regb_used_dec; logic regc_used_dec; + logic branch_taken_ex; + logic [1:0] jump_in_id; logic [1:0] jump_in_dec; logic misaligned_stall; @@ -321,6 +320,8 @@ module riscv_id_stage // signal to 0 for instructions that are done assign clear_instr_valid_o = id_ready_o; + assign branch_taken_ex = branch_in_ex_o & branch_decision_i; + /////////////////////////////////////////////// // _ ___ ___ ___ ___ ____ // @@ -607,7 +608,7 @@ module riscv_id_stage // jump/branches .jump_in_dec_o ( jump_in_dec ), - .jump_in_id_o ( jump_in_id_o ), + .jump_in_id_o ( jump_in_id ), .jump_target_mux_sel_o ( jump_target_mux_sel ) ); @@ -659,11 +660,9 @@ module riscv_id_stage .hwloop_jump_i ( hwloop_jump ), // jump/branch control + .branch_taken_ex_i ( branch_taken_ex ), + .jump_in_id_i ( jump_in_id ), .jump_in_dec_i ( jump_in_dec ), - .jump_in_id_i ( jump_in_id_o ), - .jump_in_ex_i ( jump_in_ex_o ), - - .branch_decision_i ( branch_decision_i ), // Exception Controller Signals .exc_req_i ( exc_req ), @@ -821,7 +820,7 @@ module riscv_id_stage branch_pc_ex_o <= '0; end else begin - if (jump_in_id_o == `BRANCH_COND && id_valid_o) + if (jump_in_id == `BRANCH_COND && id_valid_o) branch_pc_ex_o <= current_pc_id_i; end end @@ -860,7 +859,7 @@ module riscv_id_stage data_misaligned_ex_o <= 1'b0; - jump_in_ex_o <= `BRANCH_NONE; + branch_in_ex_o <= 1'b0; end else if (data_misaligned_i) begin @@ -917,7 +916,7 @@ module riscv_id_stage data_misaligned_ex_o <= 1'b0; - jump_in_ex_o <= jump_in_id_o; + branch_in_ex_o <= jump_in_id == `BRANCH_COND; end else if(ex_ready_i) begin // EX stage is ready but we don't have a new instruction for it, // so we set all write enables to 0, but unstall the pipe @@ -932,7 +931,7 @@ module riscv_id_stage data_misaligned_ex_o <= 1'b0; - jump_in_ex_o <= `BRANCH_NONE; + branch_in_ex_o <= 1'b0; end end end @@ -942,4 +941,12 @@ module riscv_id_stage assign id_ready_o = (~misaligned_stall) & (~jr_stall) & (~load_stall) & ex_ready_i; assign id_valid_o = (~halt_id) & id_ready_o; + //---------------------------------------------------------------------------- + // Assertions + //---------------------------------------------------------------------------- + + // make sure that branch decision is valid when jumping + assert property ( + @(posedge clk) (branch_in_ex_o) |-> (branch_decision_i !== 1'bx) ); + endmodule diff --git a/if_stage.sv b/if_stage.sv index 796cf500..7d13f381 100644 --- a/if_stage.sv +++ b/if_stage.sv @@ -70,14 +70,9 @@ module riscv_if_stage input logic [1:0] exc_pc_mux_i, // selects ISR address input logic [4:0] exc_vec_pc_mux_i, // selects ISR address for vectorized interrupt lines - 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) input logic [31:0] jump_target_id_i, // jump target address input logic [31:0] jump_target_ex_i, // jump target address - input logic branch_decision_i, // from hwloop controller input logic hwloop_jump_i, @@ -421,6 +416,4 @@ module riscv_if_stage assign if_ready_o = valid & id_ready_i; assign if_valid_o = (~halt_if_i) & if_ready_o; - assign branch_done_o = branch_req_Q; - endmodule diff --git a/riscv_core.sv b/riscv_core.sv index e8c58813..c7f995cd 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -98,8 +98,6 @@ module riscv_core logic [1:0] exc_pc_mux_id; // Mux selector for exception PC logic [4:0] exc_vec_pc_mux_id; // Mux selector for vectorized IR lines - logic branch_done; // Branch already done - logic lsu_load_err; logic lsu_store_err; @@ -111,8 +109,7 @@ module riscv_core // Jump and branch target and decision (EX->IF) logic [31:0] jump_target_id, jump_target_ex; - logic [1:0] jump_in_id; - logic [1:0] jump_in_ex; + logic branch_in_ex; logic branch_decision; logic core_busy; @@ -273,8 +270,6 @@ module riscv_core .exc_pc_mux_i ( exc_pc_mux_id ), .exc_vec_pc_mux_i ( exc_vec_pc_mux_id ), - .branch_done_o ( branch_done ), - // from hwloop controller .hwloop_jump_i ( hwloop_jump ), .hwloop_target_i ( hwloop_target ), // pc from hwloop start address @@ -283,10 +278,7 @@ module riscv_core .dbg_npc_i ( dbg_npc ), .dbg_set_npc_i ( dbg_set_npc ), - // Jump and branch target and decision - .jump_in_id_i ( jump_in_id ), - .jump_in_ex_i ( jump_in_ex ), - .branch_decision_i ( branch_decision ), + // Jump targets .jump_target_id_i ( jump_target_id ), .jump_target_ex_i ( jump_target_ex ), @@ -327,8 +319,7 @@ module riscv_core .instr_req_o ( instr_req_int ), // Jumps and branches - .jump_in_id_o ( jump_in_id ), - .jump_in_ex_o ( jump_in_ex ), + .branch_in_ex_o ( branch_in_ex ), .branch_decision_i ( branch_decision ), .jump_target_o ( jump_target_id ), @@ -339,8 +330,6 @@ module riscv_core .exc_pc_mux_o ( exc_pc_mux_id ), .exc_vec_pc_mux_o ( exc_vec_pc_mux_id ), - .branch_done_i ( branch_done ), - .illegal_c_insn_i ( illegal_c_insn_id ), .is_compressed_i ( is_compressed_id ), @@ -671,7 +660,7 @@ module riscv_core .curr_pc_id_i ( current_pc_id ), // from IF stage .branch_pc_i ( branch_pc_ex ), // PC of last executed branch (in EX stage) - .jump_in_ex_i ( jump_in_ex ), + .branch_in_ex_i ( branch_in_ex ), .branch_taken_i ( branch_decision ), .npc_o ( dbg_npc ), // PC from debug unit