Line 42... |
Line 42... |
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.12 2002/08/22 02:16:45 lampret
|
|
// Fixed IMMU bug.
|
|
//
|
// Revision 1.11 2002/08/18 19:54:28 lampret
|
// Revision 1.11 2002/08/18 19:54:28 lampret
|
// Added store buffer.
|
// Added store buffer.
|
//
|
//
|
// Revision 1.10 2002/07/14 22:17:17 lampret
|
// Revision 1.10 2002/07/14 22:17:17 lampret
|
// Added simple trace buffer [only for Xilinx Virtex target]. Fixed instruction fetch abort when new exception is recognized.
|
// Added simple trace buffer [only for Xilinx Virtex target]. Fixed instruction fetch abort when new exception is recognized.
|
Line 141... |
Line 144... |
sig_int, sig_syscall, sig_trap, sig_itlbmiss, sig_immufault, sig_tick,
|
sig_int, sig_syscall, sig_trap, sig_itlbmiss, sig_immufault, sig_tick,
|
branch_taken, genpc_freeze, id_freeze, ex_freeze, wb_freeze, if_stall,
|
branch_taken, genpc_freeze, id_freeze, ex_freeze, wb_freeze, if_stall,
|
if_pc, lr_sav, flushpipe, extend_flush, except_type, except_start,
|
if_pc, lr_sav, flushpipe, extend_flush, except_type, except_start,
|
except_started, except_stop, ex_void,
|
except_started, except_stop, ex_void,
|
spr_dat_ppc, spr_dat_npc, datain, du_dsr, epcr_we, eear_we, esr_we, pc_we, epcr, eear,
|
spr_dat_ppc, spr_dat_npc, datain, du_dsr, epcr_we, eear_we, esr_we, pc_we, epcr, eear,
|
esr, sr, lsu_addr, abort_ex, icpu_ack_i, icpu_err_i, dcpu_ack_i, dcpu_err_i
|
esr, sr_we, to_sr, sr, lsu_addr, abort_ex, icpu_ack_i, icpu_err_i, dcpu_ack_i, dcpu_err_i
|
);
|
);
|
|
|
//
|
//
|
// I/O
|
// I/O
|
//
|
//
|
Line 179... |
Line 182... |
input esr_we;
|
input esr_we;
|
input pc_we;
|
input pc_we;
|
output [31:0] epcr;
|
output [31:0] epcr;
|
output [31:0] eear;
|
output [31:0] eear;
|
output [`OR1200_SR_WIDTH-1:0] esr;
|
output [`OR1200_SR_WIDTH-1:0] esr;
|
|
input [`OR1200_SR_WIDTH-1:0] to_sr;
|
|
input sr_we;
|
input [`OR1200_SR_WIDTH-1:0] sr;
|
input [`OR1200_SR_WIDTH-1:0] sr;
|
input [31:0] lsu_addr;
|
input [31:0] lsu_addr;
|
output flushpipe;
|
output flushpipe;
|
output extend_flush;
|
output extend_flush;
|
output [`OR1200_EXCEPT_WIDTH-1:0] except_type;
|
output [`OR1200_EXCEPT_WIDTH-1:0] except_type;
|
Line 229... |
Line 234... |
//
|
//
|
assign except_started = extend_flush & except_start;
|
assign except_started = extend_flush & except_start;
|
assign lr_sav = ex_pc[31:2];
|
assign lr_sav = ex_pc[31:2];
|
assign spr_dat_ppc = wb_pc;
|
assign spr_dat_ppc = wb_pc;
|
assign spr_dat_npc = ex_void ? id_pc : ex_pc;
|
assign spr_dat_npc = ex_void ? id_pc : ex_pc;
|
//assign except_start = (except_type != `OR1200_EXCEPT_NONE); // damjan
|
|
assign except_start = (except_type != `OR1200_EXCEPT_NONE) & extend_flush;
|
assign except_start = (except_type != `OR1200_EXCEPT_NONE) & extend_flush;
|
assign int_pending = sig_int & sr[`OR1200_SR_IEE] & delayed_iee[2] & ~ex_freeze & ~branch_taken & ~ex_dslot;
|
assign int_pending = sig_int & sr[`OR1200_SR_IEE] & delayed_iee[2] & ~ex_freeze & ~branch_taken & ~ex_dslot;
|
//assign tick_pending = sig_tick & sr[`OR1200_SR_TEE] & delayed_tee[2] & ~ex_freeze & ~branch_taken & ~ex_dslot; // works with uclinux. except_test fails
|
|
//assign tick_pending = sig_tick & sr[`OR1200_SR_TEE] & ~ex_freeze & ~branch_taken & ~ex_dslot; // works with uclinux, except_tets almost works (priority fails)
|
|
assign tick_pending = sig_tick & sr[`OR1200_SR_TEE] & ~ex_freeze & ~branch_taken & ~ex_dslot;
|
assign tick_pending = sig_tick & sr[`OR1200_SR_TEE] & ~ex_freeze & ~branch_taken & ~ex_dslot;
|
assign abort_ex = sig_dbuserr | sig_dmmufault | sig_dtlbmiss | sig_align | sig_illegal; // Abort write into RF by load & other instructions
|
assign abort_ex = sig_dbuserr | sig_dmmufault | sig_dtlbmiss | sig_align | sig_illegal; // Abort write into RF by load & other instructions
|
|
|
//
|
//
|
// Order defines exception detection priority
|
// Order defines exception detection priority
|
Line 347... |
Line 349... |
ex_exceptflags <= #1 3'b000;
|
ex_exceptflags <= #1 3'b000;
|
delayed1_ex_dslot <= #1 ex_dslot;
|
delayed1_ex_dslot <= #1 ex_dslot;
|
delayed2_ex_dslot <= #1 delayed1_ex_dslot;
|
delayed2_ex_dslot <= #1 delayed1_ex_dslot;
|
end
|
end
|
else if (!ex_freeze) begin
|
else if (!ex_freeze) begin
|
`ifdef OR1200_VERBOSE
|
|
// synopsys translate_off
|
|
$display("%t: ex_pc <= %h", $time, id_pc);
|
|
// synopsys translate_on
|
|
`endif
|
|
ex_dslot <= #1 branch_taken;
|
ex_dslot <= #1 branch_taken;
|
ex_pc <= #1 id_pc;
|
ex_pc <= #1 id_pc;
|
ex_exceptflags <= #1 id_exceptflags;
|
ex_exceptflags <= #1 id_exceptflags;
|
delayed1_ex_dslot <= #1 ex_dslot;
|
delayed1_ex_dslot <= #1 ex_dslot;
|
delayed2_ex_dslot <= #1 delayed1_ex_dslot;
|
delayed2_ex_dslot <= #1 delayed1_ex_dslot;
|
Line 406... |
Line 403... |
case (state) // synopsys full_case parallel_case
|
case (state) // synopsys full_case parallel_case
|
`OR1200_EXCEPTFSM_IDLE:
|
`OR1200_EXCEPTFSM_IDLE:
|
if (except_flushpipe) begin
|
if (except_flushpipe) begin
|
state <= #1 `OR1200_EXCEPTFSM_FLU1;
|
state <= #1 `OR1200_EXCEPTFSM_FLU1;
|
extend_flush <= #1 1'b1;
|
extend_flush <= #1 1'b1;
|
if (ex_dslot) begin
|
esr <= #1 sr_we ? to_sr : sr;
|
`ifdef OR1200_VERBOSE
|
|
// synopsys translate_off
|
|
$display(" INFO: Exception during first delay slot instruction.");
|
|
// synopsys translate_on
|
|
`endif
|
|
end
|
|
else if (delayed1_ex_dslot) begin
|
|
`ifdef OR1200_VERBOSE
|
|
// synopsys translate_off
|
|
$display(" INFO: Exception during second (NOP) delay slot instruction.");
|
|
// synopsys translate_on
|
|
`endif
|
|
end
|
|
else if (delayed2_ex_dslot) begin
|
|
`ifdef OR1200_VERBOSE
|
|
// synopsys translate_off
|
|
$display(" INFO: Exception during third delay slot (SHOULD NOT HAPPEN).");
|
|
// synopsys translate_on
|
|
`endif
|
|
end
|
|
else begin
|
|
`ifdef OR1200_VERBOSE
|
|
// synopsys translate_off
|
|
$display(" INFO: Exception during normal (no delay slot) instruction.");
|
|
// synopsys translate_on
|
|
`endif
|
|
end
|
|
|
|
esr <= #1 sr;
|
|
casex (except_trig)
|
casex (except_trig)
|
13'b1_xxxx_xxxx_xxxx: begin
|
13'b1_xxxx_xxxx_xxxx: begin
|
except_type <= #1 `OR1200_EXCEPT_TICK;
|
except_type <= #1 `OR1200_EXCEPT_TICK;
|
epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
|
epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
|
end
|
end
|
Line 525... |
Line 493... |
if (esr_we)
|
if (esr_we)
|
esr <= #1 {1'b1, datain[`OR1200_SR_WIDTH-2:0]};
|
esr <= #1 {1'b1, datain[`OR1200_SR_WIDTH-2:0]};
|
end
|
end
|
`OR1200_EXCEPTFSM_FLU1:
|
`OR1200_EXCEPTFSM_FLU1:
|
if (icpu_ack_i | icpu_err_i | genpc_freeze)
|
if (icpu_ack_i | icpu_err_i | genpc_freeze)
|
// if (!if_stall | genpc_freeze)
|
|
state <= #1 `OR1200_EXCEPTFSM_FLU2;
|
state <= #1 `OR1200_EXCEPTFSM_FLU2;
|
`OR1200_EXCEPTFSM_FLU2:
|
`OR1200_EXCEPTFSM_FLU2:
|
if (except_type == `OR1200_EXCEPT_TRAP) begin
|
if (except_type == `OR1200_EXCEPT_TRAP) begin
|
state <= #1 `OR1200_EXCEPTFSM_IDLE;
|
state <= #1 `OR1200_EXCEPTFSM_IDLE;
|
extend_flush <= #1 1'b0;
|
extend_flush <= #1 1'b0;
|
extend_flush_last <= #1 1'b0;
|
extend_flush_last <= #1 1'b0;
|
except_type <= #1 `OR1200_EXCEPT_NONE;
|
except_type <= #1 `OR1200_EXCEPT_NONE;
|
end
|
end
|
else
|
else
|
// if (!if_stall & !id_freeze)
|
|
state <= #1 `OR1200_EXCEPTFSM_FLU3;
|
state <= #1 `OR1200_EXCEPTFSM_FLU3;
|
`OR1200_EXCEPTFSM_FLU3:
|
`OR1200_EXCEPTFSM_FLU3:
|
// if (!if_stall && !id_freeze)
|
|
begin
|
begin
|
`ifdef OR1200_VERBOSE
|
|
// synopsys translate_off
|
|
if (except_flushpipe)
|
|
$display(" INFO: EPCR0 %h EEAR %h ESR %h", epcr, eear, esr);
|
|
// synopsys translate_on
|
|
`endif
|
|
state <= #1 `OR1200_EXCEPTFSM_FLU4;
|
state <= #1 `OR1200_EXCEPTFSM_FLU4;
|
end
|
end
|
`OR1200_EXCEPTFSM_FLU4: begin
|
`OR1200_EXCEPTFSM_FLU4: begin
|
state <= #1 `OR1200_EXCEPTFSM_FLU5;
|
state <= #1 `OR1200_EXCEPTFSM_FLU5;
|
extend_flush <= #1 1'b0;
|
extend_flush <= #1 1'b0;
|
extend_flush_last <= #1 1'b0; // damjan
|
extend_flush_last <= #1 1'b0; // damjan
|
end
|
end
|
`OR1200_EXCEPTFSM_FLU5: begin
|
`OR1200_EXCEPTFSM_FLU5: begin
|
if (!if_stall && !id_freeze) begin
|
if (!if_stall && !id_freeze) begin
|
`ifdef OR1200_VERBOSE
|
|
// synopsys translate_off
|
|
$display(" INFO: Just finished flushing pipeline.");
|
|
// synopsys translate_on
|
|
`endif
|
|
state <= #1 `OR1200_EXCEPTFSM_IDLE;
|
state <= #1 `OR1200_EXCEPTFSM_IDLE;
|
except_type <= #1 `OR1200_EXCEPT_NONE;
|
except_type <= #1 `OR1200_EXCEPT_NONE;
|
extend_flush_last <= #1 1'b0;
|
extend_flush_last <= #1 1'b0;
|
end
|
end
|
end
|
end
|