diff --git a/controller.sv b/controller.sv index 83e96d9e..77ff3e7e 100644 --- a/controller.sv +++ b/controller.sv @@ -59,6 +59,7 @@ module riscv_controller // LSU input logic data_req_ex_i, // data memory access is currently performed in EX stage input logic data_misaligned_i, + input logic data_load_event_i, // from ALU input logic mult_multicycle_i, // multiplier is taken multiple cycles and uses op c as storage @@ -328,6 +329,13 @@ module riscv_controller ctrl_fsm_ns = DBG_WAIT_BRANCH; else ctrl_fsm_ns = DBG_SIGNAL; + end else if (data_load_event_i) begin + // special case for p.elw + // If there was a load event (which means p.elw), we go to debug + // even though we are still blocked + // we don't have to distuinguish between branch and non-branch, + // since the p.elw sits in the EX stage + ctrl_fsm_ns = DBG_SIGNAL; end end end diff --git a/cs_registers.sv b/cs_registers.sv index f0d6068b..77693b73 100644 --- a/cs_registers.sv +++ b/cs_registers.sv @@ -57,8 +57,8 @@ module riscv_cs_registers output logic irq_enable_o, output logic [31:0] mepc_o, - input logic [31:0] curr_pc_id_i, - input logic [31:0] data_pc_ex_i, + input logic [31:0] pc_id_i, + input logic [31:0] pc_ex_i, input logic data_load_event_ex_i, input logic exc_save_i, input logic exc_restore_i, @@ -206,7 +206,7 @@ module riscv_cs_registers // exception controller gets priority over other writes if (exc_save_i) begin - mepc_n = data_load_event_ex_i ? data_pc_ex_i : curr_pc_id_i; // save EX PC if special event load + mepc_n = data_load_event_ex_i ? pc_ex_i : pc_id_i; // save EX PC if special event load mestatus_n = mstatus_q; mstatus_n = 1'b0; end diff --git a/debug_unit.sv b/debug_unit.sv index fe656d0e..00626dac 100644 --- a/debug_unit.sv +++ b/debug_unit.sv @@ -65,9 +65,11 @@ module riscv_debug_unit input logic [31:0] csr_rdata_i, // Signals for PPC & NPC register - input logic [31:0] curr_pc_if_i, - input logic [31:0] curr_pc_id_i, - input logic [31:0] branch_pc_i, + input logic [31:0] pc_if_i, + input logic [31:0] pc_id_i, + input logic [31:0] pc_ex_i, + + input logic data_load_event_i, input logic branch_in_ex_i, input logic branch_taken_i, @@ -407,24 +409,24 @@ module riscv_debug_unit begin pc_tracking_fsm_ns = pc_tracking_fsm_cs; - ppc_int = curr_pc_id_i; - npc_int = curr_pc_if_i; + ppc_int = pc_id_i; + npc_int = pc_if_i; // PPC/NPC mux unique case (pc_tracking_fsm_cs) IFID: begin - ppc_int = curr_pc_id_i; - npc_int = curr_pc_if_i; + ppc_int = pc_id_i; + npc_int = pc_if_i; end IFEX: begin - ppc_int = branch_pc_i; - npc_int = curr_pc_if_i; + ppc_int = pc_ex_i; + npc_int = pc_if_i; end IDEX: begin - ppc_int = branch_pc_i; - npc_int = curr_pc_id_i; + ppc_int = pc_ex_i; + npc_int = pc_id_i; if (jump_req_o) pc_tracking_fsm_ns = IFEX; @@ -444,6 +446,9 @@ module riscv_debug_unit pc_tracking_fsm_ns = IFEX; else pc_tracking_fsm_ns = IDEX; + end else if (data_load_event_i) begin + // for p.elw + pc_tracking_fsm_ns = IDEX; end end end diff --git a/id_stage.sv b/id_stage.sv index b941016a..76aadd66 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -82,7 +82,7 @@ module riscv_id_stage input logic wb_valid_i, // WB stage is done // Pipeline ID/EX - output logic [31:0] branch_pc_ex_o, + output logic [31:0] pc_ex_o, output logic [31:0] alu_operand_a_ex_o, output logic [31:0] alu_operand_b_ex_o, @@ -137,7 +137,6 @@ module riscv_id_stage output logic [1:0] data_type_ex_o, output logic data_sign_ext_ex_o, output logic [1:0] data_reg_offset_ex_o, - output logic [31:0] data_pc_ex_o, output logic data_load_event_ex_o, output logic data_misaligned_ex_o, @@ -839,6 +838,7 @@ module riscv_id_stage // LSU .data_req_ex_i ( data_req_ex_o ), .data_misaligned_i ( data_misaligned_i ), + .data_load_event_i ( data_load_event_ex_o ), // ALU .mult_multicycle_i ( mult_multicycle_i ), @@ -998,17 +998,6 @@ module riscv_id_stage // |___|____/ |_____/_/\_\ |_| |___|_| |_____|_____|___|_| \_|_____| // // // ///////////////////////////////////////////////////////////////////////////////// - always_ff @(posedge clk, negedge rst_n) - begin - if (rst_n == 1'b0) - begin - branch_pc_ex_o <= '0; - end - else begin - if (jump_in_id == `BRANCH_COND && id_valid_o) - branch_pc_ex_o <= pc_id_i; - end - end always_ff @(posedge clk, negedge rst_n) begin : ID_EX_PIPE_REGISTERS @@ -1052,11 +1041,12 @@ module riscv_id_stage data_sign_ext_ex_o <= 1'b0; data_reg_offset_ex_o <= 2'b0; data_req_ex_o <= 1'b0; - data_pc_ex_o <= '0; data_load_event_ex_o <= 1'b0; data_misaligned_ex_o <= 1'b0; + pc_ex_o <= '0; + branch_in_ex_o <= 1'b0; end @@ -1139,19 +1129,17 @@ module riscv_id_stage data_type_ex_o <= data_type_id; data_sign_ext_ex_o <= data_sign_ext_id; data_reg_offset_ex_o <= data_reg_offset_id; - - if (data_load_event_id) begin - data_pc_ex_o <= pc_id_i; - data_load_event_ex_o <= 1'b1; - end else begin - data_load_event_ex_o <= 1'b0; - end + data_load_event_ex_o <= data_load_event_id;; end else begin data_load_event_ex_o <= 1'b0; end data_misaligned_ex_o <= 1'b0; + if ((jump_in_id == `BRANCH_COND) || data_load_event_id) begin + pc_ex_o <= pc_id_i; + end + 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, diff --git a/riscv_core.sv b/riscv_core.sv index d41007dc..d3360709 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -124,7 +124,7 @@ module riscv_core logic lsu_busy; - logic [31:0] branch_pc_ex; // PC of last executed branch + logic [31:0] pc_ex; // PC of last executed branch or p.elw // ALU Control logic [`ALU_OP_WIDTH-1:0] alu_operator_ex; @@ -425,7 +425,7 @@ module riscv_core .wb_valid_i ( wb_valid ), // From the Pipeline ID/EX - .branch_pc_ex_o ( branch_pc_ex ), + .pc_ex_o ( pc_ex ), .alu_operator_ex_o ( alu_operator_ex ), .alu_operand_a_ex_o ( alu_operand_a_ex ), @@ -477,7 +477,6 @@ module riscv_core .data_type_ex_o ( data_type_ex ), // to load store unit .data_sign_ext_ex_o ( data_sign_ext_ex ), // to load store unit .data_reg_offset_ex_o ( data_reg_offset_ex ), // to load store unit - .data_pc_ex_o ( data_pc_ex ), // to load store unit .data_load_event_ex_o ( data_load_event_ex ), // to load store unit .data_misaligned_ex_o ( data_misaligned_ex ), // to load store unit @@ -696,8 +695,8 @@ module riscv_core .irq_enable_o ( irq_enable ), .mepc_o ( mepc ), - .curr_pc_id_i ( pc_id ), // from IF stage - .data_pc_ex_i ( data_pc_ex ), // from ID/EX pipeline + .pc_id_i ( pc_id ), // from IF stage + .pc_ex_i ( pc_ex ), // from ID/EX pipeline .data_load_event_ex_i ( data_load_event_ex ), // from ID/EX pipeline .exc_save_i ( exc_save_id ), .exc_restore_i ( exc_restore_id ), @@ -754,55 +753,57 @@ module riscv_core riscv_debug_unit debug_unit_i ( - .clk ( clk_i ), // always-running clock for debug - .rst_n ( rst_ni ), + .clk ( clk_i ), // always-running clock for debug + .rst_n ( rst_ni ), // Debug Interface - .debug_req_i ( debug_req_i ), - .debug_gnt_o ( debug_gnt_o ), - .debug_rvalid_o ( debug_rvalid_o ), - .debug_addr_i ( debug_addr_i ), - .debug_we_i ( debug_we_i ), - .debug_wdata_i ( debug_wdata_i ), - .debug_rdata_o ( debug_rdata_o ), - .debug_halt_i ( debug_halt_i ), - .debug_halted_o ( debug_halted_o ), + .debug_req_i ( debug_req_i ), + .debug_gnt_o ( debug_gnt_o ), + .debug_rvalid_o ( debug_rvalid_o ), + .debug_addr_i ( debug_addr_i ), + .debug_we_i ( debug_we_i ), + .debug_wdata_i ( debug_wdata_i ), + .debug_rdata_o ( debug_rdata_o ), + .debug_halt_i ( debug_halt_i ), + .debug_halted_o ( debug_halted_o ), // To/From Core - .settings_o ( dbg_settings ), - .trap_i ( dbg_trap ), - .exc_cause_i ( exc_cause ), - .stall_o ( dbg_stall ), - .dbg_req_o ( dbg_req ), - .dbg_ack_i ( dbg_ack ), + .settings_o ( dbg_settings ), + .trap_i ( dbg_trap ), + .exc_cause_i ( exc_cause ), + .stall_o ( dbg_stall ), + .dbg_req_o ( dbg_req ), + .dbg_ack_i ( dbg_ack ), // register file read port - .regfile_rreq_o ( dbg_reg_rreq ), - .regfile_raddr_o ( dbg_reg_raddr ), - .regfile_rdata_i ( dbg_reg_rdata ), + .regfile_rreq_o ( dbg_reg_rreq ), + .regfile_raddr_o ( dbg_reg_raddr ), + .regfile_rdata_i ( dbg_reg_rdata ), // register file write port - .regfile_wreq_o ( dbg_reg_wreq ), - .regfile_waddr_o ( dbg_reg_waddr ), - .regfile_wdata_o ( dbg_reg_wdata ), + .regfile_wreq_o ( dbg_reg_wreq ), + .regfile_waddr_o ( dbg_reg_waddr ), + .regfile_wdata_o ( dbg_reg_wdata ), // CSR read/write port - .csr_req_o ( dbg_csr_req ), - .csr_addr_o ( dbg_csr_addr ), - .csr_we_o ( dbg_csr_we ), - .csr_wdata_o ( dbg_csr_wdata ), - .csr_rdata_i ( csr_rdata ), + .csr_req_o ( dbg_csr_req ), + .csr_addr_o ( dbg_csr_addr ), + .csr_we_o ( dbg_csr_we ), + .csr_wdata_o ( dbg_csr_wdata ), + .csr_rdata_i ( csr_rdata ), // signals for PPC and NPC - .curr_pc_if_i ( pc_if ), // from IF stage - .curr_pc_id_i ( pc_id ), // from IF stage - .branch_pc_i ( branch_pc_ex ), // PC of last executed branch (in EX stage) + .pc_if_i ( pc_if ), // from IF stage + .pc_id_i ( pc_id ), // from IF stage + .pc_ex_i ( pc_ex ), // PC of last executed branch (in EX stage) or p.elw - .branch_in_ex_i ( branch_in_ex ), - .branch_taken_i ( branch_decision ), + .data_load_event_i ( data_load_event_ex ), - .jump_addr_o ( dbg_jump_addr ), // PC from debug unit - .jump_req_o ( dbg_jump_req ) // set PC to new value + .branch_in_ex_i ( branch_in_ex ), + .branch_taken_i ( branch_decision ), + + .jump_addr_o ( dbg_jump_addr ), // PC from debug unit + .jump_req_o ( dbg_jump_req ) // set PC to new value );