diff --git a/controller.sv b/controller.sv index b6dbeaf8..013f6227 100644 --- a/controller.sv +++ b/controller.sv @@ -1254,7 +1254,10 @@ module controller case (dbg_fsm_cs) DBG_IDLE: begin - if(trap_hit_i == 1'b1 && stall_ex_o == 1'b0 && jump_in_id_o == 2'b0) + // branches take two cycles, jumps just one + // everything else can be done immediately + // TODO: there is a bug here, I'm sure of it + if(trap_hit_i == 1'b1 && stall_ex_o == 1'b0 && jump_in_id_o == 2'b0 && jump_in_ex_i == 2'b0) begin dbg_halt = 1'b1; dbg_fsm_ns = DBG_EX; diff --git a/cs_registers.sv b/cs_registers.sv index a6541a81..2ef2da06 100644 --- a/cs_registers.sv +++ b/cs_registers.sv @@ -58,11 +58,7 @@ module cs_registers output logic [31:0] hwlp_end_o, output logic [31:0] hwlp_counter_o, output logic [1:0] hwlp_regid_o, - output logic [2:0] hwlp_we_o, - - // Signals for NPC register - output logic [31:0] npc_o, // TODO: check if needed - output logic set_npc_o // TODO: check if needed + output logic [2:0] hwlp_we_o ); @@ -106,6 +102,11 @@ module cs_registers 12'hF01: constant_rdata_int = 32'h00_00_80_00; // mimpid: PULP3, anonymous source (no allocated ID) 12'hF10: constant_rdata_int = {22'b0, cluster_id_i, core_id_i}; // mhartid: unique hardware thread id + // debug registers + 12'hFC0: constant_rdata_int = curr_pc_id_i; // Previous Program Counter for Debug + + 12'h780: constant_rdata_int = curr_pc_if_i; // Next Program Counter for Debug + default: is_constant = 1'b0; endcase end diff --git a/debug_unit.sv b/debug_unit.sv index 12423e3b..ab832afd 100644 --- a/debug_unit.sv +++ b/debug_unit.sv @@ -57,25 +57,25 @@ module debug_unit output logic sp_mux_o, output logic regfile_mux_o, output logic regfile_we_o, - output logic [15:0] regfile_addr_o, + output logic [11:0] regfile_addr_o, output logic [31:0] regfile_wdata_o, - input logic [31:0] regfile_rdata_i + input logic [31:0] regfile_rdata_i, + + // Signals for NPC register + output logic [31:0] npc_o, + output logic set_npc_o ); // registers for debug control logic [1:0] DSR_DP, DSR_DN; // Debug Stop Register: IIE, INTE logic [1:0] DMR1_DP, DMR1_DN; // only single step trace and branch trace bits - logic [2*`N_WP-1:0] DMR2_DP, DMR2_DN; // only BP enable control and BP cause status - - // watchpoint status - logic [`N_WP-1:0] WP_Status_D; // BP control FSM enum logic [2:0] {Idle, Trap, DebugStall, StallCore} BP_State_SN, BP_State_SP; // ack to debug interface - assign dbginf_ack_o = (dbginf_strobe_i && (BP_State_SP == StallCore)); + assign dbginf_ack_o = dbginf_strobe_i && ((BP_State_SP == StallCore) || (dbginf_addr_i[15:11] == 5'b00110)); always_comb begin @@ -83,38 +83,32 @@ module debug_unit stall_core_o = 1'b0; dbginf_bp_o = 1'b0; flush_pipe_o = 1'b0; + case (BP_State_SP) Idle: begin if(trap_i == 1'b1) - BP_State_SN = Trap; - - if(dbginf_stall_i) + begin + dbginf_bp_o = 1'b1; + stall_core_o = 1'b1; + BP_State_SN = StallCore; + end + else if(dbginf_stall_i) begin flush_pipe_o = 1'b1; - BP_State_SN = DebugStall; + BP_State_SN = DebugStall; end end - // A trap was encountered, wait for for the pipeline to be - // flushed - Trap: - begin - if(pipe_flushed_i == 1'b1) - begin - dbginf_bp_o = 1'b1; - BP_State_SN = StallCore; - end - end - - // A stall from adv dbg was seen, flush the pipeline and wait for unstalling + // A stall from adv dbg unit was seen, flush the pipeline and wait for unstalling DebugStall: begin flush_pipe_o = 1'b1; - if(pipe_flushed_i == 1'b1) + if(trap_i == 1'b1) begin - BP_State_SN = StallCore; + stall_core_o = 1'b1; + BP_State_SN = StallCore; end end @@ -137,15 +131,19 @@ module debug_unit assign dbg_st_en_o = DMR1_DP[0]; assign dbg_dsr_o = DSR_DP; + // handle set next program counter + assign set_npc_o = (regfile_addr_o == 12'h780) && (sp_mux_o == 1'b1) && (regfile_we_o == 1'b1); + assign npc_o = dbginf_data_i; + + // address decoding, write and read controller always_comb begin DMR1_DN = DMR1_DP; - DMR2_DN[`N_WP-1:0] = DMR2_DP[`N_WP-1:0]; DSR_DN = DSR_DP; dbginf_data_o = 32'b0; regfile_we_o = 1'b0; - regfile_addr_o = 16'b0; + regfile_addr_o = 'h0; regfile_mux_o = 1'b0; sp_mux_o = 1'b0; @@ -160,13 +158,6 @@ module debug_unit else dbginf_data_o[`DMR1_ST+1:`DMR1_ST] = DMR1_DP; end - 11'd17: begin // SP_DMR2 - if(dbginf_we_i == 1'b1) - DMR2_DN[`N_WP-1:0] = dbginf_data_i[`DMR2_WGB0 + (`N_WP-1):`DMR2_WGB0]; - else - dbginf_data_o[`DMR2_WGB0 + (`N_WP-1):`DMR2_WGB0] = DMR2_DP[`N_WP-1:0]; - dbginf_data_o[`DMR2_WBS0 + (`N_WP-1):`DMR2_WBS0] = DMR2_DP[2*`N_WP-1:`N_WP]; - end 11'd20: begin // SP_DSR // currently we only handle IIE and INTE if(dbginf_we_i == 1'b1) @@ -177,27 +168,31 @@ module debug_unit default: ; endcase // casex [10:0] end - // check if GPRs are accessed - else if(dbginf_addr_i[15:10] == 6'b000001) + // check if internal registers (GPR or SPR) are accessed + else if(BP_State_SP == StallCore) begin - regfile_mux_o = 1'b1; - regfile_addr_o[4:0] = dbginf_addr_i[4:0]; + // check if GPRs are accessed + if(dbginf_addr_i[15:10] == 6'b000001) + begin + regfile_mux_o = 1'b1; + regfile_addr_o[4:0] = dbginf_addr_i[4:0]; - if(dbginf_we_i == 1'b1) - regfile_we_o = 1'b1; + if(dbginf_we_i == 1'b1) + regfile_we_o = 1'b1; + else + dbginf_data_o = regfile_rdata_i; + end + // some other SPR is accessed else - dbginf_data_o = regfile_rdata_i; - end - // some other SPR is accessed - else - begin - sp_mux_o = 1'b1; - regfile_addr_o = dbginf_addr_i; + begin + sp_mux_o = 1'b1; + regfile_addr_o = dbginf_addr_i[11:0]; - if(dbginf_we_i == 1'b1) - regfile_we_o = 1'b1; - else - dbginf_data_o = regfile_rdata_i; + if(dbginf_we_i == 1'b1) + regfile_we_o = 1'b1; + else + dbginf_data_o = regfile_rdata_i; + end end end end @@ -206,13 +201,11 @@ module debug_unit always_ff@(posedge clk or negedge rst_n) begin if (~rst_n) begin DMR1_DP <= 2'b0; - DMR2_DP <= 'b0; DSR_DP <= 'b0; BP_State_SP <= Idle; end else begin DMR1_DP <= DMR1_DN; - DMR2_DP <= DMR2_DN; DSR_DP <= DSR_DN; BP_State_SP <= BP_State_SN; end diff --git a/riscv_core.sv b/riscv_core.sv index d29ed1c5..b30bc7b0 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -236,12 +236,6 @@ module riscv_core `endif - // TODO: Temporary assignments while not everything from OR10N is implemented (e.g. debug unit) - assign dbg_dsr = 2'b0; - assign dbg_st_en = 1'b0; - assign dbg_sp_mux = 1'b0; - assign dbg_flush_pipe = 1'b0; - ////////////////////////////////////////////////// // ___ _____ ____ _____ _ ____ _____ // @@ -646,10 +640,7 @@ module riscv_core .save_pc_if_i ( save_pc_if ), .save_pc_id_i ( save_pc_id ), .epcr_o ( epcr ), - .irq_enable_o ( irq_enable ), - - .npc_o ( dbg_npc ), // PC from debug unit - .set_npc_o ( dbg_set_npc ) // set PC to new value + .irq_enable_o ( irq_enable ) ); // Mux for SPR access through Debug Unit @@ -747,6 +738,7 @@ module riscv_core assign hwlp_cnt_data = (hwlp_we_ex[2] == 1'b1) ? hwlp_cnt_data_ex : sp_hwlp_cnt; assign hwlp_regid = (|hwlp_we_ex) ? hwlp_regid_ex : sp_hwlp_regid; assign hwlp_we = hwlp_we_ex | sp_hwlp_we; + */ ///////////////////////////////////////////////////////////// @@ -786,13 +778,12 @@ module riscv_core .regfile_we_o ( dbg_reg_we ), .regfile_addr_o ( dbg_reg_addr ), .regfile_wdata_o ( dbg_reg_wdata ), - .regfile_rdata_i ( dbg_rdata ) + .regfile_rdata_i ( dbg_rdata ), + + .npc_o ( dbg_npc ), // PC from debug unit + .set_npc_o ( dbg_set_npc ) // set PC to new value ); - */ - - assign dbg_reg_mux = 0; - assign dbg_stall = 0; // Execution trace generation