1.1 diff -r 000000000000 -r 267b5a25932f rtl/verilog/tpio.v 1.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 +++ b/rtl/verilog/tpio.v Fri Aug 13 10:41:29 2010 +0100 1.4 @@ -0,0 +1,168 @@ 1.5 +// ============================================================================= 1.6 +// COPYRIGHT NOTICE 1.7 +// Copyright 2006 (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 +// FILE DETAILS 1.22 +// Project : GPIO for LM32 1.23 +// File : tpio.v 1.24 +// Title : Tri State IO control 1.25 +// Dependencies : system_conf.v 1.26 +// Description : Implements the logic to interface tri-state IO with 1.27 +// Wishbone bus. 1.28 +// ============================================================================= 1.29 +// REVISION HISTORY 1.30 +// Version : 7.0 1.31 +// Mod. Date : Jun 27, 2005 1.32 +// Changes Made : Initial Creation 1.33 +// 1.34 +// Version : 7.0SP2, 3.0 1.35 +// Mod. Date : 20 Nov. 2007 1.36 +// Changes Made : Code clean up and add the BB for the inout port. 1.37 +// 1.38 +// Version : 3.1 1.39 +// Mod. Date : 11 Oct. 2008 1.40 +// Changes Made : Update the Edge Capture Register clean method 1.41 +// Make IRQ Mask register readable 1.42 +// ============================================================================= 1.43 +`ifndef TPIO_V 1.44 +`define TPIO_V 1.45 +`timescale 1ns/100 ps 1.46 +`include "system_conf.v" 1.47 +module TRI_PIO #(parameter DATA_WIDTH = 16, 1.48 + parameter IRQ_MODE = 1, 1.49 + parameter LEVEL = 0, 1.50 + parameter EDGE = 1, 1.51 + parameter POSE_EDGE_IRQ = 1, 1.52 + parameter NEGE_EDGE_IRQ = 0, 1.53 + parameter EITHER_EDGE_IRQ = 0) 1.54 + (RST_I, 1.55 + CLK_I, 1.56 + DAT_I, 1.57 + DAT_O, 1.58 + PIO_IO, 1.59 + IRQ_O, 1.60 + PIO_TRI_WR_EN, 1.61 + PIO_TRI_RE_EN, 1.62 + PIO_DATA_RE_EN, 1.63 + PIO_DATA_WR_EN, 1.64 + IRQ_MASK_RE_EN, 1.65 + IRQ_MASK_WR_EN, 1.66 + EDGE_CAP_WR_EN); 1.67 + 1.68 + parameter UDLY = 1;//user delay 1.69 + 1.70 + input RST_I; 1.71 + input CLK_I; 1.72 + input DAT_I; 1.73 + input PIO_TRI_RE_EN; 1.74 + input PIO_TRI_WR_EN; 1.75 + input PIO_DATA_RE_EN; 1.76 + input PIO_DATA_WR_EN; 1.77 + output DAT_O; 1.78 + input IRQ_MASK_RE_EN; 1.79 + input IRQ_MASK_WR_EN; 1.80 + input EDGE_CAP_WR_EN; 1.81 + output IRQ_O; 1.82 + inout PIO_IO; 1.83 + 1.84 + wire PIO_IO_I; 1.85 + wire DAT_O; 1.86 + wire IRQ_O; 1.87 + reg PIO_DATA_O; 1.88 + reg PIO_DATA_I; 1.89 + reg PIO_TRI; 1.90 + reg IRQ_MASK; 1.91 + reg IRQ_TEMP; 1.92 + reg EDGE_CAPTURE; 1.93 + reg PIO_DATA_DLY; 1.94 + 1.95 + always @(posedge CLK_I or posedge RST_I) 1.96 + if (RST_I) 1.97 + PIO_TRI <= #UDLY 0; 1.98 + else if (PIO_TRI_WR_EN) 1.99 + PIO_TRI <= #UDLY DAT_I; 1.100 + 1.101 + always @(posedge CLK_I or posedge RST_I) 1.102 + if (RST_I) 1.103 + PIO_DATA_O <= #UDLY 0; 1.104 + else if (PIO_DATA_WR_EN) 1.105 + PIO_DATA_O <= #UDLY DAT_I; 1.106 + 1.107 + always @(posedge CLK_I or posedge RST_I) 1.108 + if (RST_I) 1.109 + PIO_DATA_I <= #UDLY 0; 1.110 + else if (PIO_DATA_RE_EN) 1.111 + PIO_DATA_I <= #UDLY PIO_IO_I; 1.112 + 1.113 + BB tpio_inst(.I(PIO_DATA_O), .T(~PIO_TRI), .O(PIO_IO_I), .B(PIO_IO)); 1.114 + assign DAT_O = PIO_TRI_RE_EN ? PIO_TRI : 1.115 + IRQ_MASK_RE_EN ? IRQ_MASK : PIO_DATA_I; 1.116 + 1.117 + //IRQ_MODE 1.118 + 1.119 + generate 1.120 + if (IRQ_MODE == 1) begin 1.121 + //CONFIG THE IRQ_MASK REG. 1.122 + always @(posedge CLK_I or posedge RST_I) 1.123 + if (RST_I) 1.124 + IRQ_MASK <= #UDLY 0; 1.125 + else if (IRQ_MASK_WR_EN) 1.126 + IRQ_MASK <= #UDLY DAT_I; 1.127 + end 1.128 + endgenerate 1.129 + 1.130 + generate 1.131 + if (IRQ_MODE == 1 && LEVEL == 1) begin 1.132 + always @(posedge CLK_I or posedge RST_I) 1.133 + if (RST_I) 1.134 + IRQ_TEMP <= #UDLY 0; 1.135 + else 1.136 + IRQ_TEMP <= #UDLY PIO_IO_I & IRQ_MASK & ~PIO_TRI;//bit-and 1.137 + assign IRQ_O = IRQ_TEMP; 1.138 + end 1.139 + else if (IRQ_MODE == 1 && EDGE == 1) begin 1.140 + always @(posedge CLK_I or posedge RST_I) 1.141 + if (RST_I) 1.142 + PIO_DATA_DLY <= #UDLY 0; 1.143 + else 1.144 + PIO_DATA_DLY <= PIO_IO_I; 1.145 + 1.146 + always @(posedge CLK_I or posedge RST_I) 1.147 + if (RST_I) 1.148 + EDGE_CAPTURE <= #UDLY 0; 1.149 + else if ((PIO_IO_I & ~PIO_DATA_DLY & ~PIO_TRI) && POSE_EDGE_IRQ == 1) 1.150 + EDGE_CAPTURE <= #UDLY PIO_IO_I & ~PIO_DATA_DLY; 1.151 + else if ((~PIO_IO_I & PIO_DATA_DLY & ~PIO_TRI) && NEGE_EDGE_IRQ == 1) 1.152 + EDGE_CAPTURE <= #UDLY ~PIO_IO_I & PIO_DATA_DLY; 1.153 + else if ((PIO_IO_I & ~PIO_DATA_DLY & ~PIO_TRI) && EITHER_EDGE_IRQ == 1) 1.154 + EDGE_CAPTURE <= #UDLY PIO_IO_I & ~PIO_DATA_DLY; 1.155 + else if ((~PIO_IO_I & PIO_DATA_DLY & ~PIO_TRI) && EITHER_EDGE_IRQ == 1) 1.156 + EDGE_CAPTURE <= #UDLY ~PIO_IO_I & PIO_DATA_DLY; 1.157 + else if ( (~IRQ_MASK) & DAT_I & IRQ_MASK_WR_EN ) 1.158 + // interrupt mask's being set, so clear edge-capture 1.159 + EDGE_CAPTURE <= #UDLY 0; 1.160 + else if ( EDGE_CAP_WR_EN ) 1.161 + // user's writing to the edge-register, so update edge-capture 1.162 + // register 1.163 + EDGE_CAPTURE <= #UDLY EDGE_CAPTURE & DAT_I; 1.164 + 1.165 + assign IRQ_O = |(EDGE_CAPTURE & IRQ_MASK); 1.166 + end 1.167 + else // IRQ_MODE ==0 1.168 + assign IRQ_O = 0; 1.169 + endgenerate 1.170 +endmodule 1.171 +`endif // TPIO_V 1.172 +