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