OpenCores
URL https://opencores.org/ocsvn/claw/claw/trunk

Subversion Repositories claw

[/] [claw/] [trunk/] [or1200_cpu/] [or1200_except.v] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 conte
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  OR1200's Exception logic                                    ////
4
////                                                              ////
5
////  This file is part of the OpenRISC 1200 project              ////
6
////  http://www.opencores.org/cores/or1k/                        ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  Handles all OR1K exceptions inside CPU block.               ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////   - make it smaller and faster                               ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Damjan Lampret, lampret@opencores.org                 ////
16
//// Modified by:                                                 ////
17
////      - Balaji V. Iyer, bviyer@ncsu.edu                       ////
18
//// Advisor:                                                     ////
19
////      - Dr. Tom Conte                                         ////
20
////                                                              ////
21
//////////////////////////////////////////////////////////////////////
22
////                                                              ////
23
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
24
////                                                              ////
25
//// This source file may be used and distributed without         ////
26
//// restriction provided that this copyright statement is not    ////
27
//// removed from the file and that any derivative work contains  ////
28
//// the original copyright notice and the associated disclaimer. ////
29
////                                                              ////
30
//// This source file is free software; you can redistribute it   ////
31
//// and/or modify it under the terms of the GNU Lesser General   ////
32
//// Public License as published by the Free Software Foundation; ////
33
//// either version 2.1 of the License, or (at your option) any   ////
34
//// later version.                                               ////
35
////                                                              ////
36
//// This source is distributed in the hope that it will be       ////
37
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
38
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
39
//// PURPOSE.  See the GNU Lesser General Public License for more ////
40
//// details.                                                     ////
41
////                                                              ////
42
//// You should have received a copy of the GNU Lesser General    ////
43
//// Public License along with this source; if not, download it   ////
44
//// from http://www.opencores.org/lgpl.shtml                     ////
45
////                                                              ////
46
//////////////////////////////////////////////////////////////////////
47
//
48
// CVS Revision History
49
//
50
// $Log: not supported by cvs2svn $
51
// Revision 1.16  2004/04/05 08:29:57  lampret
52
// Merged branch_qmem into main tree.
53
//
54
// Revision 1.15.4.1  2004/02/11 01:40:11  lampret
55
// preliminary HW breakpoints support in debug unit (by default disabled). To enable define OR1200_DU_HWBKPTS.
56
//
57
// Revision 1.15  2003/04/20 22:23:57  lampret
58
// No functional change. Only added customization for exception vectors.
59
//
60
// Revision 1.14  2002/09/03 22:28:21  lampret
61
// As per Taylor Su suggestion all case blocks are full case by default and optionally (OR1200_CASE_DEFAULT) can be disabled to increase clock frequncy.
62
//
63
// Revision 1.13  2002/08/28 01:44:25  lampret
64
// Removed some commented RTL. Fixed SR/ESR flag bug.
65
//
66
// Revision 1.12  2002/08/22 02:16:45  lampret
67
// Fixed IMMU bug.
68
//
69
// Revision 1.11  2002/08/18 19:54:28  lampret
70
// Added store buffer.
71
//
72
// Revision 1.10  2002/07/14 22:17:17  lampret
73
// Added simple trace buffer [only for Xilinx Virtex target]. Fixed instruction fetch abort when new exception is recognized.
74
//
75
// Revision 1.9  2002/02/11 04:33:17  lampret
76
// Speed optimizations (removed duplicate _cyc_ and _stb_). Fixed D/IMMU cache-inhibit attr.
77
//
78
// Revision 1.8  2002/01/28 01:16:00  lampret
79
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways.
80
//
81
// Revision 1.7  2002/01/23 07:52:36  lampret
82
// Changed default reset values for SR and ESR to match or1ksim's. Fixed flop model in or1200_dpram_32x32 when OR1200_XILINX_RAM32X1D is defined.
83
//
84
// Revision 1.6  2002/01/18 14:21:43  lampret
85
// Fixed 'the NPC single-step fix'.
86
//
87
// Revision 1.5  2002/01/18 07:56:00  lampret
88
// No more low/high priority interrupts (PICPR removed). Added tick timer exception. Added exception prefix (SR[EPH]). Fixed single-step bug whenreading NPC.
89
//
90
// Revision 1.4  2002/01/14 21:11:50  lampret
91
// Changed alignment exception EPCR. Not tested yet.
92
//
93
// Revision 1.3  2002/01/14 19:09:57  lampret
94
// Fixed order of syscall and range exceptions.
95
//
96
// Revision 1.2  2002/01/14 06:18:22  lampret
97
// Fixed mem2reg bug in FAST implementation. Updated debug unit to work with new genpc/if.
98
//
99
// Revision 1.1  2002/01/03 08:16:15  lampret
100
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
101
//
102
// Revision 1.15  2001/11/27 23:13:11  lampret
103
// Fixed except_stop width and fixed EX PC for 1400444f no-ops.
104
//
105
// Revision 1.14  2001/11/23 08:38:51  lampret
106
// Changed DSR/DRR behavior and exception detection.
107
//
108
// Revision 1.13  2001/11/20 18:46:15  simons
109
// Break point bug fixed
110
//
111
// Revision 1.12  2001/11/18 09:58:28  lampret
112
// Fixed some l.trap typos.
113
//
114
// Revision 1.11  2001/11/18 08:36:28  lampret
115
// For GDB changed single stepping and disabled trap exception.
116
//
117
// Revision 1.10  2001/11/13 10:02:21  lampret
118
// Added 'setpc'. Renamed some signals (except_flushpipe into flushpipe etc)
119
//
120
// Revision 1.9  2001/11/10 03:43:57  lampret
121
// Fixed exceptions.
122
//
123
// Revision 1.8  2001/10/21 17:57:16  lampret
124
// Removed params from generic_XX.v. Added translate_off/on in sprs.v and id.v. Removed spr_addr from dc.v and ic.v. Fixed CR+LF.
125
//
126
// Revision 1.7  2001/10/14 13:12:09  lampret
127
// MP3 version.
128
//
129
// Revision 1.1.1.1  2001/10/06 10:18:36  igorm
130
// no message
131
//
132
// Revision 1.2  2001/08/09 13:39:33  lampret
133
// Major clean-up.
134
//
135
// Revision 1.1  2001/07/20 00:46:03  lampret
136
// Development version of RTL. Libraries are missing.
137
//
138
//
139
 
