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

Subversion Repositories amber

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

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
                          i_tm_timer_int[2],        // 7: Timer Module Interrupt 2
142
                          i_tm_timer_int[1],        // 6: Timer Module Interrupt 1
143
                          i_tm_timer_int[0],        // 5: Timer Module Interrupt 0
144
                          1'd0,
145
                          1'd0,
146
                          i_uart1_int,              // 2: Uart 1 interrupt
147
                          i_uart0_int,              // 1: Uart 0 interrupt
148
                          1'd0                      // 0: Software interrupt not 
149
                         };                         // here because its not maskable
150
 
151
assign irq0_interrupts  = {raw_interrupts[31:1], softint_0_reg} & irq0_enable_reg;
152
assign firq0_interrupts = raw_interrupts & firq0_enable_reg;
153
assign irq1_interrupts  = {raw_interrupts[31:1], softint_1_reg} & irq1_enable_reg;
154
assign firq1_interrupts  = raw_interrupts & firq1_enable_reg;
155
 
156
// The interrupts from the test registers module are not masked,
157
// just to keep their usage really simple
158
assign irq_0  = |{irq0_interrupts, i_test_reg_irq};
159
assign firq_0 = |{firq0_interrupts, i_test_reg_firq};
160
assign irq_1  = |irq1_interrupts;
161
assign firq_1 = |firq1_interrupts;
162
 
163
assign o_irq  = irq_0  | irq_1;
164
assign o_firq = firq_0 | firq_1;
165
 
166
// ========================================================
167
// Register Writes
168
// ========================================================
169
always @( posedge i_clk )
170
    if ( wb_start_write )
171
        case ( i_wb_adr[15:0] )
172
            AMBER_IC_IRQ0_ENABLESET:  irq0_enable_reg  <=  irq0_enable_reg  | ( i_wb_dat);
173
            AMBER_IC_IRQ0_ENABLECLR:  irq0_enable_reg  <=  irq0_enable_reg  & (~i_wb_dat);
174
            AMBER_IC_FIRQ0_ENABLESET: firq0_enable_reg <=  firq0_enable_reg | ( i_wb_dat);
175
            AMBER_IC_FIRQ0_ENABLECLR: firq0_enable_reg <=  firq0_enable_reg & (~i_wb_dat);
176
 
177
            AMBER_IC_INT_SOFTSET_0:   softint_0_reg    <=  softint_0_reg   | ( i_wb_dat[0]);
178
            AMBER_IC_INT_SOFTCLEAR_0: softint_0_reg    <=  softint_0_reg   & (~i_wb_dat[0]);
179
 
180
            AMBER_IC_IRQ1_ENABLESET:  irq1_enable_reg  <=  irq1_enable_reg  | ( i_wb_dat);
181
            AMBER_IC_IRQ1_ENABLECLR:  irq1_enable_reg  <=  irq1_enable_reg  & (~i_wb_dat);
182
            AMBER_IC_FIRQ1_ENABLESET: firq1_enable_reg <=  firq1_enable_reg | ( i_wb_dat);
183
            AMBER_IC_FIRQ1_ENABLECLR: firq1_enable_reg <=  firq1_enable_reg & (~i_wb_dat);
184
 
185
            AMBER_IC_INT_SOFTSET_1:   softint_1_reg    <=  softint_1_reg   | ( i_wb_dat[0]);
186
            AMBER_IC_INT_SOFTCLEAR_1: softint_1_reg    <=  softint_1_reg   & (~i_wb_dat[0]);
187
        endcase
188
 
189
 
190
// ========================================================
191
// Register Reads
192
// ========================================================
193
always @( posedge i_clk )
194
    if ( wb_start_read )
195
        case ( i_wb_adr[15:0] )
196
 
197 35 csantifort
            AMBER_IC_IRQ0_ENABLESET:    wb_rdata32 <= irq0_enable_reg;
198
            AMBER_IC_FIRQ0_ENABLESET:   wb_rdata32 <= firq0_enable_reg;
199
            AMBER_IC_IRQ0_RAWSTAT:      wb_rdata32 <= raw_interrupts;
200
            AMBER_IC_IRQ0_STATUS:       wb_rdata32 <= irq0_interrupts;
201
            AMBER_IC_FIRQ0_RAWSTAT:     wb_rdata32 <= raw_interrupts;
202
            AMBER_IC_FIRQ0_STATUS:      wb_rdata32 <= firq0_interrupts;
203 2 csantifort
 
