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

Subversion Repositories interrupt_controller

[/] [interrupt_controller/] [trunk/] [rtl/] [int_contr.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 Bjarneorn
`timescale 1ns / 1ps
2
 
3
module interrupt_controller( clk,
4
                             reset,
5
                                                                          cs,
6
                                                                          adr,
7
                                                                          oe,
8
                                                                          we,
9
                                                                          data_i,
10
                                                                          data_o,
11
                                                                          int1,
12
                             int2,
13
                                                                          int3,
14
                                                                          int4,
15
                                                                          int5,
16
                                                                          int6,
17
                                                                          int7,
18
                                                                          ack,
19
                                                                          dtack,
20
                                                                          ipl
21
                            );
22
 
23
input  clk;
24
input  reset;
25
input  cs;
26
input  [3:0] adr;
27
input  oe;
28
input  we;
29
input  [7:0] data_i;
30
output [7:0] data_o;
31
input  int1, int2, int3, int4, int5, int6, int7;
32
input  ack;
33
output dtack;
34
output [2:0] ipl;
35
 
36
reg dtack = 1'b0;
37
reg ack_r = 1'b0;
38
reg [7:0] data_r;
39
reg [7:0] vectors [0:6];
40
reg [2:0] irq_nr [0:6];
41
reg [6:0] int_mask;
42
reg [6:0] int_pending;
43
reg [6:0] ie_reg;
44
reg [2:0] ipl_r, ipl_n;
45
 
46
wire [2:0] int_no = (6 - ipl_r);
47
wire assert_ack   = (ack && ~ack_r);
48
wire deassert_ack = (ack_r && ~ack);
49
 
50
wire [2:0] ix = adr[2:0];
51
wire vectors_stb_we = (cs && we && adr[3] == 1'b0 && adr[2:0] != 3'b111 );
52
wire vectors_stb_oe = (cs && oe && adr[3] == 1'b0 && adr[2:0] != 3'b111 );
53
wire irq_stb_we     = (cs && we && adr[3] == 1'b1 && adr[2:0] != 3'b111 );
54
wire irq_stb_oe     = (cs && oe && adr[3] == 1'b1 && adr[2:0] != 3'b111 );
55
wire ier_stb_we     = (cs && we && adr == 4'b0111);
56
wire ier_stb_oe     = (cs && oe && adr == 4'b0111);
57
 
58
reg int1_r, int2_r, int3_r, int4_r, int5_r, int6_r, int7_r;
59
 
60
wire int1_on = (int1_r == 1'b0 && int1);
61
wire int2_on = (int2_r == 1'b0 && int2);
62
wire int3_on = (int3_r == 1'b0 && int3);
63
wire int4_on = (int4_r == 1'b0 && int4);
64
wire int5_on = (int5_r == 1'b0 && int5);
65
wire int6_on = (int6_r == 1'b0 && int6);
66
wire int7_on = (int7_r == 1'b0 && int7);
67
wire int1_of = (int1_r == 1'b1 && !int1);
68
wire int2_of = (int2_r == 1'b1 && !int2);
69
wire int3_of = (int3_r == 1'b1 && !int3);
70
wire int4_of = (int4_r == 1'b1 && !int4);
71
wire int5_of = (int5_r == 1'b1 && !int5);
72
wire int6_of = (int6_r == 1'b1 && !int6);
73
wire int7_of = (int7_r == 1'b1 && !int7);
74
 
75
wire pos_edge_trigger = (int1_on || int2_on || int3_on || int4_on || int5_on || int6_on || int7_on );
76
wire neg_edge_trigger = (int1_of || int2_of || int3_of || int4_of || int5_of || int6_of || int7_of );
77
 
78
integer i;
79
 
80
initial
81
begin
82
        int_pending = 7'b0000000;
83
        int_mask    = 7'b1111111;
84
        ie_reg      = 7'b1111111;
85
        ipl_r       = 3'b111;
86
        dtack       = 1'b1;
87
        int1_r      = 1'b0;
88
        int2_r      = 1'b0;
89
        int3_r      = 1'b0;
90
        int4_r      = 1'b0;
91
        int5_r      = 1'b0;
92
        int6_r      = 1'b0;
93
        int7_r      = 1'b0;
94
        for(i=0;i<7;i=i+1)
95
        begin
96
                vectors[i] = 25 + i;
97
                irq_nr[i]  = i;
98
        end
99
end
100
 
101
always @(posedge clk)
102
begin
103
        if( reset )
104
        begin
105
                int1_r <= 1'b0;
106
                int2_r <= 1'b0;
107
                int3_r <= 1'b0;
108
                int4_r <= 1'b0;
109
                int5_r <= 1'b0;
110
                int6_r <= 1'b0;
111
                int7_r <= 1'b0;
112
        end else begin
113
                int1_r <= int1;
114
                int2_r <= int2;
115
                int3_r <= int3;
116
                int4_r <= int4;
117
                int5_r <= int5;
118
                int6_r <= int6;
119
                int7_r <= int7;
120
        end
121
end
122
 
123
always @(posedge clk)
124
        if( reset )
125
                ack_r <= 1'b0;
126
        else
127
                ack_r <= ack;
128
 
129
always @(posedge clk)
130
begin
131
        if( vectors_stb_we )
132
                vectors[ix] = data_i;
133
end
134
 
135
always @(posedge clk)
136
begin
137
        if( irq_stb_we )
138
                irq_nr[ix]  = data_i;
139
end
140
 
141
always @(posedge clk)
142
begin
143
        if( reset )
144
                ie_reg      = 7'b1111111;
145
        else if( ier_stb_we )
146
                ie_reg      = data_i;
147
end
148
 
149
always @(posedge clk)
150
begin
151
        dtack = 1'b1;
152
        if( ack )
153
        begin
154
                if( assert_ack )
155
                        data_r = vectors[int_no];
156
                dtack  = (ipl_r == 3'b111);
157
        end else if( cs ) begin
158
                if( vectors_stb_oe )
159
                        data_r = vectors[ix];
160
                else if( irq_stb_oe )
161
                        data_r = irq_nr[ix];
162
                else if( ier_stb_oe )
163
                        data_r = ie_reg;
164
                else
165
                        data_r = 8'bZ;
166
                dtack = 1'b0;
167
        end else
168
                data_r = 8'bZ;
169
end
170
 
171
always @(posedge clk)
172
begin
173
        if( reset )
174
        begin
175
                int_pending = 7'b0000000;
176
        end else if( pos_edge_trigger ) begin
177
                if(int7 && ie_reg[6])
178
                        int_pending[6] = 1;
179
                else if(int6 && ie_reg[5])
180
                        int_pending[5] = 1;
181
                else if(int5 && ie_reg[4])
182
                        int_pending[4] = 1;
183
                else if(int4 && ie_reg[3])
184
                        int_pending[3] = 1;
185
                else if(int3 && ie_reg[2])
186
                        int_pending[2] = 1;
187
                else if(int2 && ie_reg[1])
188
                        int_pending[1] = 1;
189
                else if(int1 && ie_reg[0])
190
                        int_pending[0] = 1;
191
        end else if( neg_edge_trigger ) begin
192
                if(!int7)
193
                        int_pending[6] = 0;
194
                if(!int6)
195
                        int_pending[5] = 0;
196
                if(!int5)
197
                        int_pending[4] = 0;
198
                if(!int4)
199
                        int_pending[3] = 0;
200
                if(!int3)
201
                        int_pending[2] = 0;
202
                if(!int2)
203
                        int_pending[1] = 0;
204
                if(!int1)
205
                        int_pending[0] = 0;
206
        end
207
end
208
 
209
always @(posedge clk)
210
begin
211
        if( deassert_ack || reset )
212
        begin
213
                ipl_r  = 3'b111;
214
        end else if( ipl_r == 3'b111 ) begin
215
                if( int_pending[6] && int_mask[6] )
216
                        ipl_r     = ~irq_nr[6];
217
                else if( int_pending[5] && int_mask[5] )
218
                        ipl_r     = ~irq_nr[5];
219
                else if( int_pending[4] && int_mask[4] )
220
                        ipl_r     = ~irq_nr[4];
221
                else if( int_pending[3] && int_mask[3] )
222
                        ipl_r     = ~irq_nr[3];
223
                else if( int_pending[2] && int_mask[2] )
224
                        ipl_r     = ~irq_nr[2];
225
                else if( int_pending[1] && int_mask[1] )
226
                        ipl_r     = ~irq_nr[1];
227
                else if( int_pending[0] && int_mask[0] )
228
                        ipl_r     = ~irq_nr[0];
229
        end
230
end
231
 
232
always @(posedge clk)
233
begin
234
        if( reset )
235
                int_mask = 7'b1111111;
236
        else if ( !pos_edge_trigger && !neg_edge_trigger )
237
                casex(int_pending)
238
                        7'b1xxxxxx: int_mask = 7'b0000000;
239
                        7'b01xxxxx: int_mask = 7'b1000000;
240
                        7'b001xxxx: int_mask = 7'b1100000;
241
                        7'b0001xxx: int_mask = 7'b1110000;
242
                        7'b00001xx: int_mask = 7'b1111000;
243
                        7'b000001x: int_mask = 7'b1111100;
244
                        7'b0000001: int_mask = 7'b1111110;
245
                        7'b0000000: int_mask = 7'b1111111;
246
                endcase
247
end
248
 
249
assign data_o = data_r;
250
 
251
assign ipl = ipl_r;
252
 
253
endmodule

powered by: WebSVN 2.1.0

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