140
// synopsys translate_off
141
`include "timescale.v"
142
// synopsys translate_on
143
`include "or1200_defines.v"
144
 
145
`define OR1200_EXCEPTFSM_WIDTH 3
146
`define OR1200_EXCEPTFSM_IDLE   `OR1200_EXCEPTFSM_WIDTH'd0
147
`define OR1200_EXCEPTFSM_FLU1   `OR1200_EXCEPTFSM_WIDTH'd1
148
`define OR1200_EXCEPTFSM_FLU2   `OR1200_EXCEPTFSM_WIDTH'd2
149
`define OR1200_EXCEPTFSM_FLU3   `OR1200_EXCEPTFSM_WIDTH'd3
150
`define OR1200_EXCEPTFSM_FLU4   `OR1200_EXCEPTFSM_WIDTH'd4
151
`define OR1200_EXCEPTFSM_FLU5   `OR1200_EXCEPTFSM_WIDTH'd5
152
 
153
//
154
// Exception recognition and sequencing
155
//
156
 
157
module or1200_except(
158
        // Clock and reset
159
        clk, rst,
160
 
161
        // Internal i/f
162
        sig_ibuserr, sig_dbuserr, sig_illegal, sig_align, sig_range, sig_dtlbmiss, sig_dmmufault,
163
        sig_int, sig_syscall, sig_trap, sig_itlbmiss, sig_immufault, sig_tick,
164
        branch_taken, genpc_freeze, id_freeze, ex_freeze, wb_freeze, if_stall,
165
        if_pc, id_pc, lr_sav, flushpipe, extend_flush, except_type, except_start,
166
        except_started, except_stop, ex_void,
167
        spr_dat_ppc, spr_dat_npc, datain, du_dsr, epcr_we, eear_we, esr_we, pc_we, epcr, eear,
168
        esr, sr_we, to_sr, sr, lsu_addr, abort_ex, icpu_ack_i, icpu_err_i, dcpu_ack_i, dcpu_err_i, thread_in, thread_out
169
);
170
 
171
//
172
// I/O
173
//
174
input                           clk;
175
input                           rst;
176
input                           sig_ibuserr;
177
input                           sig_dbuserr;
178
input                           sig_illegal;
179
input                           sig_align;
180
input                           sig_range;
181
input                           sig_dtlbmiss;
182
input                           sig_dmmufault;
183
input                           sig_int;
184
input                           sig_syscall;
185
input                           sig_trap;
186
input                           sig_itlbmiss;
187
input                           sig_immufault;
188
input                           sig_tick;
189
input                           branch_taken;
190
input                           genpc_freeze;
191
input                           id_freeze;
192
input                           ex_freeze;
193
input                           wb_freeze;
194
input                           if_stall;
195
input   [31:0]                   if_pc;
196
output  [31:0]                   id_pc;
197
output  [31:2]                  lr_sav;
198
input   [31:0]                   datain;
199
input   [`OR1200_DU_DSR_WIDTH-1:0]     du_dsr;
200
input                           epcr_we;
201
input                           eear_we;
202
input                           esr_we;
203
input                           pc_we;
204
output  [31:0]                   epcr;
205
output  [31:0]                   eear;
206
output  [`OR1200_SR_WIDTH-1:0]   esr;
207
input   [`OR1200_SR_WIDTH-1:0]   to_sr;
208
input                           sr_we;
209
input   [`OR1200_SR_WIDTH-1:0]   sr;
210
input   [31:0]                   lsu_addr;
211
output                          flushpipe;
212
output                          extend_flush;
213
output  [`OR1200_EXCEPT_WIDTH-1:0]       except_type;
214
output                          except_start;
215
output                          except_started;
216
output  [12:0]                   except_stop;
217
input                           ex_void;
218
output  [31:0]                   spr_dat_ppc;
219
output  [31:0]                   spr_dat_npc;
220
output                          abort_ex;
221
input                           icpu_ack_i;
222
input                           icpu_err_i;
223
input                           dcpu_ack_i;
224
input                           dcpu_err_i;
225
input [2:0]                      thread_in;
226
output[2:0]                      thread_out;
227
 
