Some fixes to debug

This commit is contained in:
Andreas Traber 2016-04-21 15:59:10 +02:00
parent 57b77ba394
commit 1284e315ec
6 changed files with 68 additions and 42 deletions

View file

@ -115,8 +115,9 @@ module riscv_controller
output logic jr_stall_o,
output logic load_stall_o,
input logic id_ready_i, // ID stage is ready
input logic if_valid_i, // IF stage is done
input logic id_valid_i, // ID stage is done
input logic ex_valid_i, // EX stage is done
input logic wb_valid_i, // WB stage is done
@ -219,7 +220,7 @@ module riscv_controller
FIRST_FETCH:
begin
// Stall because of IF miss
if ((id_valid_i == 1'b1) && (dbg_stall_i == 1'b0))
if ((id_ready_i == 1'b1) && (dbg_stall_i == 1'b0))
begin
ctrl_fsm_ns = DECODE;
end
@ -310,7 +311,7 @@ module riscv_controller
// make sure the current instruction has been executed
// before changing state to non-decode
if (id_valid_i) begin
if (id_ready_i) begin
if (jump_in_id_i == `BRANCH_COND)
ctrl_fsm_ns = DBG_WAIT_BRANCH;
else
@ -402,7 +403,7 @@ module riscv_controller
// unstall pipeline and continue operation
halt_if_o = 1'b0;
if (id_valid_i)
if (id_ready_i)
ctrl_fsm_ns = DECODE;
end
end
@ -515,7 +516,7 @@ module riscv_controller
ctrl_fsm_cs <= ctrl_fsm_ns;
// clear when id is valid (no instruction incoming)
jump_done_q <= jump_done & (~id_valid_i);
jump_done_q <= jump_done & (~id_ready_i);
end
end

View file

@ -41,8 +41,9 @@ module riscv_debug_unit
// signals to core
output logic [`DBG_SETS_W-1:0] settings_o,
input logic trap_i, // trap found, need to stop the core now
output logic stall_o, // after we got control, we control the stall signal
input logic trap_i, // trap found, need to stop the core now
input logic [5:0] exc_cause_i, // if it was a trap, then the exception controller knows more
output logic stall_o, // after we got control, we control the stall signal
output logic dbg_req_o,
input logic dbg_ack_i,
@ -96,6 +97,8 @@ module riscv_debug_unit
logic [31:0] dbg_rdata;
logic dbg_resume;
logic dbg_halt;
logic [5:0] dbg_cause_q, dbg_cause_n;
logic dbg_ssth_q, dbg_ssth_n;
// ppc/npc tracking
@ -150,19 +153,19 @@ module riscv_debug_unit
unique case (debug_addr_i[6:2])
5'b0_0000: begin // DBG_CTRL
// RESUME takes precedence over HALT
if (debug_wdata_i[31]) begin
// RESUME set
if (debug_halted_o) begin
dbg_resume = 1'b1;
end
end else if (debug_wdata_i[16]) begin
if (debug_wdata_i[16]) begin
// HALT set
if (~debug_halted_o) begin
// not halt, so STOP
dbg_halt = 1'b1;
end
end else begin
// RESUME set
if (debug_halted_o) begin
dbg_resume = 1'b1;
end
end
settings_n[`DBG_SETS_SSTE] = debug_wdata_i[0];
end
5'b0_0001: begin // DBG_HIT
@ -185,7 +188,7 @@ module riscv_debug_unit
if (debug_halted_o) begin
unique case (debug_addr_i[6:2])
5'b0_0001: jump_req_n = 1'b1; // DNPC
5'b0_0000: jump_req_n = 1'b1; // DNPC
default:;
endcase
end
@ -261,8 +264,8 @@ module riscv_debug_unit
case (rdata_sel_q)
RD_DBGA: begin
unique case (addr_q[6:2])
5'h00: dbg_rdata[31:0] = {31'b0, settings_q[`DBG_SETS_SSTE]}; // DBG_CTRL
5'h01: dbg_rdata[31:0] = {15'b0, debug_halted_o, 16'b0}; // DBG_HIT, TODO: SSTH is missing
5'h00: dbg_rdata[31:0] = {15'b0, debug_halted_o, 15'b0, settings_q[`DBG_SETS_SSTE]}; // DBG_CTRL
5'h01: dbg_rdata[31:0] = {31'b0, dbg_ssth_q}; // DBG_HIT
5'h02: begin // DBG_IE
dbg_rdata[31:16] = '0;
dbg_rdata[15:12] = '0;
@ -276,7 +279,7 @@ module riscv_debug_unit
dbg_rdata[ 2] = settings_q[`DBG_SETS_EILL];
dbg_rdata[ 1: 0] = '0;
end
5'h03: dbg_rdata = '1; // DBG_CAUSE. TODO: maybe take from exc controller directly?
5'h03: dbg_rdata = {dbg_cause_q[5], 26'b0, dbg_cause_q[4:0]}; // DBG_CAUSE
5'h10: dbg_rdata = '0; // DBG_BPCTRL0
5'h12: dbg_rdata = '0; // DBG_BPCTRL1
5'h14: dbg_rdata = '0; // DBG_BPCTRL2
@ -337,17 +340,32 @@ module riscv_debug_unit
dbg_req_o = 1'b0;
stall_o = 1'b0;
debug_halted_o = 1'b0;
dbg_cause_n = dbg_cause_q;
dbg_ssth_n = dbg_ssth_q;
case (stall_cs)
RUNNING: begin
if (dbg_halt)
stall_ns = HALT_REQ;
dbg_ssth_n = 1'b0;
if (dbg_halt | trap_i) begin
dbg_req_o = 1'b1;
stall_ns = HALT_REQ;
if (trap_i) begin
if (settings_q[`DBG_SETS_SSTE])
dbg_ssth_n = 1'b1;
dbg_cause_n = exc_cause_i;
end else begin
dbg_cause_n = `DBG_CAUSE_HALT;
end
end
end
HALT_REQ: begin
dbg_req_o = 1'b1;
if (dbg_ack_i) // TODO: check if we need to set stall already
if (dbg_ack_i)
stall_ns = HALT;
if (dbg_resume)
@ -363,19 +381,18 @@ module riscv_debug_unit
end
endcase
// if a trap is found, halt immediately
if (trap_i) begin
dbg_req_o = 1'b1;
stall_ns = HALT;
end
end
always_ff @(posedge clk, negedge rst_n)
begin
if (~rst_n) begin
stall_cs <= RUNNING;
stall_cs <= RUNNING;
dbg_cause_q <= `DBG_CAUSE_HALT;
dbg_ssth_q <= 1'b0;
end else begin
stall_cs <= stall_ns;
stall_cs <= stall_ns;
dbg_cause_q <= dbg_cause_n;
dbg_ssth_q <= dbg_ssth_n;
end
end

