lm32_interrupt.v

Sun, 04 Apr 2010 20:52:32 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sun, 04 Apr 2010 20:52:32 +0100
changeset 2
a61bb364ae1f
parent 0
cd0b58aa6f83
child 12
e8125a6a3bd8
child 26
73de224304c1
permissions
-rw-r--r--

Disable Lattice-specific stuff by default

To build on Lattice platforms, `define PLATFORM_LATTICE in lm32_include.v.
Otherwise, non-optimal "platform independent" HDL will be used.
This means LM32 can now be built for non-Lattice FPGAs.

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