228
//
229
// Internal regs and wires
230
//
231
reg     [`OR1200_EXCEPT_WIDTH-1:0]       except_type;
232
reg     [31:0]                   id_pc;
233
reg     [31:0]                   ex_pc;
234
reg     [31:0]                   wb_pc;
235
reg     [31:0]                   epcr;
236
reg     [31:0]                   eear;
237
reg     [`OR1200_SR_WIDTH-1:0]           esr;
238
reg     [2:0]                    id_exceptflags;
239
reg     [2:0]                    ex_exceptflags;
240
reg     [`OR1200_EXCEPTFSM_WIDTH-1:0]    state;
241
reg                             extend_flush;
242
reg                             extend_flush_last;
243
reg                             ex_dslot;
244
reg                             delayed1_ex_dslot;
245
reg                             delayed2_ex_dslot;
246
wire                            except_started;
247
wire    [12:0]                   except_trig;
248
wire                            except_flushpipe;
249
reg     [2:0]                    delayed_iee;
250
reg     [2:0]                    delayed_tee;
251
wire                            int_pending;
252
wire                            tick_pending;
253
 
254
//
255
// Simple combinatorial logic
256
//
257
assign except_started = extend_flush & except_start;
258
assign lr_sav = ex_pc[31:2];
259
assign spr_dat_ppc = wb_pc;
260
assign spr_dat_npc = ex_void ? id_pc : ex_pc;
261
assign except_start = (except_type != `OR1200_EXCEPT_NONE) & extend_flush;
262
assign int_pending = sig_int & sr[`OR1200_SR_IEE] & delayed_iee[2] & ~ex_freeze & ~branch_taken & ~ex_dslot & ~sr_we;
263
assign tick_pending = sig_tick & sr[`OR1200_SR_TEE] & ~ex_freeze & ~branch_taken & ~ex_dslot & ~sr_we;
264
assign abort_ex = sig_dbuserr | sig_dmmufault | sig_dtlbmiss | sig_align | sig_illegal;         // Abort write into RF by load & other instructions
265
 
