lm32_interrupt.v

Sun, 06 Mar 2011 19:48:34 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sun, 06 Mar 2011 19:48:34 +0000
changeset 16
5fb37de64edc
parent 12
e8125a6a3bd8
permissions
-rwxr-xr-x

Add JTAG interface for Xilinx Spartan 6 (Michael Walle)

Original-Source: Milkymist mailing list posting, 2010-09-23
Original-Message-Id: <201009232334.04219.michael@walle.cc>
Original-Author: Michael Walle <michael walle.cc>

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