Index: or1200_cpu.v
===================================================================
--- or1200_cpu.v	(révision 850)
+++ or1200_cpu.v	(copie de travail)
@@ -66,7 +66,7 @@
 	id_void, id_insn, ex_void, 
 	ex_insn, ex_freeze, wb_insn, wb_freeze, id_pc, ex_pc, wb_pc, branch_op,
 	spr_dat_npc, rf_dataw, ex_flushpipe, 
-	du_stall, du_addr, du_dat_du, du_read, du_write, du_except_stop, 
+	du_stall, du_addr, du_dat_du, du_read, du_write, du_except_stop, du_flush_pipe,
 	du_except_trig, du_dsr, du_dmr1, du_hwbkpt, du_hwbkpt_ls_r, du_dat_cpu,
 	du_lsu_store_dat, du_lsu_load_dat, 
 	abort_mvspr, abort_ex,
@@ -153,6 +153,7 @@
 output	[dw-1:0]		rf_dataw;
 output	[dw-1:0]		du_lsu_store_dat;
 output	[dw-1:0]		du_lsu_load_dat;
+input				du_flush_pipe;
 
 //
 // Data (DC) interface
@@ -442,7 +443,9 @@
 	.genpc_refetch(genpc_refetch),
 	.genpc_freeze(genpc_freeze),
 	.no_more_dslot(no_more_dslot),
-	.lsu_stall(lsu_stall)
+	.lsu_stall(lsu_stall),
+	.du_flush_pipe(du_flush_pipe),
+	.spr_dat_npc(spr_dat_npc)
 );
 
 //
@@ -534,7 +537,8 @@
 	.rfe(rfe),
 	.du_hwbkpt(du_hwbkpt),
 	.except_illegal(except_illegal),
-	.dc_no_writethrough(dc_no_writethrough)
+	.dc_no_writethrough(dc_no_writethrough),
+	.du_flush_pipe(du_flush_pipe)
 );
 
 //
Index: or1200_ctrl.v
===================================================================
--- or1200_ctrl.v	(révision 850)
+++ or1200_ctrl.v	(copie de travail)
@@ -69,7 +69,7 @@
    cust5_op, cust5_limm, id_pc, ex_pc, du_hwbkpt, 
    multicycle, wait_on, wbforw_valid, sig_syscall, sig_trap,
    force_dslot_fetch, no_more_dslot, id_void, ex_void, ex_spr_read, 
-   ex_spr_write, 
+   ex_spr_write, du_flush_pipe,
    id_mac_op, id_macrc_op, ex_macrc_op, rfe, except_illegal, dc_no_writethrough
    );
 
@@ -136,8 +136,8 @@
 output					rfe;
 output					except_illegal;
 output  				dc_no_writethrough;
-   
-				
+input					du_flush_pipe;
+
 //
 // Internal wires and regs
 //
@@ -244,10 +244,10 @@
 //
 // Flush pipeline
 //
-assign if_flushpipe = except_flushpipe | pc_we | extend_flush;
-assign id_flushpipe = except_flushpipe | pc_we | extend_flush;
-assign ex_flushpipe = except_flushpipe | pc_we | extend_flush;
-assign wb_flushpipe = except_flushpipe | pc_we | extend_flush;
+assign if_flushpipe = except_flushpipe | pc_we | extend_flush | du_flush_pipe;
+assign id_flushpipe = except_flushpipe | pc_we | extend_flush | du_flush_pipe;
+assign ex_flushpipe = except_flushpipe | pc_we | extend_flush | du_flush_pipe;
+assign wb_flushpipe = except_flushpipe | pc_we | extend_flush | du_flush_pipe;
 
 //
 // EX Sign/Zero extension of immediates
Index: or1200_du.v
===================================================================
--- or1200_du.v	(révision 850)
+++ or1200_du.v	(copie de travail)
@@ -64,7 +64,7 @@
 	ex_freeze, branch_op, ex_insn, id_pc,
 	spr_dat_npc, rf_dataw,
 	du_dsr, du_dmr1, du_stall, du_addr, du_dat_i, du_dat_o,