266
//
267
// Order defines exception detection priority
268
//
269
assign except_trig = {
270
                        tick_pending            & ~du_dsr[`OR1200_DU_DSR_TTE],
271
                        int_pending             & ~du_dsr[`OR1200_DU_DSR_IE],
272
                        ex_exceptflags[1]       & ~du_dsr[`OR1200_DU_DSR_IME],
273
                        ex_exceptflags[0]        & ~du_dsr[`OR1200_DU_DSR_IPFE],
274
                        ex_exceptflags[2]       & ~du_dsr[`OR1200_DU_DSR_BUSEE],
275
                        sig_illegal             & ~du_dsr[`OR1200_DU_DSR_IIE],
276
                        sig_align               & ~du_dsr[`OR1200_DU_DSR_AE],
277
                        sig_dtlbmiss            & ~du_dsr[`OR1200_DU_DSR_DME],
278
                        sig_dmmufault           & ~du_dsr[`OR1200_DU_DSR_DPFE],
279
                        sig_dbuserr             & ~du_dsr[`OR1200_DU_DSR_BUSEE],
280
                        sig_range               & ~du_dsr[`OR1200_DU_DSR_RE],
281
                        sig_trap                & ~du_dsr[`OR1200_DU_DSR_TE] & ~ex_freeze,
282
                        sig_syscall             & ~du_dsr[`OR1200_DU_DSR_SCE] & ~ex_freeze
283
                };
284
assign except_stop = {
285
                        tick_pending            & du_dsr[`OR1200_DU_DSR_TTE],
286
                        int_pending             & du_dsr[`OR1200_DU_DSR_IE],
287
                        ex_exceptflags[1]       & du_dsr[`OR1200_DU_DSR_IME],
288
                        ex_exceptflags[0]        & du_dsr[`OR1200_DU_DSR_IPFE],
289
                        ex_exceptflags[2]       & du_dsr[`OR1200_DU_DSR_BUSEE],
290
                        sig_illegal             & du_dsr[`OR1200_DU_DSR_IIE],
291
                        sig_align               & du_dsr[`OR1200_DU_DSR_AE],
292
                        sig_dtlbmiss            & du_dsr[`OR1200_DU_DSR_DME],
293
                        sig_dmmufault           & du_dsr[`OR1200_DU_DSR_DPFE],
294
                        sig_dbuserr             & du_dsr[`OR1200_DU_DSR_BUSEE],
295
                        sig_range               & du_dsr[`OR1200_DU_DSR_RE],
296
                        sig_trap                & du_dsr[`OR1200_DU_DSR_TE] & ~ex_freeze,
297
                        sig_syscall             & du_dsr[`OR1200_DU_DSR_SCE] & ~ex_freeze
298
                };
299
 
300
//
301
// PC and Exception flags pipelines
302
//
303
always @(posedge clk or posedge rst) begin
304
        if (rst) begin
305
                id_pc <=  32'd0;
306
                id_exceptflags <=  3'b000;
307
        end
308
        else if (flushpipe) begin
309
                id_pc <=  32'h0000_0000;
310
                id_exceptflags <=  3'b000;
311
        end
312
        else if (!id_freeze) begin
313
                id_pc <=  if_pc;
314
                id_exceptflags <=  { sig_ibuserr, sig_itlbmiss, sig_immufault };
315
        end
316
end
317
 
