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

Subversion Repositories amber

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

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 35 csantifort
module interrupt_controller  #(
44
parameter WB_DWIDTH  = 32,
45
parameter WB_SWIDTH  = 4
46
)(
47 2 csantifort
input                       i_clk,
48
 
49
input       [31:0]          i_wb_adr,
50 35 csantifort
input       [WB_SWIDTH-1:0] i_wb_sel,
51 2 csantifort
input                       i_wb_we,
52 35 csantifort
output      [WB_DWIDTH-1:0] o_wb_dat,
53
input       [WB_DWIDTH-1:0] i_wb_dat,
54 2 csantifort
input                       i_wb_cyc,
55
input                       i_wb_stb,
56
output                      o_wb_ack,
57
output                      o_wb_err,
58
 
59
output                      o_irq,
60
output                      o_firq,
61
 
62
input                       i_uart0_int,
63
input                       i_uart1_int,
64
input                       i_ethmac_int,
65
input                       i_test_reg_irq,
66
input                       i_test_reg_firq,
67
input       [2:0]           i_tm_timer_int
68
 
69
);
70
 
71
 
72
`include "register_addresses.v"
73
 
74
 
75
// Wishbone registers
76
reg  [31:0]     irq0_enable_reg  = 'd0;
77
reg  [31:0]     firq0_enable_reg = 'd0;
78
reg  [31:0]     irq1_enable_reg  = 'd0;
79
reg  [31:0]     firq1_enable_reg = 'd0;
80
reg             softint_0_reg    = 'd0;
81
reg             softint_1_reg    = 'd0;
82
 
83
wire [31:0]     raw_interrupts;
84
wire [31:0]     irq0_interrupts;
85
wire [31:0]     firq0_interrupts;
86
wire [31:0]     irq1_interrupts;
87
wire [31:0]     firq1_interrupts;
88
 
89
wire            irq_0;
90
wire            firq_0;
91
wire            irq_1;
92
wire            firq_1;
93
 
94
// Wishbone interface
95 35 csantifort
reg  [31:0]     wb_rdata32 = 'd0;
96 2 csantifort
wire            wb_start_write;
97
wire            wb_start_read;
98
reg             wb_start_read_d1 = 'd0;
99 35 csantifort
wire [31:0]     wb_wdata32;
100 2 csantifort
 
101
 
102
// ======================================================
103
// Wishbone Interface
104
// ======================================================
105
 
106
// Can't start a write while a read is completing. The ack for the read cycle
107
// needs to be sent first
108
assign wb_start_write = i_wb_stb && i_wb_we && !wb_start_read_d1;
109
assign wb_start_read  = i_wb_stb && !i_wb_we && !o_wb_ack;
110
 
111
always @( posedge i_clk )
112
    wb_start_read_d1 <= wb_start_read;
113
 
114
 
115
assign o_wb_err = 1'd0;
116
assign o_wb_ack = i_wb_stb && ( wb_start_write || wb_start_read_d1 );
117
 
118 35 csantifort
generate
119
if (WB_DWIDTH == 128)
120
    begin : wb128
121
    assign wb_wdata32   = i_wb_adr[3:2] == 2'd3 ? i_wb_dat[127:96] :
122
                          i_wb_adr[3:2] == 2'd2 ? i_wb_dat[ 95:64] :
123
                          i_wb_adr[3:2] == 2'd1 ? i_wb_dat[ 63:32] :
124
                                                  i_wb_dat[ 31: 0] ;
125
 
126
    assign o_wb_dat    = {4{wb_rdata32}};
127
    end
128
else
129
    begin : wb32
130
    assign wb_wdata32  = i_wb_dat;
131
    assign o_wb_dat    = wb_rdata32;
132
    end
133
endgenerate
134 2 csantifort
 
135 35 csantifort
 
136 2 csantifort
// ======================================
137
// Interrupts
138
// ======================================
139
assign raw_interrupts =  {23'd0,
140
                          i_ethmac_int,             // 8: Ethernet MAC interrupt
141 61 csantifort
 
142 2 csantifort
                          i_tm_timer_int[2],        // 7: Timer Module Interrupt 2
143
                          i_tm_timer_int[1],        // 6: Timer Module Interrupt 1
144
                          i_tm_timer_int[0],        // 5: Timer Module Interrupt 0
145
                          1'd0,
146 61 csantifort
 
147 2 csantifort
                          1'd0,
148
                          i_uart1_int,              // 2: Uart 1 interrupt
149
                          i_uart0_int,              // 1: Uart 0 interrupt
150
                          1'd0                      // 0: Software interrupt not 
151
                         };                         // here because its not maskable
152
 
153
assign irq0_interrupts  = {raw_interrupts[31:1], softint_0_reg} & irq0_enable_reg;
154
assign firq0_interrupts = raw_interrupts & firq0_enable_reg;
155
assign irq1_interrupts  = {raw_interrupts[31:1], softint_1_reg} & irq1_enable_reg;
156
assign firq1_interrupts  = raw_interrupts & firq1_enable_reg;
157
 
158
// The interrupts from the test registers module are not masked,
159
// just to keep their usage really simple
160
assign irq_0  = |{irq0_interrupts, i_test_reg_irq};
161
assign firq_0 = |{firq0_interrupts, i_test_reg_firq};
162
assign irq_1  = |irq1_interrupts;
163
assign firq_1 = |firq1_interrupts;
164
 
165
assign o_irq  = irq_0  | irq_1;
166
assign o_firq = firq_0 | firq_1;
167
 
168
// ========================================================
169
// Register Writes
170
// ========================================================
171
always @( posedge i_clk )
172
    if ( wb_start_write )
173
        case ( i_wb_adr[15:0] )
174
            AMBER_IC_IRQ0_ENABLESET:  irq0_enable_reg  <=  irq0_enable_reg  | ( i_wb_dat);
175
            AMBER_IC_IRQ0_ENABLECLR:  irq0_enable_reg  <=  irq0_enable_reg  & (~i_wb_dat);
176
            AMBER_IC_FIRQ0_ENABLESET: firq0_enable_reg <=  firq0_enable_reg | ( i_wb_dat);
177
            AMBER_IC_FIRQ0_ENABLECLR: firq0_enable_reg <=  firq0_enable_reg & (~i_wb_dat);
178
 
179
            AMBER_IC_INT_SOFTSET_0:   softint_0_reg    <=  softint_0_reg   | ( i_wb_dat[0]);
180
            AMBER_IC_INT_SOFTCLEAR_0: softint_0_reg    <=  softint_0_reg   & (~i_wb_dat[0]);
181
 
182
            AMBER_IC_IRQ1_ENABLESET:  irq1_enable_reg  <=  irq1_enable_reg  | ( i_wb_dat);
183
            AMBER_IC_IRQ1_ENABLECLR:  irq1_enable_reg  <=  irq1_enable_reg  & (~i_wb_dat);
184
            AMBER_IC_FIRQ1_ENABLESET: firq1_enable_reg <=  firq1_enable_reg | ( i_wb_dat);
185
            AMBER_IC_FIRQ1_ENABLECLR: firq1_enable_reg <=  firq1_enable_reg & (~i_wb_dat);
186
 
187
            AMBER_IC_INT_SOFTSET_1:   softint_1_reg    <=  softint_1_reg   | ( i_wb_dat[0]);
188
            AMBER_IC_INT_SOFTCLEAR_1: softint_1_reg    <=  softint_1_reg   & (~i_wb_dat[0]);
189
        endcase
190
 
191
 
192
// ========================================================
193
// Register Reads
194
// ========================================================
195
always @( posedge i_clk )
196
    if ( wb_start_read )
197
        case ( i_wb_adr[15:0] )
198
 
199 35 csantifort
            AMBER_IC_IRQ0_ENABLESET:    wb_rdata32 <= irq0_enable_reg;
200
            AMBER_IC_FIRQ0_ENABLESET:   wb_rdata32 <= firq0_enable_reg;
201
            AMBER_IC_IRQ0_RAWSTAT:      wb_rdata32 <= raw_interrupts;
202
            AMBER_IC_IRQ0_STATUS:       wb_rdata32 <= irq0_interrupts;
203
            AMBER_IC_FIRQ0_RAWSTAT:     wb_rdata32 <= raw_interrupts;
204
            AMBER_IC_FIRQ0_STATUS:      wb_rdata32 <= firq0_interrupts;
205 2 csantifort
 
206 35 csantifort
            AMBER_IC_INT_SOFTSET_0:     wb_rdata32 <= {31'd0, softint_0_reg};
207
            AMBER_IC_INT_SOFTCLEAR_0:   wb_rdata32 <= {31'd0, softint_0_reg};
208 2 csantifort
 
209 35 csantifort
            AMBER_IC_IRQ1_ENABLESET:    wb_rdata32 <= irq1_enable_reg;
210
            AMBER_IC_FIRQ1_ENABLESET:   wb_rdata32 <= firq1_enable_reg;
211
            AMBER_IC_IRQ1_RAWSTAT:      wb_rdata32 <= raw_interrupts;
212
            AMBER_IC_IRQ1_STATUS:       wb_rdata32 <= irq1_interrupts;
213
            AMBER_IC_FIRQ1_RAWSTAT:     wb_rdata32 <= raw_interrupts;
214
            AMBER_IC_FIRQ1_STATUS:      wb_rdata32 <= firq1_interrupts;
215 2 csantifort
 
216 35 csantifort
            AMBER_IC_INT_SOFTSET_1:     wb_rdata32 <= {31'd0, softint_1_reg};
217
            AMBER_IC_INT_SOFTCLEAR_1:   wb_rdata32 <= {31'd0, softint_1_reg};
218 2 csantifort
 
219 35 csantifort
            default:                    wb_rdata32 <= 32'h22334455;
220 2 csantifort
 
221
        endcase
222
 
223
 
224
 
225
// =======================================================================================
226
// =======================================================================================
227
// =======================================================================================
228
// Non-synthesizable debug code
229
// =======================================================================================
230
 
231
 
232
//synopsys translate_off
233
`ifdef AMBER_IC_DEBUG
234
 
