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

Subversion Repositories or1k

[/] [or1k/] [tags/] [first/] [mp3/] [rtl/] [verilog/] [or1200.xcv/] [except.v] - Blame information for rev 266

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 266 lampret
//////////////////////////////////////////////////////////////////////
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
////                                                              ////
17
//////////////////////////////////////////////////////////////////////
18
////                                                              ////
19
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
20
////                                                              ////
21
//// This source file may be used and distributed without         ////
22
//// restriction provided that this copyright statement is not    ////
23
//// removed from the file and that any derivative work contains  ////
24
//// the original copyright notice and the associated disclaimer. ////
25
////                                                              ////
26
//// This source file is free software; you can redistribute it   ////
27
//// and/or modify it under the terms of the GNU Lesser General   ////
28
//// Public License as published by the Free Software Foundation; ////
29
//// either version 2.1 of the License, or (at your option) any   ////
30
//// later version.                                               ////
31
////                                                              ////
32
//// This source is distributed in the hope that it will be       ////
33
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
34
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
35
//// PURPOSE.  See the GNU Lesser General Public License for more ////
36
//// details.                                                     ////
37
////                                                              ////
38
//// You should have received a copy of the GNU Lesser General    ////
39
//// Public License along with this source; if not, download it   ////
40
//// from http://www.opencores.org/lgpl.shtml                     ////
41
////                                                              ////
42
//////////////////////////////////////////////////////////////////////
43
//
44
// CVS Revision History
45
//
46
// $Log: not supported by cvs2svn $
47
// Revision 1.1.1.1  2001/10/06 10:18:36  igorm
48
// no message
49
//
50
// Revision 1.2  2001/08/09 13:39:33  lampret
51
// Major clean-up.
52
//
53
// Revision 1.1  2001/07/20 00:46:03  lampret
54
// Development version of RTL. Libraries are missing.
55
//
56
//
57
 
58
// synopsys translate_off
59
`include "timescale.v"
60
// synopsys translate_on
61
`include "defines.v"
62
 
63
`define EXCEPTFSM_WIDTH 2
64
`define EXCEPTFSM_IDLE  `EXCEPTFSM_WIDTH'd0
65
`define EXCEPTFSM_FLU1  `EXCEPTFSM_WIDTH'd1
66
`define EXCEPTFSM_FLU2  `EXCEPTFSM_WIDTH'd2
67
`define EXCEPTFSM_FLU3  `EXCEPTFSM_WIDTH'd3
68
 
69
//
70
// Exception recognition and sequencing
71
//
72
 
73
module except(
74
        // Clock and reset
75
        clk, rst,
76
 
77
        // Internal i/f
78
        sig_buserr, sig_illegal, sig_align, sig_range, sig_dtlbmiss, sig_dmmufault,
79
        sig_inthigh, sig_syscall, sig_trap, sig_itlbmiss, sig_immufault, sig_intlow,
80
        branch_taken, id_freeze, ex_freeze, wb_freeze, if_stall,
81
        if_pc, lr_sav, except_flushpipe, except_type, except_start,
82
        except_started, wb_pc, ex_pc, datain, epcr_we, eear_we, esr_we, epcr, eear,
83
        esr, sr, lsu_addr
84
);
85
 
86
//
87
// I/O
88
//
89
input                           clk;
90
input                           rst;
91
input                           sig_buserr;
92
input                           sig_illegal;
93
input                           sig_align;
94
input                           sig_range;
95
input                           sig_dtlbmiss;
96
input                           sig_dmmufault;
97
input                           sig_inthigh;
98
input                           sig_syscall;
99
input                           sig_trap;
100
input                           sig_itlbmiss;
101
input                           sig_immufault;
102
input                           sig_intlow;
103
input                           branch_taken;
104
input                           id_freeze;
105
input                           ex_freeze;
106
input                           wb_freeze;
107
input                           if_stall;
108
input   [31:0]                   if_pc;
109
output  [31:2]                  lr_sav;
110
input   [31:0]                   datain;
111
input                           epcr_we;
112
input                           eear_we;
113
input                           esr_we;
114
output  [31:0]                   epcr;
115
output  [31:0]                   eear;
116
output  [`SR_WIDTH-1:0]          esr;
117
input   [`SR_WIDTH-1:0]          sr;
118
input   [31:0]                   lsu_addr;
119
output                          except_flushpipe;
120
output  [`EXCEPT_WIDTH-1:0]      except_type;
121
output                          except_start;
122
output                          except_started;
123
output  [31:0]                   wb_pc;
124
output  [31:0]                   ex_pc;
125
 