318
//
319
// delayed_iee
320
//
321
// SR[IEE] should not enable interrupts right away
322
// when it is restored with l.rfe. Instead delayed_iee
323
// together with SR[IEE] enables interrupts once
324
// pipeline is again ready.
325
//
326
always @(posedge rst or posedge clk)
327
        if (rst)
328
                delayed_iee <=  3'b000;
329
        else if (!sr[`OR1200_SR_IEE])
330
                delayed_iee <=  3'b000;
331
        else
332
                delayed_iee <=  {delayed_iee[1:0], 1'b1};
333
 
334
//
335
// delayed_tee
336
//
337
// SR[TEE] should not enable tick exceptions right away
338
// when it is restored with l.rfe. Instead delayed_tee
339
// together with SR[TEE] enables tick exceptions once
340
// pipeline is again ready.
341
//
342
always @(posedge rst or posedge clk)
343
        if (rst)
344
                delayed_tee <=  3'b000;
345
        else if (!sr[`OR1200_SR_TEE])
346
                delayed_tee <=  3'b000;
347
        else
348
                delayed_tee <=  {delayed_tee[1:0], 1'b1};
349
 
350
//
351
// PC and Exception flags pipelines
352
//
353
always @(posedge clk or posedge rst) begin
354
        if (rst) begin
355
                ex_dslot <=  1'b0;
356
                ex_pc <=  32'd0;
357
                ex_exceptflags <=  3'b000;
358
                delayed1_ex_dslot <=  1'b0;
359
                delayed2_ex_dslot <=  1'b0;
360
        end
361
        else if (flushpipe) begin
362
                ex_dslot <=  1'b0;
363
                ex_pc <=  32'h0000_0000;
364
                ex_exceptflags <=  3'b000;
365
                delayed1_ex_dslot <=  1'b0;
366
                delayed2_ex_dslot <=  1'b0;
367
        end
368
        else if (!ex_freeze & id_freeze) begin
369
                ex_dslot <=  1'b0;
370
                ex_pc <=  id_pc;
371
                ex_exceptflags <=  3'b000;
372
                delayed1_ex_dslot <=  ex_dslot;
373
                delayed2_ex_dslot <=  delayed1_ex_dslot;
374
        end
375
        else if (!ex_freeze) begin
376
                ex_dslot <=  branch_taken;
377
                ex_pc <=  id_pc;
378
                ex_exceptflags <=  id_exceptflags;
379
                delayed1_ex_dslot <=  ex_dslot;
380
                delayed2_ex_dslot <=  delayed1_ex_dslot;
381
        end
382
end
383
 
384
//
385
// PC and Exception flags pipelines
386
//
387
always @(posedge clk or posedge rst) begin
388
        if (rst) begin
389
                wb_pc <=  32'd0;
390
        end
391
        else if (!wb_freeze) begin
392
                wb_pc <=  ex_pc;
393
        end
394
end
395
 
396
//
397
// Flush pipeline
398
//
399
assign flushpipe = except_flushpipe | pc_we | extend_flush;
400
 
401
//
402
// We have started execution of exception handler:
403
//  1. Asserted for 3 clock cycles
404
//  2. Don't execute any instruction that is still in pipeline and is not part of exception handler
405
//
406
assign except_flushpipe = |except_trig & !state;
407
 
408
//
409
// Exception FSM that sequences execution of exception handler
410
//
411
// except_type signals which exception handler we start fetching in:
412
//  1. Asserted in next clock cycle after exception is recognized
413
//
414
always @(posedge clk or posedge rst) begin
415
        if (rst) begin
416
                state <=  `OR1200_EXCEPTFSM_IDLE;
417
                except_type <=  `OR1200_EXCEPT_NONE;
418
                extend_flush <=  1'b0;
419
                epcr <=  32'b0;
420
                eear <=  32'b0;
421
                esr <=  {1'b1, {`OR1200_SR_WIDTH-2{1'b0}}, 1'b1};
422
                extend_flush_last <=  1'b0;
423
        end
424
        else begin