-	du_read, du_write, du_except_stop, du_hwbkpt,
+	du_read, du_write, du_except_stop, du_hwbkpt, du_flush_pipe,
 	spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
 
 	// External Debug Interface
@@ -106,6 +106,7 @@
 output				du_write;	// Debug Unit Write Enable
 input	[13:0]			du_except_stop;	// Exception masked by DSR
 output				du_hwbkpt;	// Cause trap exception (HW Breakpoints)
+output				du_flush_pipe;	// Cause pipeline flush and pc<-npc
 input				spr_cs;		// SPR Chip Select
 input				spr_write;	// SPR Read/Write
 input	[aw-1:0]		spr_addr;	// SPR Address
@@ -164,6 +165,27 @@
 assign du_read = dbg_stb_i && !dbg_we_i;
 assign du_write = dbg_stb_i && dbg_we_i;
 
+//
+// After a sw breakpoint, the replaced instruction need to be executed.
+// We flush the entire pipeline and set the pc to the current address
+// to execute the restored address.
+//
+assign du_flush_pipe = (dbg_stall_i_r && !dbg_stall_i && |du_except_stop);
+
+reg dbg_stall_i_r;
+
+//
+// Detect dbg_stall falling edge
+//
+always @(posedge clk or `OR1200_RST_EVENT rst) begin
+	if (rst == `OR1200_RST_VALUE) begin
+		dbg_stall_i_r   <=  1'b0;
+	end
+	else begin
+		dbg_stall_i_r   <=  dbg_stall_i;
+	end
+end
+
 reg				dbg_ack;
 //
 // Generate acknowledge -- just delay stb signal
Index: or1200_genpc.v
===================================================================
--- or1200_genpc.v	(révision 850)
+++ or1200_genpc.v	(copie de travail)
@@ -64,7 +64,7 @@
 	id_branch_addrtarget, ex_branch_addrtarget, muxed_b, operand_b, 
 	flag, flagforw, ex_branch_taken, except_start,
 	epcr, spr_dat_i, spr_pc_we, genpc_refetch,
-	genpc_freeze, no_more_dslot, lsu_stall
+	genpc_freeze, no_more_dslot, lsu_stall, du_flush_pipe, spr_dat_npc
 );
 
 //
@@ -105,10 +105,12 @@
 input	[31:0]			epcr;
 input	[31:0]			spr_dat_i;
 input				spr_pc_we;
+input [31:0] 			spr_dat_npc;
 input				genpc_refetch;
 input				genpc_freeze;
 input				no_more_dslot;
 input				lsu_stall;
