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

Reply via email to