View file

@ -87,11 +87,11 @@ module riscv_exc_controller
| (irq_enable_i & (|irq_i) & dbg_settings_i[`DBG_SETS_IRQ]);
// request for exception/interrupt
assign req_int = (ecall_insn_i & (~dbg_settings_i[`DBG_SETS_ECALL]))
| (lsu_load_err_i & (~dbg_settings_i[`DBG_SETS_ELSU]))
| (lsu_store_err_i & (~dbg_settings_i[`DBG_SETS_ELSU]))
| (illegal_insn_i & (~dbg_settings_i[`DBG_SETS_EILL]))
| (irq_enable_i & (|irq_i) & (~dbg_settings_i[`DBG_SETS_IRQ]));
assign req_int = ecall_insn_i
| lsu_load_err_i
| lsu_store_err_i
| illegal_insn_i
| (irq_enable_i & (|irq_i));
// Exception cause and ISR address selection
@ -100,7 +100,7 @@ module riscv_exc_controller
cause_int = 6'b0;
pc_mux_int = 'x;
if (irq_enable_i & (~dbg_settings_i[`DBG_SETS_IRQ])) begin
if (irq_enable_i) begin
// pc_mux_int is a critical signal, so try to get it as soon as possible
if (|irq_i)
pc_mux_int = `EXC_PC_IRQ;
@ -114,22 +114,26 @@ module riscv_exc_controller
end
end
if (ecall_insn_i & (~dbg_settings_i[`DBG_SETS_ECALL])) begin
cause_int = 6'b0_01000;
if (ebrk_insn_i) begin
cause_int = 6'b0_00011;
end
if (ecall_insn_i) begin
cause_int = 6'b0_01011;
pc_mux_int = `EXC_PC_ECALL;
end
if (illegal_insn_i & (~dbg_settings_i[`DBG_SETS_EILL])) begin
if (illegal_insn_i) begin
cause_int = 6'b0_00010;
pc_mux_int = `EXC_PC_ILLINSN;
end
if (lsu_load_err_i & (~dbg_settings_i[`DBG_SETS_ELSU])) begin
if (lsu_load_err_i) begin
cause_int = 6'b0_00101;
pc_mux_int = `EXC_PC_LOAD;
end
if (lsu_store_err_i & (~dbg_settings_i[`DBG_SETS_ELSU])) begin
if (lsu_store_err_i) begin
cause_int = 6'b0_00111;
pc_mux_int = `EXC_PC_STORE;
end
@ -149,7 +153,7 @@ module riscv_exc_controller
// Exception cause and mux output (with bypass)
assign cause_o = (exc_ctrl_cs == IDLE && req_int) ? cause_int : cause_int_q;
assign cause_o = ((exc_ctrl_cs == IDLE && req_int) || ebrk_insn_i) ? cause_int : cause_int_q;
assign pc_mux_o = (exc_ctrl_cs == IDLE && req_int) ? pc_mux_int : pc_mux_int_q;
// for vectorized IRQ PC mux

View file

@ -895,8 +895,9 @@ module riscv_id_stage
.jr_stall_o ( jr_stall ),
.load_stall_o ( load_stall ),
.id_ready_i ( id_ready_o ),
.if_valid_i ( if_valid_i ),
.id_valid_i ( id_valid_o ),
.ex_valid_i ( ex_valid_i ),
.wb_valid_i ( wb_valid_i ),

View file

@ -327,5 +327,7 @@
`define DBG_SETS_EBRK 1
`define DBG_SETS_SSTE 0
`define DBG_CAUSE_HALT 6'h1F
`endif

View file

@ -754,10 +754,11 @@ module riscv_core
// 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 ),
.trap_i ( dbg_trap ),
// register file read port
.regfile_rreq_o ( dbg_reg_rreq ),