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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [system/] [interrupt_controller.v] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 csantifort
//////////////////////////////////////////////////////////////////
2
//                                                              //
3
//  Interrupt Controller for Amber                              //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9
//  Wishbone slave module that arbitrates between a number of   //
10
//  interrupt sources.
11
//                                                              //
12
//  Author(s):                                                  //
13
//      - Conor Santifort, csantifort.amber@gmail.com           //
14
//                                                              //
15
//////////////////////////////////////////////////////////////////
16
//                                                              //
17
// Copyright (C) 2010 Authors and OPENCORES.ORG                 //
18
//                                                              //
19
// This source file may be used and distributed without         //
20
// restriction provided that this copyright statement is not    //
21
// removed from the file and that any derivative work contains  //
22
// the original copyright notice and the associated disclaimer. //
23
//                                                              //
24
// This source file is free software; you can redistribute it   //
25
// and/or modify it under the terms of the GNU Lesser General   //
26
// Public License as published by the Free Software Foundation; //
27
// either version 2.1 of the License, or (at your option) any   //
28
// later version.                                               //
29
//                                                              //
30
// This source is distributed in the hope that it will be       //
31
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
32
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
33
// PURPOSE.  See the GNU Lesser General Public License for more //
34
// details.                                                     //
35
//                                                              //
36
// You should have received a copy of the GNU Lesser General    //
37
// Public License along with this source; if not, download it   //
38
// from http://www.opencores.org/lgpl.shtml                     //
39
//                                                              //
40
//////////////////////////////////////////////////////////////////
41
 
42
 
43
module interrupt_controller (
44
input                       i_clk,
45
 
46
input       [31:0]          i_wb_adr,
47
input       [3:0]           i_wb_sel,
48
input                       i_wb_we,
49
output      [31:0]          o_wb_dat,
50
input       [31:0]          i_wb_dat,
51
input                       i_wb_cyc,
52
input                       i_wb_stb,
53
output                      o_wb_ack,
54
output                      o_wb_err,
55
 
56
output                      o_irq,
57
output                      o_firq,
58
 
59
input                       i_uart0_int,
60
input                       i_uart1_int,
61
input                       i_ethmac_int,
62
input                       i_test_reg_irq,
63
input                       i_test_reg_firq,
64
input       [2:0]           i_tm_timer_int
65
 
66
);
67
 
68
 