+input				du_flush_pipe;
 
 parameter boot_adr = `OR1200_BOOT_ADR;
 //
@@ -126,7 +128,7 @@
    //
    // Address of insn to be fecthed
    //
-   assign icpu_adr_o = !no_more_dslot & !except_start & !spr_pc_we 
+   assign icpu_adr_o = !no_more_dslot & !except_start & !spr_pc_we & !du_flush_pipe
 		       & (icpu_rty_i | genpc_refetch) ? 
 		       icpu_adr_i : {pc[31:2], 1'b0, ex_branch_taken|spr_pc_we};
 
@@ -165,14 +167,14 @@
    //
    always @(pcreg or ex_branch_addrtarget or flag or branch_op or except_type
 	    or except_start or operand_b or epcr or spr_pc_we or spr_dat_i or 
-	    except_prefix) 
+	    except_prefix or du_flush_pipe) 
      begin
-	casez ({spr_pc_we, except_start, branch_op}) // synopsys parallel_case
-	  {2'b00, `OR1200_BRANCHOP_NOP}: begin
+	casez ({du_flush_pipe, spr_pc_we, except_start, branch_op}) // synopsys parallel_case
+	  {3'b000, `OR1200_BRANCHOP_NOP}: begin
 	     pc = {pcreg + 30'd1, 2'b0};
 	     ex_branch_taken = 1'b0;
 	  end
-	  {2'b00, `OR1200_BRANCHOP_J}: begin
+	  {3'b000, `OR1200_BRANCHOP_J}: begin
 `ifdef OR1200_VERBOSE
 	     // synopsys translate_off
 	     $display("%t: BRANCHOP_J: pc <= ex_branch_addrtarget %h"
@@ -182,7 +184,7 @@
 	     pc = {ex_branch_addrtarget, 2'b00};
 	     ex_branch_taken = 1'b1;
 	  end
-	  {2'b00, `OR1200_BRANCHOP_JR}: begin
+	  {3'b000, `OR1200_BRANCHOP_JR}: begin
 `ifdef OR1200_VERBOSE
 	     // synopsys translate_off
 	     $display("%t: BRANCHOP_JR: pc <= operand_b %h", 
@@ -192,7 +194,7 @@
 	     pc = operand_b;
 	     ex_branch_taken = 1'b1;
 	  end
-	  {2'b00, `OR1200_BRANCHOP_BF}:
+	  {3'b000, `OR1200_BRANCHOP_BF}:
 	    if (flag) begin
 `ifdef OR1200_VERBOSE
 	       // synopsys translate_off
@@ -212,7 +214,7 @@
 	       pc = {pcreg + 30'd1, 2'b0};
 	       ex_branch_taken = 1'b0;
 	    end
-	  {2'b00, `OR1200_BRANCHOP_BNF}:
+	  {3'b000, `OR1200_BRANCHOP_BNF}:
 	    if (flag) begin
 `ifdef OR1200_VERBOSE
 	       // synopsys translate_off
@@ -232,7 +234,7 @@
 	       pc = {ex_branch_addrtarget, 2'b00};
 	       ex_branch_taken = 1'b1;
 	    end
-	  {2'b00, `OR1200_BRANCHOP_RFE}: begin
+	  {3'b000, `OR1200_BRANCHOP_RFE}: begin
 `ifdef OR1200_VERBOSE
 	     // synopsys translate_off
 	     $display("%t: BRANCHOP_RFE: pc <= epcr %h", 
@@ -242,9 +244,18 @@
 	     pc = epcr;
 	     ex_branch_taken = 1'b1;
 	  end
-	  {2'b01, 3'b???}: begin
+	  {3'b100, 3'b???}: begin
 `ifdef OR1200_VERBOSE
 	     // synopsys translate_off
+	     $display("Reload breaked ins at : %h.", spr_dat_npc);
+	     // synopsys translate_on
+`endif
+	     pc = spr_dat_npc;
+	     ex_branch_taken = 1'b1;
+	  end
+	  {3'b001, 3'b???}: begin
+`ifdef OR1200_VERBOSE
+	     // synopsys translate_off
 	     $display("Starting exception: %h.", except_type);
 	     // synopsys translate_on
 `endif
@@ -284,7 +295,7 @@
      else if (spr_pc_we) begin
 	pcreg_default <=  spr_dat_i[31:2];
      end
-     else if (no_more_dslot | except_start | !genpc_freeze & !icpu_rty_i 
+     else if (du_flush_pipe | no_more_dslot | except_start | !genpc_freeze & !icpu_rty_i 
 	      & !genpc_refetch) begin
 	pcreg_default <=  pc[31:2];
      end
Index: or1200_top.v
===================================================================
--- or1200_top.v	(révision 850)
+++ or1200_top.v	(copie de travail)
@@ -665,6 +665,7 @@
 	.du_lsu_load_dat(du_lsu_load_dat),
 	.abort_mvspr(abort_mvspr),
 	.abort_ex(abort_ex),
+	.du_flush_pipe(du_flush_pipe),
 
 	// Connection IMMU and CPU internally
 	.immu_en(immu_en),
@@ -926,6 +927,7 @@
 	.id_pc(id_pc),
 	.du_dsr(du_dsr),
 	.du_dmr1(du_dmr1),
+	.du_flush_pipe(du_flush_pipe),
 
 	// For Trace buffer
 	.spr_dat_npc(spr_dat_npc),
