1.1 diff -r 000000000000 -r cd0b58aa6f83 lm32_interrupt.v 1.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 +++ b/lm32_interrupt.v Sun Apr 04 20:40:03 2010 +0100 1.4 @@ -0,0 +1,335 @@ 1.5 +// ============================================================================= 1.6 +// COPYRIGHT NOTICE 1.7 +// Copyright 2006 (c) Lattice Semiconductor Corporation 1.8 +// ALL RIGHTS RESERVED 1.9 +// This confidential and proprietary software may be used only as authorised by 1.10 +// a licensing agreement from Lattice Semiconductor Corporation. 1.11 +// The entire notice above must be reproduced on all authorized copies and 1.12 +// copies may only be made to the extent permitted by a licensing agreement from 1.13 +// Lattice Semiconductor Corporation. 1.14 +// 1.15 +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) 1.16 +// 5555 NE Moore Court 408-826-6000 (other locations) 1.17 +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ 1.18 +// U.S.A email: techsupport@latticesemi.com 1.19 +// =============================================================================/ 1.20 +// FILE DETAILS 1.21 +// Project : LatticeMico32 1.22 +// File : lm32_interrupt.v 1.23 +// Title : Interrupt logic 1.24 +// Dependencies : lm32_include.v 1.25 +// Version : 6.1.17 1.26 +// : Initial Release 1.27 +// Version : 7.0SP2, 3.0 1.28 +// : No Change 1.29 +// Version : 3.1 1.30 +// : No Change 1.31 +// ============================================================================= 1.32 + 1.33 +`include "lm32_include.v" 1.34 + 1.35 +///////////////////////////////////////////////////// 1.36 +// Module interface 1.37 +///////////////////////////////////////////////////// 1.38 + 1.39 +module lm32_interrupt ( 1.40 + // ----- Inputs ------- 1.41 + clk_i, 1.42 + rst_i, 1.43 + // From external devices 1.44 + interrupt_n, 1.45 + // From pipeline 1.46 + stall_x, 1.47 +`ifdef CFG_DEBUG_ENABLED 1.48 + non_debug_exception, 1.49 + debug_exception, 1.50 +`else 1.51 + exception, 1.52 +`endif 1.53 + eret_q_x, 1.54 +`ifdef CFG_DEBUG_ENABLED 1.55 + bret_q_x, 1.56 +`endif 1.57 + csr, 1.58 + csr_write_data, 1.59 + csr_write_enable, 1.60 + // ----- Outputs ------- 1.61 + interrupt_exception, 1.62 + // To pipeline 1.63 + csr_read_data 1.64 + ); 1.65 + 1.66 +///////////////////////////////////////////////////// 1.67 +// Parameters 1.68 +///////////////////////////////////////////////////// 1.69 + 1.70 +parameter interrupts = `CFG_INTERRUPTS; // Number of interrupts 1.71 + 1.72 +///////////////////////////////////////////////////// 1.73 +// Inputs 1.74 +///////////////////////////////////////////////////// 1.75 + 1.76 +input clk_i; // Clock 1.77 +input rst_i; // Reset 1.78 + 1.79 +input [interrupts-1:0] interrupt_n; // Interrupt pins, active-low 1.80 + 1.81 +input stall_x; // Stall X pipeline stage 1.82 + 1.83 +`ifdef CFG_DEBUG_ENABLED 1.84 +input non_debug_exception; // Non-debug related exception has been raised 1.85 +input debug_exception; // Debug-related exception has been raised 1.86 +`else 1.87 +input exception; // Exception has been raised 1.88 +`endif 1.89 +input eret_q_x; // Return from exception 1.90 +`ifdef CFG_DEBUG_ENABLED 1.91 +input bret_q_x; // Return from breakpoint 1.92 +`endif 1.93 + 1.94 +input [`LM32_CSR_RNG] csr; // CSR read/write index 1.95 +input [`LM32_WORD_RNG] csr_write_data; // Data to write to specified CSR 1.96 +input csr_write_enable; // CSR write enable 1.97 + 1.98 +///////////////////////////////////////////////////// 1.99 +// Outputs 1.100 +///////////////////////////////////////////////////// 1.101 + 1.102 +output interrupt_exception; // Request to raide an interrupt exception 1.103 +wire interrupt_exception; 1.104 + 1.105 +output [`LM32_WORD_RNG] csr_read_data; // Data read from CSR 1.106 +reg [`LM32_WORD_RNG] csr_read_data; 1.107 + 1.108 +///////////////////////////////////////////////////// 1.109 +// Internal nets and registers 1.110 +///////////////////////////////////////////////////// 1.111 + 1.112 +wire [interrupts-1:0] asserted; // Which interrupts are currently being asserted 1.113 +//pragma attribute asserted preserve_signal true 1.114 +wire [interrupts-1:0] interrupt_n_exception; 1.115 + 1.116 +// Interrupt CSRs 1.117 + 1.118 +reg ie; // Interrupt enable 1.119 +reg eie; // Exception interrupt enable 1.120 +`ifdef CFG_DEBUG_ENABLED 1.121 +reg bie; // Breakpoint interrupt enable 1.122 +`endif 1.123 +reg [interrupts-1:0] ip; // Interrupt pending 1.124 +reg [interrupts-1:0] im; // Interrupt mask 1.125 + 1.126 +///////////////////////////////////////////////////// 1.127 +// Combinational Logic 1.128 +///////////////////////////////////////////////////// 1.129 + 1.130 +// Determine which interrupts have occured and are unmasked 1.131 +assign interrupt_n_exception = ip & im; 1.132 + 1.133 +// Determine if any unmasked interrupts have occured 1.134 +assign interrupt_exception = (|interrupt_n_exception) & ie; 1.135 + 1.136 +// Determine which interrupts are currently being asserted (active-low) or are already pending 1.137 +assign asserted = ip | ~interrupt_n; 1.138 + 1.139 +assign ie_csr_read_data = {{`LM32_WORD_WIDTH-3{1'b0}}, 1.140 +`ifdef CFG_DEBUG_ENABLED 1.141 + bie, 1.142 +`else 1.143 + 1'b0, 1.144 +`endif 1.145 + eie, 1.146 + ie 1.147 + }; 1.148 +assign ip_csr_read_data = ip; 1.149 +assign im_csr_read_data = im; 1.150 +generate 1.151 + if (interrupts > 1) 1.152 + begin 1.153 +// CSR read 1.154 +always @(*) 1.155 +begin 1.156 + case (csr) 1.157 + `LM32_CSR_IE: csr_read_data = {{`LM32_WORD_WIDTH-3{1'b0}}, 1.158 +`ifdef CFG_DEBUG_ENABLED 1.159 + bie, 1.160 +`else 1.161 + 1'b0, 1.162 +`endif 1.163 + eie, 1.164 + ie 1.165 + }; 1.166 + `LM32_CSR_IP: csr_read_data = ip; 1.167 + `LM32_CSR_IM: csr_read_data = im; 1.168 + default: csr_read_data = {`LM32_WORD_WIDTH{1'bx}}; 1.169 + endcase 1.170 +end 1.171 + end 1.172 + else 1.173 + begin 1.174 +// CSR read 1.175 +always @(*) 1.176 +begin 1.177 + case (csr) 1.178 + `LM32_CSR_IE: csr_read_data = {{`LM32_WORD_WIDTH-3{1'b0}}, 1.179 +`ifdef CFG_DEBUG_ENABLED 1.180 + bie, 1.181 +`else 1.182 + 1'b0, 1.183 +`endif 1.184 + eie, 1.185 + ie 1.186 + }; 1.187 + `LM32_CSR_IP: csr_read_data = ip; 1.188 + default: csr_read_data = {`LM32_WORD_WIDTH{1'bx}}; 1.189 + endcase 1.190 +end 1.191 + end 1.192 +endgenerate 1.193 + 1.194 +///////////////////////////////////////////////////// 1.195 +// Sequential Logic 1.196 +///////////////////////////////////////////////////// 1.197 + 1.198 +generate 1.199 + if (interrupts > 1) 1.200 + begin 1.201 +// IE, IM, IP - Interrupt Enable, Interrupt Mask and Interrupt Pending CSRs 1.202 +always @(posedge clk_i `CFG_RESET_SENSITIVITY) 1.203 +begin 1.204 + if (rst_i == `TRUE) 1.205 + begin 1.206 + ie <= `FALSE; 1.207 + eie <= `FALSE; 1.208 +`ifdef CFG_DEBUG_ENABLED 1.209 + bie <= `FALSE; 1.210 +`endif 1.211 + im <= {interrupts{1'b0}}; 1.212 + ip <= {interrupts{1'b0}}; 1.213 + end 1.214 + else 1.215 + begin 1.216 + // Set IP bit when interrupt line is asserted 1.217 + ip <= asserted; 1.218 +`ifdef CFG_DEBUG_ENABLED 1.219 + if (non_debug_exception == `TRUE) 1.220 + begin 1.221 + // Save and then clear interrupt enable 1.222 + eie <= ie; 1.223 + ie <= `FALSE; 1.224 + end 1.225 + else if (debug_exception == `TRUE) 1.226 + begin 1.227 + // Save and then clear interrupt enable 1.228 + bie <= ie; 1.229 + ie <= `FALSE; 1.230 + end 1.231 +`else 1.232 + if (exception == `TRUE) 1.233 + begin 1.234 + // Save and then clear interrupt enable 1.235 + eie <= ie; 1.236 + ie <= `FALSE; 1.237 + end 1.238 +`endif 1.239 + else if (stall_x == `FALSE) 1.240 + begin 1.241 + if (eret_q_x == `TRUE) 1.242 + // Restore interrupt enable 1.243 + ie <= eie; 1.244 +`ifdef CFG_DEBUG_ENABLED 1.245 + else if (bret_q_x == `TRUE) 1.246 + // Restore interrupt enable 1.247 + ie <= bie; 1.248 +`endif 1.249 + else if (csr_write_enable == `TRUE) 1.250 + begin 1.251 + // Handle wcsr write 1.252 + if (csr == `LM32_CSR_IE) 1.253 + begin 1.254 + ie <= csr_write_data[0]; 1.255 + eie <= csr_write_data[1]; 1.256 +`ifdef CFG_DEBUG_ENABLED 1.257 + bie <= csr_write_data[2]; 1.258 +`endif 1.259 + end 1.260 + if (csr == `LM32_CSR_IM) 1.261 + im <= csr_write_data[interrupts-1:0]; 1.262 + if (csr == `LM32_CSR_IP) 1.263 + ip <= asserted & ~csr_write_data[interrupts-1:0]; 1.264 + end 1.265 + end 1.266 + end 1.267 +end 1.268 + end 1.269 +else 1.270 + begin 1.271 +// IE, IM, IP - Interrupt Enable, Interrupt Mask and Interrupt Pending CSRs 1.272 +always @(posedge clk_i `CFG_RESET_SENSITIVITY) 1.273 +begin 1.274 + if (rst_i == `TRUE) 1.275 + begin 1.276 + ie <= `FALSE; 1.277 + eie <= `FALSE; 1.278 +`ifdef CFG_DEBUG_ENABLED 1.279 + bie <= `FALSE; 1.280 +`endif 1.281 + ip <= {interrupts{1'b0}}; 1.282 + end 1.283 + else 1.284 + begin 1.285 + // Set IP bit when interrupt line is asserted 1.286 + ip <= asserted; 1.287 +`ifdef CFG_DEBUG_ENABLED 1.288 + if (non_debug_exception == `TRUE) 1.289 + begin 1.290 + // Save and then clear interrupt enable 1.291 + eie <= ie; 1.292 + ie <= `FALSE; 1.293 + end 1.294 + else if (debug_exception == `TRUE) 1.295 + begin 1.296 + // Save and then clear interrupt enable 1.297 + bie <= ie; 1.298 + ie <= `FALSE; 1.299 + end 1.300 +`else 1.301 + if (exception == `TRUE) 1.302 + begin 1.303 + // Save and then clear interrupt enable 1.304 + eie <= ie; 1.305 + ie <= `FALSE; 1.306 + end 1.307 +`endif 1.308 + else if (stall_x == `FALSE) 1.309 + begin 1.310 + if (eret_q_x == `TRUE) 1.311 + // Restore interrupt enable 1.312 + ie <= eie; 1.313 +`ifdef CFG_DEBUG_ENABLED 1.314 + else if (bret_q_x == `TRUE) 1.315 + // Restore interrupt enable 1.316 + ie <= bie; 1.317 +`endif 1.318 + else if (csr_write_enable == `TRUE) 1.319 + begin 1.320 + // Handle wcsr write 1.321 + if (csr == `LM32_CSR_IE) 1.322 + begin 1.323 + ie <= csr_write_data[0]; 1.324 + eie <= csr_write_data[1]; 1.325 +`ifdef CFG_DEBUG_ENABLED 1.326 + bie <= csr_write_data[2]; 1.327 +`endif 1.328 + end 1.329 + if (csr == `LM32_CSR_IP) 1.330 + ip <= asserted & ~csr_write_data[interrupts-1:0]; 1.331 + end 1.332 + end 1.333 + end 1.334 +end 1.335 + end 1.336 +endgenerate 1.337 + 1.338 +endmodule 1.339 +