126
//
127
// Internal regs and wires
128
//
129
reg     [`EXCEPT_WIDTH-1:0]      except_type;
130
reg     [31:0]                   id_pc;
131
reg     [31:0]                   ex_pc;
132
reg     [31:0]                   wb_pc;
133
reg     [31:0]                   epcr;
134
reg     [31:0]                   eear;
135
reg     [`SR_WIDTH-1:0]          esr;
136
reg     [2:0]                    id_exceptflags;
137
reg     [2:0]                    ex_exceptflags;
138
reg     [`EXCEPTFSM_WIDTH-1:0]   state;
139
reg                             extend_flush;
140
reg                             ex_dslot;
141
reg                             delayed1_ex_dslot;
142
reg                             delayed2_ex_dslot;
143
wire                            except_started;
144
wire    [12:0]                   except_trig;
145
 
146
//
147
// Simple combinatorial logic
148
//
149
assign except_started = ~except_start & extend_flush;
150
assign lr_sav = ex_pc[31:2];
151
assign except_start = (except_type != `EXCEPT_NONE);
152
assign except_trig = { sig_buserr, sig_illegal, sig_align,
153
                        sig_range, sig_dtlbmiss, sig_dmmufault,
154
                        sig_inthigh, sig_trap, sig_syscall,
155
                        ex_exceptflags[2:0]};
156
 
157
//
158
// PC and Exception flags pipelines
159
//
160
always @(posedge clk or posedge rst) begin
161
        if (rst) begin
162
                id_pc <= #1 32'd0;
163
                id_exceptflags <= #1 3'b0;
164
        end
165
        else if (!id_freeze) begin
166
`ifdef OR1200_VERBOSE
167
// synopsys translate_off
168
                $display("%t: id_pc <= %h", $time, if_pc);
169
// synopsys translate_on
170
`endif
171
                id_pc <= #1 if_pc;
172
                id_exceptflags <= #1 { sig_itlbmiss, sig_immufault, sig_intlow & sr[`SR_EXR]};
173
        end
174
end
175
 
176
//
177
// PC and Exception flags pipelines
178
//
179
always @(posedge clk or posedge rst) begin
180
        if (rst) begin
181
                ex_dslot <= #1 1'b0;
182
                ex_pc <= #1 32'd0;
183
                ex_exceptflags <= #1 3'b0;
184
                delayed1_ex_dslot <= #1 1'b0;
185
                delayed2_ex_dslot <= #1 1'b0;
186
        end
187
        else if (!ex_freeze & id_freeze) begin
188
                ex_dslot <= #1 1'b0;
189
                ex_pc <= #1 id_pc;
190
                ex_exceptflags <= #1 3'b000;
191
                delayed1_ex_dslot <= #1 ex_dslot;
192
                delayed2_ex_dslot <= #1 delayed1_ex_dslot;
193
        end
194
        else if (!ex_freeze) begin
195
`ifdef OR1200_VERBOSE
196
// synopsys translate_off
197
                $display("%t: ex_pc <= %h", $time, id_pc);
198
// synopsys translate_on
199
`endif
200
                ex_dslot <= #1 branch_taken;
201
                ex_pc <= #1 id_pc;
202
                ex_exceptflags <= #1 id_exceptflags;
203
                delayed1_ex_dslot <= #1 ex_dslot;
204
                delayed2_ex_dslot <= #1 delayed1_ex_dslot;
205
        end
206
end
207
 
208
 
209
//
210
// PC and Exception flags pipelines
211
//
212
always @(posedge clk or posedge rst) begin
213
        if (rst) begin
214
                wb_pc <= #1 32'd0;
215
        end
216
        else if (!wb_freeze) begin
217
                wb_pc <= #1 ex_pc;
218
        end
219
end
220
 
