/* Copyright (c) 2006-2011 by Lattice Semiconductor Corporation Name: lm8_interrupt.v Description: Interrupt controller Permission: Lattice Semiconductor grants permission to use this code for use in synthesis for any Lattice programmable logic product. Other use of this code, including the selling or duplication of any portion is strictly prohibited. Disclaimer: This VHDL or Verilog source code is intended as a design reference which illustrates how these types of functions can be implemented. It is the user's responsibility to verify their design for consistency and functionality through the use of formal verification methods. Lattice Semiconductor provides no warranty regarding the use or functionality of this code. Lattice Semiconductor Corporation 5555 NE Moore Court Hillsboro, OR 97124 U.S.A TEL: 1-800-Lattice (USA and Canada) 408-826-6000 (other locations) web: http://www.latticesemi.com/ email: techsupport@latticesemi.com */ module lm8_interrupt #( parameter INTERRUPTS = 1 ) ( input clk, input rst_n, input [INTERRUPTS-1:0] interrupts, input wren_csr, input [4:0] addr_rd, input [7:0] dout_rb, input clri, input seti, output reg [INTERRUPTS-1:0] ip, output reg [INTERRUPTS-1:0] im, output reg ie, output reg irq ); reg [INTERRUPTS-1:0] ip_nxt; reg [INTERRUPTS-1:0] im_nxt; reg ie_nxt; reg [INTERRUPTS-1:0] irq_active; reg [INTERRUPTS-1:0] incoming_ip; generate if (INTERRUPTS > 1) begin always @(/*ATUOSENSE*/ip or im or ie) begin // Determine which interrupts have occured and are unmasked irq_active = ip & im; // Determine if interrupt request can be serviced irq = ie & |irq_active; end end else begin always @(/*ATUOSENSE*/ip or ie) begin // Determine which interrupts have occured and are unmasked irq_active = ip; // Determine if interrupt request can be serviced irq = ie & |irq_active; end end endgenerate always @(addr_rd or dout_rb or im or wren_csr) begin if (wren_csr && (addr_rd == `LM8_CSR_IM)) im_nxt = dout_rb[INTERRUPTS-1:0]; else im_nxt = im; end always @(addr_rd or dout_rb or interrupts or ip or wren_csr) begin incoming_ip = ip | interrupts; if (wren_csr && (addr_rd == `LM8_CSR_IP)) ip_nxt = incoming_ip & ~dout_rb[INTERRUPTS-1:0]; else ip_nxt = incoming_ip; end always @(addr_rd or clri or dout_rb or ie or seti or wren_csr) begin if (wren_csr && (addr_rd == `LM8_CSR_IE)) ie_nxt = dout_rb[0]; else if (clri || seti) ie_nxt = ~clri; else ie_nxt = ie; end always @(posedge clk or negedge rst_n) begin if (rst_n == 1'b0) begin ip <= #1 {INTERRUPTS{1'b0}}; im <= #1 {INTERRUPTS{1'b1}}; ie <= #1 1'b0; end else begin ip <= #1 ip_nxt; im <= #1 im_nxt; ie <= #1 ie_nxt; end end endmodule