69
`include "register_addresses.v"
70
 
71
 
72
// Wishbone registers
73
reg  [31:0]     irq0_enable_reg  = 'd0;
74
reg  [31:0]     firq0_enable_reg = 'd0;
75
reg  [31:0]     irq1_enable_reg  = 'd0;
76
reg  [31:0]     firq1_enable_reg = 'd0;
77
reg             softint_0_reg    = 'd0;
78
reg             softint_1_reg    = 'd0;
79
 
80
wire [31:0]     raw_interrupts;
81
wire [31:0]     irq0_interrupts;
82
wire [31:0]     firq0_interrupts;
83
wire [31:0]     irq1_interrupts;
84
wire [31:0]     firq1_interrupts;
85
 
86
wire            irq_0;
87
wire            firq_0;
88
wire            irq_1;
89
wire            firq_1;
90
 
91
// Wishbone interface
92
reg  [31:0]     wb_rdata = 'd0;
93
wire            wb_start_write;
94
wire            wb_start_read;
95
reg             wb_start_read_d1 = 'd0;
96
 
97
 
98
// ======================================================
99
// Wishbone Interface
100
// ======================================================
101
 
102
// Can't start a write while a read is completing. The ack for the read cycle
103
// needs to be sent first
104
assign wb_start_write = i_wb_stb && i_wb_we && !wb_start_read_d1;
105
assign wb_start_read  = i_wb_stb && !i_wb_we && !o_wb_ack;
106
 
107
always @( posedge i_clk )
108
    wb_start_read_d1 <= wb_start_read;
109
 
110
assign o_wb_dat = wb_rdata;
111
 
112
assign o_wb_err = 1'd0;
113
assign o_wb_ack = i_wb_stb && ( wb_start_write || wb_start_read_d1 );
114
 
115
 
116
// ======================================
117
// Interrupts
118
// ======================================
119
assign raw_interrupts =  {23'd0,
120
                          i_ethmac_int,             // 8: Ethernet MAC interrupt
121
                          i_tm_timer_int[2],        // 7: Timer Module Interrupt 2
122
                          i_tm_timer_int[1],        // 6: Timer Module Interrupt 1
123
                          i_tm_timer_int[0],        // 5: Timer Module Interrupt 0
124
                          1'd0,
125
                          1'd0,
126
                          i_uart1_int,              // 2: Uart 1 interrupt
127
                          i_uart0_int,              // 1: Uart 0 interrupt
128
                          1'd0                      // 0: Software interrupt not 
129
                         };                         // here because its not maskable
130
 
131
assign irq0_interrupts  = {raw_interrupts[31:1], softint_0_reg} & irq0_enable_reg;
132
assign firq0_interrupts = raw_interrupts & firq0_enable_reg;
133
assign irq1_interrupts  = {raw_interrupts[31:1], softint_1_reg} & irq1_enable_reg;
134
assign firq1_interrupts  = raw_interrupts & firq1_enable_reg;
135
 
136
// The interrupts from the test registers module are not masked,
137
// just to keep their usage really simple
138
assign irq_0  = |{irq0_interrupts, i_test_reg_irq};
139
assign firq_0 = |{firq0_interrupts, i_test_reg_firq};
140
assign irq_1  = |irq1_interrupts;
141
assign firq_1 = |firq1_interrupts;
142
 
143
assign o_irq  = irq_0  | irq_1;
144
assign o_firq = firq_0 | firq_1;
145
 
146
// ========================================================
147
// Register Writes
148
// ========================================================
149
always @( posedge i_clk )
150
    if ( wb_start_write )
151
        case ( i_wb_adr[15:0] )
152
            AMBER_IC_IRQ0_ENABLESET:  irq0_enable_reg  <=  irq0_enable_reg  | ( i_wb_dat);
153
            AMBER_IC_IRQ0_ENABLECLR:  irq0_enable_reg  <=  irq0_enable_reg  & (~i_wb_dat);
154
            AMBER_IC_FIRQ0_ENABLESET: firq0_enable_reg <=  firq0_enable_reg | ( i_wb_dat);
155
            AMBER_IC_FIRQ0_ENABLECLR: firq0_enable_reg <=  firq0_enable_reg & (~i_wb_dat);
156
 
157
            AMBER_IC_INT_SOFTSET_0:   softint_0_reg    <=  softint_0_reg   | ( i_wb_dat[0]);
158
            AMBER_IC_INT_SOFTCLEAR_0: softint_0_reg    <=  softint_0_reg   & (~i_wb_dat[0]);
159
 
160
            AMBER_IC_IRQ1_ENABLESET:  irq1_enable_reg  <=  irq1_enable_reg  | ( i_wb_dat);
161
            AMBER_IC_IRQ1_ENABLECLR:  irq1_enable_reg  <=  irq1_enable_reg  & (~i_wb_dat);
162
            AMBER_IC_FIRQ1_ENABLESET: firq1_enable_reg <=  firq1_enable_reg | ( i_wb_dat);
163
            AMBER_IC_FIRQ1_ENABLECLR: firq1_enable_reg <=  firq1_enable_reg & (~i_wb_dat);
164
 
165
            AMBER_IC_INT_SOFTSET_1:   softint_1_reg    <=  softint_1_reg   | ( i_wb_dat[0]);
166
            AMBER_IC_INT_SOFTCLEAR_1: softint_1_reg    <=  softint_1_reg   & (~i_wb_dat[0]);
167
        endcase
168
 
169
 
170
// ========================================================
171
// Register Reads
172
// ========================================================
173
always @( posedge i_clk )
174
    if ( wb_start_read )
175
        case ( i_wb_adr[15:0] )
176
 
177
            AMBER_IC_IRQ0_ENABLESET:    wb_rdata <= irq0_enable_reg;
178
            AMBER_IC_FIRQ0_ENABLESET:   wb_rdata <= firq0_enable_reg;
179
            AMBER_IC_IRQ0_RAWSTAT:      wb_rdata <= raw_interrupts;
180
            AMBER_IC_IRQ0_STATUS:       wb_rdata <= irq0_interrupts;
181
            AMBER_IC_FIRQ0_RAWSTAT:     wb_rdata <= raw_interrupts;
182
            AMBER_IC_FIRQ0_STATUS:      wb_rdata <= firq0_interrupts;
183
 
184
            AMBER_IC_INT_SOFTSET_0:     wb_rdata <= {31'd0, softint_0_reg};
185
            AMBER_IC_INT_SOFTCLEAR_0:   wb_rdata <= {31'd0, softint_0_reg};
186
 
187
            AMBER_IC_IRQ1_ENABLESET:    wb_rdata <= irq1_enable_reg;
188
            AMBER_IC_FIRQ1_ENABLESET:   wb_rdata <= firq1_enable_reg;
189
            AMBER_IC_IRQ1_RAWSTAT:      wb_rdata <= raw_interrupts;
190
            AMBER_IC_IRQ1_STATUS:       wb_rdata <= irq1_interrupts;
191
            AMBER_IC_FIRQ1_RAWSTAT:     wb_rdata <= raw_interrupts;
192
            AMBER_IC_FIRQ1_STATUS:      wb_rdata <= firq1_interrupts;
193
 
194
            AMBER_IC_INT_SOFTSET_1:     wb_rdata <= {31'd0, softint_1_reg};
195
            AMBER_IC_INT_SOFTCLEAR_1:   wb_rdata <= {31'd0, softint_1_reg};
196
 
197
            default:                    wb_rdata <= 32'h22334455;
198
 
199
        endcase
200
 
201
 
202
 
203
// =======================================================================================
204
// =======================================================================================
205
// =======================================================================================
206
// Non-synthesizable debug code
207
// =======================================================================================
208
 
209
 
210
//synopsys translate_off
211
`ifdef AMBER_IC_DEBUG
212
 
