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

Subversion Repositories amber

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

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

powered by: WebSVN 2.1.0

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