221
//
222
// We have started execution of exception handler:
223
//  1. Asserted for 3 clock cycles
224
//  2. Don't execute any instruction that is still in pipeline and is not part of exception handler
225
//
226
assign except_flushpipe = (sr[`SR_EXR] & (sig_dtlbmiss | sig_dmmufault | sig_inthigh | sig_syscall |sig_trap | (|ex_exceptflags))
227
        | extend_flush);
228
 
229
//
230
// Exception FSM that sequences execution of exception handler
231
//
232
// except_type signals which exception handler we start fetching in:
233
//  1. Asserted in next clock cycle after exception is recognized
234
//
235
always @(posedge clk or posedge rst) begin
236
        if (rst) begin
237
                state <= #1 `EXCEPTFSM_IDLE;
238
                except_type <= #1 `EXCEPT_NONE;
239
                extend_flush <= #1 1'b0;
240
                epcr <= #1 32'b0;
241
                eear <= #1 32'b0;
242
                esr <= #1 `SR_WIDTH'b0;
243
        end
244
        else begin
245
                case (state)    // synopsys full_case parallel_case
246
                        `EXCEPTFSM_IDLE:
247
                                if (except_flushpipe) begin
248
                                        state <= #1 `EXCEPTFSM_FLU1;
249
                                        extend_flush <= #1 1'b1;
250
                                        if (ex_dslot) begin
251
`ifdef OR1200_VERBOSE
252
// synopsys translate_off
253
                                                $display(" INFO: Exception during first delay slot instruction.");
254
// synopsys translate_on
255
`endif
256
                                                epcr <= #1 wb_pc;
257
                                        end
258
                                        else if (delayed1_ex_dslot) begin
259
`ifdef OR1200_VERBOSE
260
// synopsys translate_off
261
                                                $display(" INFO: Exception during second (NOP) delay slot instruction.");
262
// synopsys translate_on
263
`endif
264
                                                epcr <= #1 id_pc;
265
                                        end
266
                                        else if (delayed2_ex_dslot) begin
267
`ifdef OR1200_VERBOSE
268
// synopsys translate_off
269
                                                $display(" INFO: Exception during third delay slot (SHOULD NOT HAPPEN).");
270
// synopsys translate_on
271
`endif
272
                                                epcr <= #1 id_pc;
273
                                        end
274
                                        else begin
275
`ifdef OR1200_VERBOSE
276
// synopsys translate_off
277
                                                $display(" INFO: Exception during normal (no delay slot) instruction.");
278
// synopsys translate_on
279
`endif
280
                                                epcr <= #1 ex_pc;
281
                                        end
282
                                        esr <= #1 sr;
283
                                        eear <= #1 lsu_addr;
284
                                        casex (except_trig)
285
                                                13'b1_xxxx_xxxx_xxxx:
286
                                                        except_type <= #1 `EXCEPT_BUSERR;
287
                                                13'b0_1xxx_xxxx_xxxx:
288
                                                        except_type <= #1 `EXCEPT_ILLEGAL;
289
                                                13'b0_01xx_xxxx_xxxx:
290
                                                        except_type <= #1 `EXCEPT_ALIGN;
291
                                                13'b0_0001_xxxx_xxxx:
292
                                                        except_type <= #1 `EXCEPT_RANGE;
293
                                                13'b0_0000_1xxx_xxxx:
294
                                                        except_type <= #1 `EXCEPT_DTLBMISS;
295
                                                13'b0_0000_01xx_xxxx:
296
                                                        except_type <= #1 `EXCEPT_DPF;
297
                                                13'b0_0000_001x_xxxx:
298
                                                        except_type <= #1 `EXCEPT_HPINT;
299
                                                13'b0_0000_0001_xxxx:
300
                                                        except_type <= #1 `EXCEPT_TRAP;
301
                                                13'b0_0000_0000_1xxx:
302
                                                        except_type <= #1 `EXCEPT_SYSCALL;
303
                                                13'b0_0000_0000_01xx:
304
                                                        except_type <= #1 `EXCEPT_ITLBMISS;
305
                                                13'b0_0000_0000_001x:
306
                                                        except_type <= #1 `EXCEPT_IPF;
307
                                                13'b0_0000_0000_0001:
308
                                                        except_type <= #1 `EXCEPT_LPINT;
309
                                                default:
310
                                                        except_type <= #1 `EXCEPT_NONE;
311
                                        endcase
312
                                end
313
                                else begin
314
                                        if (epcr_we)
315
                                                epcr <= #1 datain;
316
                                        if (eear_we)
317
                                                eear <= #1 datain;
318
                                        if (esr_we)
319
                                                esr <= #1 datain[`SR_WIDTH-1:0];
320
                                end
321
                        `EXCEPTFSM_FLU1:
322
                                if (!if_stall && !id_freeze)
323
                                        begin
324
`ifdef OR1200_VERBOSE
325
// synopsys translate_off
326
                                                $display(" INFO: EPCR0 %h  EEAR %h  ESR %h", epcr, eear, esr);
327
// synopsys translate_on
328
`endif
329
                                                state <= #1 `EXCEPTFSM_FLU2;
330
                                                except_type <= #1 `EXCEPT_NONE;
331
                                        end
332
                        `EXCEPTFSM_FLU2:
333
                                state <= #1 `EXCEPTFSM_FLU3;
334
                        `EXCEPTFSM_FLU3: begin
335
`ifdef OR1200_VERBOSE
336
// synopsys translate_off
337
                                $display(" INFO: Exception just finished flushing pipeline.");
338
// synopsys translate_on
339
`endif
340
                                state <= #1 `EXCEPTFSM_IDLE;
341
                                extend_flush <= #1 1'b0;
342
                        end
343
                endcase
344
        end
345
end
346
 
347
endmodule

powered by: WebSVN 2.1.0

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