lm32_interrupt.v

Sat, 06 Aug 2011 01:26:56 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 06 Aug 2011 01:26:56 +0100
changeset 27
d6c693415d59
parent 26
73de224304c1
permissions
-rwxr-xr-x

remove synthesis delay entities to ease merge

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