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

Subversion Repositories oms8051mini

[/] [oms8051mini/] [trunk/] [rtl/] [8051/] [oc8051_int.v] - Blame information for rev 36

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dinesha
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  8051 cores interrupt control module                         ////
4
////                                                              ////
5
////  This file is part of the 8051 cores project                 ////
6
////  http://www.opencores.org/cores/oms8051mini/                 ////
7
////                                                              ////
8
////  Description                                                 ////
9
////   contains sfr's: tcon, ip, ie;                              ////
10
////   interrupt handling                                         ////
11
////                                                              ////
12
////  To Do:                                                      ////
13
////   Nothing                                                    ////
14
////                                                              ////
15
////  Author(s):                                                  ////
16
////      - Simon Teran, simont@opencores.org                     ////
17
////      - Jaka Simsic, jakas@opencores.org                      ////
18
////      - Dinesh Annayya, dinesha@opencores.org                 ////
19
////                                                              ////
20
//////////////////////////////////////////////////////////////////////
21 25 dinesha
////   v0.0 - Dinesh A, 5th Jan 2017
22
////        1. Active edge of reset changed from High to Low
23
//////////////////////////////////////////////////////////////////////
24 2 dinesha
////                                                              ////
25
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
26
////                                                              ////
27
//// This source file may be used and distributed without         ////
28
//// restriction provided that this copyright statement is not    ////
29
//// removed from the file and that any derivative work contains  ////
30
//// the original copyright notice and the associated disclaimer. ////
31
////                                                              ////
32
//// This source file is free software; you can redistribute it   ////
33
//// and/or modify it under the terms of the GNU Lesser General   ////
34
//// Public License as published by the Free Software Foundation; ////
35
//// either version 2.1 of the License, or (at your option) any   ////
36
//// later version.                                               ////
37
////                                                              ////
38
//// This source is distributed in the hope that it will be       ////
39
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
40
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
41
//// PURPOSE.  See the GNU Lesser General Public License for more ////
42
//// details.                                                     ////
43
////                                                              ////
44
//// You should have received a copy of the GNU Lesser General    ////
45
//// Public License along with this source; if not, download it   ////
46
//// from http://www.opencores.org/lgpl.shtml                     ////
47
////                                                              ////
48
//////////////////////////////////////////////////////////////////////
49
//
50
// CVS Revision History
51
//
52
// $Log: not supported by cvs2svn $
53
// Revision 1.9  2003/06/03 17:12:05  simont
54
// fix some bugs.
55
//
56
// Revision 1.8  2003/04/07 14:58:02  simont
57
// change sfr's interface.
58
//
59
// Revision 1.7  2003/03/28 17:45:57  simont
60
// change module name.
61
//
62
// Revision 1.6  2003/01/13 14:14:41  simont
63
// replace some modules
64
//
65
// Revision 1.5  2002/09/30 17:33:59  simont
66
// prepared header
67
//
68
//
69
 
70
 