235
wire wb_read_ack = i_wb_stb && ( wb_start_write || wb_start_read_d1 );
236
 
237
// -----------------------------------------------
238
// Report Interrupt Controller Register accesses
239
// -----------------------------------------------  
240
always @(posedge i_clk)
241
    if ( wb_read_ack || wb_start_write )
242
        begin
243
        `TB_DEBUG_MESSAGE
244
 
245
        if ( wb_start_write )
246
            $write("Write 0x%08x to   ", i_wb_dat);
247
        else
248
            $write("Read  0x%08x from ", o_wb_dat);
249
 
250
        case ( i_wb_adr[15:0] )
251
            AMBER_IC_IRQ0_STATUS:
252
                $write(" Interrupt Controller module IRQ0 Status");
253
            AMBER_IC_IRQ0_RAWSTAT:
254
                $write(" Interrupt Controller module IRQ0 Raw Status");
255
            AMBER_IC_IRQ0_ENABLESET:
256
                $write(" Interrupt Controller module IRQ0 Enable Set");
257
            AMBER_IC_IRQ0_ENABLECLR:
258
                $write(" Interrupt Controller module IRQ0 Enable Clear");
259
            AMBER_IC_FIRQ0_STATUS:
260
                $write(" Interrupt Controller module FIRQ0 Status");
261
            AMBER_IC_FIRQ0_RAWSTAT:
262
                $write(" Interrupt Controller module FIRQ0 Raw Status");
263
            AMBER_IC_FIRQ0_ENABLESET:
264
                $write(" Interrupt Controller module FIRQ0 Enable set");
265
            AMBER_IC_FIRQ0_ENABLECLR:
266
                $write(" Interrupt Controller module FIRQ0 Enable Clear");
267
            AMBER_IC_INT_SOFTSET_0:
268
                $write(" Interrupt Controller module SoftInt 0 Set");
269
            AMBER_IC_INT_SOFTCLEAR_0:
270
                $write(" Interrupt Controller module SoftInt 0 Clear");
271
            AMBER_IC_IRQ1_STATUS:
272
                $write(" Interrupt Controller module IRQ1 Status");
273
            AMBER_IC_IRQ1_RAWSTAT:
274
                $write(" Interrupt Controller module IRQ1 Raw Status");
275
            AMBER_IC_IRQ1_ENABLESET:
276
                $write(" Interrupt Controller module IRQ1 Enable Set");
277
            AMBER_IC_IRQ1_ENABLECLR:
278
                $write(" Interrupt Controller module IRQ1 Enable Clear");
279
            AMBER_IC_FIRQ1_STATUS:
280
                $write(" Interrupt Controller module FIRQ1 Status");
281
            AMBER_IC_FIRQ1_RAWSTAT:
282
                $write(" Interrupt Controller module FIRQ1 Raw Status");
283
            AMBER_IC_FIRQ1_ENABLESET:
284
                $write(" Interrupt Controller module FIRQ1 Enable set");
285
            AMBER_IC_FIRQ1_ENABLECLR:
286
                $write(" Interrupt Controller module FIRQ1 Enable Clear");
287
            AMBER_IC_INT_SOFTSET_1:
288
                $write(" Interrupt Controller module SoftInt 1 Set");
289
            AMBER_IC_INT_SOFTCLEAR_1:
290
                $write(" Interrupt Controller module SoftInt 1 Clear");
291
 
292
            default:
293
                begin
294
                $write(" unknown Amber IC Register region");
295
                $write(", Address 0x%08h\n", i_wb_adr);
296
                `TB_ERROR_MESSAGE
297
                end
298
        endcase
299
 
300
        $write(", Address 0x%08h\n", i_wb_adr);
301
        end
302
`endif
303
 
304
//synopsys translate_on
305
 
306
 
307
endmodule
308
 

powered by: WebSVN 2.1.0

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