rtl/verilog/gpio.v

Sat, 06 Aug 2011 01:43:24 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 06 Aug 2011 01:43:24 +0100
changeset 1
dfc32cad81ba
parent 0
267b5a25932f
permissions
-rw-r--r--

Update to latest Lattice code dump (LM32 V3.8, GPIO V3.2)

Version : 3.2
Mod. Data : Jun 6, 2010
Changes Made : 1. Provide capability to read/write bytes (when GPIO larger than 8 bits wide)
2. Provide capability to use a 32-bit or 8-bit data bus on the WISHBONE slave port
3. Perform a big-endian to little-endian conversion in hardware

philpem@1 1 // ==================================================================
philpem@1 2 // >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
philpem@1 3 // ------------------------------------------------------------------
philpem@1 4 // Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
philpem@1 5 // ALL RIGHTS RESERVED
philpem@1 6 // ------------------------------------------------------------------
philpem@1 7 //
philpem@1 8 // IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
philpem@1 9 //
philpem@1 10 // Permission:
philpem@1 11 //
philpem@1 12 // Lattice Semiconductor grants permission to use this code
philpem@1 13 // pursuant to the terms of the Lattice Semiconductor Corporation
philpem@1 14 // Open Source License Agreement.
philpem@1 15 //
philpem@1 16 // Disclaimer:
philpem@0 17 //
philpem@1 18 // Lattice Semiconductor provides no warranty regarding the use or
philpem@1 19 // functionality of this code. It is the user's responsibility to
philpem@1 20 // verify the user’s design for consistency and functionality through
philpem@1 21 // the use of formal verification methods.
philpem@1 22 //
philpem@1 23 // --------------------------------------------------------------------
philpem@1 24 //
philpem@1 25 // Lattice Semiconductor Corporation
philpem@1 26 // 5555 NE Moore Court
philpem@1 27 // Hillsboro, OR 97214
philpem@1 28 // U.S.A
philpem@1 29 //
philpem@1 30 // TEL: 1-800-Lattice (USA and Canada)
philpem@1 31 // 503-286-8001 (other locations)
philpem@1 32 //
philpem@1 33 // web: http://www.latticesemi.com/
philpem@1 34 // email: techsupport@latticesemi.com
philpem@1 35 //
philpem@1 36 // --------------------------------------------------------------------
philpem@0 37 // FILE DETAILS
philpem@0 38 // Project : GPIO for LM32
philpem@0 39 // File : gpio.v
philpem@0 40 // Title : General Purpose IO Component
philpem@0 41 // Dependencies : system_conf.v
philpem@0 42 // Description : Implements the logic to interface general purpuse IO with
philpem@0 43 // Wishbone bus.
philpem@0 44 // =============================================================================
philpem@0 45 // REVISION HISTORY
philpem@0 46 // Version : 7.0
philpem@0 47 // Mod. Date : Jun 27, 2005
philpem@0 48 // Changes Made : Initial Creation
philpem@0 49 //
philpem@0 50 // Version : 7.0SP2, 3.0
philpem@0 51 // Mod. Date : 20 Nov. 2007
philpem@0 52 // Changes Made : Code clean up.
philpem@0 53 //
philpem@0 54 // Version : 3.1
philpem@0 55 // Mod. Date : 11 Oct. 2008
philpem@0 56 // Changes Made : Update the Edge Capture Register clean method
philpem@0 57 // Make IRQ Mask register readable
philpem@1 58 //
philpem@1 59 // Version : 3.2
philpem@1 60 // Mod. Data : Jun 6, 2010
philpem@1 61 // Changes Made : 1. Provide capability to read/write bytes (when GPIO larger
philpem@1 62 // than 8 bits wide)
philpem@1 63 // 2. Provide capability to use a 32-bit or 8-bit data bus on
philpem@1 64 // the WISHBONE slave port
philpem@1 65 // 3. Perform a big-endian to little-endian conversion in
philpem@1 66 // hardware
philpem@0 67 // =============================================================================
philpem@0 68 `ifndef GPIO_V
philpem@0 69 `define GPIO_V
philpem@0 70 `timescale 1ns/100 ps
philpem@0 71 `include "system_conf.v"
philpem@1 72 module gpio
philpem@1 73 #(
philpem@1 74 parameter GPIO_WB_DAT_WIDTH = 32,
philpem@1 75 parameter GPIO_WB_ADR_WIDTH = 4,
philpem@1 76 parameter DATA_WIDTH = 16,
philpem@1 77 parameter INPUT_WIDTH = 16,
philpem@1 78 parameter OUTPUT_WIDTH = 16,
philpem@1 79 parameter IRQ_MODE = 0,
philpem@1 80 parameter LEVEL = 0,
philpem@1 81 parameter EDGE = 0,
philpem@1 82 parameter POSE_EDGE_IRQ = 0,
philpem@1 83 parameter NEGE_EDGE_IRQ = 0,
philpem@1 84 parameter EITHER_EDGE_IRQ = 0,
philpem@1 85 parameter INPUT_PORTS_ONLY = 1,
philpem@1 86 parameter OUTPUT_PORTS_ONLY = 0,
philpem@1 87 parameter BOTH_INPUT_AND_OUTPUT = 0,
philpem@1 88 parameter TRISTATE_PORTS = 0
philpem@1 89 )
philpem@1 90 (
philpem@1 91 // system clock and reset
philpem@1 92 input CLK_I,
philpem@1 93 input RST_I,
philpem@1 94
philpem@1 95 // wishbone interface signals
philpem@1 96 input GPIO_CYC_I,
philpem@1 97 input GPIO_STB_I,
philpem@1 98 input GPIO_WE_I,
philpem@1 99 input GPIO_LOCK_I,
philpem@1 100 input [2:0] GPIO_CTI_I,
philpem@1 101 input [1:0] GPIO_BTE_I,
philpem@1 102 input [GPIO_WB_ADR_WIDTH-1:0] GPIO_ADR_I,
philpem@1 103 input [GPIO_WB_DAT_WIDTH-1:0] GPIO_DAT_I,
philpem@1 104 input [GPIO_WB_DAT_WIDTH/8-1:0] GPIO_SEL_I,
philpem@1 105 output reg GPIO_ACK_O,
philpem@1 106 output GPIO_ERR_O,
philpem@1 107 output GPIO_RTY_O,
philpem@1 108 output [GPIO_WB_DAT_WIDTH-1:0] GPIO_DAT_O,
philpem@1 109
philpem@1 110 output IRQ_O,
philpem@1 111
philpem@1 112 // PIO side
philpem@1 113 input [DATA_WIDTH-1:0] PIO_IN,
philpem@1 114 input [INPUT_WIDTH-1:0] PIO_BOTH_IN,
philpem@1 115 output [DATA_WIDTH-1:0] PIO_OUT,
philpem@1 116 output [OUTPUT_WIDTH-1:0] PIO_BOTH_OUT,
philpem@1 117 inout [DATA_WIDTH-1:0] PIO_IO
philpem@1 118 );
philpem@0 119
philpem@1 120 // The incoming data bus is big-endian and the internal memory-mapped registers of GPIO
philpem@1 121 // component are little-endian. Performing a big-endian to little-endian conversion!
philpem@1 122 wire [GPIO_WB_DAT_WIDTH-1:0] GPIO_DAT_I_switch, GPIO_DAT_O_switch;
philpem@1 123 wire [GPIO_WB_DAT_WIDTH/8-1:0] GPIO_SEL_I_switch;
philpem@1 124 generate
philpem@1 125 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 126 assign GPIO_DAT_I_switch = GPIO_DAT_I;
philpem@1 127 assign GPIO_SEL_I_switch = GPIO_SEL_I;
philpem@1 128 assign GPIO_DAT_O = GPIO_DAT_O_switch;
philpem@1 129 end
philpem@1 130 else begin
philpem@1 131 assign GPIO_DAT_I_switch = {GPIO_DAT_I[7:0], GPIO_DAT_I[15:8], GPIO_DAT_I[23:16], GPIO_DAT_I[31:24]};
philpem@1 132 assign GPIO_SEL_I_switch = {GPIO_SEL_I[0], GPIO_SEL_I[1], GPIO_SEL_I[2], GPIO_SEL_I[3]};
philpem@1 133 assign GPIO_DAT_O = {GPIO_DAT_O_switch[7:0], GPIO_DAT_O_switch[15:8], GPIO_DAT_O_switch[23:16], GPIO_DAT_O_switch[31:24]};
philpem@1 134 end
philpem@1 135 endgenerate
philpem@1 136
philpem@1 137 reg [OUTPUT_WIDTH-1:0] PIO_DATAO;
philpem@1 138 reg [INPUT_WIDTH-1:0] PIO_DATAI;
philpem@1 139 wire ADR_0, ADR_4, ADR_8, ADR_C;
philpem@1 140 wire [DATA_WIDTH-1:0] tpio_out;
philpem@1 141
philpem@1 142 wire PIO_DATA_WR_EN;
philpem@1 143 wire PIO_DATA_WR_EN_0, PIO_DATA_WR_EN_1, PIO_DATA_WR_EN_2, PIO_DATA_WR_EN_3;
philpem@0 144
philpem@1 145 wire PIO_TRI_WR_EN;
philpem@1 146 wire PIO_TRI_WR_EN_0, PIO_TRI_WR_EN_1, PIO_TRI_WR_EN_2, PIO_TRI_WR_EN_3;
philpem@1 147
philpem@1 148 wire IRQ_MASK_WR_EN;
philpem@1 149 wire IRQ_MASK_WR_EN_0, IRQ_MASK_WR_EN_1, IRQ_MASK_WR_EN_2, IRQ_MASK_WR_EN_3;
philpem@1 150
philpem@1 151 wire EDGE_CAP_WR_EN;
philpem@1 152 wire EDGE_CAP_WR_EN_0, EDGE_CAP_WR_EN_1, EDGE_CAP_WR_EN_2, EDGE_CAP_WR_EN_3;
philpem@1 153
philpem@1 154 wire PIO_DATA_RE_EN;
philpem@1 155 wire PIO_TRI_RE_EN;
philpem@1 156 wire IRQ_MASK_RE_EN;
philpem@1 157 wire [DATA_WIDTH-1:0] IRQ_TRI_TEMP;
philpem@1 158 reg [DATA_WIDTH-1:0] PIO_DATA;
philpem@1 159 reg [DATA_WIDTH-1:0] IRQ_MASK;
philpem@1 160 reg [INPUT_WIDTH-1:0] IRQ_MASK_BOTH;
philpem@1 161 reg [DATA_WIDTH-1:0] IRQ_TEMP;
philpem@1 162 reg [INPUT_WIDTH-1:0] IRQ_TEMP_BOTH;
philpem@1 163 reg [DATA_WIDTH-1:0] EDGE_CAPTURE;
philpem@1 164 reg [INPUT_WIDTH-1:0] EDGE_CAPTURE_BOTH;
philpem@1 165 reg [DATA_WIDTH-1:0] PIO_DATA_DLY;
philpem@1 166 reg [INPUT_WIDTH-1:0] PIO_DATA_DLY_BOTH;
philpem@1 167
philpem@1 168 parameter UDLY = 1;
philpem@1 169
philpem@0 170 assign GPIO_RTY_O = 1'b0;
philpem@0 171 assign GPIO_ERR_O = 1'b0;
philpem@1 172 assign ADR_0 = (GPIO_ADR_I[3:2] == 4'b00 ? 1'b1 : 0); // IO Data
philpem@1 173 assign ADR_4 = (GPIO_ADR_I[3:2] == 4'b01 ? 1'b1 : 0); // Tri-state Control
philpem@1 174 assign ADR_8 = (GPIO_ADR_I[3:2] == 4'b10 ? 1'b1 : 0); // IRQ Mask
philpem@1 175 assign ADR_C = (GPIO_ADR_I[3:2] == 4'b11 ? 1'b1 : 0); // Edge Capture
philpem@1 176
philpem@1 177 always @(posedge CLK_I or posedge RST_I)
philpem@1 178 if(RST_I)
philpem@1 179 GPIO_ACK_O <= #UDLY 1'b0;
philpem@1 180 else if(GPIO_STB_I && (GPIO_ACK_O == 1'b0))
philpem@1 181 GPIO_ACK_O <= #UDLY 1'b1;
philpem@1 182 else
philpem@1 183 GPIO_ACK_O <= #UDLY 1'b0;
philpem@1 184
philpem@1 185
philpem@1 186 generate
philpem@1 187 if (INPUT_PORTS_ONLY == 1) begin
philpem@1 188 always @(posedge CLK_I or posedge RST_I)
philpem@1 189 if (RST_I)
philpem@1 190 PIO_DATA <= #UDLY 0;
philpem@1 191 else if (GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && GPIO_ADR_I[3:2] == 2'b00)
philpem@1 192 PIO_DATA <= #UDLY PIO_IN;
philpem@1 193 end
philpem@1 194 endgenerate
philpem@1 195
philpem@1 196 generate
philpem@1 197 if (OUTPUT_PORTS_ONLY == 1) begin
philpem@1 198 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 199 genvar ipd_idx;
philpem@1 200 for (ipd_idx = 0; (ipd_idx < DATA_WIDTH) && (ipd_idx < 8); ipd_idx = ipd_idx + 1)
philpem@1 201 begin
philpem@1 202 always @(posedge CLK_I or posedge RST_I)
philpem@1 203 if (RST_I)
philpem@1 204 PIO_DATA[ipd_idx] <= #UDLY 0;
philpem@1 205 else if (GPIO_STB_I && !GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0000)
philpem@1 206 PIO_DATA[ipd_idx] <= #UDLY GPIO_DAT_I_switch[ipd_idx];
philpem@1 207 end
philpem@1 208 if (DATA_WIDTH > 8) begin
philpem@1 209 genvar jpd_idx;
philpem@1 210 for (jpd_idx = 8; (jpd_idx < DATA_WIDTH) && (jpd_idx < 16); jpd_idx = jpd_idx + 1)
philpem@1 211 begin
philpem@1 212 always @(posedge CLK_I or posedge RST_I)
philpem@1 213 if (RST_I)
philpem@1 214 PIO_DATA[jpd_idx] <= #UDLY 0;
philpem@1 215 else if (GPIO_STB_I && !GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0001)
philpem@1 216 PIO_DATA[jpd_idx] <= #UDLY GPIO_DAT_I_switch[jpd_idx-8];
philpem@1 217 end
philpem@1 218 end
philpem@1 219 if (DATA_WIDTH > 16) begin
philpem@1 220 genvar kpd_idx;
philpem@1 221 for (kpd_idx = 16; (kpd_idx < DATA_WIDTH) && (kpd_idx < 24); kpd_idx = kpd_idx + 1)
philpem@1 222 begin
philpem@1 223 always @(posedge CLK_I or posedge RST_I)
philpem@1 224 if (RST_I)
philpem@1 225 PIO_DATA[kpd_idx] <= #UDLY 0;
philpem@1 226 else if (GPIO_STB_I && !GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0010)
philpem@1 227 PIO_DATA[kpd_idx] <= #UDLY GPIO_DAT_I_switch[kpd_idx-16];
philpem@1 228 end
philpem@1 229 end
philpem@1 230 if (DATA_WIDTH > 24) begin
philpem@1 231 genvar lpd_idx;
philpem@1 232 for (lpd_idx = 24; (lpd_idx < DATA_WIDTH) && (lpd_idx < 32); lpd_idx = lpd_idx + 1)
philpem@1 233 begin
philpem@1 234 always @(posedge CLK_I or posedge RST_I)
philpem@1 235 if (RST_I)
philpem@1 236 PIO_DATA[lpd_idx] <= #UDLY 0;
philpem@1 237 else if (GPIO_STB_I && !GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0011)
philpem@1 238 PIO_DATA[lpd_idx] <= #UDLY GPIO_DAT_I_switch[lpd_idx-24];
philpem@1 239 end
philpem@1 240 end
philpem@1 241 end // if (GPIO_WB_DAT_WIDTH == 8)
philpem@1 242
philpem@1 243 else if (GPIO_WB_DAT_WIDTH == 32) begin
philpem@1 244 genvar ipd_idx;
philpem@1 245 for (ipd_idx = 0; (ipd_idx < DATA_WIDTH) && (ipd_idx < 8); ipd_idx = ipd_idx + 1)
philpem@1 246 begin
philpem@1 247 always @(posedge CLK_I or posedge RST_I)
philpem@1 248 if (RST_I)
philpem@1 249 PIO_DATA[ipd_idx] <= #UDLY 0;
philpem@1 250 else if (GPIO_STB_I && !GPIO_ACK_O && GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I_switch[0])
philpem@1 251 PIO_DATA[ipd_idx] <= #UDLY GPIO_DAT_I_switch[ipd_idx];
philpem@1 252 end
philpem@1 253 if (DATA_WIDTH > 8) begin
philpem@1 254 genvar jpd_idx;
philpem@1 255 for (jpd_idx = 8; (jpd_idx < DATA_WIDTH) && (jpd_idx < 16); jpd_idx = jpd_idx + 1)
philpem@1 256 begin
philpem@1 257 always @(posedge CLK_I or posedge RST_I)
philpem@1 258 if (RST_I)
philpem@1 259 PIO_DATA[jpd_idx] <= #UDLY 0;
philpem@1 260 else if (GPIO_STB_I && !GPIO_ACK_O && GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I_switch[1])
philpem@1 261 PIO_DATA[jpd_idx] <= #UDLY GPIO_DAT_I_switch[jpd_idx];
philpem@1 262 end
philpem@1 263 end
philpem@1 264 if (DATA_WIDTH > 16) begin
philpem@1 265 genvar kpd_idx;
philpem@1 266 for (kpd_idx = 16; (kpd_idx < DATA_WIDTH) && (kpd_idx < 24); kpd_idx = kpd_idx + 1)
philpem@1 267 begin
philpem@1 268 always @(posedge CLK_I or posedge RST_I)
philpem@1 269 if (RST_I)
philpem@1 270 PIO_DATA[kpd_idx] <= #UDLY 0;
philpem@1 271 else if (GPIO_STB_I && !GPIO_ACK_O && GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I_switch[2])
philpem@1 272 PIO_DATA[kpd_idx] <= #UDLY GPIO_DAT_I_switch[kpd_idx];
philpem@1 273 end
philpem@1 274 end
philpem@1 275 if (DATA_WIDTH > 24) begin
philpem@1 276 genvar lpd_idx;
philpem@1 277 for (lpd_idx = 24; (lpd_idx < DATA_WIDTH) && (lpd_idx < 32); lpd_idx = lpd_idx + 1)
philpem@1 278 begin
philpem@1 279 always @(posedge CLK_I or posedge RST_I)
philpem@1 280 if (RST_I)
philpem@1 281 PIO_DATA[lpd_idx] <= #UDLY 0;
philpem@1 282 else if (GPIO_STB_I && !GPIO_ACK_O && GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I_switch[3])
philpem@1 283 PIO_DATA[lpd_idx] <= #UDLY GPIO_DAT_I_switch[lpd_idx];
philpem@1 284 end
philpem@1 285 end
philpem@1 286 end // if (GPIO_WB_DAT_WIDTH == 32)
philpem@1 287
philpem@1 288 assign PIO_OUT = PIO_DATA;
philpem@1 289 end
philpem@1 290 endgenerate
philpem@1 291
philpem@1 292 generate
philpem@1 293 if (BOTH_INPUT_AND_OUTPUT == 1) begin
philpem@1 294 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 295 genvar iopd_idx;
philpem@1 296 for (iopd_idx = 0; (iopd_idx < OUTPUT_WIDTH) && (iopd_idx < 8); iopd_idx = iopd_idx + 1)
philpem@1 297 begin
philpem@1 298 always @(posedge CLK_I or posedge RST_I)
philpem@1 299 if (RST_I)
philpem@1 300 begin
philpem@1 301 PIO_DATAI[iopd_idx] <= #UDLY 0;
philpem@1 302 PIO_DATAO[iopd_idx] <= #UDLY 0;
philpem@1 303 end
philpem@1 304 else if (GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0000)
philpem@1 305 PIO_DATAI[iopd_idx] <= #UDLY PIO_BOTH_IN[iopd_idx];
philpem@1 306 else if (GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0000)
philpem@1 307 PIO_DATAO[iopd_idx] <= #UDLY GPIO_DAT_I_switch[iopd_idx];
philpem@1 308 end
philpem@1 309 if (OUTPUT_WIDTH > 8) begin
philpem@1 310 genvar jopd_idx;
philpem@1 311 for (jopd_idx = 8; (jopd_idx < OUTPUT_WIDTH) && (jopd_idx < 16); jopd_idx = jopd_idx + 1)
philpem@1 312 begin
philpem@1 313 always @(posedge CLK_I or posedge RST_I)
philpem@1 314 if (RST_I)
philpem@1 315 begin
philpem@1 316 PIO_DATAI[jopd_idx] <= #UDLY 0;
philpem@1 317 PIO_DATAO[jopd_idx] <= #UDLY 0;
philpem@1 318 end
philpem@1 319 else if (GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0001)
philpem@1 320 PIO_DATAI[jopd_idx] <= #UDLY PIO_BOTH_IN[jopd_idx];
philpem@1 321 else if (GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0001)
philpem@1 322 PIO_DATAO[jopd_idx] <= #UDLY GPIO_DAT_I_switch[jopd_idx-8];
philpem@1 323 end
philpem@1 324 end
philpem@1 325 if (OUTPUT_WIDTH > 16) begin
philpem@1 326 genvar kopd_idx;
philpem@1 327 for (kopd_idx = 16; (kopd_idx < OUTPUT_WIDTH) && (kopd_idx < 24); kopd_idx = kopd_idx + 1)
philpem@1 328 begin
philpem@1 329 always @(posedge CLK_I or posedge RST_I)
philpem@1 330 if (RST_I)
philpem@1 331 begin
philpem@1 332 PIO_DATAI[kopd_idx] <= #UDLY 0;
philpem@1 333 PIO_DATAO[kopd_idx] <= #UDLY 0;
philpem@1 334 end
philpem@1 335 else if (GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0010)
philpem@1 336 PIO_DATAI[kopd_idx] <= #UDLY PIO_BOTH_IN[kopd_idx];
philpem@1 337 else if (GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0010)
philpem@1 338 PIO_DATAO[kopd_idx] <= #UDLY GPIO_DAT_I_switch[kopd_idx-16];
philpem@1 339 end
philpem@1 340 end
philpem@1 341 if (OUTPUT_WIDTH > 24) begin
philpem@1 342 genvar lopd_idx;
philpem@1 343 for (lopd_idx = 24; (lopd_idx < OUTPUT_WIDTH) && (lopd_idx < 32); lopd_idx = lopd_idx + 1)
philpem@1 344 begin
philpem@1 345 always @(posedge CLK_I or posedge RST_I)
philpem@1 346 if (RST_I)
philpem@1 347 begin
philpem@1 348 PIO_DATAI[lopd_idx] <= #UDLY 0;
philpem@1 349 PIO_DATAO[lopd_idx] <= #UDLY 0;
philpem@1 350 end
philpem@1 351 else if (GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0011)
philpem@1 352 PIO_DATAI[lopd_idx] <= #UDLY PIO_BOTH_IN[lopd_idx];
philpem@1 353 else if (GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0011)
philpem@1 354 PIO_DATAO[lopd_idx] <= #UDLY GPIO_DAT_I_switch[lopd_idx-24];
philpem@1 355 end
philpem@1 356 end
philpem@1 357 end // if (GPIO_WB_DAT_WIDTH == 8)
philpem@1 358
philpem@1 359 else if (GPIO_WB_DAT_WIDTH == 32) begin
philpem@1 360 genvar iopd_idx;
philpem@1 361 for (iopd_idx = 0; (iopd_idx < OUTPUT_WIDTH) && (iopd_idx < 8); iopd_idx = iopd_idx + 1)
philpem@1 362 begin
philpem@1 363 always @(posedge CLK_I or posedge RST_I)
philpem@1 364 if (RST_I)
philpem@1 365 begin
philpem@1 366 PIO_DATAI[iopd_idx] <= #UDLY 0;
philpem@1 367 PIO_DATAO[iopd_idx] <= #UDLY 0;
philpem@1 368 end
philpem@1 369 else if (GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I_switch[0])
philpem@1 370 PIO_DATAI[iopd_idx] <= #UDLY PIO_BOTH_IN[iopd_idx];
philpem@1 371 else if (GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I_switch[0])
philpem@1 372 PIO_DATAO[iopd_idx] <= #UDLY GPIO_DAT_I_switch[iopd_idx];
philpem@1 373 end
philpem@1 374 if (OUTPUT_WIDTH > 8) begin
philpem@1 375 genvar jopd_idx;
philpem@1 376 for (jopd_idx = 8; (jopd_idx < OUTPUT_WIDTH) && (jopd_idx < 16); jopd_idx = jopd_idx + 1)
philpem@1 377 begin
philpem@1 378 always @(posedge CLK_I or posedge RST_I)
philpem@1 379 if (RST_I)
philpem@1 380 begin
philpem@1 381 PIO_DATAI[jopd_idx] <= #UDLY 0;
philpem@1 382 PIO_DATAO[jopd_idx] <= #UDLY 0;
philpem@1 383 end
philpem@1 384 else if (GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I_switch[1])
philpem@1 385 PIO_DATAI[jopd_idx] <= #UDLY PIO_BOTH_IN[jopd_idx];
philpem@1 386 else if (GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I_switch[1])
philpem@1 387 PIO_DATAO[jopd_idx] <= #UDLY GPIO_DAT_I_switch[jopd_idx];
philpem@1 388 end
philpem@1 389 end
philpem@1 390 if (OUTPUT_WIDTH > 16) begin
philpem@1 391 genvar kopd_idx;
philpem@1 392 for (kopd_idx = 16; (kopd_idx < OUTPUT_WIDTH) && (kopd_idx < 24); kopd_idx = kopd_idx + 1)
philpem@1 393 begin
philpem@1 394 always @(posedge CLK_I or posedge RST_I)
philpem@1 395 if (RST_I)
philpem@1 396 begin
philpem@1 397 PIO_DATAI[kopd_idx] <= #UDLY 0;
philpem@1 398 PIO_DATAO[kopd_idx] <= #UDLY 0;
philpem@1 399 end
philpem@1 400 else if (GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I_switch[2])
philpem@1 401 PIO_DATAI[kopd_idx] <= #UDLY PIO_BOTH_IN[kopd_idx];
philpem@1 402 else if (GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I_switch[2])
philpem@1 403 PIO_DATAO[kopd_idx] <= #UDLY GPIO_DAT_I_switch[kopd_idx];
philpem@1 404 end
philpem@1 405 end
philpem@1 406 if (OUTPUT_WIDTH > 24) begin
philpem@1 407 genvar lopd_idx;
philpem@1 408 for (lopd_idx = 24; (lopd_idx < OUTPUT_WIDTH) && (lopd_idx < 32); lopd_idx = lopd_idx + 1)
philpem@1 409 begin
philpem@1 410 always @(posedge CLK_I or posedge RST_I)
philpem@1 411 if (RST_I)
philpem@1 412 begin
philpem@1 413 PIO_DATAI[lopd_idx] <= #UDLY 0;
philpem@1 414 PIO_DATAO[lopd_idx] <= #UDLY 0;
philpem@1 415 end
philpem@1 416 else if (GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I_switch[3])
philpem@1 417 PIO_DATAI[lopd_idx] <= #UDLY PIO_BOTH_IN[lopd_idx];
philpem@1 418 else if (GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && ADR_0 == 1'b1 && GPIO_SEL_I_switch[3])
philpem@1 419 PIO_DATAO[lopd_idx] <= #UDLY GPIO_DAT_I_switch[lopd_idx];
philpem@1 420 end
philpem@1 421 end
philpem@1 422 end // if (GPIO_WB_DAT_WIDTH == 32)
philpem@1 423
philpem@1 424 assign PIO_BOTH_OUT = PIO_DATAO[OUTPUT_WIDTH-1:0];
philpem@1 425 end
philpem@1 426 endgenerate
philpem@1 427
philpem@1 428 assign PIO_DATA_RE_EN = GPIO_STB_I && !GPIO_ACK_O && !GPIO_WE_I && (GPIO_ADR_I[3:2] == 2'b00);
philpem@1 429
philpem@1 430 assign PIO_TRI_RE_EN = GPIO_STB_I && GPIO_ACK_O && !GPIO_WE_I && (GPIO_ADR_I[3:2] == 2'b01);
philpem@1 431
philpem@1 432 assign IRQ_MASK_RE_EN = GPIO_STB_I && GPIO_ACK_O && !GPIO_WE_I && (GPIO_ADR_I[3:2] == 2'b10);
philpem@1 433
philpem@1 434 assign PIO_DATA_WR_EN = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && (GPIO_ADR_I[3:2] == 2'b00);
philpem@1 435 generate
philpem@1 436 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 437 assign PIO_DATA_WR_EN_0 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0000;
philpem@1 438 assign PIO_DATA_WR_EN_1 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0001;
philpem@1 439 assign PIO_DATA_WR_EN_2 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0010;
philpem@1 440 assign PIO_DATA_WR_EN_3 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0011;
philpem@1 441 end
philpem@1 442 endgenerate
philpem@1 443
philpem@1 444 assign PIO_TRI_WR_EN = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && (GPIO_ADR_I[3:2] == 4'b01);
philpem@1 445 generate
philpem@1 446 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 447 assign PIO_TRI_WR_EN_0 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0100;
philpem@1 448 assign PIO_TRI_WR_EN_1 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0101;
philpem@1 449 assign PIO_TRI_WR_EN_2 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0110;
philpem@1 450 assign PIO_TRI_WR_EN_3 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b0111;
philpem@1 451 end
philpem@1 452 endgenerate
philpem@1 453
philpem@1 454 assign IRQ_MASK_WR_EN = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && (GPIO_ADR_I[3:2] == 2'b10);
philpem@1 455 generate
philpem@1 456 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 457 assign IRQ_MASK_WR_EN_0 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b1000;
philpem@1 458 assign IRQ_MASK_WR_EN_1 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b1001;
philpem@1 459 assign IRQ_MASK_WR_EN_2 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b1010;
philpem@1 460 assign IRQ_MASK_WR_EN_3 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b1011;
philpem@1 461 end
philpem@1 462 endgenerate
philpem@1 463
philpem@1 464 assign EDGE_CAP_WR_EN = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && (GPIO_ADR_I[3:2] == 2'b11);
philpem@1 465 generate
philpem@1 466 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 467 assign EDGE_CAP_WR_EN_0 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b1100;
philpem@1 468 assign EDGE_CAP_WR_EN_1 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b1101;
philpem@1 469 assign EDGE_CAP_WR_EN_2 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b1110;
philpem@1 470 assign EDGE_CAP_WR_EN_3 = GPIO_STB_I && GPIO_ACK_O && GPIO_WE_I && GPIO_ADR_I[3:0] == 4'b1111;
philpem@1 471 end
philpem@1 472 endgenerate
philpem@1 473
philpem@1 474 generate
philpem@1 475
philpem@1 476 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 477
philpem@1 478 genvar iti;
philpem@1 479 for (iti = 0; (iti < DATA_WIDTH) && (iti < 8); iti = iti + 1)
philpem@1 480 begin : itio_inst
philpem@1 481 TRI_PIO
philpem@1 482 #(.DATA_WIDTH(1),
philpem@1 483 .IRQ_MODE(IRQ_MODE),
philpem@1 484 .LEVEL(LEVEL),
philpem@1 485 .EDGE(EDGE),
philpem@1 486 .POSE_EDGE_IRQ(POSE_EDGE_IRQ),
philpem@1 487 .NEGE_EDGE_IRQ(NEGE_EDGE_IRQ),
philpem@1 488 .EITHER_EDGE_IRQ(EITHER_EDGE_IRQ))
philpem@1 489 TP
philpem@1 490 (.CLK_I(CLK_I),
philpem@1 491 .RST_I(RST_I),
philpem@1 492 .DAT_I(GPIO_DAT_I_switch[iti]),
philpem@1 493 .DAT_O(tpio_out[iti]),
philpem@1 494 .PIO_IO(PIO_IO[iti]),
philpem@1 495 .IRQ_O(IRQ_TRI_TEMP[iti]),
philpem@1 496 .PIO_TRI_WR_EN(PIO_TRI_WR_EN_0),
philpem@1 497 .PIO_TRI_RE_EN(PIO_TRI_RE_EN),
philpem@1 498 .PIO_DATA_WR_EN(PIO_DATA_WR_EN_0),
philpem@1 499 .PIO_DATA_RE_EN(PIO_DATA_RE_EN),
philpem@1 500 .IRQ_MASK_WR_EN(IRQ_MASK_WR_EN_0),
philpem@1 501 .IRQ_MASK_RE_EN(IRQ_MASK_RE_EN),
philpem@1 502 .EDGE_CAP_WR_EN(EDGE_CAP_WR_EN_0));
philpem@1 503 end
philpem@1 504 if (DATA_WIDTH > 8) begin
philpem@1 505 genvar jti;
philpem@1 506 for (jti = 8; (jti < DATA_WIDTH) && (jti < 16); jti = jti + 1)
philpem@1 507 begin : jtio_inst
philpem@1 508 TRI_PIO
philpem@1 509 #(.DATA_WIDTH(1),
philpem@1 510 .IRQ_MODE(IRQ_MODE),
philpem@1 511 .LEVEL(LEVEL),
philpem@1 512 .EDGE(EDGE),
philpem@1 513 .POSE_EDGE_IRQ(POSE_EDGE_IRQ),
philpem@1 514 .NEGE_EDGE_IRQ(NEGE_EDGE_IRQ),
philpem@1 515 .EITHER_EDGE_IRQ(EITHER_EDGE_IRQ))
philpem@1 516 TP
philpem@1 517 (.CLK_I(CLK_I),
philpem@1 518 .RST_I(RST_I),
philpem@1 519 .DAT_I(GPIO_DAT_I_switch[jti-8]),
philpem@1 520 .DAT_O(tpio_out[jti]),
philpem@1 521 .PIO_IO(PIO_IO[jti]),
philpem@1 522 .IRQ_O(IRQ_TRI_TEMP[jti]),
philpem@1 523 .PIO_TRI_WR_EN(PIO_TRI_WR_EN_1),
philpem@1 524 .PIO_TRI_RE_EN(PIO_TRI_RE_EN),
philpem@1 525 .PIO_DATA_WR_EN(PIO_DATA_WR_EN_1),
philpem@1 526 .PIO_DATA_RE_EN(PIO_DATA_RE_EN),
philpem@1 527 .IRQ_MASK_WR_EN(IRQ_MASK_WR_EN_1),
philpem@1 528 .IRQ_MASK_RE_EN(IRQ_MASK_RE_EN),
philpem@1 529 .EDGE_CAP_WR_EN(EDGE_CAP_WR_EN_1));
philpem@1 530 end
philpem@1 531 end
philpem@1 532 if (DATA_WIDTH > 16) begin
philpem@1 533 genvar kti;
philpem@1 534 for (kti = 16; (kti < DATA_WIDTH) && (kti < 24); kti = kti + 1)
philpem@1 535 begin : ktio_inst
philpem@1 536 TRI_PIO
philpem@1 537 #(.DATA_WIDTH(1),
philpem@1 538 .IRQ_MODE(IRQ_MODE),
philpem@1 539 .LEVEL(LEVEL),
philpem@1 540 .EDGE(EDGE),
philpem@1 541 .POSE_EDGE_IRQ(POSE_EDGE_IRQ),
philpem@1 542 .NEGE_EDGE_IRQ(NEGE_EDGE_IRQ),
philpem@1 543 .EITHER_EDGE_IRQ(EITHER_EDGE_IRQ))
philpem@1 544 TP
philpem@1 545 (.CLK_I(CLK_I),
philpem@1 546 .RST_I(RST_I),
philpem@1 547 .DAT_I(GPIO_DAT_I_switch[kti-16]),
philpem@1 548 .DAT_O(tpio_out[kti]),
philpem@1 549 .PIO_IO(PIO_IO[kti]),
philpem@1 550 .IRQ_O(IRQ_TRI_TEMP[kti]),
philpem@1 551 .PIO_TRI_WR_EN(PIO_TRI_WR_EN_2),
philpem@1 552 .PIO_TRI_RE_EN(PIO_TRI_RE_EN),
philpem@1 553 .PIO_DATA_WR_EN(PIO_DATA_WR_EN_2),
philpem@1 554 .PIO_DATA_RE_EN(PIO_DATA_RE_EN),
philpem@1 555 .IRQ_MASK_WR_EN(IRQ_MASK_WR_EN_2),
philpem@1 556 .IRQ_MASK_RE_EN(IRQ_MASK_RE_EN),
philpem@1 557 .EDGE_CAP_WR_EN(EDGE_CAP_WR_EN_2));
philpem@1 558 end
philpem@1 559 end
philpem@1 560 if (DATA_WIDTH > 24) begin
philpem@1 561 genvar lti;
philpem@1 562 for (lti = 24; (lti < DATA_WIDTH) && (lti < 32); lti = lti + 1)
philpem@1 563 begin : ltio_inst
philpem@1 564 TRI_PIO
philpem@1 565 #(.DATA_WIDTH(1),
philpem@1 566 .IRQ_MODE(IRQ_MODE),
philpem@1 567 .LEVEL(LEVEL),
philpem@1 568 .EDGE(EDGE),
philpem@1 569 .POSE_EDGE_IRQ(POSE_EDGE_IRQ),
philpem@1 570 .NEGE_EDGE_IRQ(NEGE_EDGE_IRQ),
philpem@1 571 .EITHER_EDGE_IRQ(EITHER_EDGE_IRQ))
philpem@1 572 TP
philpem@1 573 (.CLK_I(CLK_I),
philpem@1 574 .RST_I(RST_I),
philpem@1 575 .DAT_I(GPIO_DAT_I_switch[lti-24]),
philpem@1 576 .DAT_O(tpio_out[lti]),
philpem@1 577 .PIO_IO(PIO_IO[lti]),
philpem@1 578 .IRQ_O(IRQ_TRI_TEMP[lti]),
philpem@1 579 .PIO_TRI_WR_EN(PIO_TRI_WR_EN_3),
philpem@1 580 .PIO_TRI_RE_EN(PIO_TRI_RE_EN),
philpem@1 581 .PIO_DATA_WR_EN(PIO_DATA_WR_EN_3),
philpem@1 582 .PIO_DATA_RE_EN(PIO_DATA_RE_EN),
philpem@1 583 .IRQ_MASK_WR_EN(IRQ_MASK_WR_EN_3),
philpem@1 584 .IRQ_MASK_RE_EN(IRQ_MASK_RE_EN),
philpem@1 585 .EDGE_CAP_WR_EN(EDGE_CAP_WR_EN_3));
philpem@1 586 end
philpem@1 587 end
philpem@1 588
philpem@1 589 end // if (GPIO_WB_DAT_WIDTH == 8)
philpem@1 590
philpem@1 591 else if (GPIO_WB_DAT_WIDTH == 32) begin
philpem@1 592
philpem@1 593 genvar iti;
philpem@1 594 for (iti = 0; (iti < DATA_WIDTH) && (iti < 8); iti = iti + 1)
philpem@1 595 begin : itio_inst
philpem@1 596 TRI_PIO
philpem@1 597 #(.DATA_WIDTH(1),
philpem@1 598 .IRQ_MODE(IRQ_MODE),
philpem@1 599 .LEVEL(LEVEL),
philpem@1 600 .EDGE(EDGE),
philpem@1 601 .POSE_EDGE_IRQ(POSE_EDGE_IRQ),
philpem@1 602 .NEGE_EDGE_IRQ(NEGE_EDGE_IRQ),
philpem@1 603 .EITHER_EDGE_IRQ(EITHER_EDGE_IRQ))
philpem@1 604 TP
philpem@1 605 (.CLK_I(CLK_I),
philpem@1 606 .RST_I(RST_I),
philpem@1 607 .DAT_I(GPIO_DAT_I_switch[iti]),
philpem@1 608 .DAT_O(tpio_out[iti]),
philpem@1 609 .PIO_IO(PIO_IO[iti]),
philpem@1 610 .IRQ_O(IRQ_TRI_TEMP[iti]),
philpem@1 611 .PIO_TRI_WR_EN(PIO_TRI_WR_EN & GPIO_SEL_I_switch[0]),
philpem@1 612 .PIO_TRI_RE_EN(PIO_TRI_RE_EN),
philpem@1 613 .PIO_DATA_WR_EN(PIO_DATA_WR_EN & GPIO_SEL_I_switch[0]),
philpem@1 614 .PIO_DATA_RE_EN(PIO_DATA_RE_EN),
philpem@1 615 .IRQ_MASK_WR_EN(IRQ_MASK_WR_EN & GPIO_SEL_I_switch[0]),
philpem@1 616 .IRQ_MASK_RE_EN(IRQ_MASK_RE_EN),
philpem@1 617 .EDGE_CAP_WR_EN(EDGE_CAP_WR_EN & GPIO_SEL_I_switch[0]));
philpem@1 618 end
philpem@1 619 if (DATA_WIDTH > 8) begin
philpem@1 620 genvar jti;
philpem@1 621 for (jti = 8; (jti < DATA_WIDTH) && (jti < 16); jti = jti + 1)
philpem@1 622 begin : jtio_inst
philpem@1 623 TRI_PIO
philpem@1 624 #(.DATA_WIDTH(1),
philpem@1 625 .IRQ_MODE(IRQ_MODE),
philpem@1 626 .LEVEL(LEVEL),
philpem@1 627 .EDGE(EDGE),
philpem@1 628 .POSE_EDGE_IRQ(POSE_EDGE_IRQ),
philpem@1 629 .NEGE_EDGE_IRQ(NEGE_EDGE_IRQ),
philpem@1 630 .EITHER_EDGE_IRQ(EITHER_EDGE_IRQ))
philpem@1 631 TP
philpem@1 632 (.CLK_I(CLK_I),
philpem@1 633 .RST_I(RST_I),
philpem@1 634 .DAT_I(GPIO_DAT_I_switch[jti]),
philpem@1 635 .DAT_O(tpio_out[jti]),
philpem@1 636 .PIO_IO(PIO_IO[jti]),
philpem@1 637 .IRQ_O(IRQ_TRI_TEMP[jti]),
philpem@1 638 .PIO_TRI_WR_EN(PIO_TRI_WR_EN & GPIO_SEL_I_switch[1]),
philpem@1 639 .PIO_TRI_RE_EN(PIO_TRI_RE_EN),
philpem@1 640 .PIO_DATA_WR_EN(PIO_DATA_WR_EN & GPIO_SEL_I_switch[1]),
philpem@1 641 .PIO_DATA_RE_EN(PIO_DATA_RE_EN),
philpem@1 642 .IRQ_MASK_WR_EN(IRQ_MASK_WR_EN & GPIO_SEL_I_switch[1]),
philpem@1 643 .IRQ_MASK_RE_EN(IRQ_MASK_RE_EN),
philpem@1 644 .EDGE_CAP_WR_EN(EDGE_CAP_WR_EN & GPIO_SEL_I_switch[1]));
philpem@1 645 end
philpem@1 646 end
philpem@1 647 if (DATA_WIDTH > 16) begin
philpem@1 648 genvar kti;
philpem@1 649 for (kti = 16; (kti < DATA_WIDTH) && (kti < 24); kti = kti + 1)
philpem@1 650 begin : ktio_inst
philpem@1 651 TRI_PIO
philpem@1 652 #(.DATA_WIDTH(1),
philpem@1 653 .IRQ_MODE(IRQ_MODE),
philpem@1 654 .LEVEL(LEVEL),
philpem@1 655 .EDGE(EDGE),
philpem@1 656 .POSE_EDGE_IRQ(POSE_EDGE_IRQ),
philpem@1 657 .NEGE_EDGE_IRQ(NEGE_EDGE_IRQ),
philpem@1 658 .EITHER_EDGE_IRQ(EITHER_EDGE_IRQ))
philpem@1 659 TP
philpem@1 660 (.CLK_I(CLK_I),
philpem@1 661 .RST_I(RST_I),
philpem@1 662 .DAT_I(GPIO_DAT_I_switch[kti]),
philpem@1 663 .DAT_O(tpio_out[kti]),
philpem@1 664 .PIO_IO(PIO_IO[kti]),
philpem@1 665 .IRQ_O(IRQ_TRI_TEMP[kti]),
philpem@1 666 .PIO_TRI_WR_EN(PIO_TRI_WR_EN & GPIO_SEL_I_switch[2]),
philpem@1 667 .PIO_TRI_RE_EN(PIO_TRI_RE_EN),
philpem@1 668 .PIO_DATA_WR_EN(PIO_DATA_WR_EN & GPIO_SEL_I_switch[2]),
philpem@1 669 .PIO_DATA_RE_EN(PIO_DATA_RE_EN),
philpem@1 670 .IRQ_MASK_WR_EN(IRQ_MASK_WR_EN & GPIO_SEL_I_switch[2]),
philpem@1 671 .IRQ_MASK_RE_EN(IRQ_MASK_RE_EN),
philpem@1 672 .EDGE_CAP_WR_EN(EDGE_CAP_WR_EN & GPIO_SEL_I_switch[2]));
philpem@1 673 end
philpem@1 674 end
philpem@1 675 if (DATA_WIDTH > 24) begin
philpem@1 676 genvar lti;
philpem@1 677 for (lti = 24; (lti < DATA_WIDTH) && (lti < 32); lti = lti + 1)
philpem@1 678 begin : ltio_inst
philpem@1 679 TRI_PIO
philpem@1 680 #(.DATA_WIDTH(1),
philpem@1 681 .IRQ_MODE(IRQ_MODE),
philpem@1 682 .LEVEL(LEVEL),
philpem@1 683 .EDGE(EDGE),
philpem@1 684 .POSE_EDGE_IRQ(POSE_EDGE_IRQ),
philpem@1 685 .NEGE_EDGE_IRQ(NEGE_EDGE_IRQ),
philpem@1 686 .EITHER_EDGE_IRQ(EITHER_EDGE_IRQ))
philpem@1 687 TP
philpem@1 688 (.CLK_I(CLK_I),
philpem@1 689 .RST_I(RST_I),
philpem@1 690 .DAT_I(GPIO_DAT_I_switch[lti]),
philpem@1 691 .DAT_O(tpio_out[lti]),
philpem@1 692 .PIO_IO(PIO_IO[lti]),
philpem@1 693 .IRQ_O(IRQ_TRI_TEMP[lti]),
philpem@1 694 .PIO_TRI_WR_EN(PIO_TRI_WR_EN & GPIO_SEL_I_switch[3]),
philpem@1 695 .PIO_TRI_RE_EN(PIO_TRI_RE_EN),
philpem@1 696 .PIO_DATA_WR_EN(PIO_DATA_WR_EN & GPIO_SEL_I_switch[3]),
philpem@1 697 .PIO_DATA_RE_EN(PIO_DATA_RE_EN),
philpem@1 698 .IRQ_MASK_WR_EN(IRQ_MASK_WR_EN & GPIO_SEL_I_switch[3]),
philpem@1 699 .IRQ_MASK_RE_EN(IRQ_MASK_RE_EN),
philpem@1 700 .EDGE_CAP_WR_EN(EDGE_CAP_WR_EN & GPIO_SEL_I_switch[3]));
philpem@1 701 end
philpem@1 702 end
philpem@1 703
philpem@1 704 end // if (GPIO_WB_DAT_WIDTH == 32)
philpem@1 705
philpem@1 706 endgenerate
philpem@1 707
philpem@1 708
philpem@1 709 wire read_addr_0, read_addr_4, read_addr_8, read_addr_C;
philpem@0 710 assign read_addr_0 = (ADR_0 & GPIO_STB_I & ~GPIO_WE_I) ;
philpem@0 711 assign read_addr_4 = (ADR_4 & GPIO_STB_I & ~GPIO_WE_I) ;
philpem@0 712 assign read_addr_8 = (IRQ_MODE == 1 && (ADR_8 & GPIO_STB_I & ~GPIO_WE_I));
philpem@1 713 assign read_addr_C = (IRQ_MODE == 1 && (ADR_C & GPIO_STB_I & ~GPIO_WE_I));
philpem@0 714
philpem@1 715 wire read_byte_0, read_byte_1, read_byte_2, read_byte_3;
philpem@1 716 wire read_byte_4, read_byte_5, read_byte_6, read_byte_7;
philpem@1 717 wire read_byte_8, read_byte_9, read_byte_A, read_byte_B;
philpem@1 718 wire read_byte_C, read_byte_D, read_byte_E, read_byte_F;
philpem@1 719 assign read_byte_0 = ((GPIO_ADR_I[3:0] == 4'b0000) & GPIO_STB_I & ~GPIO_WE_I) ;
philpem@1 720 assign read_byte_1 = ((GPIO_ADR_I[3:0] == 4'b0001) & GPIO_STB_I & ~GPIO_WE_I) ;
philpem@1 721 assign read_byte_2 = ((GPIO_ADR_I[3:0] == 4'b0010) & GPIO_STB_I & ~GPIO_WE_I) ;
philpem@1 722 assign read_byte_3 = ((GPIO_ADR_I[3:0] == 4'b0011) & GPIO_STB_I & ~GPIO_WE_I) ;
philpem@1 723 assign read_byte_4 = ((GPIO_ADR_I[3:0] == 4'b0100) & GPIO_STB_I & ~GPIO_WE_I) ;
philpem@1 724 assign read_byte_5 = ((GPIO_ADR_I[3:0] == 4'b0101) & GPIO_STB_I & ~GPIO_WE_I) ;
philpem@1 725 assign read_byte_6 = ((GPIO_ADR_I[3:0] == 4'b0110) & GPIO_STB_I & ~GPIO_WE_I) ;
philpem@1 726 assign read_byte_7 = ((GPIO_ADR_I[3:0] == 4'b0111) & GPIO_STB_I & ~GPIO_WE_I) ;
philpem@1 727 assign read_byte_8 = (IRQ_MODE == 1 && ((GPIO_ADR_I[3:0] == 4'b1000) & GPIO_STB_I & ~GPIO_WE_I));
philpem@1 728 assign read_byte_9 = (IRQ_MODE == 1 && ((GPIO_ADR_I[3:0] == 4'b1001) & GPIO_STB_I & ~GPIO_WE_I));
philpem@1 729 assign read_byte_A = (IRQ_MODE == 1 && ((GPIO_ADR_I[3:0] == 4'b1010) & GPIO_STB_I & ~GPIO_WE_I));
philpem@1 730 assign read_byte_B = (IRQ_MODE == 1 && ((GPIO_ADR_I[3:0] == 4'b1011) & GPIO_STB_I & ~GPIO_WE_I));
philpem@1 731 assign read_byte_C = (IRQ_MODE == 1 && ((GPIO_ADR_I[3:0] == 4'b1100) & GPIO_STB_I & ~GPIO_WE_I));
philpem@1 732 assign read_byte_D = (IRQ_MODE == 1 && ((GPIO_ADR_I[3:0] == 4'b1101) & GPIO_STB_I & ~GPIO_WE_I));
philpem@1 733 assign read_byte_E = (IRQ_MODE == 1 && ((GPIO_ADR_I[3:0] == 4'b1110) & GPIO_STB_I & ~GPIO_WE_I));
philpem@1 734 assign read_byte_F = (IRQ_MODE == 1 && ((GPIO_ADR_I[3:0] == 4'b1111) & GPIO_STB_I & ~GPIO_WE_I));
philpem@0 735
philpem@0 736 generate
philpem@0 737
philpem@1 738 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 739
philpem@1 740 if (INPUT_PORTS_ONLY == 1) begin
philpem@1 741 if (DATA_WIDTH > 24)
philpem@1 742 assign GPIO_DAT_O_switch = read_byte_0 ? PIO_DATA[ 7: 0] :
philpem@1 743 read_byte_1 ? PIO_DATA[15: 8] :
philpem@1 744 read_byte_2 ? PIO_DATA[23:16] :
philpem@1 745 read_byte_3 ? PIO_DATA[DATA_WIDTH-1:24] :
philpem@1 746 read_byte_8 ? IRQ_MASK[ 7: 0] :
philpem@1 747 read_byte_9 ? IRQ_MASK[15: 8] :
philpem@1 748 read_byte_A ? IRQ_MASK[23:16] :
philpem@1 749 read_byte_B ? IRQ_MASK[DATA_WIDTH-1:24] :
philpem@1 750 read_byte_C ? EDGE_CAPTURE[ 7: 0] :
philpem@1 751 read_byte_D ? EDGE_CAPTURE[15: 8] :
philpem@1 752 read_byte_E ? EDGE_CAPTURE[23:16] :
philpem@1 753 read_byte_F ? EDGE_CAPTURE[DATA_WIDTH-1:24] :
philpem@1 754 0;
philpem@1 755 else if (DATA_WIDTH > 16)
philpem@1 756 assign GPIO_DAT_O_switch = read_byte_0 ? PIO_DATA[ 7: 0] :
philpem@1 757 read_byte_1 ? PIO_DATA[15: 8] :
philpem@1 758 read_byte_2 ? PIO_DATA[DATA_WIDTH-1:16] :
philpem@1 759 read_byte_3 ? 8'h00 :
philpem@1 760 read_byte_8 ? IRQ_MASK[ 7: 0] :
philpem@1 761 read_byte_9 ? IRQ_MASK[15: 8] :
philpem@1 762 read_byte_A ? IRQ_MASK[DATA_WIDTH-1:16] :
philpem@1 763 read_byte_B ? 8'h00 :
philpem@1 764 read_byte_C ? EDGE_CAPTURE[ 7: 0] :
philpem@1 765 read_byte_D ? EDGE_CAPTURE[15: 8] :
philpem@1 766 read_byte_E ? EDGE_CAPTURE[DATA_WIDTH-1:16] :
philpem@1 767 read_byte_F ? 8'h00 :
philpem@1 768 0;
philpem@1 769 else if (DATA_WIDTH > 8)
philpem@1 770 assign GPIO_DAT_O_switch = read_byte_0 ? PIO_DATA[ 7: 0] :
philpem@1 771 read_byte_1 ? PIO_DATA[DATA_WIDTH-1: 8] :
philpem@1 772 read_byte_2 ? 8'h00 :
philpem@1 773 read_byte_3 ? 8'h00 :
philpem@1 774 read_byte_8 ? IRQ_MASK[ 7: 0] :
philpem@1 775 read_byte_9 ? IRQ_MASK[DATA_WIDTH-1: 8] :
philpem@1 776 read_byte_A ? 8'h00 :
philpem@1 777 read_byte_B ? 8'h00 :
philpem@1 778 read_byte_C ? EDGE_CAPTURE[ 7: 0] :
philpem@1 779 read_byte_D ? EDGE_CAPTURE[DATA_WIDTH-1: 8] :
philpem@1 780 read_byte_E ? 8'h00 :
philpem@1 781 read_byte_F ? 8'h00 :
philpem@1 782 0;
philpem@1 783 else
philpem@1 784 assign GPIO_DAT_O_switch = read_byte_0 ? PIO_DATA[DATA_WIDTH-1: 0] :
philpem@1 785 read_byte_1 ? 8'h00 :
philpem@1 786 read_byte_2 ? 8'h00 :
philpem@1 787 read_byte_3 ? 8'h00 :
philpem@1 788 read_byte_8 ? IRQ_MASK[DATA_WIDTH-1: 0] :
philpem@1 789 read_byte_9 ? 8'h00 :
philpem@1 790 read_byte_A ? 8'h00 :
philpem@1 791 read_byte_B ? 8'h00 :
philpem@1 792 read_byte_C ? EDGE_CAPTURE[DATA_WIDTH-1: 0] :
philpem@1 793 read_byte_D ? 8'h00 :
philpem@1 794 read_byte_E ? 8'h00 :
philpem@1 795 read_byte_F ? 8'h00 :
philpem@1 796 0;
philpem@1 797 end
philpem@1 798 else if (BOTH_INPUT_AND_OUTPUT == 1) begin
philpem@1 799 if (INPUT_WIDTH > 24)
philpem@1 800 assign GPIO_DAT_O_switch = read_byte_0 ? PIO_DATAI[ 7: 0] :
philpem@1 801 read_byte_1 ? PIO_DATAI[15: 8] :
philpem@1 802 read_byte_2 ? PIO_DATAI[23:16] :
philpem@1 803 read_byte_3 ? PIO_DATAI[INPUT_WIDTH-1:24] :
philpem@1 804 read_byte_8 ? IRQ_MASK_BOTH[ 7: 0] :
philpem@1 805 read_byte_9 ? IRQ_MASK_BOTH[15: 8] :
philpem@1 806 read_byte_A ? IRQ_MASK_BOTH[23:16] :
philpem@1 807 read_byte_B ? IRQ_MASK_BOTH[INPUT_WIDTH-1:24] :
philpem@1 808 read_byte_C ? EDGE_CAPTURE_BOTH[ 7: 0] :
philpem@1 809 read_byte_D ? EDGE_CAPTURE_BOTH[15: 8] :
philpem@1 810 read_byte_E ? EDGE_CAPTURE_BOTH[23:16] :
philpem@1 811 read_byte_F ? EDGE_CAPTURE_BOTH[INPUT_WIDTH-1:24] :
philpem@1 812 0;
philpem@1 813 else if (INPUT_WIDTH > 16)
philpem@1 814 assign GPIO_DAT_O_switch = read_byte_0 ? PIO_DATAI[ 7: 0] :
philpem@1 815 read_byte_1 ? PIO_DATAI[15: 8] :
philpem@1 816 read_byte_2 ? PIO_DATAI[INPUT_WIDTH-1:16] :
philpem@1 817 read_byte_3 ? 8'h00 :
philpem@1 818 read_byte_8 ? IRQ_MASK_BOTH[ 7: 0] :
philpem@1 819 read_byte_9 ? IRQ_MASK_BOTH[15: 8] :
philpem@1 820 read_byte_A ? IRQ_MASK_BOTH[INPUT_WIDTH-1:16] :
philpem@1 821 read_byte_B ? 8'h00 :
philpem@1 822 read_byte_C ? EDGE_CAPTURE_BOTH[ 7: 0] :
philpem@1 823 read_byte_D ? EDGE_CAPTURE_BOTH[15: 8] :
philpem@1 824 read_byte_E ? EDGE_CAPTURE_BOTH[INPUT_WIDTH-1:16] :
philpem@1 825 read_byte_F ? 8'h00 :
philpem@1 826 0;
philpem@1 827 else if (INPUT_WIDTH > 8)
philpem@1 828 assign GPIO_DAT_O_switch = read_byte_0 ? PIO_DATAI[ 7: 0] :
philpem@1 829 read_byte_1 ? PIO_DATAI[INPUT_WIDTH-1: 8] :
philpem@1 830 read_byte_2 ? 8'h00 :
philpem@1 831 read_byte_3 ? 8'h00 :
philpem@1 832 read_byte_8 ? IRQ_MASK_BOTH[ 7: 0] :
philpem@1 833 read_byte_9 ? IRQ_MASK_BOTH[INPUT_WIDTH-1: 8] :
philpem@1 834 read_byte_A ? 8'h00 :
philpem@1 835 read_byte_B ? 8'h00 :
philpem@1 836 read_byte_C ? EDGE_CAPTURE_BOTH[ 7: 0] :
philpem@1 837 read_byte_D ? EDGE_CAPTURE_BOTH[INPUT_WIDTH-1: 8] :
philpem@1 838 read_byte_E ? 8'h00 :
philpem@1 839 read_byte_F ? 8'h00 :
philpem@1 840 0;
philpem@1 841 else
philpem@1 842 assign GPIO_DAT_O_switch = read_byte_0 ? PIO_DATAI[INPUT_WIDTH-1: 0] :
philpem@1 843 read_byte_1 ? 8'h00 :
philpem@1 844 read_byte_2 ? 8'h00 :
philpem@1 845 read_byte_3 ? 8'h00 :
philpem@1 846 read_byte_8 ? IRQ_MASK_BOTH[INPUT_WIDTH-1: 0] :
philpem@1 847 read_byte_9 ? 8'h00 :
philpem@1 848 read_byte_A ? 8'h00 :
philpem@1 849 read_byte_B ? 8'h00 :
philpem@1 850 read_byte_C ? EDGE_CAPTURE_BOTH[INPUT_WIDTH-1: 0] :
philpem@1 851 read_byte_D ? 8'h00 :
philpem@1 852 read_byte_E ? 8'h00 :
philpem@1 853 read_byte_F ? 8'h00 :
philpem@1 854 0;
philpem@1 855 end
philpem@1 856 else if (TRISTATE_PORTS == 1) begin
philpem@1 857 if (DATA_WIDTH > 24)
philpem@1 858 assign GPIO_DAT_O_switch = read_byte_0 ? tpio_out[ 7: 0] :
philpem@1 859 read_byte_1 ? tpio_out[15: 8] :
philpem@1 860 read_byte_2 ? tpio_out[23:16] :
philpem@1 861 read_byte_3 ? tpio_out[DATA_WIDTH-1:24] :
philpem@1 862 read_byte_4 ? tpio_out[ 7: 0] :
philpem@1 863 read_byte_5 ? tpio_out[15: 8] :
philpem@1 864 read_byte_6 ? tpio_out[23:16] :
philpem@1 865 read_byte_7 ? tpio_out[DATA_WIDTH-1:24] :
philpem@1 866 read_byte_8 ? tpio_out[ 7: 0] :
philpem@1 867 read_byte_9 ? tpio_out[15: 8] :
philpem@1 868 read_byte_A ? tpio_out[23:16] :
philpem@1 869 read_byte_B ? tpio_out[DATA_WIDTH-1:24] :
philpem@1 870 read_byte_C ? IRQ_TRI_TEMP[ 7: 0] :
philpem@1 871 read_byte_D ? IRQ_TRI_TEMP[15: 8] :
philpem@1 872 read_byte_E ? IRQ_TRI_TEMP[23:16] :
philpem@1 873 read_byte_F ? IRQ_TRI_TEMP[DATA_WIDTH-1:24] :
philpem@1 874 0;
philpem@1 875 else if (DATA_WIDTH > 16)
philpem@1 876 assign GPIO_DAT_O_switch = read_byte_0 ? tpio_out[ 7: 0] :
philpem@1 877 read_byte_1 ? tpio_out[15: 8] :
philpem@1 878 read_byte_2 ? tpio_out[DATA_WIDTH-1:16] :
philpem@1 879 read_byte_3 ? 8'h00 :
philpem@1 880 read_byte_4 ? tpio_out[ 7: 0] :
philpem@1 881 read_byte_5 ? tpio_out[15: 8] :
philpem@1 882 read_byte_6 ? tpio_out[DATA_WIDTH-1:16] :
philpem@1 883 read_byte_7 ? 8'h00 :
philpem@1 884 read_byte_8 ? tpio_out[ 7: 0] :
philpem@1 885 read_byte_9 ? tpio_out[15: 8] :
philpem@1 886 read_byte_A ? tpio_out[DATA_WIDTH-1:16] :
philpem@1 887 read_byte_B ? 8'h00 :
philpem@1 888 read_byte_C ? IRQ_TRI_TEMP[ 7: 0] :
philpem@1 889 read_byte_D ? IRQ_TRI_TEMP[15: 8] :
philpem@1 890 read_byte_E ? IRQ_TRI_TEMP[DATA_WIDTH-1:16] :
philpem@1 891 read_byte_F ? 8'h00 :
philpem@1 892 0;
philpem@1 893 else if (DATA_WIDTH > 8)
philpem@1 894 assign GPIO_DAT_O_switch = read_byte_0 ? tpio_out[ 7: 0] :
philpem@1 895 read_byte_1 ? tpio_out[DATA_WIDTH-1: 8] :
philpem@1 896 read_byte_2 ? 8'h00 :
philpem@1 897 read_byte_3 ? 8'h00 :
philpem@1 898 read_byte_4 ? tpio_out[ 7: 0] :
philpem@1 899 read_byte_5 ? tpio_out[DATA_WIDTH-1: 8] :
philpem@1 900 read_byte_6 ? 8'h00 :
philpem@1 901 read_byte_7 ? 8'h00 :
philpem@1 902 read_byte_8 ? tpio_out[ 7: 0] :
philpem@1 903 read_byte_9 ? tpio_out[DATA_WIDTH-1: 8] :
philpem@1 904 read_byte_A ? 8'h00 :
philpem@1 905 read_byte_B ? 8'h00 :
philpem@1 906 read_byte_C ? IRQ_TRI_TEMP[ 7: 0] :
philpem@1 907 read_byte_D ? IRQ_TRI_TEMP[DATA_WIDTH-1: 8] :
philpem@1 908 read_byte_E ? 8'h00 :
philpem@1 909 read_byte_F ? 8'h00 :
philpem@1 910 0;
philpem@1 911 else
philpem@1 912 assign GPIO_DAT_O_switch = read_byte_0 ? tpio_out[DATA_WIDTH-1: 0] :
philpem@1 913 read_byte_1 ? 8'h00 :
philpem@1 914 read_byte_2 ? 8'h00 :
philpem@1 915 read_byte_3 ? 8'h00 :
philpem@1 916 read_byte_4 ? tpio_out[DATA_WIDTH-1: 0] :
philpem@1 917 read_byte_5 ? 8'h00 :
philpem@1 918 read_byte_6 ? 8'h00 :
philpem@1 919 read_byte_7 ? 8'h00 :
philpem@1 920 read_byte_8 ? tpio_out[DATA_WIDTH-1: 0] :
philpem@1 921 read_byte_9 ? 8'h00 :
philpem@1 922 read_byte_A ? 8'h00 :
philpem@1 923 read_byte_B ? 8'h00 :
philpem@1 924 read_byte_C ? IRQ_TRI_TEMP[DATA_WIDTH-1: 0] :
philpem@1 925 read_byte_D ? 8'h00 :
philpem@1 926 read_byte_E ? 8'h00 :
philpem@1 927 read_byte_F ? 8'h00 :
philpem@1 928 0;
philpem@1 929 end
philpem@1 930 else
philpem@1 931 assign GPIO_DAT_O_switch = 0;
philpem@1 932
philpem@1 933 end // if (GPIO_WB_DAT_WIDTH == 8)
philpem@1 934
philpem@1 935 else if (GPIO_WB_DAT_WIDTH == 32) begin
philpem@1 936
philpem@1 937 if (INPUT_PORTS_ONLY == 1)
philpem@1 938 assign GPIO_DAT_O_switch = read_addr_0 ? PIO_DATA :
philpem@1 939 read_addr_8 ? IRQ_MASK :
philpem@1 940 read_addr_C ? EDGE_CAPTURE :
philpem@1 941 0;
philpem@1 942 else if (BOTH_INPUT_AND_OUTPUT == 1)
philpem@1 943 assign GPIO_DAT_O_switch = read_addr_0 ? PIO_DATAI :
philpem@1 944 read_addr_8 ? IRQ_MASK_BOTH :
philpem@1 945 read_addr_C ? EDGE_CAPTURE_BOTH :
philpem@1 946 0;
philpem@1 947 else if (TRISTATE_PORTS == 1)
philpem@1 948 assign GPIO_DAT_O_switch = read_addr_0 ? tpio_out :
philpem@1 949 read_addr_4 ? tpio_out :
philpem@1 950 read_addr_8 ? tpio_out :
philpem@1 951 read_addr_C ? IRQ_TRI_TEMP :
philpem@1 952 0;
philpem@1 953 else
philpem@1 954 assign GPIO_DAT_O_switch = 0;
philpem@1 955
philpem@1 956 end // if (GPIO_WB_DAT_WIDTH == 32)
philpem@1 957
philpem@0 958 endgenerate
philpem@0 959
philpem@1 960
philpem@1 961
philpem@1 962 //-----------------------------------------------------------------------------
philpem@1 963 //-------------------------------IRQ Generation--------------------------------
philpem@1 964 //-----------------------------------------------------------------------------
philpem@0 965 generate
philpem@1 966
philpem@0 967 if (IRQ_MODE == 1) begin
philpem@1 968
philpem@1 969 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 970
philpem@1 971 genvar im_idx;
philpem@1 972 for (im_idx = 0; (im_idx < DATA_WIDTH) && (im_idx < 8); im_idx = im_idx + 1)
philpem@1 973 begin
philpem@1 974 always @(posedge CLK_I or posedge RST_I)
philpem@1 975 if (RST_I)
philpem@1 976 IRQ_MASK[im_idx] <= #UDLY 0;
philpem@1 977 else if (IRQ_MASK_WR_EN_0)
philpem@1 978 IRQ_MASK[im_idx] <= #UDLY GPIO_DAT_I_switch[im_idx];
philpem@1 979 end
philpem@1 980 if (DATA_WIDTH > 8) begin
philpem@1 981 genvar jm_idx;
philpem@1 982 for (jm_idx = 8; (jm_idx < DATA_WIDTH) && (jm_idx < 16); jm_idx = jm_idx + 1)
philpem@1 983 begin
philpem@1 984 always @(posedge CLK_I or posedge RST_I)
philpem@1 985 if (RST_I)
philpem@1 986 IRQ_MASK[jm_idx] <= #UDLY 0;
philpem@1 987 else if (IRQ_MASK_WR_EN_1)
philpem@1 988 IRQ_MASK[jm_idx] <= #UDLY GPIO_DAT_I_switch[jm_idx-8];
philpem@1 989 end
philpem@1 990 end
philpem@1 991 if (DATA_WIDTH > 16) begin
philpem@1 992 genvar km_idx;
philpem@1 993 for (km_idx = 16; (km_idx < DATA_WIDTH) && (km_idx < 24); km_idx = km_idx + 1)
philpem@1 994 begin
philpem@1 995 always @(posedge CLK_I or posedge RST_I)
philpem@1 996 if (RST_I)
philpem@1 997 IRQ_MASK[km_idx] <= #UDLY 0;
philpem@1 998 else if (IRQ_MASK_WR_EN_2)
philpem@1 999 IRQ_MASK[km_idx] <= #UDLY GPIO_DAT_I_switch[km_idx-16];
philpem@1 1000 end
philpem@1 1001 end
philpem@1 1002 if (DATA_WIDTH > 24) begin
philpem@1 1003 genvar lm_idx;
philpem@1 1004 for (lm_idx = 24; (lm_idx < DATA_WIDTH) && (lm_idx < 32); lm_idx = lm_idx + 1)
philpem@1 1005 begin
philpem@1 1006 always @(posedge CLK_I or posedge RST_I)
philpem@1 1007 if (RST_I)
philpem@1 1008 IRQ_MASK[lm_idx] <= #UDLY 0;
philpem@1 1009 else if (IRQ_MASK_WR_EN_3)
philpem@1 1010 IRQ_MASK[lm_idx] <= #UDLY GPIO_DAT_I_switch[lm_idx-24];
philpem@1 1011 end
philpem@1 1012 end
philpem@1 1013
philpem@1 1014 genvar imb_idx;
philpem@1 1015 for (imb_idx = 0; (imb_idx < INPUT_WIDTH) && (imb_idx < 8); imb_idx = imb_idx + 1)
philpem@1 1016 begin
philpem@1 1017 always @(posedge CLK_I or posedge RST_I)
philpem@1 1018 if (RST_I)
philpem@1 1019 IRQ_MASK_BOTH[imb_idx] <= #UDLY 0;
philpem@1 1020 else if (IRQ_MASK_WR_EN_0)
philpem@1 1021 IRQ_MASK_BOTH[imb_idx] <= #UDLY GPIO_DAT_I_switch[imb_idx];
philpem@1 1022 end
philpem@1 1023 if (INPUT_WIDTH > 8) begin
philpem@1 1024 genvar jmb_idx;
philpem@1 1025 for (jmb_idx = 8; (jmb_idx < INPUT_WIDTH) && (jmb_idx < 16); jmb_idx = jmb_idx + 1)
philpem@1 1026 begin
philpem@1 1027 always @(posedge CLK_I or posedge RST_I)
philpem@1 1028 if (RST_I)
philpem@1 1029 IRQ_MASK_BOTH[jmb_idx] <= #UDLY 0;
philpem@1 1030 else if (IRQ_MASK_WR_EN_1)
philpem@1 1031 IRQ_MASK_BOTH[jmb_idx] <= #UDLY GPIO_DAT_I_switch[jmb_idx-8];
philpem@1 1032 end
philpem@1 1033 end
philpem@1 1034 if (INPUT_WIDTH > 16) begin
philpem@1 1035 genvar kmb_idx;
philpem@1 1036 for (kmb_idx = 16; (kmb_idx < INPUT_WIDTH) && (kmb_idx < 24); kmb_idx = kmb_idx + 1)
philpem@1 1037 begin
philpem@1 1038 always @(posedge CLK_I or posedge RST_I)
philpem@1 1039 if (RST_I)
philpem@1 1040 IRQ_MASK_BOTH[kmb_idx] <= #UDLY 0;
philpem@1 1041 else if (IRQ_MASK_WR_EN_2)
philpem@1 1042 IRQ_MASK_BOTH[kmb_idx] <= #UDLY GPIO_DAT_I_switch[kmb_idx-16];
philpem@1 1043 end
philpem@1 1044 end
philpem@1 1045 if (INPUT_WIDTH > 24) begin
philpem@1 1046 genvar lmb_idx;
philpem@1 1047 for (lmb_idx = 24; (lmb_idx < INPUT_WIDTH) && (lmb_idx < 32); lmb_idx = lmb_idx + 1)
philpem@1 1048 begin
philpem@1 1049 always @(posedge CLK_I or posedge RST_I)
philpem@1 1050 if (RST_I)
philpem@1 1051 IRQ_MASK_BOTH[lmb_idx] <= #UDLY 0;
philpem@1 1052 else if (IRQ_MASK_WR_EN_3)
philpem@1 1053 IRQ_MASK_BOTH[lmb_idx] <= #UDLY GPIO_DAT_I_switch[lmb_idx-24];
philpem@1 1054 end
philpem@1 1055 end
philpem@1 1056
philpem@1 1057 end // if (GPIO_WB_DAT_WIDTH == 8)
philpem@1 1058 else if (GPIO_WB_DAT_WIDTH == 32) begin
philpem@1 1059
philpem@1 1060 genvar im_idx;
philpem@1 1061 for (im_idx = 0; (im_idx < DATA_WIDTH) && (im_idx < 8); im_idx = im_idx + 1)
philpem@1 1062 begin
philpem@1 1063 always @(posedge CLK_I or posedge RST_I)
philpem@1 1064 if (RST_I)
philpem@1 1065 IRQ_MASK[im_idx] <= #UDLY 0;
philpem@1 1066 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[0])
philpem@1 1067 IRQ_MASK[im_idx] <= #UDLY GPIO_DAT_I_switch[im_idx];
philpem@1 1068 end
philpem@1 1069 if (DATA_WIDTH > 8) begin
philpem@1 1070 genvar jm_idx;
philpem@1 1071 for (jm_idx = 8; (jm_idx < DATA_WIDTH) && (jm_idx < 16); jm_idx = jm_idx + 1)
philpem@1 1072 begin
philpem@1 1073 always @(posedge CLK_I or posedge RST_I)
philpem@1 1074 if (RST_I)
philpem@1 1075 IRQ_MASK[jm_idx] <= #UDLY 0;
philpem@1 1076 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[1])
philpem@1 1077 IRQ_MASK[jm_idx] <= #UDLY GPIO_DAT_I_switch[jm_idx];
philpem@1 1078 end
philpem@1 1079 end
philpem@1 1080 if (DATA_WIDTH > 16) begin
philpem@1 1081 genvar km_idx;
philpem@1 1082 for (km_idx = 16; (km_idx < DATA_WIDTH) && (km_idx < 24); km_idx = km_idx + 1)
philpem@1 1083 begin
philpem@1 1084 always @(posedge CLK_I or posedge RST_I)
philpem@1 1085 if (RST_I)
philpem@1 1086 IRQ_MASK[km_idx] <= #UDLY 0;
philpem@1 1087 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[2])
philpem@1 1088 IRQ_MASK[km_idx] <= #UDLY GPIO_DAT_I_switch[km_idx];
philpem@1 1089 end
philpem@1 1090 end
philpem@1 1091 if (DATA_WIDTH > 24) begin
philpem@1 1092 genvar lm_idx;
philpem@1 1093 for (lm_idx = 24; (lm_idx < DATA_WIDTH) && (lm_idx < 32); lm_idx = lm_idx + 1)
philpem@1 1094 begin
philpem@1 1095 always @(posedge CLK_I or posedge RST_I)
philpem@1 1096 if (RST_I)
philpem@1 1097 IRQ_MASK[lm_idx] <= #UDLY 0;
philpem@1 1098 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[3])
philpem@1 1099 IRQ_MASK[lm_idx] <= #UDLY GPIO_DAT_I_switch[lm_idx];
philpem@1 1100 end
philpem@1 1101 end
philpem@1 1102
philpem@1 1103 genvar imb_idx;
philpem@1 1104 for (imb_idx = 0; (imb_idx < INPUT_WIDTH) && (imb_idx < 8); imb_idx = imb_idx + 1)
philpem@1 1105 begin
philpem@1 1106 always @(posedge CLK_I or posedge RST_I)
philpem@1 1107 if (RST_I)
philpem@1 1108 IRQ_MASK_BOTH[imb_idx] <= #UDLY 0;
philpem@1 1109 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[0])
philpem@1 1110 IRQ_MASK_BOTH[imb_idx] <= #UDLY GPIO_DAT_I_switch[imb_idx];
philpem@1 1111 end
philpem@1 1112 if (INPUT_WIDTH > 8) begin
philpem@1 1113 genvar jmb_idx;
philpem@1 1114 for (jmb_idx = 8; (jmb_idx < INPUT_WIDTH) && (jmb_idx < 16); jmb_idx = jmb_idx + 1)
philpem@1 1115 begin
philpem@1 1116 always @(posedge CLK_I or posedge RST_I)
philpem@1 1117 if (RST_I)
philpem@1 1118 IRQ_MASK_BOTH[jmb_idx] <= #UDLY 0;
philpem@1 1119 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[1])
philpem@1 1120 IRQ_MASK_BOTH[jmb_idx] <= #UDLY GPIO_DAT_I_switch[jmb_idx];
philpem@1 1121 end
philpem@1 1122 end
philpem@1 1123 if (INPUT_WIDTH > 16) begin
philpem@1 1124 genvar kmb_idx;
philpem@1 1125 for (kmb_idx = 16; (kmb_idx < INPUT_WIDTH) && (kmb_idx < 24); kmb_idx = kmb_idx + 1)
philpem@1 1126 begin
philpem@1 1127 always @(posedge CLK_I or posedge RST_I)
philpem@1 1128 if (RST_I)
philpem@1 1129 IRQ_MASK_BOTH[kmb_idx] <= #UDLY 0;
philpem@1 1130 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[2])
philpem@1 1131 IRQ_MASK_BOTH[kmb_idx] <= #UDLY GPIO_DAT_I_switch[kmb_idx];
philpem@1 1132 end
philpem@1 1133 end
philpem@1 1134 if (INPUT_WIDTH > 24) begin
philpem@1 1135 genvar lmb_idx;
philpem@1 1136 for (lmb_idx = 24; (lmb_idx < INPUT_WIDTH) && (lmb_idx < 32); lmb_idx = lmb_idx + 1)
philpem@1 1137 begin
philpem@1 1138 always @(posedge CLK_I or posedge RST_I)
philpem@1 1139 if (RST_I)
philpem@1 1140 IRQ_MASK_BOTH[lmb_idx] <= #UDLY 0;
philpem@1 1141 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[3])
philpem@1 1142 IRQ_MASK_BOTH[lmb_idx] <= #UDLY GPIO_DAT_I_switch[lmb_idx];
philpem@1 1143 end
philpem@1 1144 end
philpem@1 1145
philpem@1 1146 end // if (GPIO_WB_DAT_WIDTH == 32)
philpem@1 1147
philpem@1 1148 end // if (IRQ_MODE == 1)
philpem@1 1149
philpem@0 1150 endgenerate
philpem@1 1151
philpem@1 1152
philpem@1 1153
philpem@0 1154 generate
philpem@0 1155 //--------------------------------
philpem@0 1156 //--INPUT_PORTS_ONLY MODE IRQ
philpem@0 1157 //--------------------------------
philpem@1 1158 if ((IRQ_MODE == 1) && (INPUT_PORTS_ONLY == 1) && (LEVEL == 1)) begin
philpem@1 1159 // level mode IRQ
philpem@1 1160
philpem@1 1161 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 1162
philpem@1 1163 genvar i;
philpem@1 1164 for (i = 0; (i < DATA_WIDTH) && (i < 8); i = i + 1)
philpem@1 1165 begin
philpem@1 1166 always @(posedge CLK_I or posedge RST_I)
philpem@1 1167 if (RST_I)
philpem@1 1168 IRQ_TEMP[i] <= #UDLY 0;
philpem@1 1169 else if (IRQ_MASK_WR_EN_0)
philpem@1 1170 IRQ_TEMP[i] <= #UDLY IRQ_TEMP[i] & GPIO_DAT_I_switch[i];
philpem@1 1171 else
philpem@1 1172 IRQ_TEMP[i] <= #UDLY PIO_IN[i] & IRQ_MASK[i];
philpem@1 1173 end
philpem@1 1174 if (DATA_WIDTH > 8) begin
philpem@1 1175 genvar j;
philpem@1 1176 for (j = 8; (j < DATA_WIDTH) && (j < 16); j = j + 1)
philpem@1 1177 begin
philpem@1 1178 always @(posedge CLK_I or posedge RST_I)
philpem@1 1179 if (RST_I)
philpem@1 1180 IRQ_TEMP[j] <= #UDLY 0;
philpem@1 1181 else if (IRQ_MASK_WR_EN_1)
philpem@1 1182 IRQ_TEMP[j] <= #UDLY IRQ_TEMP[j] & GPIO_DAT_I_switch[j-8];
philpem@1 1183 else
philpem@1 1184 IRQ_TEMP[j] <= #UDLY PIO_IN[j] & IRQ_MASK[j];
philpem@1 1185 end
philpem@1 1186 end
philpem@1 1187 if (DATA_WIDTH > 16) begin
philpem@1 1188 genvar k;
philpem@1 1189 for (k = 16; (k < DATA_WIDTH) && (k < 24); k = k + 1)
philpem@1 1190 begin
philpem@1 1191 always @(posedge CLK_I or posedge RST_I)
philpem@1 1192 if (RST_I)
philpem@1 1193 IRQ_TEMP[k] <= #UDLY 0;
philpem@1 1194 else if (IRQ_MASK_WR_EN_2)
philpem@1 1195 IRQ_TEMP[k] <= #UDLY IRQ_TEMP[k] & GPIO_DAT_I_switch[k-16];
philpem@1 1196 else
philpem@1 1197 IRQ_TEMP[k] <= #UDLY PIO_IN[k] & IRQ_MASK[k];
philpem@1 1198 end
philpem@1 1199 end
philpem@1 1200 if (DATA_WIDTH > 24) begin
philpem@1 1201 genvar l;
philpem@1 1202 for (l = 24; (l < DATA_WIDTH) && (l < 32); l = l + 1)
philpem@1 1203 begin
philpem@1 1204 always @(posedge CLK_I or posedge RST_I)
philpem@1 1205 if (RST_I)
philpem@1 1206 IRQ_TEMP[l] <= #UDLY 0;
philpem@1 1207 else if (IRQ_MASK_WR_EN_3)
philpem@1 1208 IRQ_TEMP[l] <= #UDLY IRQ_TEMP[l] & GPIO_DAT_I_switch[l-24];
philpem@1 1209 else
philpem@1 1210 IRQ_TEMP[l] <= #UDLY PIO_IN[l] & IRQ_MASK[l];
philpem@1 1211 end
philpem@1 1212 end
philpem@1 1213
philpem@1 1214 end // if (GPIO_WB_DAT_WIDTH == 8)
philpem@1 1215
philpem@1 1216 else if (GPIO_WB_DAT_WIDTH == 32) begin
philpem@1 1217
philpem@1 1218 genvar i;
philpem@1 1219 for (i = 0; (i < DATA_WIDTH) && (i < 8); i = i + 1)
philpem@1 1220 begin
philpem@1 1221 always @(posedge CLK_I or posedge RST_I)
philpem@1 1222 if (RST_I)
philpem@1 1223 IRQ_TEMP[i] <= #UDLY 0;
philpem@1 1224 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[0])
philpem@1 1225 IRQ_TEMP[i] <= #UDLY IRQ_TEMP[i] & GPIO_DAT_I_switch[i];
philpem@1 1226 else
philpem@1 1227 IRQ_TEMP[i] <= #UDLY PIO_IN[i] & IRQ_MASK[i];
philpem@1 1228 end
philpem@1 1229 if (DATA_WIDTH > 8) begin
philpem@1 1230 genvar j;
philpem@1 1231 for (j = 8; (j < DATA_WIDTH) && (j < 16); j = j + 1)
philpem@1 1232 begin
philpem@1 1233 always @(posedge CLK_I or posedge RST_I)
philpem@1 1234 if (RST_I)
philpem@1 1235 IRQ_TEMP[j] <= #UDLY 0;
philpem@1 1236 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[1])
philpem@1 1237 IRQ_TEMP[j] <= #UDLY IRQ_TEMP[j] & GPIO_DAT_I_switch[j];
philpem@1 1238 else
philpem@1 1239 IRQ_TEMP[j] <= #UDLY PIO_IN[j] & IRQ_MASK[j];
philpem@1 1240 end
philpem@1 1241 end
philpem@1 1242 if (DATA_WIDTH > 16) begin
philpem@1 1243 genvar k;
philpem@1 1244 for (k = 16; (k < DATA_WIDTH) && (k < 24); k = k + 1)
philpem@1 1245 begin
philpem@1 1246 always @(posedge CLK_I or posedge RST_I)
philpem@1 1247 if (RST_I)
philpem@1 1248 IRQ_TEMP[k] <= #UDLY 0;
philpem@1 1249 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[2])
philpem@1 1250 IRQ_TEMP[k] <= #UDLY IRQ_TEMP[k] & GPIO_DAT_I_switch[k];
philpem@1 1251 else
philpem@1 1252 IRQ_TEMP[k] <= #UDLY PIO_IN[k] & IRQ_MASK[k];
philpem@1 1253 end
philpem@1 1254 end
philpem@1 1255 if (DATA_WIDTH > 24) begin
philpem@1 1256 genvar l;
philpem@1 1257 for (l = 24; (l < DATA_WIDTH) && (l < 32); l = l + 1)
philpem@1 1258 begin
philpem@1 1259 always @(posedge CLK_I or posedge RST_I)
philpem@1 1260 if (RST_I)
philpem@1 1261 IRQ_TEMP[l] <= #UDLY 0;
philpem@1 1262 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[3])
philpem@1 1263 IRQ_TEMP[l] <= #UDLY IRQ_TEMP[l] & GPIO_DAT_I_switch[l];
philpem@1 1264 else
philpem@1 1265 IRQ_TEMP[l] <= #UDLY PIO_IN[l] & IRQ_MASK[l];
philpem@1 1266 end
philpem@1 1267 end
philpem@1 1268
philpem@1 1269 end // if (GPIO_WB_DAT_WIDTH == 32)
philpem@1 1270
philpem@0 1271 assign IRQ_O = |IRQ_TEMP;
philpem@1 1272
philpem@1 1273 end // if ((IRQ_MODE == 1) && (INPUT_PORTS_ONLY == 1) && (LEVEL == 1))
philpem@1 1274
philpem@1 1275 else if ((IRQ_MODE == 1) && (INPUT_PORTS_ONLY == 1) && (EDGE == 1)) begin
philpem@1 1276 // edge mode IRQ
philpem@1 1277
philpem@0 1278 always @(posedge CLK_I or posedge RST_I)
philpem@0 1279 if (RST_I)
philpem@0 1280 PIO_DATA_DLY <= #UDLY 0;
philpem@0 1281 else
philpem@0 1282 PIO_DATA_DLY <= PIO_IN;
philpem@1 1283
philpem@0 1284 // edge-capture register bits are treated as individual bits.
philpem@1 1285 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 1286
philpem@1 1287 genvar i;
philpem@1 1288 for (i = 0; (i < DATA_WIDTH) && (i < 8); i = i + 1)
philpem@1 1289 begin
philpem@1 1290 always @(posedge CLK_I or posedge RST_I)
philpem@1 1291 if (RST_I)
philpem@1 1292 EDGE_CAPTURE[i] <= #UDLY 0;
philpem@1 1293 else if (|(PIO_IN[i] & ~PIO_DATA_DLY[i]) && (POSE_EDGE_IRQ == 1))
philpem@1 1294 EDGE_CAPTURE[i] <= #UDLY PIO_IN[i] & ~PIO_DATA_DLY[i];
philpem@1 1295 else if (|(~PIO_IN[i] & PIO_DATA_DLY[i]) && (NEGE_EDGE_IRQ == 1))
philpem@1 1296 EDGE_CAPTURE[i] <= #UDLY ~PIO_IN[i] & PIO_DATA_DLY[i];
philpem@1 1297 else if (|(PIO_IN[i] & ~PIO_DATA_DLY[i]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1298 EDGE_CAPTURE[i] <= #UDLY PIO_IN[i] & ~PIO_DATA_DLY[i];
philpem@1 1299 else if (|(~PIO_IN[i] & PIO_DATA_DLY[i]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1300 EDGE_CAPTURE[i] <= #UDLY ~PIO_IN[i] & PIO_DATA_DLY[i];
philpem@1 1301 else if ( (~IRQ_MASK[i]) & GPIO_DAT_I_switch[i] & IRQ_MASK_WR_EN_0)
philpem@1 1302 // interrupt mask is being set, so clear edge-capture
philpem@1 1303 EDGE_CAPTURE[i] <= #UDLY 0;
philpem@1 1304 else if (EDGE_CAP_WR_EN_0)
philpem@1 1305 // user's writing to the edge register, so update edge capture
philpem@1 1306 // register
philpem@1 1307 EDGE_CAPTURE[i] <= #UDLY EDGE_CAPTURE[i] & GPIO_DAT_I_switch[i];
philpem@1 1308 end
philpem@1 1309
philpem@1 1310 if (DATA_WIDTH > 8) begin
philpem@1 1311 genvar j;
philpem@1 1312 for (j = 8; (j < DATA_WIDTH) && (j < 16); j = j + 1)
philpem@1 1313 begin
philpem@1 1314 always @(posedge CLK_I or posedge RST_I)
philpem@1 1315 if (RST_I)
philpem@1 1316 EDGE_CAPTURE[j] <= #UDLY 0;
philpem@1 1317 else if (|(PIO_IN[j] & ~PIO_DATA_DLY[j]) && (POSE_EDGE_IRQ == 1))
philpem@1 1318 EDGE_CAPTURE[j] <= #UDLY PIO_IN[j] & ~PIO_DATA_DLY[j];
philpem@1 1319 else if (|(~PIO_IN[j] & PIO_DATA_DLY[j]) && (NEGE_EDGE_IRQ == 1))
philpem@1 1320 EDGE_CAPTURE[j] <= #UDLY ~PIO_IN[j] & PIO_DATA_DLY[j];
philpem@1 1321 else if (|(PIO_IN[j] & ~PIO_DATA_DLY[j]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1322 EDGE_CAPTURE[j] <= #UDLY PIO_IN[j] & ~PIO_DATA_DLY[j];
philpem@1 1323 else if (|(~PIO_IN[j] & PIO_DATA_DLY[j]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1324 EDGE_CAPTURE[j] <= #UDLY ~PIO_IN[j] & PIO_DATA_DLY[j];
philpem@1 1325 else if ( (~IRQ_MASK[j]) & GPIO_DAT_I_switch[j-8] & IRQ_MASK_WR_EN_1)
philpem@1 1326 // interrupt mask is being set, so clear edge-capture
philpem@1 1327 EDGE_CAPTURE[j] <= #UDLY 0;
philpem@1 1328 else if (EDGE_CAP_WR_EN_1)
philpem@1 1329 // user's writing to the edge register, so update edge capture
philpem@1 1330 // register
philpem@1 1331 EDGE_CAPTURE[j] <= #UDLY EDGE_CAPTURE[j] & GPIO_DAT_I_switch[j-8];
philpem@1 1332 end
philpem@1 1333 end
philpem@1 1334
philpem@1 1335 if (DATA_WIDTH > 16) begin
philpem@1 1336 genvar k;
philpem@1 1337 for (k = 16; (k < DATA_WIDTH) && (k < 24); k = k + 1)
philpem@1 1338 begin
philpem@1 1339 always @(posedge CLK_I or posedge RST_I)
philpem@1 1340 if (RST_I)
philpem@1 1341 EDGE_CAPTURE[k] <= #UDLY 0;
philpem@1 1342 else if (|(PIO_IN[k] & ~PIO_DATA_DLY[k]) && (POSE_EDGE_IRQ == 1))
philpem@1 1343 EDGE_CAPTURE[k] <= #UDLY PIO_IN[k] & ~PIO_DATA_DLY[k];
philpem@1 1344 else if (|(~PIO_IN[k] & PIO_DATA_DLY[k]) && (NEGE_EDGE_IRQ == 1))
philpem@1 1345 EDGE_CAPTURE[k] <= #UDLY ~PIO_IN[k] & PIO_DATA_DLY[k];
philpem@1 1346 else if (|(PIO_IN[k] & ~PIO_DATA_DLY[k]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1347 EDGE_CAPTURE[k] <= #UDLY PIO_IN[k] & ~PIO_DATA_DLY[k];
philpem@1 1348 else if (|(~PIO_IN[k] & PIO_DATA_DLY[k]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1349 EDGE_CAPTURE[k] <= #UDLY ~PIO_IN[k] & PIO_DATA_DLY[k];
philpem@1 1350 else if ( (~IRQ_MASK[k]) & GPIO_DAT_I_switch[k-16] & IRQ_MASK_WR_EN_2)
philpem@1 1351 // interrupt mask is being set, so clear edge-capture
philpem@1 1352 EDGE_CAPTURE[k] <= #UDLY 0;
philpem@1 1353 else if (EDGE_CAP_WR_EN_2)
philpem@1 1354 // user's writing to the edge register, so update edge capture
philpem@1 1355 // register
philpem@1 1356 EDGE_CAPTURE[k] <= #UDLY EDGE_CAPTURE[k] & GPIO_DAT_I_switch[k-16];
philpem@1 1357 end
philpem@1 1358 end
philpem@1 1359
philpem@1 1360 if (DATA_WIDTH > 24) begin
philpem@1 1361 genvar l;
philpem@1 1362 for (l = 24; l < DATA_WIDTH; l = l + 1)
philpem@1 1363 begin
philpem@1 1364 always @(posedge CLK_I or posedge RST_I)
philpem@1 1365 if (RST_I)
philpem@1 1366 EDGE_CAPTURE[l] <= #UDLY 0;
philpem@1 1367 else if (|(PIO_IN[l] & ~PIO_DATA_DLY[l]) && (POSE_EDGE_IRQ == 1))
philpem@1 1368 EDGE_CAPTURE[l] <= #UDLY PIO_IN[l] & ~PIO_DATA_DLY[l];
philpem@1 1369 else if (|(~PIO_IN[l] & PIO_DATA_DLY[l]) && (NEGE_EDGE_IRQ == 1))
philpem@1 1370 EDGE_CAPTURE[l] <= #UDLY ~PIO_IN[l] & PIO_DATA_DLY[l];
philpem@1 1371 else if (|(PIO_IN[l] & ~PIO_DATA_DLY[l]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1372 EDGE_CAPTURE[l] <= #UDLY PIO_IN[l] & ~PIO_DATA_DLY[l];
philpem@1 1373 else if (|(~PIO_IN[l] & PIO_DATA_DLY[l]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1374 EDGE_CAPTURE[l] <= #UDLY ~PIO_IN[l] & PIO_DATA_DLY[l];
philpem@1 1375 else if ( (~IRQ_MASK[l]) & GPIO_DAT_I_switch[l-24] & IRQ_MASK_WR_EN_3)
philpem@1 1376 // interrupt mask is being set, so clear edge-capture
philpem@1 1377 EDGE_CAPTURE[l] <= #UDLY 0;
philpem@1 1378 else if (EDGE_CAP_WR_EN_3)
philpem@1 1379 // user's writing to the edge register, so update edge capture
philpem@1 1380 // register
philpem@1 1381 EDGE_CAPTURE[l] <= #UDLY EDGE_CAPTURE[l] & GPIO_DAT_I_switch[l-24];
philpem@1 1382 end
philpem@1 1383 end
philpem@1 1384
philpem@1 1385 end // if (GPIO_WB_DAT_WIDTH == 8)
philpem@1 1386 else if (GPIO_WB_DAT_WIDTH == 32) begin
philpem@1 1387
philpem@1 1388 genvar i;
philpem@1 1389 for (i = 0; (i < DATA_WIDTH) && (i < 8); i = i + 1)
philpem@1 1390 begin
philpem@1 1391 always @(posedge CLK_I or posedge RST_I)
philpem@1 1392 if (RST_I)
philpem@1 1393 EDGE_CAPTURE[i] <= #UDLY 0;
philpem@1 1394 else if (|(PIO_IN[i] & ~PIO_DATA_DLY[i]) && (POSE_EDGE_IRQ == 1))
philpem@1 1395 EDGE_CAPTURE[i] <= #UDLY PIO_IN[i] & ~PIO_DATA_DLY[i];
philpem@1 1396 else if (|(~PIO_IN[i] & PIO_DATA_DLY[i]) && (NEGE_EDGE_IRQ == 1))
philpem@1 1397 EDGE_CAPTURE[i] <= #UDLY ~PIO_IN[i] & PIO_DATA_DLY[i];
philpem@1 1398 else if (|(PIO_IN[i] & ~PIO_DATA_DLY[i]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1399 EDGE_CAPTURE[i] <= #UDLY PIO_IN[i] & ~PIO_DATA_DLY[i];
philpem@1 1400 else if (|(~PIO_IN[i] & PIO_DATA_DLY[i]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1401 EDGE_CAPTURE[i] <= #UDLY ~PIO_IN[i] & PIO_DATA_DLY[i];
philpem@1 1402 else if ( (~IRQ_MASK[i]) & GPIO_DAT_I_switch[i] & IRQ_MASK_WR_EN && GPIO_SEL_I_switch[0])
philpem@1 1403 // interrupt mask is being set, so clear edge-capture
philpem@1 1404 EDGE_CAPTURE[i] <= #UDLY 0;
philpem@1 1405 else if (EDGE_CAP_WR_EN && GPIO_SEL_I_switch[0])
philpem@1 1406 // user's writing to the edge register, so update edge capture
philpem@1 1407 // register
philpem@1 1408 EDGE_CAPTURE[i] <= #UDLY EDGE_CAPTURE[i] & GPIO_DAT_I_switch[i];
philpem@1 1409 end
philpem@1 1410
philpem@1 1411 if (DATA_WIDTH > 8) begin
philpem@1 1412 genvar j;
philpem@1 1413 for (j = 8; (j < DATA_WIDTH) && (j < 16); j = j + 1)
philpem@1 1414 begin
philpem@1 1415 always @(posedge CLK_I or posedge RST_I)
philpem@1 1416 if (RST_I)
philpem@1 1417 EDGE_CAPTURE[j] <= #UDLY 0;
philpem@1 1418 else if (|(PIO_IN[j] & ~PIO_DATA_DLY[j]) && (POSE_EDGE_IRQ == 1))
philpem@1 1419 EDGE_CAPTURE[j] <= #UDLY PIO_IN[j] & ~PIO_DATA_DLY[j];
philpem@1 1420 else if (|(~PIO_IN[j] & PIO_DATA_DLY[j]) && (NEGE_EDGE_IRQ == 1))
philpem@1 1421 EDGE_CAPTURE[j] <= #UDLY ~PIO_IN[j] & PIO_DATA_DLY[j];
philpem@1 1422 else if (|(PIO_IN[j] & ~PIO_DATA_DLY[j]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1423 EDGE_CAPTURE[j] <= #UDLY PIO_IN[j] & ~PIO_DATA_DLY[j];
philpem@1 1424 else if (|(~PIO_IN[j] & PIO_DATA_DLY[j]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1425 EDGE_CAPTURE[j] <= #UDLY ~PIO_IN[j] & PIO_DATA_DLY[j];
philpem@1 1426 else if ( (~IRQ_MASK[j]) & GPIO_DAT_I_switch[j-8] & IRQ_MASK_WR_EN && GPIO_SEL_I_switch[0])
philpem@1 1427 // interrupt mask is being set, so clear edge-capture
philpem@1 1428 EDGE_CAPTURE[j] <= #UDLY 0;
philpem@1 1429 else if (EDGE_CAP_WR_EN && GPIO_SEL_I_switch[0])
philpem@1 1430 // user's writing to the edge register, so update edge capture
philpem@1 1431 // register
philpem@1 1432 EDGE_CAPTURE[j] <= #UDLY EDGE_CAPTURE[j] & GPIO_DAT_I_switch[j];
philpem@1 1433 end
philpem@1 1434 end
philpem@1 1435
philpem@1 1436 if (DATA_WIDTH > 16) begin
philpem@1 1437 genvar k;
philpem@1 1438 for (k = 16; (k < DATA_WIDTH) && (k < 24); k = k + 1)
philpem@1 1439 begin
philpem@1 1440 always @(posedge CLK_I or posedge RST_I)
philpem@1 1441 if (RST_I)
philpem@1 1442 EDGE_CAPTURE[k] <= #UDLY 0;
philpem@1 1443 else if (|(PIO_IN[k] & ~PIO_DATA_DLY[k]) && (POSE_EDGE_IRQ == 1))
philpem@1 1444 EDGE_CAPTURE[k] <= #UDLY PIO_IN[k] & ~PIO_DATA_DLY[k];
philpem@1 1445 else if (|(~PIO_IN[k] & PIO_DATA_DLY[k]) && (NEGE_EDGE_IRQ == 1))
philpem@1 1446 EDGE_CAPTURE[k] <= #UDLY ~PIO_IN[k] & PIO_DATA_DLY[k];
philpem@1 1447 else if (|(PIO_IN[k] & ~PIO_DATA_DLY[k]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1448 EDGE_CAPTURE[k] <= #UDLY PIO_IN[k] & ~PIO_DATA_DLY[k];
philpem@1 1449 else if (|(~PIO_IN[k] & PIO_DATA_DLY[k]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1450 EDGE_CAPTURE[k] <= #UDLY ~PIO_IN[k] & PIO_DATA_DLY[k];
philpem@1 1451 else if ( (~IRQ_MASK[k]) & GPIO_DAT_I_switch[k-16] & IRQ_MASK_WR_EN && GPIO_SEL_I_switch[2])
philpem@1 1452 // interrupt mask is being set, so clear edge-capture
philpem@1 1453 EDGE_CAPTURE[k] <= #UDLY 0;
philpem@1 1454 else if (EDGE_CAP_WR_EN && GPIO_SEL_I_switch[2])
philpem@1 1455 // user's writing to the edge register, so update edge capture
philpem@1 1456 // register
philpem@1 1457 EDGE_CAPTURE[k] <= #UDLY EDGE_CAPTURE[k] & GPIO_DAT_I_switch[k];
philpem@1 1458 end
philpem@1 1459 end
philpem@1 1460
philpem@1 1461 if (DATA_WIDTH > 24) begin
philpem@1 1462 genvar l;
philpem@1 1463 for (l = 24; l < DATA_WIDTH; l = l + 1)
philpem@1 1464 begin
philpem@1 1465 always @(posedge CLK_I or posedge RST_I)
philpem@1 1466 if (RST_I)
philpem@1 1467 EDGE_CAPTURE[l] <= #UDLY 0;
philpem@1 1468 else if (|(PIO_IN[l] & ~PIO_DATA_DLY[l]) && (POSE_EDGE_IRQ == 1))
philpem@1 1469 EDGE_CAPTURE[l] <= #UDLY PIO_IN[l] & ~PIO_DATA_DLY[l];
philpem@1 1470 else if (|(~PIO_IN[l] & PIO_DATA_DLY[l]) && (NEGE_EDGE_IRQ == 1))
philpem@1 1471 EDGE_CAPTURE[l] <= #UDLY ~PIO_IN[l] & PIO_DATA_DLY[l];
philpem@1 1472 else if (|(PIO_IN[l] & ~PIO_DATA_DLY[l]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1473 EDGE_CAPTURE[l] <= #UDLY PIO_IN[l] & ~PIO_DATA_DLY[l];
philpem@1 1474 else if (|(~PIO_IN[l] & PIO_DATA_DLY[l]) && (EITHER_EDGE_IRQ == 1))
philpem@1 1475 EDGE_CAPTURE[l] <= #UDLY ~PIO_IN[l] & PIO_DATA_DLY[l];
philpem@1 1476 else if ( (~IRQ_MASK[l]) & GPIO_DAT_I_switch[l-24] & IRQ_MASK_WR_EN && GPIO_SEL_I_switch[3])
philpem@1 1477 // interrupt mask is being set, so clear edge-capture
philpem@1 1478 EDGE_CAPTURE[l] <= #UDLY 0;
philpem@1 1479 else if (EDGE_CAP_WR_EN && GPIO_SEL_I_switch[3])
philpem@1 1480 // user's writing to the edge register, so update edge capture
philpem@1 1481 // register
philpem@1 1482 EDGE_CAPTURE[l] <= #UDLY EDGE_CAPTURE[l] & GPIO_DAT_I_switch[l];
philpem@1 1483 end
philpem@1 1484 end
philpem@1 1485
philpem@1 1486 end // if (GPIO_WB_DAT_WIDTH == 32)
philpem@1 1487
philpem@1 1488 assign IRQ_O = |(EDGE_CAPTURE[DATA_WIDTH-1:0] & IRQ_MASK[DATA_WIDTH-1:0]);
philpem@1 1489
philpem@1 1490 end // if ((IRQ_MODE == 1) && (INPUT_PORTS_ONLY == 1) && (EDGE == 1))
philpem@1 1491
philpem@1 1492 //----------------------------------
philpem@1 1493 //--BOTH_INPUT_AND_OUTPUT MODE IRQ
philpem@1 1494 //----------------------------------
philpem@1 1495 else if ((IRQ_MODE == 1) && (BOTH_INPUT_AND_OUTPUT == 1) && (LEVEL == 1)) begin
philpem@0 1496
philpem@1 1497 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 1498
philpem@1 1499 genvar iitb_idx;
philpem@1 1500 for (iitb_idx = 0; (iitb_idx < INPUT_WIDTH) && (iitb_idx < 8); iitb_idx = iitb_idx + 1)
philpem@1 1501 begin
philpem@1 1502 always @(posedge CLK_I or posedge RST_I)
philpem@1 1503 if (RST_I)
philpem@1 1504 IRQ_TEMP_BOTH[iitb_idx] <= #UDLY 0;
philpem@1 1505 else if (IRQ_MASK_WR_EN_0)
philpem@1 1506 IRQ_TEMP_BOTH[iitb_idx] <= #UDLY IRQ_TEMP_BOTH[iitb_idx] & GPIO_DAT_I_switch[iitb_idx];
philpem@1 1507 else
philpem@1 1508 IRQ_TEMP_BOTH[iitb_idx] <= #UDLY PIO_BOTH_IN[iitb_idx] & IRQ_MASK_BOTH[iitb_idx];
philpem@1 1509 end
philpem@1 1510 if (INPUT_WIDTH > 8) begin
philpem@1 1511 genvar jitb_idx;
philpem@1 1512 for (jitb_idx = 8; (jitb_idx < INPUT_WIDTH) && (jitb_idx < 16); jitb_idx = jitb_idx + 1)
philpem@1 1513 begin
philpem@1 1514 always @(posedge CLK_I or posedge RST_I)
philpem@1 1515 if (RST_I)
philpem@1 1516 IRQ_TEMP_BOTH[jitb_idx] <= #UDLY 0;
philpem@1 1517 else if (IRQ_MASK_WR_EN_1)
philpem@1 1518 IRQ_TEMP_BOTH[jitb_idx] <= #UDLY IRQ_TEMP_BOTH[jitb_idx] & GPIO_DAT_I_switch[jitb_idx - 8];
philpem@1 1519 else
philpem@1 1520 IRQ_TEMP_BOTH[jitb_idx] <= #UDLY PIO_BOTH_IN[jitb_idx] & IRQ_MASK_BOTH[jitb_idx];
philpem@1 1521 end
philpem@1 1522 end
philpem@1 1523 if (INPUT_WIDTH > 16) begin
philpem@1 1524 genvar kitb_idx;
philpem@1 1525 for (kitb_idx = 16; (kitb_idx < INPUT_WIDTH) && (kitb_idx < 24); kitb_idx = kitb_idx + 1)
philpem@1 1526 begin
philpem@1 1527 always @(posedge CLK_I or posedge RST_I)
philpem@1 1528 if (RST_I)
philpem@1 1529 IRQ_TEMP_BOTH[kitb_idx] <= #UDLY 0;
philpem@1 1530 else if (IRQ_MASK_WR_EN_2)
philpem@1 1531 IRQ_TEMP_BOTH[kitb_idx] <= #UDLY IRQ_TEMP_BOTH[kitb_idx] & GPIO_DAT_I_switch[kitb_idx - 16];
philpem@1 1532 else
philpem@1 1533 IRQ_TEMP_BOTH[kitb_idx] <= #UDLY PIO_BOTH_IN[kitb_idx] & IRQ_MASK_BOTH[kitb_idx];
philpem@1 1534 end
philpem@1 1535 end
philpem@1 1536 if (INPUT_WIDTH > 24) begin
philpem@1 1537 genvar litb_idx;
philpem@1 1538 for (litb_idx = 24; (litb_idx < INPUT_WIDTH) && (litb_idx < 24); litb_idx = litb_idx + 1)
philpem@1 1539 begin
philpem@1 1540 always @(posedge CLK_I or posedge RST_I)
philpem@1 1541 if (RST_I)
philpem@1 1542 IRQ_TEMP_BOTH[litb_idx] <= #UDLY 0;
philpem@1 1543 else if (IRQ_MASK_WR_EN_3)
philpem@1 1544 IRQ_TEMP_BOTH[litb_idx] <= #UDLY IRQ_TEMP_BOTH[litb_idx] & GPIO_DAT_I_switch[litb_idx - 24];
philpem@1 1545 else
philpem@1 1546 IRQ_TEMP_BOTH[litb_idx] <= #UDLY PIO_BOTH_IN[litb_idx] & IRQ_MASK_BOTH[litb_idx];
philpem@1 1547 end
philpem@1 1548 end
philpem@1 1549
philpem@1 1550 end // if (GPIO_WB_DAT_WIDTH == 8)
philpem@1 1551
philpem@1 1552 else if (GPIO_WB_DAT_WIDTH == 32) begin
philpem@1 1553
philpem@1 1554 genvar iitb_idx;
philpem@1 1555 for (iitb_idx = 0; (iitb_idx < INPUT_WIDTH) && (iitb_idx < 8); iitb_idx = iitb_idx + 1)
philpem@1 1556 begin
philpem@1 1557 always @(posedge CLK_I or posedge RST_I)
philpem@1 1558 if (RST_I)
philpem@1 1559 IRQ_TEMP_BOTH[iitb_idx] <= #UDLY 0;
philpem@1 1560 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[0])
philpem@1 1561 IRQ_TEMP_BOTH[iitb_idx] <= #UDLY IRQ_TEMP_BOTH[iitb_idx] & GPIO_DAT_I_switch[iitb_idx];
philpem@1 1562 else
philpem@1 1563 IRQ_TEMP_BOTH[iitb_idx] <= #UDLY PIO_BOTH_IN[iitb_idx] & IRQ_MASK_BOTH[iitb_idx];
philpem@1 1564 end
philpem@1 1565 if (INPUT_WIDTH > 8) begin
philpem@1 1566 genvar jitb_idx;
philpem@1 1567 for (jitb_idx = 8; (jitb_idx < INPUT_WIDTH) && (jitb_idx < 16); jitb_idx = jitb_idx + 1)
philpem@1 1568 begin
philpem@1 1569 always @(posedge CLK_I or posedge RST_I)
philpem@1 1570 if (RST_I)
philpem@1 1571 IRQ_TEMP_BOTH[jitb_idx] <= #UDLY 0;
philpem@1 1572 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[1])
philpem@1 1573 IRQ_TEMP_BOTH[jitb_idx] <= #UDLY IRQ_TEMP_BOTH[jitb_idx] & GPIO_DAT_I_switch[jitb_idx];
philpem@1 1574 else
philpem@1 1575 IRQ_TEMP_BOTH[jitb_idx] <= #UDLY PIO_BOTH_IN[jitb_idx] & IRQ_MASK_BOTH[jitb_idx];
philpem@1 1576 end
philpem@1 1577 end
philpem@1 1578 if (INPUT_WIDTH > 16) begin
philpem@1 1579 genvar kitb_idx;
philpem@1 1580 for (kitb_idx = 16; (kitb_idx < INPUT_WIDTH) && (kitb_idx < 24); kitb_idx = kitb_idx + 1)
philpem@1 1581 begin
philpem@1 1582 always @(posedge CLK_I or posedge RST_I)
philpem@1 1583 if (RST_I)
philpem@1 1584 IRQ_TEMP_BOTH[kitb_idx] <= #UDLY 0;
philpem@1 1585 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[2])
philpem@1 1586 IRQ_TEMP_BOTH[kitb_idx] <= #UDLY IRQ_TEMP_BOTH[kitb_idx] & GPIO_DAT_I_switch[kitb_idx];
philpem@1 1587 else
philpem@1 1588 IRQ_TEMP_BOTH[kitb_idx] <= #UDLY PIO_BOTH_IN[kitb_idx] & IRQ_MASK_BOTH[kitb_idx];
philpem@1 1589 end
philpem@1 1590 end
philpem@1 1591 if (INPUT_WIDTH > 24) begin
philpem@1 1592 genvar litb_idx;
philpem@1 1593 for (litb_idx = 24; (litb_idx < INPUT_WIDTH) && (litb_idx < 24); litb_idx = litb_idx + 1)
philpem@1 1594 begin
philpem@1 1595 always @(posedge CLK_I or posedge RST_I)
philpem@1 1596 if (RST_I)
philpem@1 1597 IRQ_TEMP_BOTH[litb_idx] <= #UDLY 0;
philpem@1 1598 else if (IRQ_MASK_WR_EN && GPIO_SEL_I_switch[3])
philpem@1 1599 IRQ_TEMP_BOTH[litb_idx] <= #UDLY IRQ_TEMP_BOTH[litb_idx] & GPIO_DAT_I_switch[litb_idx];
philpem@1 1600 else
philpem@1 1601 IRQ_TEMP_BOTH[litb_idx] <= #UDLY PIO_BOTH_IN[litb_idx] & IRQ_MASK_BOTH[litb_idx];
philpem@1 1602 end
philpem@1 1603 end
philpem@1 1604
philpem@1 1605 end // if (GPIO_WB_DAT_WIDTH == 32)
philpem@1 1606
philpem@1 1607 assign IRQ_O = |IRQ_TEMP_BOTH;
philpem@1 1608
philpem@1 1609 end // if ((IRQ_MODE == 1) && (BOTH_INPUT_AND_OUTPUT == 1) && (LEVEL == 1))
philpem@1 1610
philpem@1 1611 // edge mode IRQ
philpem@1 1612 else if ((IRQ_MODE == 1) && (BOTH_INPUT_AND_OUTPUT == 1) && (EDGE == 1)) begin
philpem@1 1613
philpem@0 1614 always @(posedge CLK_I or posedge RST_I)
philpem@0 1615 if (RST_I)
philpem@0 1616 PIO_DATA_DLY_BOTH <= #UDLY 0;
philpem@0 1617 else
philpem@0 1618 PIO_DATA_DLY_BOTH <= PIO_BOTH_IN;
philpem@1 1619
philpem@0 1620 // edge-capture register bits are treated as individual bits.
philpem@1 1621 if (GPIO_WB_DAT_WIDTH == 8) begin
philpem@1 1622
philpem@1 1623 genvar i_both;
philpem@1 1624 for (i_both = 0; (i_both < INPUT_WIDTH) && (i_both < 8); i_both = i_both + 1)
philpem@1 1625 begin
philpem@1 1626 always @(posedge CLK_I or posedge RST_I)
philpem@1 1627 if (RST_I)
philpem@1 1628 EDGE_CAPTURE_BOTH[i_both] <= #UDLY 0;
philpem@1 1629 else if (|(PIO_BOTH_IN[i_both] & ~PIO_DATA_DLY_BOTH[i_both]) && POSE_EDGE_IRQ == 1)
philpem@1 1630 EDGE_CAPTURE_BOTH[i_both] <= #UDLY PIO_BOTH_IN[i_both] & ~PIO_DATA_DLY_BOTH[i_both];
philpem@1 1631 else if (|(~PIO_BOTH_IN[i_both] & PIO_DATA_DLY_BOTH[i_both]) && NEGE_EDGE_IRQ == 1)
philpem@1 1632 EDGE_CAPTURE_BOTH[i_both] <= #UDLY ~PIO_BOTH_IN[i_both] & PIO_DATA_DLY_BOTH[i_both];
philpem@1 1633 else if (|(PIO_BOTH_IN[i_both] & ~PIO_DATA_DLY_BOTH[i_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1634 EDGE_CAPTURE_BOTH[i_both] <= #UDLY PIO_BOTH_IN[i_both] & ~PIO_DATA_DLY_BOTH[i_both];
philpem@1 1635 else if (|(~PIO_BOTH_IN[i_both] & PIO_DATA_DLY_BOTH[i_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1636 EDGE_CAPTURE_BOTH[i_both] <= #UDLY ~PIO_BOTH_IN[i_both] & PIO_DATA_DLY_BOTH[i_both];
philpem@1 1637 else if ( (~IRQ_MASK_BOTH[i_both]) & GPIO_DAT_I_switch[i_both] & IRQ_MASK_WR_EN_0 )
philpem@1 1638 // interrupt mask is being set, so clear edge-capture
philpem@1 1639 EDGE_CAPTURE_BOTH[i_both] <= #UDLY 0;
philpem@1 1640 else if (EDGE_CAP_WR_EN_0)
philpem@1 1641 // user's writing to the edge register, so update edge capture
philpem@1 1642 // register
philpem@1 1643 EDGE_CAPTURE_BOTH[i_both] <= #UDLY EDGE_CAPTURE_BOTH[i_both] & GPIO_DAT_I_switch[i_both];
philpem@1 1644 end
philpem@1 1645 if (INPUT_WIDTH > 8) begin
philpem@1 1646 genvar j_both;
philpem@1 1647 for (j_both = 8; (j_both < INPUT_WIDTH) && (j_both < 16); j_both = j_both + 1)
philpem@1 1648 begin
philpem@1 1649 always @(posedge CLK_I or posedge RST_I)
philpem@1 1650 if (RST_I)
philpem@1 1651 EDGE_CAPTURE_BOTH[j_both] <= #UDLY 0;
philpem@1 1652 else if (|(PIO_BOTH_IN[j_both] & ~PIO_DATA_DLY_BOTH[j_both]) && POSE_EDGE_IRQ == 1)
philpem@1 1653 EDGE_CAPTURE_BOTH[j_both] <= #UDLY PIO_BOTH_IN[j_both] & ~PIO_DATA_DLY_BOTH[j_both];
philpem@1 1654 else if (|(~PIO_BOTH_IN[j_both] & PIO_DATA_DLY_BOTH[j_both]) && NEGE_EDGE_IRQ == 1)
philpem@1 1655 EDGE_CAPTURE_BOTH[j_both] <= #UDLY ~PIO_BOTH_IN[j_both] & PIO_DATA_DLY_BOTH[j_both];
philpem@1 1656 else if (|(PIO_BOTH_IN[j_both] & ~PIO_DATA_DLY_BOTH[j_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1657 EDGE_CAPTURE_BOTH[j_both] <= #UDLY PIO_BOTH_IN[j_both] & ~PIO_DATA_DLY_BOTH[j_both];
philpem@1 1658 else if (|(~PIO_BOTH_IN[j_both] & PIO_DATA_DLY_BOTH[j_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1659 EDGE_CAPTURE_BOTH[j_both] <= #UDLY ~PIO_BOTH_IN[j_both] & PIO_DATA_DLY_BOTH[j_both];
philpem@1 1660 else if ( (~IRQ_MASK_BOTH[j_both]) & GPIO_DAT_I_switch[j_both-8] & IRQ_MASK_WR_EN_1 )
philpem@1 1661 // interrupt mask is being set, so clear edge-capture
philpem@1 1662 EDGE_CAPTURE_BOTH[j_both] <= #UDLY 0;
philpem@1 1663 else if (EDGE_CAP_WR_EN_1)
philpem@1 1664 // user's writing to the edge register, so update edge capture
philpem@1 1665 // register
philpem@1 1666 EDGE_CAPTURE_BOTH[j_both] <= #UDLY EDGE_CAPTURE_BOTH[j_both] & GPIO_DAT_I_switch[j_both-8];
philpem@1 1667 end
philpem@1 1668 end
philpem@1 1669 if (INPUT_WIDTH > 16) begin
philpem@1 1670 genvar k_both;
philpem@1 1671 for (k_both = 16; (k_both < INPUT_WIDTH) && (k_both < 24); k_both = k_both + 1)
philpem@1 1672 begin
philpem@1 1673 always @(posedge CLK_I or posedge RST_I)
philpem@1 1674 if (RST_I)
philpem@1 1675 EDGE_CAPTURE_BOTH[k_both] <= #UDLY 0;
philpem@1 1676 else if (|(PIO_BOTH_IN[k_both] & ~PIO_DATA_DLY_BOTH[k_both]) && POSE_EDGE_IRQ == 1)
philpem@1 1677 EDGE_CAPTURE_BOTH[k_both] <= #UDLY PIO_BOTH_IN[k_both] & ~PIO_DATA_DLY_BOTH[k_both];
philpem@1 1678 else if (|(~PIO_BOTH_IN[k_both] & PIO_DATA_DLY_BOTH[k_both]) && NEGE_EDGE_IRQ == 1)
philpem@1 1679 EDGE_CAPTURE_BOTH[k_both] <= #UDLY ~PIO_BOTH_IN[k_both] & PIO_DATA_DLY_BOTH[k_both];
philpem@1 1680 else if (|(PIO_BOTH_IN[k_both] & ~PIO_DATA_DLY_BOTH[k_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1681 EDGE_CAPTURE_BOTH[k_both] <= #UDLY PIO_BOTH_IN[k_both] & ~PIO_DATA_DLY_BOTH[k_both];
philpem@1 1682 else if (|(~PIO_BOTH_IN[k_both] & PIO_DATA_DLY_BOTH[k_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1683 EDGE_CAPTURE_BOTH[k_both] <= #UDLY ~PIO_BOTH_IN[k_both] & PIO_DATA_DLY_BOTH[k_both];
philpem@1 1684 else if ( (~IRQ_MASK_BOTH[k_both]) & GPIO_DAT_I_switch[k_both-16] & IRQ_MASK_WR_EN_2 )
philpem@1 1685 // interrupt mask is being set, so clear edge-capture
philpem@1 1686 EDGE_CAPTURE_BOTH[k_both] <= #UDLY 0;
philpem@1 1687 else if (EDGE_CAP_WR_EN_2)
philpem@1 1688 // user's writing to the edge register, so update edge capture
philpem@1 1689 // register
philpem@1 1690 EDGE_CAPTURE_BOTH[k_both] <= #UDLY EDGE_CAPTURE_BOTH[k_both] & GPIO_DAT_I_switch[k_both-16];
philpem@1 1691 end
philpem@1 1692 end
philpem@1 1693 if (INPUT_WIDTH > 24) begin
philpem@1 1694 genvar l_both;
philpem@1 1695 for (l_both = 24; (l_both < INPUT_WIDTH) && (l_both < 32); l_both = l_both + 1)
philpem@1 1696 begin
philpem@1 1697 always @(posedge CLK_I or posedge RST_I)
philpem@1 1698 if (RST_I)
philpem@1 1699 EDGE_CAPTURE_BOTH[l_both] <= #UDLY 0;
philpem@1 1700 else if (|(PIO_BOTH_IN[l_both] & ~PIO_DATA_DLY_BOTH[l_both]) && POSE_EDGE_IRQ == 1)
philpem@1 1701 EDGE_CAPTURE_BOTH[l_both] <= #UDLY PIO_BOTH_IN[l_both] & ~PIO_DATA_DLY_BOTH[l_both];
philpem@1 1702 else if (|(~PIO_BOTH_IN[l_both] & PIO_DATA_DLY_BOTH[l_both]) && NEGE_EDGE_IRQ == 1)
philpem@1 1703 EDGE_CAPTURE_BOTH[l_both] <= #UDLY ~PIO_BOTH_IN[l_both] & PIO_DATA_DLY_BOTH[l_both];
philpem@1 1704 else if (|(PIO_BOTH_IN[l_both] & ~PIO_DATA_DLY_BOTH[l_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1705 EDGE_CAPTURE_BOTH[l_both] <= #UDLY PIO_BOTH_IN[l_both] & ~PIO_DATA_DLY_BOTH[l_both];
philpem@1 1706 else if (|(~PIO_BOTH_IN[l_both] & PIO_DATA_DLY_BOTH[l_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1707 EDGE_CAPTURE_BOTH[l_both] <= #UDLY ~PIO_BOTH_IN[l_both] & PIO_DATA_DLY_BOTH[l_both];
philpem@1 1708 else if ( (~IRQ_MASK_BOTH[l_both]) & GPIO_DAT_I_switch[l_both-24] & IRQ_MASK_WR_EN_3 )
philpem@1 1709 // interrupt mask is being set, so clear edge-capture
philpem@1 1710 EDGE_CAPTURE_BOTH[l_both] <= #UDLY 0;
philpem@1 1711 else if (EDGE_CAP_WR_EN_3)
philpem@1 1712 // user's writing to the edge register, so update edge capture
philpem@1 1713 // register
philpem@1 1714 EDGE_CAPTURE_BOTH[l_both] <= #UDLY EDGE_CAPTURE_BOTH[l_both] & GPIO_DAT_I_switch[l_both-24];
philpem@1 1715 end
philpem@1 1716 end
philpem@1 1717
philpem@1 1718 end // if (GPIO_WB_DAT_WIDTH == 8)
philpem@1 1719 else if (GPIO_WB_DAT_WIDTH == 32) begin
philpem@1 1720
philpem@1 1721 genvar i_both;
philpem@1 1722 for (i_both = 0; (i_both < INPUT_WIDTH) && (i_both < 8); i_both = i_both + 1)
philpem@1 1723 begin
philpem@1 1724 always @(posedge CLK_I or posedge RST_I)
philpem@1 1725 if (RST_I)
philpem@1 1726 EDGE_CAPTURE_BOTH[i_both] <= #UDLY 0;
philpem@1 1727 else if (|(PIO_BOTH_IN[i_both] & ~PIO_DATA_DLY_BOTH[i_both]) && POSE_EDGE_IRQ == 1)
philpem@1 1728 EDGE_CAPTURE_BOTH[i_both] <= #UDLY PIO_BOTH_IN[i_both] & ~PIO_DATA_DLY_BOTH[i_both];
philpem@1 1729 else if (|(~PIO_BOTH_IN[i_both] & PIO_DATA_DLY_BOTH[i_both]) && NEGE_EDGE_IRQ == 1)
philpem@1 1730 EDGE_CAPTURE_BOTH[i_both] <= #UDLY ~PIO_BOTH_IN[i_both] & PIO_DATA_DLY_BOTH[i_both];
philpem@1 1731 else if (|(PIO_BOTH_IN[i_both] & ~PIO_DATA_DLY_BOTH[i_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1732 EDGE_CAPTURE_BOTH[i_both] <= #UDLY PIO_BOTH_IN[i_both] & ~PIO_DATA_DLY_BOTH[i_both];
philpem@1 1733 else if (|(~PIO_BOTH_IN[i_both] & PIO_DATA_DLY_BOTH[i_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1734 EDGE_CAPTURE_BOTH[i_both] <= #UDLY ~PIO_BOTH_IN[i_both] & PIO_DATA_DLY_BOTH[i_both];
philpem@1 1735 else if ( (~IRQ_MASK_BOTH[i_both]) & GPIO_DAT_I_switch[i_both] & IRQ_MASK_WR_EN && GPIO_SEL_I_switch[0])
philpem@1 1736 // interrupt mask is being set, so clear edge-capture
philpem@1 1737 EDGE_CAPTURE_BOTH[i_both] <= #UDLY 0;
philpem@1 1738 else if (EDGE_CAP_WR_EN && GPIO_SEL_I_switch[0])
philpem@1 1739 // user's writing to the edge register, so update edge capture
philpem@1 1740 // register
philpem@1 1741 EDGE_CAPTURE_BOTH[i_both] <= #UDLY EDGE_CAPTURE_BOTH[i_both] & GPIO_DAT_I_switch[i_both];
philpem@1 1742 end
philpem@1 1743 if (INPUT_WIDTH > 8) begin
philpem@1 1744 genvar j_both;
philpem@1 1745 for (j_both = 8; (j_both < INPUT_WIDTH) && (j_both < 16); j_both = j_both + 1)
philpem@1 1746 begin
philpem@1 1747 always @(posedge CLK_I or posedge RST_I)
philpem@1 1748 if (RST_I)
philpem@1 1749 EDGE_CAPTURE_BOTH[j_both] <= #UDLY 0;
philpem@1 1750 else if (|(PIO_BOTH_IN[j_both] & ~PIO_DATA_DLY_BOTH[j_both]) && POSE_EDGE_IRQ == 1)
philpem@1 1751 EDGE_CAPTURE_BOTH[j_both] <= #UDLY PIO_BOTH_IN[j_both] & ~PIO_DATA_DLY_BOTH[j_both];
philpem@1 1752 else if (|(~PIO_BOTH_IN[j_both] & PIO_DATA_DLY_BOTH[j_both]) && NEGE_EDGE_IRQ == 1)
philpem@1 1753 EDGE_CAPTURE_BOTH[j_both] <= #UDLY ~PIO_BOTH_IN[j_both] & PIO_DATA_DLY_BOTH[j_both];
philpem@1 1754 else if (|(PIO_BOTH_IN[j_both] & ~PIO_DATA_DLY_BOTH[j_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1755 EDGE_CAPTURE_BOTH[j_both] <= #UDLY PIO_BOTH_IN[j_both] & ~PIO_DATA_DLY_BOTH[j_both];
philpem@1 1756 else if (|(~PIO_BOTH_IN[j_both] & PIO_DATA_DLY_BOTH[j_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1757 EDGE_CAPTURE_BOTH[j_both] <= #UDLY ~PIO_BOTH_IN[j_both] & PIO_DATA_DLY_BOTH[j_both];
philpem@1 1758 else if ( (~IRQ_MASK_BOTH[j_both]) & GPIO_DAT_I_switch[j_both-8] & IRQ_MASK_WR_EN && GPIO_SEL_I_switch[1])
philpem@1 1759 // interrupt mask is being set, so clear edge-capture
philpem@1 1760 EDGE_CAPTURE_BOTH[j_both] <= #UDLY 0;
philpem@1 1761 else if (EDGE_CAP_WR_EN && GPIO_SEL_I_switch[1])
philpem@1 1762 // user's writing to the edge register, so update edge capture
philpem@1 1763 // register
philpem@1 1764 EDGE_CAPTURE_BOTH[j_both] <= #UDLY EDGE_CAPTURE_BOTH[j_both] & GPIO_DAT_I_switch[j_both];
philpem@1 1765 end
philpem@1 1766 end
philpem@1 1767 if (INPUT_WIDTH > 16) begin
philpem@1 1768 genvar k_both;
philpem@1 1769 for (k_both = 16; (k_both < INPUT_WIDTH) && (k_both < 24); k_both = k_both + 1)
philpem@1 1770 begin
philpem@1 1771 always @(posedge CLK_I or posedge RST_I)
philpem@1 1772 if (RST_I)
philpem@1 1773 EDGE_CAPTURE_BOTH[k_both] <= #UDLY 0;
philpem@1 1774 else if (|(PIO_BOTH_IN[k_both] & ~PIO_DATA_DLY_BOTH[k_both]) && POSE_EDGE_IRQ == 1)
philpem@1 1775 EDGE_CAPTURE_BOTH[k_both] <= #UDLY PIO_BOTH_IN[k_both] & ~PIO_DATA_DLY_BOTH[k_both];
philpem@1 1776 else if (|(~PIO_BOTH_IN[k_both] & PIO_DATA_DLY_BOTH[k_both]) && NEGE_EDGE_IRQ == 1)
philpem@1 1777 EDGE_CAPTURE_BOTH[k_both] <= #UDLY ~PIO_BOTH_IN[k_both] & PIO_DATA_DLY_BOTH[k_both];
philpem@1 1778 else if (|(PIO_BOTH_IN[k_both] & ~PIO_DATA_DLY_BOTH[k_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1779 EDGE_CAPTURE_BOTH[k_both] <= #UDLY PIO_BOTH_IN[k_both] & ~PIO_DATA_DLY_BOTH[k_both];
philpem@1 1780 else if (|(~PIO_BOTH_IN[k_both] & PIO_DATA_DLY_BOTH[k_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1781 EDGE_CAPTURE_BOTH[k_both] <= #UDLY ~PIO_BOTH_IN[k_both] & PIO_DATA_DLY_BOTH[k_both];
philpem@1 1782 else if ( (~IRQ_MASK_BOTH[k_both]) & GPIO_DAT_I_switch[k_both-16] & IRQ_MASK_WR_EN && GPIO_SEL_I_switch[2])
philpem@1 1783 // interrupt mask is being set, so clear edge-capture
philpem@1 1784 EDGE_CAPTURE_BOTH[k_both] <= #UDLY 0;
philpem@1 1785 else if (EDGE_CAP_WR_EN && GPIO_SEL_I_switch[2])
philpem@1 1786 // user's writing to the edge register, so update edge capture
philpem@1 1787 // register
philpem@1 1788 EDGE_CAPTURE_BOTH[k_both] <= #UDLY EDGE_CAPTURE_BOTH[k_both] & GPIO_DAT_I_switch[k_both];
philpem@1 1789 end
philpem@1 1790 end
philpem@1 1791 if (INPUT_WIDTH > 24) begin
philpem@1 1792 genvar l_both;
philpem@1 1793 for (l_both = 24; (l_both < INPUT_WIDTH) && (l_both < 32); l_both = l_both + 1)
philpem@1 1794 begin
philpem@1 1795 always @(posedge CLK_I or posedge RST_I)
philpem@1 1796 if (RST_I)
philpem@1 1797 EDGE_CAPTURE_BOTH[l_both] <= #UDLY 0;
philpem@1 1798 else if (|(PIO_BOTH_IN[l_both] & ~PIO_DATA_DLY_BOTH[l_both]) && POSE_EDGE_IRQ == 1)
philpem@1 1799 EDGE_CAPTURE_BOTH[l_both] <= #UDLY PIO_BOTH_IN[l_both] & ~PIO_DATA_DLY_BOTH[l_both];
philpem@1 1800 else if (|(~PIO_BOTH_IN[l_both] & PIO_DATA_DLY_BOTH[l_both]) && NEGE_EDGE_IRQ == 1)
philpem@1 1801 EDGE_CAPTURE_BOTH[l_both] <= #UDLY ~PIO_BOTH_IN[l_both] & PIO_DATA_DLY_BOTH[l_both];
philpem@1 1802 else if (|(PIO_BOTH_IN[l_both] & ~PIO_DATA_DLY_BOTH[l_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1803 EDGE_CAPTURE_BOTH[l_both] <= #UDLY PIO_BOTH_IN[l_both] & ~PIO_DATA_DLY_BOTH[l_both];
philpem@1 1804 else if (|(~PIO_BOTH_IN[l_both] & PIO_DATA_DLY_BOTH[l_both]) && EITHER_EDGE_IRQ == 1)
philpem@1 1805 EDGE_CAPTURE_BOTH[l_both] <= #UDLY ~PIO_BOTH_IN[l_both] & PIO_DATA_DLY_BOTH[l_both];
philpem@1 1806 else if ( (~IRQ_MASK_BOTH[l_both]) & GPIO_DAT_I_switch[l_both-24] & IRQ_MASK_WR_EN && GPIO_SEL_I_switch[3])
philpem@1 1807 // interrupt mask is being set, so clear edge-capture
philpem@1 1808 EDGE_CAPTURE_BOTH[l_both] <= #UDLY 0;
philpem@1 1809 else if (EDGE_CAP_WR_EN && GPIO_SEL_I_switch[3])
philpem@1 1810 // user's writing to the edge register, so update edge capture
philpem@1 1811 // register
philpem@1 1812 EDGE_CAPTURE_BOTH[l_both] <= #UDLY EDGE_CAPTURE_BOTH[l_both] & GPIO_DAT_I_switch[l_both];
philpem@1 1813 end
philpem@1 1814 end
philpem@1 1815
philpem@1 1816 end // if (GPIO_WB_DAT_WIDTH == 32)
philpem@1 1817
philpem@0 1818 assign IRQ_O = |(EDGE_CAPTURE_BOTH & IRQ_MASK_BOTH);
philpem@0 1819
philpem@1 1820 end // if ((IRQ_MODE == 1) && (BOTH_INPUT_AND_OUTPUT == 1) && (EDGE == 1))
philpem@1 1821
philpem@1 1822 else if (IRQ_MODE == 1 && TRISTATE_PORTS == 1) begin
philpem@1 1823
philpem@0 1824 assign IRQ_O = |IRQ_TRI_TEMP;
philpem@1 1825 end
philpem@1 1826
philpem@1 1827 else begin
philpem@1 1828
philpem@0 1829 assign IRQ_O = 1'b0;
philpem@1 1830 end
philpem@1 1831
philpem@1 1832 endgenerate
philpem@1 1833
philpem@0 1834
philpem@0 1835 endmodule
philpem@0 1836 `endif // GPIO_V