rtl/verilog/gpio.v

changeset 0
267b5a25932f
child 1
dfc32cad81ba
     1.1 diff -r 000000000000 -r 267b5a25932f rtl/verilog/gpio.v
     1.2 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 +++ b/rtl/verilog/gpio.v	Fri Aug 13 10:41:29 2010 +0100
     1.4 @@ -0,0 +1,379 @@
     1.5 +// =============================================================================
     1.6 +//                           COPYRIGHT NOTICE
     1.7 +// Copyright 2004 (c) Lattice Semiconductor Corporation
     1.8 +// ALL RIGHTS RESERVED
     1.9 +// This confidential and proprietary software may be used only as authorised by
    1.10 +// a licensing agreement from Lattice Semiconductor Corporation.
    1.11 +// The entire notice above must be reproduced on all authorized copies and
    1.12 +// copies may only be made to the extent permitted by a licensing agreement from
    1.13 +// Lattice Semiconductor Corporation.
    1.14 +//
    1.15 +// Lattice Semiconductor Corporation        TEL : 1-800-Lattice (USA and Canada)
    1.16 +// 5555 NE Moore Court                            408-826-6000 (other locations)
    1.17 +// Hillsboro, OR 97124                     web  : http://www.latticesemi.com/
    1.18 +// U.S.A                                   email: techsupport@latticesemi.com
    1.19 +// =============================================================================/
    1.20 +//                         FILE DETAILS
    1.21 +// Project          : GPIO for LM32
    1.22 +// File             : gpio.v
    1.23 +// Title            : General Purpose IO Component 
    1.24 +// Dependencies     : system_conf.v
    1.25 +// Description      : Implements the logic to interface general purpuse IO with 
    1.26 +//                    Wishbone bus.
    1.27 +// =============================================================================
    1.28 +//                        REVISION HISTORY
    1.29 +// Version          : 7.0
    1.30 +// Mod. Date        : Jun 27, 2005
    1.31 +// Changes Made     : Initial Creation
    1.32 +//
    1.33 +// Version          : 7.0SP2, 3.0
    1.34 +// Mod. Date        : 20 Nov. 2007
    1.35 +// Changes Made     : Code clean up.
    1.36 +//
    1.37 +// Version          : 3.1
    1.38 +// Mod. Date        : 11 Oct. 2008
    1.39 +// Changes Made     : Update the Edge Capture Register clean method
    1.40 +//                    Make IRQ Mask register readable
    1.41 +// =============================================================================
    1.42 +`ifndef GPIO_V
    1.43 +`define GPIO_V
    1.44 +`timescale 1ns/100 ps
    1.45 +`include "system_conf.v"
    1.46 +module gpio #(parameter DATA_WIDTH = 16,
    1.47 +              parameter INPUT_WIDTH = 16,
    1.48 +              parameter OUTPUT_WIDTH = 16,
    1.49 +              parameter IRQ_MODE = 0,
    1.50 +              parameter LEVEL = 0,
    1.51 +              parameter EDGE = 0,
    1.52 +              parameter POSE_EDGE_IRQ = 0,
    1.53 +              parameter NEGE_EDGE_IRQ = 0,
    1.54 +              parameter EITHER_EDGE_IRQ = 0,
    1.55 +              parameter INPUT_PORTS_ONLY = 1,
    1.56 +              parameter OUTPUT_PORTS_ONLY = 0,
    1.57 +              parameter BOTH_INPUT_AND_OUTPUT = 0,
    1.58 +              parameter TRISTATE_PORTS = 0)
    1.59 +     (
    1.60 +     //system clock and reset
    1.61 +     CLK_I,
    1.62 +     RST_I,
    1.63 +     //wishbone interface signals
    1.64 +     GPIO_ADR_I,
    1.65 +     GPIO_CYC_I,
    1.66 +     GPIO_DAT_I,
    1.67 +     GPIO_SEL_I,
    1.68 +     GPIO_STB_I,
    1.69 +     GPIO_WE_I,
    1.70 +     GPIO_LOCK_I,
    1.71 +     GPIO_CTI_I,
    1.72 +     GPIO_BTE_I,
    1.73 +     GPIO_ACK_O,
    1.74 +     GPIO_RTY_O,
    1.75 +     GPIO_DAT_O,
    1.76 +     GPIO_ERR_O,
    1.77 +     IRQ_O, //bit_or of all IRQs
    1.78 +     //PIO side
    1.79 +     PIO_IN,
    1.80 +     PIO_OUT,
    1.81 +     PIO_IO,
    1.82 +     PIO_BOTH_IN,
    1.83 +     PIO_BOTH_OUT
    1.84 +     );
    1.85 +
    1.86 +//---------------------------------------------------------------------
    1.87 +// inputs
    1.88 +   //
    1.89 +   input                   CLK_I;
    1.90 +   input                   RST_I;
    1.91 +   input [31:0]            GPIO_ADR_I;
    1.92 +   input                   GPIO_CYC_I;
    1.93 +   input [31:0]            GPIO_DAT_I;
    1.94 +   input [3:0]             GPIO_SEL_I;
    1.95 +   input                   GPIO_STB_I;
    1.96 +   input                   GPIO_WE_I;
    1.97 +   input                   GPIO_LOCK_I;
    1.98 +   input [2:0]             GPIO_CTI_I;
    1.99 +   input [1:0]             GPIO_BTE_I;   
   1.100 +   input [DATA_WIDTH-1:0]  PIO_IN;
   1.101 +   input [INPUT_WIDTH-1:0] PIO_BOTH_IN;
   1.102 +//---------------------------------------------------------------------
   1.103 +// outputs
   1.104 +//
   1.105 +   output                    GPIO_ACK_O;
   1.106 +   output                    GPIO_RTY_O;
   1.107 +   output [31:0]             GPIO_DAT_O;
   1.108 +   output                    GPIO_ERR_O;
   1.109 +   output                    IRQ_O;
   1.110 +   output [DATA_WIDTH-1:0]   PIO_OUT;
   1.111 +   output [OUTPUT_WIDTH-1:0] PIO_BOTH_OUT;
   1.112 +//----------------
   1.113 +//inout mode
   1.114 +   inout [DATA_WIDTH-1:0]    PIO_IO;
   1.115 +//----------------
   1.116 +//process
   1.117 +   
   1.118 +   parameter    UDLY     = 1;
   1.119 +   
   1.120 +   wire         ADR_0;
   1.121 +   wire         ADR_4;
   1.122 +   wire         ADR_8;
   1.123 +   wire         ADR_C;
   1.124 +   wire         read_addr_0;   
   1.125 +   wire         read_addr_4;   
   1.126 +   wire         read_addr_8;   
   1.127 +   wire         read_addr_C;   
   1.128 +   wire         GPIO_RTY_O;
   1.129 +   wire         GPIO_ERR_O;
   1.130 +   wire [31:0]  GPIO_DAT_O;
   1.131 +   wire         IRQ_O;
   1.132 +   wire [DATA_WIDTH-1:0]   PIO_OUT;
   1.133 +   wire [OUTPUT_WIDTH-1:0] PIO_BOTH_OUT;
   1.134 +   wire [DATA_WIDTH-1:0]   tpio_out;
   1.135 +   wire                    PIO_DATA_WR_EN;
   1.136 +   wire                    PIO_TRI_WR_EN;
   1.137 +   wire                    IRQ_MASK_WR_EN;
   1.138 +   wire                    EDGE_CAP_WR_EN;
   1.139 +   wire                    PIO_DATA_RE_EN;
   1.140 +   wire                    PIO_TRI_RE_EN;
   1.141 +   wire                    IRQ_MASK_RE_EN;
   1.142 +   wire [DATA_WIDTH-1:0]   IRQ_TRI_TEMP;
   1.143 +   reg [DATA_WIDTH-1:0]    PIO_DATA;
   1.144 +   reg [DATA_WIDTH-1:0]    IRQ_MASK;
   1.145 +   reg [INPUT_WIDTH-1:0]   IRQ_MASK_BOTH;
   1.146 +   reg [DATA_WIDTH-1:0]    IRQ_TEMP;
   1.147 +   reg [INPUT_WIDTH-1:0]   IRQ_TEMP_BOTH;
   1.148 +   reg [DATA_WIDTH-1:0]    EDGE_CAPTURE;
   1.149 +   reg [INPUT_WIDTH-1:0]   EDGE_CAPTURE_BOTH;
   1.150 +   reg [DATA_WIDTH-1:0]    PIO_DATA_DLY;
   1.151 +   reg [INPUT_WIDTH-1:0]   PIO_DATA_DLY_BOTH;
   1.152 +   reg [OUTPUT_WIDTH-1:0]  PIO_DATAO; 
   1.153 +   reg [INPUT_WIDTH-1 :0]  PIO_DATAI;
   1.154 +   reg                     GPIO_ACK_O;
   1.155 +
   1.156 +   assign GPIO_RTY_O = 1'b0;
   1.157 +   assign GPIO_ERR_O = 1'b0;
   1.158 +   assign ADR_0 = (GPIO_ADR_I[3:0] == 4'b0000 ? 1'b1 : 0); // IO Data           
   1.159 +   assign ADR_4 = (GPIO_ADR_I[3:0] == 4'b0100 ? 1'b1 : 0); // Tri-state Control 
   1.160 +   assign ADR_8 = (GPIO_ADR_I[3:0] == 4'b1000 ? 1'b1 : 0); // IRQ Mask          
   1.161 +   assign ADR_C = (GPIO_ADR_I[3:0] == 4'b1100 ? 1'b1 : 0); // Edge Capture      
   1.162 +   assign read_addr_0 =                   (ADR_0 & GPIO_STB_I & ~GPIO_WE_I) ;   
   1.163 +   assign read_addr_4 =                   (ADR_4 & GPIO_STB_I & ~GPIO_WE_I) ;   
   1.164 +   assign read_addr_8 = (IRQ_MODE == 1 && (ADR_8 & GPIO_STB_I & ~GPIO_WE_I));   
   1.165 +   assign read_addr_C = (IRQ_MODE == 1 && (ADR_C & GPIO_STB_I & ~GPIO_WE_I));   
   1.166 +
   1.167 +   always @(posedge CLK_I or posedge RST_I)
   1.168 +     if(RST_I)
   1.169 +       GPIO_ACK_O       <= #UDLY 1'b0;
   1.170 +     else if( GPIO_STB_I && !GPIO_ACK_O)
   1.171 +       GPIO_ACK_O       <= #UDLY 1'b1;
   1.172 +     else
   1.173 +       GPIO_ACK_O       <= #UDLY 1'b0;   
   1.174 +
   1.175 +   generate
   1.176 +      if (INPUT_PORTS_ONLY == 1) begin   
   1.177 +         always @(posedge CLK_I or posedge RST_I)
   1.178 +           if (RST_I)
   1.179 +             PIO_DATA <= #UDLY 0;
   1.180 +           else if (GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I == 4'b1111)       
   1.181 +             PIO_DATA <= #UDLY PIO_IN;
   1.182 +         end
   1.183 +   endgenerate
   1.184 + 
   1.185 +   generate   
   1.186 +      if (OUTPUT_PORTS_ONLY == 1) begin
   1.187 +        always @(posedge CLK_I or posedge RST_I)
   1.188 +          if (RST_I)
   1.189 +            PIO_DATA <= #UDLY 0;
   1.190 +          else if (GPIO_STB_I && !GPIO_ACK_O && GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I == 4'b1111)
   1.191 +            PIO_DATA <= #UDLY GPIO_DAT_I[DATA_WIDTH-1:0];   
   1.192 +            
   1.193 +        assign  PIO_OUT = PIO_DATA;
   1.194 +        end
   1.195 +   endgenerate
   1.196 +   
   1.197 +   generate
   1.198 +      if (BOTH_INPUT_AND_OUTPUT == 1) begin   
   1.199 +        always @(posedge CLK_I or posedge RST_I)
   1.200 +          if (RST_I) begin
   1.201 +            PIO_DATAI <= #UDLY 0;
   1.202 +            PIO_DATAO <= #UDLY 0;
   1.203 +          end else if (GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && (ADR_0 == 1'b1) && GPIO_SEL_I == 4'b1111)
   1.204 +            PIO_DATAI <= #UDLY PIO_BOTH_IN;
   1.205 +          else if (GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && (ADR_0 == 1'b1) && GPIO_SEL_I == 4'b1111)
   1.206 +            PIO_DATAO <= #UDLY GPIO_DAT_I[OUTPUT_WIDTH-1:0];
   1.207 +               
   1.208 +        assign  PIO_BOTH_OUT = PIO_DATAO[OUTPUT_WIDTH-1:0];
   1.209 +        end
   1.210 +   endgenerate
   1.211 +   
   1.212 +   assign  PIO_DATA_RE_EN = GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && (ADR_0 == 1'b1) && GPIO_SEL_I == 4'b1111;
   1.213 +   assign  PIO_TRI_RE_EN  = GPIO_STB_I &&  GPIO_ACK_O && !GPIO_WE_I && (ADR_4 == 1'b1) && GPIO_SEL_I == 4'b1111;
   1.214 +   assign  IRQ_MASK_RE_EN = GPIO_STB_I &&  GPIO_ACK_O && !GPIO_WE_I && (ADR_8 == 1'b1) && GPIO_SEL_I == 4'b1111;
   1.215 +   assign  PIO_DATA_WR_EN = GPIO_STB_I &&  GPIO_ACK_O &&  GPIO_WE_I && (ADR_0 == 1'b1) && GPIO_SEL_I == 4'b1111;
   1.216 +   assign  PIO_TRI_WR_EN  = GPIO_STB_I &&  GPIO_ACK_O &&  GPIO_WE_I && (ADR_4 == 1'b1) && GPIO_SEL_I == 4'b1111;
   1.217 +   assign  IRQ_MASK_WR_EN = GPIO_STB_I &&  GPIO_ACK_O &&  GPIO_WE_I && (ADR_8 == 1'b1) && GPIO_SEL_I == 4'b1111;
   1.218 +   assign  EDGE_CAP_WR_EN = GPIO_STB_I &&  GPIO_ACK_O &&  GPIO_WE_I && (ADR_C == 1'b1) && GPIO_SEL_I == 4'b1111;
   1.219 +   
   1.220 +   generate
   1.221 +      genvar     ti;
   1.222 +      for (ti = 0 ; ti < DATA_WIDTH; ti = ti + 1)
   1.223 +         begin : tio_inst
   1.224 +            TRI_PIO #(.DATA_WIDTH(DATA_WIDTH),
   1.225 +               .IRQ_MODE(IRQ_MODE),
   1.226 +               .LEVEL(LEVEL),
   1.227 +               .EDGE(EDGE),
   1.228 +               .POSE_EDGE_IRQ(POSE_EDGE_IRQ),
   1.229 +               .NEGE_EDGE_IRQ(NEGE_EDGE_IRQ),
   1.230 +               .EITHER_EDGE_IRQ(EITHER_EDGE_IRQ))
   1.231 +            TP (.CLK_I(CLK_I),
   1.232 +           .RST_I(RST_I),
   1.233 +           .DAT_I(GPIO_DAT_I[ti]),
   1.234 +           .DAT_O(tpio_out[ti]),
   1.235 +           .PIO_IO(PIO_IO[ti]),
   1.236 +           .IRQ_O(IRQ_TRI_TEMP[ti]),
   1.237 +           .PIO_TRI_WR_EN(PIO_TRI_WR_EN),
   1.238 +           .PIO_TRI_RE_EN(PIO_TRI_RE_EN),
   1.239 +           .PIO_DATA_WR_EN(PIO_DATA_WR_EN),
   1.240 +           .PIO_DATA_RE_EN(PIO_DATA_RE_EN),
   1.241 +           .IRQ_MASK_WR_EN(IRQ_MASK_WR_EN),
   1.242 +           .IRQ_MASK_RE_EN(IRQ_MASK_RE_EN),
   1.243 +           .EDGE_CAP_WR_EN(EDGE_CAP_WR_EN));
   1.244 +         end
   1.245 +   endgenerate
   1.246 +
   1.247 +   generate      
   1.248 +     if (INPUT_PORTS_ONLY == 1)
   1.249 +       assign GPIO_DAT_O = read_addr_0 ? PIO_DATA : 
   1.250 +                           read_addr_8 ? IRQ_MASK :
   1.251 +                           read_addr_C ? EDGE_CAPTURE :
   1.252 +                           0;
   1.253 +     else if (BOTH_INPUT_AND_OUTPUT == 1)
   1.254 +       assign GPIO_DAT_O = read_addr_0 ? PIO_DATAI : 
   1.255 +                           read_addr_8 ? IRQ_MASK_BOTH :
   1.256 +                           read_addr_C ? EDGE_CAPTURE_BOTH :
   1.257 +                           0;
   1.258 +     else if (TRISTATE_PORTS == 1)
   1.259 +       assign GPIO_DAT_O = read_addr_0 ? tpio_out : 
   1.260 +                           read_addr_4 ? tpio_out : 
   1.261 +                           read_addr_8 ? tpio_out :
   1.262 +                           read_addr_C ? IRQ_TRI_TEMP :
   1.263 +                           0;
   1.264 +     else
   1.265 +       assign GPIO_DAT_O = 0;
   1.266 +   endgenerate
   1.267 +   
   1.268 +//-----------------------------------------------------------------------------
   1.269 +//-------------------------------IRQ Generation--------------------------------
   1.270 +//-----------------------------------------------------------------------------
   1.271 +   generate
   1.272 +      if (IRQ_MODE == 1) begin
   1.273 +        always @(posedge CLK_I or posedge RST_I)
   1.274 +          if (RST_I) begin
   1.275 +            IRQ_MASK      <= #UDLY 0;
   1.276 +            IRQ_MASK_BOTH <= #UDLY 0;
   1.277 +          end else if (IRQ_MASK_WR_EN) begin
   1.278 +            IRQ_MASK      <= #UDLY GPIO_DAT_I[DATA_WIDTH-1:0];   
   1.279 +            IRQ_MASK_BOTH <= #UDLY GPIO_DAT_I[INPUT_WIDTH-1:0];   
   1.280 +          end
   1.281 +        end
   1.282 +   endgenerate
   1.283 +
   1.284 +   generate 
   1.285 +      //--------------------------------
   1.286 +      //--INPUT_PORTS_ONLY MODE IRQ
   1.287 +      //--------------------------------
   1.288 +      if (IRQ_MODE == 1 && INPUT_PORTS_ONLY == 1 && LEVEL == 1) begin   
   1.289 +         //level mode IRQ
   1.290 +         always @(posedge CLK_I or posedge RST_I)
   1.291 +           if (RST_I)
   1.292 +             IRQ_TEMP <= #UDLY 0;
   1.293 +           else if (IRQ_MASK_WR_EN)
   1.294 +             IRQ_TEMP <= #UDLY IRQ_TEMP & GPIO_DAT_I[DATA_WIDTH-1:0];
   1.295 +              else
   1.296 +             IRQ_TEMP <= #UDLY PIO_IN & IRQ_MASK;//bit-and   
   1.297 +         assign   IRQ_O = |IRQ_TEMP;
   1.298 +      end else if (IRQ_MODE == 1 && INPUT_PORTS_ONLY == 1 && EDGE == 1) begin   
   1.299 +         always @(posedge CLK_I or posedge RST_I)
   1.300 +           if (RST_I)
   1.301 +             PIO_DATA_DLY <= #UDLY 0;
   1.302 +           else
   1.303 +             PIO_DATA_DLY <= PIO_IN;
   1.304 +
   1.305 +         // edge-capture register bits are treated as individual bits.
   1.306 +         genvar i;
   1.307 +         for( i = 0; i < DATA_WIDTH; i = i + 1)
   1.308 +         begin
   1.309 +             always @(posedge CLK_I or posedge RST_I)
   1.310 +                 if (RST_I)
   1.311 +                   EDGE_CAPTURE[i] <= #UDLY 0;
   1.312 +                 else if (|(PIO_IN[i] & ~PIO_DATA_DLY[i]) && (POSE_EDGE_IRQ == 1))
   1.313 +                   EDGE_CAPTURE[i] <= #UDLY PIO_IN[i] & ~PIO_DATA_DLY[i];
   1.314 +                 else if (|(~PIO_IN[i] & PIO_DATA_DLY[i]) && (NEGE_EDGE_IRQ == 1))
   1.315 +                   EDGE_CAPTURE[i] <= #UDLY ~PIO_IN[i] & PIO_DATA_DLY[i];
   1.316 +                 else if (|(PIO_IN[i] & ~PIO_DATA_DLY[i]) && (EITHER_EDGE_IRQ == 1))
   1.317 +                   EDGE_CAPTURE[i] <= #UDLY PIO_IN[i] & ~PIO_DATA_DLY[i];
   1.318 +                 else if (|(~PIO_IN[i] & PIO_DATA_DLY[i]) && (EITHER_EDGE_IRQ == 1))
   1.319 +                   EDGE_CAPTURE[i] <= #UDLY ~PIO_IN[i] & PIO_DATA_DLY[i];
   1.320 +                 else if ( (~IRQ_MASK[i]) & GPIO_DAT_I[i] & IRQ_MASK_WR_EN )
   1.321 +                   // interrupt mask is being set, so clear edge-capture
   1.322 +                   EDGE_CAPTURE[i] <= #UDLY 0;
   1.323 +                 else if (EDGE_CAP_WR_EN)
   1.324 +                   // user's writing to the edge register, so update edge capture
   1.325 +                   // register
   1.326 +                   EDGE_CAPTURE[i] <= #UDLY EDGE_CAPTURE[i] & GPIO_DAT_I[i];
   1.327 +         end
   1.328 +         assign  IRQ_O = |(EDGE_CAPTURE & IRQ_MASK);
   1.329 +
   1.330 +     //----------------------------------
   1.331 +     //--BOTH_INPUT_AND_OUTPUT MODE IRQ
   1.332 +     //----------------------------------
   1.333 +     end else if  (IRQ_MODE == 1 && BOTH_INPUT_AND_OUTPUT == 1 && LEVEL == 1) begin
   1.334 +         always @(posedge CLK_I or posedge RST_I)
   1.335 +            if (RST_I)
   1.336 +              IRQ_TEMP_BOTH <= #UDLY 0;
   1.337 +            else if (IRQ_MASK_WR_EN)
   1.338 +              IRQ_TEMP_BOTH <= #UDLY IRQ_TEMP_BOTH & GPIO_DAT_I[INPUT_WIDTH-1:0];   
   1.339 +            else 
   1.340 +              IRQ_TEMP_BOTH <= #UDLY PIO_BOTH_IN & IRQ_MASK_BOTH;   
   1.341 +         assign   IRQ_O = |IRQ_TEMP_BOTH;
   1.342 +
   1.343 +     //edge mode IRQ
   1.344 +     end else if  (IRQ_MODE == 1 && BOTH_INPUT_AND_OUTPUT == 1 && EDGE == 1) begin   
   1.345 +         always @(posedge CLK_I or posedge RST_I)
   1.346 +           if (RST_I)
   1.347 +             PIO_DATA_DLY_BOTH <= #UDLY 0;
   1.348 +           else
   1.349 +             PIO_DATA_DLY_BOTH <= PIO_BOTH_IN;
   1.350 +
   1.351 +         // edge-capture register bits are treated as individual bits.
   1.352 +         genvar i_both;
   1.353 +         for( i_both = 0; i_both < INPUT_WIDTH; i_both = i_both + 1)
   1.354 +         begin
   1.355 +         always @(posedge CLK_I or posedge RST_I)
   1.356 +           if (RST_I)
   1.357 +             EDGE_CAPTURE_BOTH[i_both] <= #UDLY 0;
   1.358 +           else if (|(PIO_BOTH_IN[i_both] & ~PIO_DATA_DLY_BOTH[i_both]) && POSE_EDGE_IRQ == 1)
   1.359 +             EDGE_CAPTURE_BOTH[i_both] <= #UDLY PIO_BOTH_IN[i_both] & ~PIO_DATA_DLY_BOTH[i_both];
   1.360 +           else if (|(~PIO_BOTH_IN[i_both] & PIO_DATA_DLY_BOTH[i_both]) &&  NEGE_EDGE_IRQ == 1)
   1.361 +             EDGE_CAPTURE_BOTH[i_both] <= #UDLY ~PIO_BOTH_IN[i_both] & PIO_DATA_DLY_BOTH[i_both];
   1.362 +           else if (|(PIO_BOTH_IN[i_both] & ~PIO_DATA_DLY_BOTH[i_both]) && EITHER_EDGE_IRQ == 1)
   1.363 +             EDGE_CAPTURE_BOTH[i_both] <= #UDLY PIO_BOTH_IN[i_both] & ~PIO_DATA_DLY_BOTH[i_both];
   1.364 +           else if (|(~PIO_BOTH_IN[i_both] & PIO_DATA_DLY_BOTH[i_both]) && EITHER_EDGE_IRQ == 1)
   1.365 +             EDGE_CAPTURE_BOTH[i_both] <= #UDLY ~PIO_BOTH_IN[i_both] & PIO_DATA_DLY_BOTH[i_both];
   1.366 +           else if ( (~IRQ_MASK_BOTH[i_both]) & GPIO_DAT_I[i_both] & IRQ_MASK_WR_EN )
   1.367 +             // interrupt mask is being set, so clear edge-capture
   1.368 +             EDGE_CAPTURE_BOTH[i_both] <= #UDLY 0;
   1.369 +           else if (EDGE_CAP_WR_EN)
   1.370 +             // user's writing to the edge register, so update edge capture
   1.371 +             // register
   1.372 +             EDGE_CAPTURE_BOTH[i_both] <= #UDLY EDGE_CAPTURE_BOTH[i_both] & GPIO_DAT_I[i_both];
   1.373 +         end
   1.374 +         assign   IRQ_O = |(EDGE_CAPTURE_BOTH & IRQ_MASK_BOTH);
   1.375 +
   1.376 +     end else if (IRQ_MODE == 1 && TRISTATE_PORTS == 1) begin
   1.377 +         assign  IRQ_O = |IRQ_TRI_TEMP; 
   1.378 +     end else
   1.379 +         assign  IRQ_O = 1'b0;
   1.380 +   endgenerate   
   1.381 +
   1.382 +endmodule
   1.383 +`endif // GPIO_V