Sun, 06 Mar 2011 19:22:27 +0000
Make interrupts active high
Original-Author: lekernel
Original-Source: milkymist 5e8c03b53aaa820f3b43
1 // =============================================================================
2 // COPYRIGHT NOTICE
3 // Copyright 2006 (c) Lattice Semiconductor Corporation
4 // ALL RIGHTS RESERVED
5 // This confidential and proprietary software may be used only as authorised by
6 // a licensing agreement from Lattice Semiconductor Corporation.
7 // The entire notice above must be reproduced on all authorized copies and
8 // copies may only be made to the extent permitted by a licensing agreement from
9 // Lattice Semiconductor Corporation.
10 //
11 // Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada)
12 // 5555 NE Moore Court 408-826-6000 (other locations)
13 // Hillsboro, OR 97124 web : http://www.latticesemi.com/
14 // U.S.A email: techsupport@latticesemi.com
15 // =============================================================================/
16 // FILE DETAILS
17 // Project : LatticeMico32
18 // File : lm32_interrupt.v
19 // Title : Interrupt logic
20 // Dependencies : lm32_include.v
21 // Version : 6.1.17
22 // : Initial Release
23 // Version : 7.0SP2, 3.0
24 // : No Change
25 // Version : 3.1
26 // : No Change
27 // =============================================================================
29 `include "lm32_include.v"
31 /////////////////////////////////////////////////////
32 // Module interface
33 /////////////////////////////////////////////////////
35 module lm32_interrupt (
36 // ----- Inputs -------
37 clk_i,
38 rst_i,
39 // From external devices
40 interrupt,
41 // From pipeline
42 stall_x,
43 `ifdef CFG_DEBUG_ENABLED
44 non_debug_exception,
45 debug_exception,
46 `else
47 exception,
48 `endif
49 eret_q_x,
50 `ifdef CFG_DEBUG_ENABLED
51 bret_q_x,
52 `endif
53 csr,
54 csr_write_data,
55 csr_write_enable,
56 // ----- Outputs -------
57 interrupt_exception,
58 // To pipeline
59 csr_read_data
60 );
62 /////////////////////////////////////////////////////
63 // Parameters
64 /////////////////////////////////////////////////////
66 parameter interrupts = `CFG_INTERRUPTS; // Number of interrupts
68 /////////////////////////////////////////////////////
69 // Inputs
70 /////////////////////////////////////////////////////
72 input clk_i; // Clock
73 input rst_i; // Reset
75 input [interrupts-1:0] interrupt; // Interrupt pins, active-low
77 input stall_x; // Stall X pipeline stage
79 `ifdef CFG_DEBUG_ENABLED
80 input non_debug_exception; // Non-debug related exception has been raised
81 input debug_exception; // Debug-related exception has been raised
82 `else
83 input exception; // Exception has been raised
84 `endif
85 input eret_q_x; // Return from exception
86 `ifdef CFG_DEBUG_ENABLED
87 input bret_q_x; // Return from breakpoint
88 `endif
90 input [`LM32_CSR_RNG] csr; // CSR read/write index
91 input [`LM32_WORD_RNG] csr_write_data; // Data to write to specified CSR
92 input csr_write_enable; // CSR write enable
94 /////////////////////////////////////////////////////
95 // Outputs
96 /////////////////////////////////////////////////////
98 output interrupt_exception; // Request to raide an interrupt exception
99 wire interrupt_exception;
101 output [`LM32_WORD_RNG] csr_read_data; // Data read from CSR
102 reg [`LM32_WORD_RNG] csr_read_data;
104 /////////////////////////////////////////////////////
105 // Internal nets and registers
106 /////////////////////////////////////////////////////
108 wire [interrupts-1:0] asserted; // Which interrupts are currently being asserted
109 //pragma attribute asserted preserve_signal true
110 wire [interrupts-1:0] interrupt_n_exception;
112 // Interrupt CSRs
114 reg ie; // Interrupt enable
115 reg eie; // Exception interrupt enable
116 `ifdef CFG_DEBUG_ENABLED
117 reg bie; // Breakpoint interrupt enable
118 `endif
119 reg [interrupts-1:0] ip; // Interrupt pending
120 reg [interrupts-1:0] im; // Interrupt mask
122 /////////////////////////////////////////////////////
123 // Combinational Logic
124 /////////////////////////////////////////////////////
126 // Determine which interrupts have occured and are unmasked
127 assign interrupt_n_exception = ip & im;
129 // Determine if any unmasked interrupts have occured
130 assign interrupt_exception = (|interrupt_n_exception) & ie;
132 // Determine which interrupts are currently being asserted (active-low) or are already pending
133 assign asserted = ip | interrupt;
135 assign ie_csr_read_data = {{`LM32_WORD_WIDTH-3{1'b0}},
136 `ifdef CFG_DEBUG_ENABLED
137 bie,
138 `else
139 1'b0,
140 `endif
141 eie,
142 ie
143 };
144 assign ip_csr_read_data = ip;
145 assign im_csr_read_data = im;
146 generate
147 if (interrupts > 1)
148 begin
149 // CSR read
150 always @(*)
151 begin
152 case (csr)
153 `LM32_CSR_IE: csr_read_data = {{`LM32_WORD_WIDTH-3{1'b0}},
154 `ifdef CFG_DEBUG_ENABLED
155 bie,
156 `else
157 1'b0,
158 `endif
159 eie,
160 ie
161 };
162 `LM32_CSR_IP: csr_read_data = ip;
163 `LM32_CSR_IM: csr_read_data = im;
164 default: csr_read_data = {`LM32_WORD_WIDTH{1'bx}};
165 endcase
166 end
167 end
168 else
169 begin
170 // CSR read
171 always @(*)
172 begin
173 case (csr)
174 `LM32_CSR_IE: csr_read_data = {{`LM32_WORD_WIDTH-3{1'b0}},
175 `ifdef CFG_DEBUG_ENABLED
176 bie,
177 `else
178 1'b0,
179 `endif
180 eie,
181 ie
182 };
183 `LM32_CSR_IP: csr_read_data = ip;
184 default: csr_read_data = {`LM32_WORD_WIDTH{1'bx}};
185 endcase
186 end
187 end
188 endgenerate
190 /////////////////////////////////////////////////////
191 // Sequential Logic
192 /////////////////////////////////////////////////////
194 generate
195 if (interrupts > 1)
196 begin
197 // IE, IM, IP - Interrupt Enable, Interrupt Mask and Interrupt Pending CSRs
198 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
199 begin
200 if (rst_i == `TRUE)
201 begin
202 ie <= `FALSE;
203 eie <= `FALSE;
204 `ifdef CFG_DEBUG_ENABLED
205 bie <= `FALSE;
206 `endif
207 im <= {interrupts{1'b0}};
208 ip <= {interrupts{1'b0}};
209 end
210 else
211 begin
212 // Set IP bit when interrupt line is asserted
213 ip <= asserted;
214 `ifdef CFG_DEBUG_ENABLED
215 if (non_debug_exception == `TRUE)
216 begin
217 // Save and then clear interrupt enable
218 eie <= ie;
219 ie <= `FALSE;
220 end
221 else if (debug_exception == `TRUE)
222 begin
223 // Save and then clear interrupt enable
224 bie <= ie;
225 ie <= `FALSE;
226 end
227 `else
228 if (exception == `TRUE)
229 begin
230 // Save and then clear interrupt enable
231 eie <= ie;
232 ie <= `FALSE;
233 end
234 `endif
235 else if (stall_x == `FALSE)
236 begin
237 if (eret_q_x == `TRUE)
238 // Restore interrupt enable
239 ie <= eie;
240 `ifdef CFG_DEBUG_ENABLED
241 else if (bret_q_x == `TRUE)
242 // Restore interrupt enable
243 ie <= bie;
244 `endif
245 else if (csr_write_enable == `TRUE)
246 begin
247 // Handle wcsr write
248 if (csr == `LM32_CSR_IE)
249 begin
250 ie <= csr_write_data[0];
251 eie <= csr_write_data[1];
252 `ifdef CFG_DEBUG_ENABLED
253 bie <= csr_write_data[2];
254 `endif
255 end
256 if (csr == `LM32_CSR_IM)
257 im <= csr_write_data[interrupts-1:0];
258 if (csr == `LM32_CSR_IP)
259 ip <= asserted & ~csr_write_data[interrupts-1:0];
260 end
261 end
262 end
263 end
264 end
265 else
266 begin
267 // IE, IM, IP - Interrupt Enable, Interrupt Mask and Interrupt Pending CSRs
268 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
269 begin
270 if (rst_i == `TRUE)
271 begin
272 ie <= `FALSE;
273 eie <= `FALSE;
274 `ifdef CFG_DEBUG_ENABLED
275 bie <= `FALSE;
276 `endif
277 ip <= {interrupts{1'b0}};
278 end
279 else
280 begin
281 // Set IP bit when interrupt line is asserted
282 ip <= asserted;
283 `ifdef CFG_DEBUG_ENABLED
284 if (non_debug_exception == `TRUE)
285 begin
286 // Save and then clear interrupt enable
287 eie <= ie;
288 ie <= `FALSE;
289 end
290 else if (debug_exception == `TRUE)
291 begin
292 // Save and then clear interrupt enable
293 bie <= ie;
294 ie <= `FALSE;
295 end
296 `else
297 if (exception == `TRUE)
298 begin
299 // Save and then clear interrupt enable
300 eie <= ie;
301 ie <= `FALSE;
302 end
303 `endif
304 else if (stall_x == `FALSE)
305 begin
306 if (eret_q_x == `TRUE)
307 // Restore interrupt enable
308 ie <= eie;
309 `ifdef CFG_DEBUG_ENABLED
310 else if (bret_q_x == `TRUE)
311 // Restore interrupt enable
312 ie <= bie;
313 `endif
314 else if (csr_write_enable == `TRUE)
315 begin
316 // Handle wcsr write
317 if (csr == `LM32_CSR_IE)
318 begin
319 ie <= csr_write_data[0];
320 eie <= csr_write_data[1];
321 `ifdef CFG_DEBUG_ENABLED
322 bie <= csr_write_data[2];
323 `endif
324 end
325 if (csr == `LM32_CSR_IP)
326 ip <= asserted & ~csr_write_data[interrupts-1:0];
327 end
328 end
329 end
330 end
331 end
332 endgenerate
334 endmodule