71
`include "top_defines.v"
72
 
73
 
74
 
75 25 dinesha
module oc8051_int (clk, resetn,
76 2 dinesha
        wr_addr,
77
        data_in, bit_in,
78
        wr, wr_bit,
79
//timer interrupts
80
        tf0, tf1, t2_int,
81
        tr0, tr1,
82
//external interrupts
83
        ie0, ie1,
84
//uart interrupts
85
        uart_int,
86
//to cpu
87
        intr, reti, int_vec, ack,
88
//registers
89
        ie, tcon, ip);
90
 
91
input [7:0] wr_addr, data_in;
92 25 dinesha
input wr, tf0, tf1, t2_int, ie0, ie1, clk, resetn, reti, wr_bit, bit_in, ack, uart_int;
93 2 dinesha
 
94
output tr0, tr1, intr;
95
output [7:0] int_vec,
96
             ie,
97
             tcon,
98
             ip;
99
 
100
reg [7:0] ip, ie, int_vec;
101
 
102
reg [3:0] tcon_s;
103
reg tcon_tf1, tcon_tf0, tcon_ie1, tcon_ie0;
104
 
105
//
106
// isrc         processing interrupt sources
107
// int_dept
108
wire [2:0] isrc_cur;
109
reg [2:0] isrc [1:0];
110
reg [1:0] int_dept;
111
wire [1:0] int_dept_1;
112
reg int_proc;
113
reg [1:0] int_lev [1:0];
114
wire cur_lev;
115
 
116
assign isrc_cur = int_proc ? isrc[int_dept_1] : 2'h0;
117
assign int_dept_1 = int_dept - 2'b01;
118
assign cur_lev = int_lev[int_dept_1];
119
 
120
//
121
// contains witch level of interrupts is running
122
//reg [1:0] int_levl, int_levl_w;
123
 
124
//
125
// int_ln       waiting interrupts on level n
126
// ip_ln        interrupts on level n
127
// int_src      interrupt sources
128
wire [5:0] int_l0, int_l1;
129
wire [5:0] ip_l0, ip_l1;
130
wire [5:0] int_src;
131
wire il0, il1;
132
 
133
 
134
reg tf0_buff, tf1_buff, ie0_buff, ie1_buff;
135
 
136
//
137
//interrupt priority
138
assign ip_l0 = ~ip[5:0];
139
assign ip_l1 = ip[5:0];
140
 
141
assign int_src = {t2_int, uart_int, tcon_tf1, tcon_ie1, tcon_tf0, tcon_ie0};
142
 
143
//
144
// waiting interrupts
145
assign int_l0 = ip_l0 & {ie[5:0]} & int_src;
146
assign int_l1 = ip_l1 & {ie[5:0]} & int_src;
147
assign il0 = |int_l0;
148
assign il1 = |int_l1;
149
 
150
//
151
// TCON
152
assign tcon = {tcon_tf1, tcon_s[3], tcon_tf0, tcon_s[2], tcon_ie1, tcon_s[1], tcon_ie0, tcon_s[0]};
153
assign tr0 = tcon_s[2];
154
assign tr1 = tcon_s[3];
155
assign intr = |int_vec;
156
 
157
 
158
//
159
// IP
160 25 dinesha
always @(posedge clk or negedge resetn)
161 2 dinesha
begin
162 25 dinesha
 if (resetn == 1'b0) begin
163 36 dinesha
   ip <=`OC8051_RST_IP;
164 2 dinesha
 end else if ((wr) & !(wr_bit) & (wr_addr==`OC8051_SFR_IP)) begin
165 36 dinesha
   ip <= data_in;
166 2 dinesha
 end else if ((wr) & (wr_bit) & (wr_addr[7:3]==`OC8051_SFR_B_IP))
167 36 dinesha
   ip[wr_addr[2:0]] <= bit_in;
168 2 dinesha
end
169
 
170
//
171
// IE
172 25 dinesha
always @(posedge clk or negedge resetn)
173 2 dinesha
begin
174 25 dinesha
 if (resetn == 1'b0) begin
175 36 dinesha
   ie <=`OC8051_RST_IE;
176 2 dinesha
 end else if ((wr) & !(wr_bit) & (wr_addr==`OC8051_SFR_IE)) begin
177 36 dinesha
   ie <= data_in;
178 2 dinesha
 end else if ((wr) & (wr_bit) & (wr_addr[7:3]==`OC8051_SFR_B_IE))
179 36 dinesha
   ie[wr_addr[2:0]] <= bit_in;
180 2 dinesha
end
181
 
182
//
183
// tcon_s
184
//
185 25 dinesha
always @(posedge clk or negedge resetn)
186 2 dinesha
begin
187 25 dinesha
 if (resetn == 1'b0) begin
188 36 dinesha
   tcon_s <=4'b0000;
189 2 dinesha
 end else if ((wr) & !(wr_bit) & (wr_addr==`OC8051_SFR_TCON)) begin
190 36 dinesha
   tcon_s <= {data_in[6], data_in[4], data_in[2], data_in[0]};
191 2 dinesha
 end else if ((wr) & (wr_bit) & (wr_addr[7:3]==`OC8051_SFR_B_TCON)) begin
192
   case (wr_addr[2:0]) /* synopsys full_case parallel_case */
193 36 dinesha
     3'b000: tcon_s[0] <= bit_in;
194
     3'b010: tcon_s[1] <= bit_in;
195
     3'b100: tcon_s[2] <= bit_in;
196
     3'b110: tcon_s[3] <= bit_in;
197 2 dinesha
   endcase
198
 end
199
end
200
 
201
//
202
// tf1 (tmod.7)
203
//
204 25 dinesha
always @(posedge clk or negedge resetn)
205 2 dinesha
begin
206 25 dinesha
 if (resetn == 1'b0) begin
207 36 dinesha
   tcon_tf1 <=1'b0;
208 2 dinesha
 end else if ((wr) & !(wr_bit) & (wr_addr==`OC8051_SFR_TCON)) begin
209 36 dinesha
   tcon_tf1 <= data_in[7];