425
`ifdef OR1200_CASE_DEFAULT
426
                case (state)    // synopsys parallel_case
427
`else
428
                case (state)    // synopsys full_case parallel_case
429
`endif
430
                        `OR1200_EXCEPTFSM_IDLE:
431
                                if (except_flushpipe) begin
432
                                        state <=  `OR1200_EXCEPTFSM_FLU1;
433
                                        extend_flush <=  1'b1;
434
                                        esr <=  sr_we ? to_sr : sr;
435
                                        casex (except_trig)
436
`ifdef OR1200_EXCEPT_TICK
437
                                                13'b1_xxxx_xxxx_xxxx: begin
438
                                                        except_type <=  `OR1200_EXCEPT_TICK;
439
                                                        epcr <=  ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
440
                                                end
441
`endif
442
`ifdef OR1200_EXCEPT_INT
443
                                                13'b0_1xxx_xxxx_xxxx: begin
444
                                                        except_type <=  `OR1200_EXCEPT_INT;
445
                                                        epcr <=  ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
446
                                                end
447
`endif
448
`ifdef OR1200_EXCEPT_ITLBMISS
449
                                                13'b0_01xx_xxxx_xxxx: begin
450
                                                        except_type <=  `OR1200_EXCEPT_ITLBMISS;
451
//
452
// itlb miss exception and active ex_dslot caused wb_pc to put into eear instead of +4 address of ex_pc (or id_pc since it was equal to ex_pc?)
453
//                                                      eear <=  ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
454
//      mmu-icdc-O2 ex_pc only OK when no ex_dslot      eear <=  ex_dslot ? ex_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
455
//      mmu-icdc-O2 ex_pc only OK when no ex_dslot      epcr <=  ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
456
                                                        eear <=  ex_dslot ? ex_pc : ex_pc;
457
                                                        epcr <=  ex_dslot ? wb_pc : ex_pc;
458
//                                                      eear <=  ex_dslot ? ex_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
459
//                                                      epcr <=  ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
460
                                                end
461
`endif
462
`ifdef OR1200_EXCEPT_IPF
463
                                                13'b0_001x_xxxx_xxxx: begin
464
                                                        except_type <=  `OR1200_EXCEPT_IPF;
465
//
466
// ipf exception and active ex_dslot caused wb_pc to put into eear instead of +4 address of ex_pc (or id_pc since it was equal to ex_pc?)
467
//                                                      eear <=  ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
468
                                                        eear <=  ex_dslot ? ex_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
469
                                                        epcr <=  ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
470
                                                end
471
`endif
472
`ifdef OR1200_EXCEPT_BUSERR
473
                                                13'b0_0001_xxxx_xxxx: begin
474
                                                        except_type <=  `OR1200_EXCEPT_BUSERR;
475
                                                        eear <=  ex_dslot ? wb_pc : ex_pc;
476
                                                        epcr <=  ex_dslot ? wb_pc : ex_pc;
477
                                                end
478
`endif
479
`ifdef OR1200_EXCEPT_ILLEGAL
480
                                                13'b0_0000_1xxx_xxxx: begin
481
                                                        except_type <=  `OR1200_EXCEPT_ILLEGAL;
482
                                                        eear <=  ex_pc;
483
                                                        epcr <=  ex_dslot ? wb_pc : ex_pc;
484
                                                end
485
`endif
486
`ifdef OR1200_EXCEPT_ALIGN
487
                                                13'b0_0000_01xx_xxxx: begin
488
                                                        except_type <=  `OR1200_EXCEPT_ALIGN;
489
                                                        eear <=  lsu_addr;
490
                                                        epcr <=  ex_dslot ? wb_pc : ex_pc;
491
                                                end
492
`endif
493
`ifdef OR1200_EXCEPT_DTLBMISS
494
                                                13'b0_0000_001x_xxxx: begin
495
                                                        except_type <=  `OR1200_EXCEPT_DTLBMISS;
496
                                                        eear <=  lsu_addr;
497
                                                        epcr <=  ex_dslot ? wb_pc : ex_pc;
498
                                                end