213
wire wb_read_ack = i_wb_stb && ( wb_start_write || wb_start_read_d1 );
214
 
215
// -----------------------------------------------
216
// Report Interrupt Controller Register accesses
217
// -----------------------------------------------  
218
always @(posedge i_clk)
219
    if ( wb_read_ack || wb_start_write )
220
        begin
221
        `TB_DEBUG_MESSAGE
222
 
223
        if ( wb_start_write )
224
            $write("Write 0x%08x to   ", i_wb_dat);
225
        else
226
            $write("Read  0x%08x from ", o_wb_dat);
227
 
228
        case ( i_wb_adr[15:0] )
229
            AMBER_IC_IRQ0_STATUS:
230
                $write(" Interrupt Controller module IRQ0 Status");
231
            AMBER_IC_IRQ0_RAWSTAT:
232
                $write(" Interrupt Controller module IRQ0 Raw Status");
233
            AMBER_IC_IRQ0_ENABLESET:
234
                $write(" Interrupt Controller module IRQ0 Enable Set");
235
            AMBER_IC_IRQ0_ENABLECLR:
236
                $write(" Interrupt Controller module IRQ0 Enable Clear");
237
            AMBER_IC_FIRQ0_STATUS:
238
                $write(" Interrupt Controller module FIRQ0 Status");
239
            AMBER_IC_FIRQ0_RAWSTAT:
240
                $write(" Interrupt Controller module FIRQ0 Raw Status");
241
            AMBER_IC_FIRQ0_ENABLESET:
242
                $write(" Interrupt Controller module FIRQ0 Enable set");
243
            AMBER_IC_FIRQ0_ENABLECLR:
244
                $write(" Interrupt Controller module FIRQ0 Enable Clear");
245
            AMBER_IC_INT_SOFTSET_0:
246
                $write(" Interrupt Controller module SoftInt 0 Set");
247
            AMBER_IC_INT_SOFTCLEAR_0:
248
                $write(" Interrupt Controller module SoftInt 0 Clear");
249
            AMBER_IC_IRQ1_STATUS:
250
                $write(" Interrupt Controller module IRQ1 Status");
251
            AMBER_IC_IRQ1_RAWSTAT:
252
                $write(" Interrupt Controller module IRQ1 Raw Status");
253
            AMBER_IC_IRQ1_ENABLESET:
254
                $write(" Interrupt Controller module IRQ1 Enable Set");
255
            AMBER_IC_IRQ1_ENABLECLR:
256
                $write(" Interrupt Controller module IRQ1 Enable Clear");
257
            AMBER_IC_FIRQ1_STATUS:
258
                $write(" Interrupt Controller module FIRQ1 Status");
259
            AMBER_IC_FIRQ1_RAWSTAT:
260
                $write(" Interrupt Controller module FIRQ1 Raw Status");
261
            AMBER_IC_FIRQ1_ENABLESET:
262
                $write(" Interrupt Controller module FIRQ1 Enable set");
263
            AMBER_IC_FIRQ1_ENABLECLR:
264
                $write(" Interrupt Controller module FIRQ1 Enable Clear");
265
            AMBER_IC_INT_SOFTSET_1:
266
                $write(" Interrupt Controller module SoftInt 1 Set");
267
            AMBER_IC_INT_SOFTCLEAR_1:
268
                $write(" Interrupt Controller module SoftInt 1 Clear");
269
 
270
            default:
271
                begin
272
                $write(" unknown Amber IC Register region");
273
                $write(", Address 0x%08h\n", i_wb_adr);
274
                `TB_ERROR_MESSAGE
275
                end
276
        endcase
277
 
278
        $write(", Address 0x%08h\n", i_wb_adr);
279
        end
280
`endif
281
 
282
//synopsys translate_on
283
 
284
 
285
endmodule
286
 

powered by: WebSVN 2.1.0

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