210 2 dinesha
 end else if ((wr) & (wr_bit) & (wr_addr=={`OC8051_SFR_B_TCON, 3'b111})) begin
211 36 dinesha
   tcon_tf1 <= bit_in;
212 2 dinesha
 end else if (!(tf1_buff) & (tf1)) begin
213 36 dinesha
   tcon_tf1 <= 1'b1;
214 2 dinesha
 end else if (ack & (isrc_cur==`OC8051_ISRC_TF1)) begin
215 36 dinesha
   tcon_tf1 <= 1'b0;
216 2 dinesha
 end
217
end
218
 
219
//
220
// tf0 (tmod.5)
221
//
222 25 dinesha
always @(posedge clk or negedge resetn)
223 2 dinesha
begin
224 25 dinesha
 if (resetn == 1'b0) begin
225 36 dinesha
   tcon_tf0 <=1'b0;
226 2 dinesha
 end else if ((wr) & !(wr_bit) & (wr_addr==`OC8051_SFR_TCON)) begin
227 36 dinesha
   tcon_tf0 <= data_in[5];
228 2 dinesha
 end else if ((wr) & (wr_bit) & (wr_addr=={`OC8051_SFR_B_TCON, 3'b101})) begin
229 36 dinesha
   tcon_tf0 <= bit_in;
230 2 dinesha
 end else if (!(tf0_buff) & (tf0)) begin
231 36 dinesha
   tcon_tf0 <= 1'b1;
232 2 dinesha
 end else if (ack & (isrc_cur==`OC8051_ISRC_TF0)) begin
233 36 dinesha
   tcon_tf0 <= 1'b0;
234 2 dinesha
 end
235
end
236
 
237
 
238
//
239
// ie0 (tmod.1)
240
//
241 25 dinesha
always @(posedge clk or negedge resetn)
242 2 dinesha
begin
243 25 dinesha
 if (resetn == 1'b0) begin
244 36 dinesha
   tcon_ie0 <=1'b0;
245 2 dinesha
 end else if ((wr) & !(wr_bit) & (wr_addr==`OC8051_SFR_TCON)) begin
246 36 dinesha
   tcon_ie0 <= data_in[1];
247 2 dinesha
 end else if ((wr) & (wr_bit) & (wr_addr=={`OC8051_SFR_B_TCON, 3'b001})) begin
248 36 dinesha
   tcon_ie0 <= bit_in;
249 2 dinesha
 end else if (((tcon_s[0]) & (ie0_buff) & !(ie0)) | (!(tcon_s[0]) & !(ie0))) begin
250 36 dinesha
   tcon_ie0 <= 1'b1;
251 2 dinesha
 end else if (ack & (isrc_cur==`OC8051_ISRC_IE0) & (tcon_s[0])) begin
252 36 dinesha
   tcon_ie0 <= 1'b0;
253 2 dinesha
 end else if (!(tcon_s[0]) & (ie0)) begin
254 36 dinesha
   tcon_ie0 <= 1'b0;
255 2 dinesha
 end
256
end
257
 
258
 
259
//
260
// ie1 (tmod.3)
261
//
262 25 dinesha
always @(posedge clk or negedge resetn)
263 2 dinesha
begin
264 25 dinesha
 if (resetn == 1'b0) begin
265 36 dinesha
   tcon_ie1 <=1'b0;
266 2 dinesha
 end else if ((wr) & !(wr_bit) & (wr_addr==`OC8051_SFR_TCON)) begin
267 36 dinesha
   tcon_ie1 <= data_in[3];
268 2 dinesha
 end else if ((wr) & (wr_bit) & (wr_addr=={`OC8051_SFR_B_TCON, 3'b011})) begin
269 36 dinesha
   tcon_ie1 <= bit_in;
270 2 dinesha
 end else if (((tcon_s[1]) & (ie1_buff) & !(ie1)) | (!(tcon_s[1]) & !(ie1))) begin
271 36 dinesha
   tcon_ie1 <= 1'b1;
272 2 dinesha
 end else if (ack & (isrc_cur==`OC8051_ISRC_IE1) & (tcon_s[1])) begin
273 36 dinesha
   tcon_ie1 <= 1'b0;
274 2 dinesha
 end else if (!(tcon_s[1]) & (ie1)) begin
275 36 dinesha
   tcon_ie1 <= 1'b0;
276 2 dinesha
 end
277
end
278
 
279
//
280
// interrupt processing
281 25 dinesha
always @(posedge clk or negedge resetn)
282 2 dinesha
begin
283 25 dinesha
  if (resetn == 1'b0) begin
284 36 dinesha
    int_vec <= 8'h00;
285
    int_dept <= 2'b0;
286
    isrc[0] <= 3'h0;
287
    isrc[1] <= 3'h0;
288
    int_proc <= 1'b0;
289
    int_lev[0] <= 1'b0;
290
    int_lev[1] <= 1'b0;
291 2 dinesha
  end else if (reti & int_proc) begin  // return from interrupt
292
   if (int_dept==2'b01)
293 36 dinesha
     int_proc <= 1'b0;
294
   int_dept <= int_dept - 2'b01;
295 2 dinesha
  end else if (((ie[7]) & (!cur_lev) || !int_proc) & il1) begin  // interrupt on level 1
296 36 dinesha
   int_proc <= 1'b1;
297
   int_lev[int_dept] <= `OC8051_ILEV_L1;
298
   int_dept <= int_dept + 2'b01;
299 2 dinesha
   if (int_l1[0]) begin
300 36 dinesha
     int_vec <= `OC8051_INT_X0;
301
     isrc[int_dept] <= `OC8051_ISRC_IE0;
302 2 dinesha
   end else if (int_l1[1]) begin
303 36 dinesha
     int_vec <= `OC8051_INT_T0;
304
     isrc[int_dept] <= `OC8051_ISRC_TF0;
305 2 dinesha
   end else if (int_l1[2]) begin
306 36 dinesha
     int_vec <= `OC8051_INT_X1;
307
     isrc[int_dept] <= `OC8051_ISRC_IE1;
308 2 dinesha
   end else if (int_l1[3]) begin
309 36 dinesha
     int_vec <= `OC8051_INT_T1;
310
     isrc[int_dept] <= `OC8051_ISRC_TF1;
311 2 dinesha
   end else if (int_l1[4]) begin
312 36 dinesha
     int_vec <= `OC8051_INT_UART;
313
     isrc[int_dept] <= `OC8051_ISRC_UART;
314 2 dinesha
   end else if (int_l1[5]) begin
315 36 dinesha
     int_vec <= `OC8051_INT_T2;
316
     isrc[int_dept] <= `OC8051_ISRC_T2;
317 2 dinesha
   end
318
 
319
 end else if ((ie[7]) & !int_proc & il0) begin  // interrupt on level 0
320 36 dinesha
   int_proc <= 1'b1;
321
   int_lev[int_dept] <= `OC8051_ILEV_L0;
322
   int_dept <= 2'b01;
323 2 dinesha
   if (int_l0[0]) begin
324 36 dinesha
     int_vec <= `OC8051_INT_X0;
325
     isrc[int_dept] <= `OC8051_ISRC_IE0;
326 2 dinesha
   end else if (int_l0[1]) begin
327 36 dinesha
     int_vec <= `OC8051_INT_T0;
328
     isrc[int_dept] <= `OC8051_ISRC_TF0;
329 2 dinesha
   end else if (int_l0[2]) begin
330 36 dinesha
     int_vec <= `OC8051_INT_X1;
331
     isrc[int_dept] <= `OC8051_ISRC_IE1;
332 2 dinesha
   end else if (int_l0[3]) begin
333 36 dinesha
     int_vec <= `OC8051_INT_T1;
334
     isrc[int_dept] <= `OC8051_ISRC_TF1;
335 2 dinesha
   end else if (int_l0[4]) begin
336 36 dinesha
     int_vec <= `OC8051_INT_UART;
337
     isrc[int_dept] <= `OC8051_ISRC_UART;
338 2 dinesha
   end else if (int_l0[5]) begin
339 36 dinesha
     int_vec <= `OC8051_INT_T2;
340
     isrc[int_dept] <= `OC8051_ISRC_T2;
341 2 dinesha
   end
342
 end else begin
343 36 dinesha
   int_vec <= 8'h00;
344 2 dinesha
 end
345
end
346
 
347
 
348 25 dinesha
always @(posedge clk or negedge resetn)
349
  if (resetn == 1'b0) begin
350 36 dinesha
    tf0_buff <= 1'b0;
351
    tf1_buff <= 1'b0;
352
    ie0_buff <= 1'b0;
353
    ie1_buff <= 1'b0;
354 2 dinesha
  end else begin
355 36 dinesha
    tf0_buff <= tf0;
356
    tf1_buff <= tf1;
357
    ie0_buff <= ie0;
358
    ie1_buff <= ie1;
359 2 dinesha
  end
360
 
361
endmodule

powered by: WebSVN 2.1.0

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