diff --git a/rtl/core/exception.sv b/rtl/core/exception.sv index 0f85423..62fad1f 100644 --- a/rtl/core/exception.sv +++ b/rtl/core/exception.sv @@ -27,6 +27,10 @@ `define MIE_MEIE_BIT 11 `define MIE_MSIE_BIT 3 +`define DCSR_CAUSE_NONE 3'h0 +`define DCSR_CAUSE_STEP 3'h4 +`define DCSR_CAUSE_DBGREQ 3'h3 +`define DCSR_CAUSE_EBREAK 3'h1 module exception ( @@ -82,13 +86,14 @@ module exception ( localparam FAST_INT_OFFSET = 44; - localparam S_IDLE = 3'b001; - localparam S_W_MEPC = 3'b010; - localparam S_ASSERT = 3'b100; + localparam S_IDLE = 4'b0001; + localparam S_W_MEPC = 4'b0010; + localparam S_W_DCSR = 4'b0100; + localparam S_ASSERT = 4'b1000; reg debug_mode_d, debug_mode_q; - reg[2:0] state_d, state_q; + reg[3:0] state_d, state_q; reg[31:0] assert_addr_d, assert_addr_q; reg[31:0] return_addr_d, return_addr_q; reg csr_we; @@ -179,9 +184,32 @@ module exception ( assign int_or_exception_cause = exception_req ? exception_cause : interrupt_cause; assign int_or_exception_offset = exception_req ? exception_offset : interrupt_offset; - wire debug_mode_req = ((~debug_mode_q) & debug_req_i & inst_valid_i) | - (inst_ebreak_i & dcsr_i[15]) | - (inst_ebreak_i & debug_mode_q); + reg enter_debug_cause_debugger_req; + reg enter_debug_cause_single_step; + reg enter_debug_cause_ebreak; + reg[2:0] dcsr_cause_d, dcsr_cause_q; + + always @ (*) begin + enter_debug_cause_debugger_req = 1'b0; + enter_debug_cause_single_step = 1'b0; + enter_debug_cause_ebreak = 1'b0; + dcsr_cause_d = `DCSR_CAUSE_NONE; + + if (inst_ebreak_i & debug_mode_q) begin + enter_debug_cause_ebreak = 1'b1; + dcsr_cause_d = `DCSR_CAUSE_EBREAK; + end else if ((~debug_mode_q) & debug_req_i & inst_valid_i) begin + enter_debug_cause_debugger_req = 1'b1; + dcsr_cause_d = `DCSR_CAUSE_DBGREQ; + end else if (inst_ebreak_i & dcsr_i[15]) begin + enter_debug_cause_single_step = 1'b1; + dcsr_cause_d = `DCSR_CAUSE_STEP; + end + end + + wire debug_mode_req = enter_debug_cause_debugger_req | + enter_debug_cause_single_step | + enter_debug_cause_ebreak; assign stall_flag_o = ((state_q != S_IDLE) & (state_q != S_ASSERT)) | (interrupt_req & global_int_en) | exception_req | @@ -209,13 +237,13 @@ module exception ( state_d = S_W_MEPC; end else if (debug_mode_req) begin debug_mode_d = 1'b1; - if (!inst_ebreak_i) begin + if (enter_debug_cause_debugger_req) begin csr_we = 1'b1; csr_waddr = {20'h0, `CSR_DPC}; csr_wdata = inst_addr_i; end assert_addr_d = debug_halt_addr_i; - state_d = S_ASSERT; + state_d = S_W_DCSR; end else if (inst_mret_i) begin assert_addr_d = mepc_i; state_d = S_ASSERT; @@ -233,6 +261,13 @@ module exception ( state_d = S_ASSERT; end + S_W_DCSR: begin + csr_we = 1'b1; + csr_waddr = {20'h0, `CSR_DCSR}; + csr_wdata = {dcsr_i[31:9], dcsr_cause_q, dcsr_i[5:0]}; + state_d = S_ASSERT; + end + S_ASSERT: begin csr_we = 1'b0; state_d = S_IDLE; @@ -256,11 +291,13 @@ module exception ( assert_addr_q <= 32'h0; debug_mode_q <= 1'b0; return_addr_q <= 32'h0; + dcsr_cause_q <= `DCSR_CAUSE_NONE; end else begin state_q <= state_d; assert_addr_q <= assert_addr_d; debug_mode_q <= debug_mode_d; return_addr_q <= return_addr_d; + dcsr_cause_q <= dcsr_cause_d; end end diff --git a/rtl/debug/jtag_def.sv b/rtl/debug/jtag_def.sv index 5828dbe..a558df6 100644 --- a/rtl/debug/jtag_def.sv +++ b/rtl/debug/jtag_def.sv @@ -68,6 +68,8 @@ `define SBData1 6'h3D `define SBData2 6'h3E `define SBData3 6'h3F +`define HaltSum0 6'h40 +`define HaltSum1 6'h13 // dmstatus bit index `define Impebreak 22 diff --git a/rtl/debug/jtag_dm.sv b/rtl/debug/jtag_dm.sv index 9780dd1..682631f 100644 --- a/rtl/debug/jtag_dm.sv +++ b/rtl/debug/jtag_dm.sv @@ -252,6 +252,8 @@ module jtag_dm #( cmderr_d = CmdErrorBusy; end end + `HaltSum0: dm_resp_data_d = {31'h0, halted}; + `HaltSum1: dm_resp_data_d = {31'h0, halted}; default: dm_resp_data_d = 32'h0; endcase // write @@ -479,7 +481,7 @@ module jtag_dm #( .resumereq_i(resumereq), .haltreq_i(debug_req_o), - .progbuf_i(), + .progbuf_i(progbuf_q), .data_i(data0_q), .data_o(data0), .data_valid_o(data_valid), diff --git a/sim/jtag_compliance_test.cfg b/sim/jtag_compliance_test.cfg index 9b7b5f6..5512cad 100644 --- a/sim/jtag_compliance_test.cfg +++ b/sim/jtag_compliance_test.cfg @@ -14,7 +14,7 @@ foreach t [jtag names] { } set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME riscv -chain-position $_TARGETNAME +target create $_TARGETNAME riscv -chain-position $_TARGETNAME -rtos riscv riscv set_reset_timeout_sec 2000 riscv set_command_timeout_sec 2000