204 35 csantifort
            AMBER_IC_INT_SOFTSET_0:     wb_rdata32 <= {31'd0, softint_0_reg};
205
            AMBER_IC_INT_SOFTCLEAR_0:   wb_rdata32 <= {31'd0, softint_0_reg};
206 2 csantifort
 
207 35 csantifort
            AMBER_IC_IRQ1_ENABLESET:    wb_rdata32 <= irq1_enable_reg;
208
            AMBER_IC_FIRQ1_ENABLESET:   wb_rdata32 <= firq1_enable_reg;
209
            AMBER_IC_IRQ1_RAWSTAT:      wb_rdata32 <= raw_interrupts;
210
            AMBER_IC_IRQ1_STATUS:       wb_rdata32 <= irq1_interrupts;
211
            AMBER_IC_FIRQ1_RAWSTAT:     wb_rdata32 <= raw_interrupts;
212
            AMBER_IC_FIRQ1_STATUS:      wb_rdata32 <= firq1_interrupts;
213 2 csantifort
 
214 35 csantifort
            AMBER_IC_INT_SOFTSET_1:     wb_rdata32 <= {31'd0, softint_1_reg};
215
            AMBER_IC_INT_SOFTCLEAR_1:   wb_rdata32 <= {31'd0, softint_1_reg};
216 2 csantifort
 
217 35 csantifort
            default:                    wb_rdata32 <= 32'h22334455;
218 2 csantifort
 
219
        endcase
220
 
221
 
222
 
223
// =======================================================================================
224
// =======================================================================================
225
// =======================================================================================
226
// Non-synthesizable debug code
227
// =======================================================================================
228
 
229
 
230
//synopsys translate_off
231
`ifdef AMBER_IC_DEBUG
232
 
233
wire wb_read_ack = i_wb_stb && ( wb_start_write || wb_start_read_d1 );
234
 
235
// -----------------------------------------------
236
// Report Interrupt Controller Register accesses
237
// -----------------------------------------------  
238
always @(posedge i_clk)
239
    if ( wb_read_ack || wb_start_write )
240
        begin
241
        `TB_DEBUG_MESSAGE
242
 
243
        if ( wb_start_write )
244
            $write("Write 0x%08x to   ", i_wb_dat);
245
        else
246
            $write("Read  0x%08x from ", o_wb_dat);
247
 
248
        case ( i_wb_adr[15:0] )
249
            AMBER_IC_IRQ0_STATUS:
250
                $write(" Interrupt Controller module IRQ0 Status");
251
            AMBER_IC_IRQ0_RAWSTAT:
252
                $write(" Interrupt Controller module IRQ0 Raw Status");
253
            AMBER_IC_IRQ0_ENABLESET:
254
                $write(" Interrupt Controller module IRQ0 Enable Set");
255
            AMBER_IC_IRQ0_ENABLECLR:
256
                $write(" Interrupt Controller module IRQ0 Enable Clear");
257
            AMBER_IC_FIRQ0_STATUS:
258
                $write(" Interrupt Controller module FIRQ0 Status");
259
            AMBER_IC_FIRQ0_RAWSTAT:
260
                $write(" Interrupt Controller module FIRQ0 Raw Status");
261
            AMBER_IC_FIRQ0_ENABLESET:
262
                $write(" Interrupt Controller module FIRQ0 Enable set");
263
            AMBER_IC_FIRQ0_ENABLECLR:
264
                $write(" Interrupt Controller module FIRQ0 Enable Clear");
265
            AMBER_IC_INT_SOFTSET_0:
266
                $write(" Interrupt Controller module SoftInt 0 Set");
267
            AMBER_IC_INT_SOFTCLEAR_0:
268
                $write(" Interrupt Controller module SoftInt 0 Clear");
269
            AMBER_IC_IRQ1_STATUS:
270
                $write(" Interrupt Controller module IRQ1 Status");
271
            AMBER_IC_IRQ1_RAWSTAT:
272
                $write(" Interrupt Controller module IRQ1 Raw Status");
273
            AMBER_IC_IRQ1_ENABLESET:
274
                $write(" Interrupt Controller module IRQ1 Enable Set");
275
            AMBER_IC_IRQ1_ENABLECLR:
276
                $write(" Interrupt Controller module IRQ1 Enable Clear");
277
            AMBER_IC_FIRQ1_STATUS:
278
                $write(" Interrupt Controller module FIRQ1 Status");
279
            AMBER_IC_FIRQ1_RAWSTAT:
280
                $write(" Interrupt Controller module FIRQ1 Raw Status");
281
            AMBER_IC_FIRQ1_ENABLESET:
282
                $write(" Interrupt Controller module FIRQ1 Enable set");
283
            AMBER_IC_FIRQ1_ENABLECLR:
284
                $write(" Interrupt Controller module FIRQ1 Enable Clear");
285
            AMBER_IC_INT_SOFTSET_1:
286
                $write(" Interrupt Controller module SoftInt 1 Set");
287
            AMBER_IC_INT_SOFTCLEAR_1:
288
                $write(" Interrupt Controller module SoftInt 1 Clear");
289
 
290
            default:
291
                begin
292
                $write(" unknown Amber IC Register region");
293
                $write(", Address 0x%08h\n", i_wb_adr);
294
                `TB_ERROR_MESSAGE
295
                end
296
        endcase
297
 
298
        $write(", Address 0x%08h\n", i_wb_adr);
299
        end
300
`endif
301
 
302
//synopsys translate_on
303
 
304
 
305
endmodule
306
 

powered by: WebSVN 2.1.0

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