The thread http://opencores.org/forum,OpenRISC,0,5005 about GDB failing to single-step after certain breakpoints led us to a logic error in the debug unit. When the pipeline is stalled for other reasons, for instance an instruction fetch (therefore affected by instruction cache), at the cycle _after_ a trap instruction is decoded, the trap signal is never lowered since no new instruction is decoded. This locks the debug unit into stalling continuously.
Attached is a workaround to make the debug unit aware that the sig_trap and sig_syscall signals only update when the ex stage is not stalled. This fixes the issue we've observed, although similar conditions may exist for any other exceptions. Also note that the debug interface uses a priority encoder to only catch one of the events that occur; short-lived events may therefore be ignored completely. Any comments? Personally I feel it's a bit of a stopgap measure, addressing this problem narrowly, but it's better than the current state.
Index: or1200_du.v =================================================================== --- or1200_du.v (revision 663) +++ or1200_du.v (working copy) @@ -412,6 +412,7 @@ wire dwcr0_sel, dwcr1_sel; // DWCR selects reg dbg_bp_r; +reg ex_freeze_q; `ifdef OR1200_DU_HWBKPTS reg [31:0] match_cond0_ct; reg [31:0] match_cond1_ct; @@ -529,12 +530,16 @@ assign dwcr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_DWCR1)); `endif +// Track previous ex_freeze to detect when signals are updated +always @(posedge clk) + ex_freeze_q <= ex_freeze; + // // Decode started exception // // du_except_stop comes from or1200_except // -always @(du_except_stop) begin +always @(du_except_stop or ex_freeze_q) begin except_stop = 14'b00_0000_0000_0000; casez (du_except_stop) 14'b1?_????_????_????: @@ -566,16 +571,16 @@ except_stop[`OR1200_DU_DRR_RE] = 1'b1; end 14'b00_0000_0000_01??: begin - except_stop[`OR1200_DU_DRR_TE] = 1'b1; + except_stop[`OR1200_DU_DRR_TE] = 1'b1 & ~ex_freeze_q; end 14'b00_0000_0000_001?: begin except_stop[`OR1200_DU_DRR_FPE] = 1'b1; end 14'b00_0000_0000_0001: - except_stop[`OR1200_DU_DRR_SCE] = 1'b1; + except_stop[`OR1200_DU_DRR_SCE] = 1'b1 & ~ex_freeze_q; default: except_stop = 14'b00_0000_0000_0000; - endcase + endcase // casez (du_except_stop) end //
_______________________________________________ OpenRISC mailing list [email protected] http://lists.openrisc.net/listinfo/openrisc
