lm32_interrupt.v

Mon, 05 Apr 2010 21:00:31 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 05 Apr 2010 21:00:31 +0100
changeset 6
a8e459b24c31
parent 0
cd0b58aa6f83
child 12
e8125a6a3bd8
child 26
73de224304c1
permissions
-rw-r--r--

reduce size of caches to fit in DE1 FPGA

The default cache size makes the Icache and Dcache "just a bit" too big to
fit in the EP2C20 FPGA on the DE1 board. This commit reduces the Icache and
Dcache sizes to the defaults shown in the LatticeMico32 Processor Reference
Manual (pages 36 and 37).

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@0 40 interrupt_n,
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@0 75 input [interrupts-1:0] interrupt_n; // Interrupt pins, active-low
philpem@0 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@0 133 assign asserted = ip | ~interrupt_n;
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