499
`endif
500
`ifdef OR1200_EXCEPT_DPF
501
                                                13'b0_0000_0001_xxxx: begin
502
                                                        except_type <=  `OR1200_EXCEPT_DPF;
503
                                                        eear <=  lsu_addr;
504
                                                        epcr <=  ex_dslot ? wb_pc : ex_pc;
505
                                                end
506
`endif
507
`ifdef OR1200_EXCEPT_BUSERR
508
                                                13'b0_0000_0000_1xxx: begin     // Data Bus Error
509
                                                        except_type <=  `OR1200_EXCEPT_BUSERR;
510
                                                        eear <=  lsu_addr;
511
                                                        epcr <=  ex_dslot ? wb_pc : ex_pc;
512
                                                end
513
`endif
514
`ifdef OR1200_EXCEPT_RANGE
515
                                                13'b0_0000_0000_01xx: begin
516
                                                        except_type <=  `OR1200_EXCEPT_RANGE;
517
                                                        epcr <=  ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
518
                                                end
519
`endif
520
`ifdef OR1200_EXCEPT_TRAP                       13'b0_0000_0000_001x: begin
521
                                                        except_type <=  `OR1200_EXCEPT_TRAP;
522
                                                        epcr <=  ex_dslot ? wb_pc : ex_pc;
523
                                                end
524
`endif
525
`ifdef OR1200_EXCEPT_SYSCALL
526
                                                13'b0_0000_0000_0001: begin
527
                                                        except_type <=  `OR1200_EXCEPT_SYSCALL;
528
                                                        epcr <=  ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
529
                                                end
530
`endif
531
                                                default:
532
                                                        except_type <=  `OR1200_EXCEPT_NONE;
533
                                        endcase
534
                                end
535
                                else if (pc_we) begin
536
                                        state <=  `OR1200_EXCEPTFSM_FLU1;
537
                                        extend_flush <=  1'b1;
538
                                end
539
                                else begin
540
                                        if (epcr_we)
541
                                                epcr <=  datain;
542
                                        if (eear_we)
543
                                                eear <=  datain;
544
                                        if (esr_we)
545
                                                esr <=  {1'b1, datain[`OR1200_SR_WIDTH-2:0]};
546
                                end
547
                        `OR1200_EXCEPTFSM_FLU1:
548
                                if (icpu_ack_i | icpu_err_i | genpc_freeze)
549
                                        state <=  `OR1200_EXCEPTFSM_FLU2;
550
                        `OR1200_EXCEPTFSM_FLU2:
551
`ifdef OR1200_EXCEPT_TRAP
552
                                if (except_type == `OR1200_EXCEPT_TRAP) begin
553
                                        state <=  `OR1200_EXCEPTFSM_IDLE;
554
                                        extend_flush <=  1'b0;
555
                                        extend_flush_last <=  1'b0;
556
                                        except_type <=  `OR1200_EXCEPT_NONE;
557
                                end
558
                                else
559
`endif
560
                                        state <=  `OR1200_EXCEPTFSM_FLU3;
561
                        `OR1200_EXCEPTFSM_FLU3:
562
                                        begin
563
                                                state <=  `OR1200_EXCEPTFSM_FLU4;
564
                                        end
565
                        `OR1200_EXCEPTFSM_FLU4: begin
566
                                        state <=  `OR1200_EXCEPTFSM_FLU5;
567
                                        extend_flush <=  1'b0;
568
                                        extend_flush_last <=  1'b0; // damjan
569
                                end
570
`ifdef OR1200_CASE_DEFAULT
571
                        default: begin
572
`else
573
                        `OR1200_EXCEPTFSM_FLU5: begin
574
`endif
575
                                if (!if_stall && !id_freeze) begin
576
                                        state <=  `OR1200_EXCEPTFSM_IDLE;
577
                                        except_type <=  `OR1200_EXCEPT_NONE;
578
                                        extend_flush_last <=  1'b0;
579
                                end
580
                        end
581
                endcase
582
        end
583
end
584
 
585
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.