Fri, 13 Aug 2010 10:41:29 +0100
Initial commit, GPIO v3.1
| philpem@0 | 1 | // ============================================================================= |
| philpem@0 | 2 | // COPYRIGHT NOTICE |
| philpem@0 | 3 | // Copyright 2006 (c) Lattice Semiconductor Corporation |
| philpem@0 | 4 | // ALL RIGHTS RESERVED |
| philpem@0 | 5 | // This confidential and proprietary software may be used only as authorised by |
| philpem@0 | 6 | // a licensing agreement from Lattice Semiconductor Corporation. |
| philpem@0 | 7 | // The entire notice above must be reproduced on all authorized copies and |
| philpem@0 | 8 | // copies may only be made to the extent permitted by a licensing agreement from |
| philpem@0 | 9 | // Lattice Semiconductor Corporation. |
| philpem@0 | 10 | // |
| philpem@0 | 11 | // Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) |
| philpem@0 | 12 | // 5555 NE Moore Court 408-826-6000 (other locations) |
| philpem@0 | 13 | // Hillsboro, OR 97124 web : http://www.latticesemi.com/ |
| philpem@0 | 14 | // U.S.A email: techsupport@latticesemi.com |
| philpem@0 | 15 | // ============================================================================/ |
| philpem@0 | 16 | // FILE DETAILS |
| philpem@0 | 17 | // FILE DETAILS |
| philpem@0 | 18 | // Project : GPIO for LM32 |
| philpem@0 | 19 | // File : tpio.v |
| philpem@0 | 20 | // Title : Tri State IO control |
| philpem@0 | 21 | // Dependencies : system_conf.v |
| philpem@0 | 22 | // Description : Implements the logic to interface tri-state IO with |
| philpem@0 | 23 | // Wishbone bus. |
| philpem@0 | 24 | // ============================================================================= |
| philpem@0 | 25 | // REVISION HISTORY |
| philpem@0 | 26 | // Version : 7.0 |
| philpem@0 | 27 | // Mod. Date : Jun 27, 2005 |
| philpem@0 | 28 | // Changes Made : Initial Creation |
| philpem@0 | 29 | // |
| philpem@0 | 30 | // Version : 7.0SP2, 3.0 |
| philpem@0 | 31 | // Mod. Date : 20 Nov. 2007 |
| philpem@0 | 32 | // Changes Made : Code clean up and add the BB for the inout port. |
| philpem@0 | 33 | // |
| philpem@0 | 34 | // Version : 3.1 |
| philpem@0 | 35 | // Mod. Date : 11 Oct. 2008 |
| philpem@0 | 36 | // Changes Made : Update the Edge Capture Register clean method |
| philpem@0 | 37 | // Make IRQ Mask register readable |
| philpem@0 | 38 | // ============================================================================= |
| philpem@0 | 39 | `ifndef TPIO_V |
| philpem@0 | 40 | `define TPIO_V |
| philpem@0 | 41 | `timescale 1ns/100 ps |
| philpem@0 | 42 | `include "system_conf.v" |
| philpem@0 | 43 | module TRI_PIO #(parameter DATA_WIDTH = 16, |
| philpem@0 | 44 | parameter IRQ_MODE = 1, |
| philpem@0 | 45 | parameter LEVEL = 0, |
| philpem@0 | 46 | parameter EDGE = 1, |
| philpem@0 | 47 | parameter POSE_EDGE_IRQ = 1, |
| philpem@0 | 48 | parameter NEGE_EDGE_IRQ = 0, |
| philpem@0 | 49 | parameter EITHER_EDGE_IRQ = 0) |
| philpem@0 | 50 | (RST_I, |
| philpem@0 | 51 | CLK_I, |
| philpem@0 | 52 | DAT_I, |
| philpem@0 | 53 | DAT_O, |
| philpem@0 | 54 | PIO_IO, |
| philpem@0 | 55 | IRQ_O, |
| philpem@0 | 56 | PIO_TRI_WR_EN, |
| philpem@0 | 57 | PIO_TRI_RE_EN, |
| philpem@0 | 58 | PIO_DATA_RE_EN, |
| philpem@0 | 59 | PIO_DATA_WR_EN, |
| philpem@0 | 60 | IRQ_MASK_RE_EN, |
| philpem@0 | 61 | IRQ_MASK_WR_EN, |
| philpem@0 | 62 | EDGE_CAP_WR_EN); |
| philpem@0 | 63 | |
| philpem@0 | 64 | parameter UDLY = 1;//user delay |
| philpem@0 | 65 | |
| philpem@0 | 66 | input RST_I; |
| philpem@0 | 67 | input CLK_I; |
| philpem@0 | 68 | input DAT_I; |
| philpem@0 | 69 | input PIO_TRI_RE_EN; |
| philpem@0 | 70 | input PIO_TRI_WR_EN; |
| philpem@0 | 71 | input PIO_DATA_RE_EN; |
| philpem@0 | 72 | input PIO_DATA_WR_EN; |
| philpem@0 | 73 | output DAT_O; |
| philpem@0 | 74 | input IRQ_MASK_RE_EN; |
| philpem@0 | 75 | input IRQ_MASK_WR_EN; |
| philpem@0 | 76 | input EDGE_CAP_WR_EN; |
| philpem@0 | 77 | output IRQ_O; |
| philpem@0 | 78 | inout PIO_IO; |
| philpem@0 | 79 | |
| philpem@0 | 80 | wire PIO_IO_I; |
| philpem@0 | 81 | wire DAT_O; |
| philpem@0 | 82 | wire IRQ_O; |
| philpem@0 | 83 | reg PIO_DATA_O; |
| philpem@0 | 84 | reg PIO_DATA_I; |
| philpem@0 | 85 | reg PIO_TRI; |
| philpem@0 | 86 | reg IRQ_MASK; |
| philpem@0 | 87 | reg IRQ_TEMP; |
| philpem@0 | 88 | reg EDGE_CAPTURE; |
| philpem@0 | 89 | reg PIO_DATA_DLY; |
| philpem@0 | 90 | |
| philpem@0 | 91 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 92 | if (RST_I) |
| philpem@0 | 93 | PIO_TRI <= #UDLY 0; |
| philpem@0 | 94 | else if (PIO_TRI_WR_EN) |
| philpem@0 | 95 | PIO_TRI <= #UDLY DAT_I; |
| philpem@0 | 96 | |
| philpem@0 | 97 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 98 | if (RST_I) |
| philpem@0 | 99 | PIO_DATA_O <= #UDLY 0; |
| philpem@0 | 100 | else if (PIO_DATA_WR_EN) |
| philpem@0 | 101 | PIO_DATA_O <= #UDLY DAT_I; |
| philpem@0 | 102 | |
| philpem@0 | 103 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 104 | if (RST_I) |
| philpem@0 | 105 | PIO_DATA_I <= #UDLY 0; |
| philpem@0 | 106 | else if (PIO_DATA_RE_EN) |
| philpem@0 | 107 | PIO_DATA_I <= #UDLY PIO_IO_I; |
| philpem@0 | 108 | |
| philpem@0 | 109 | BB tpio_inst(.I(PIO_DATA_O), .T(~PIO_TRI), .O(PIO_IO_I), .B(PIO_IO)); |
| philpem@0 | 110 | assign DAT_O = PIO_TRI_RE_EN ? PIO_TRI : |
| philpem@0 | 111 | IRQ_MASK_RE_EN ? IRQ_MASK : PIO_DATA_I; |
| philpem@0 | 112 | |
| philpem@0 | 113 | //IRQ_MODE |
| philpem@0 | 114 | |
| philpem@0 | 115 | generate |
| philpem@0 | 116 | if (IRQ_MODE == 1) begin |
| philpem@0 | 117 | //CONFIG THE IRQ_MASK REG. |
| philpem@0 | 118 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 119 | if (RST_I) |
| philpem@0 | 120 | IRQ_MASK <= #UDLY 0; |
| philpem@0 | 121 | else if (IRQ_MASK_WR_EN) |
| philpem@0 | 122 | IRQ_MASK <= #UDLY DAT_I; |
| philpem@0 | 123 | end |
| philpem@0 | 124 | endgenerate |
| philpem@0 | 125 | |
| philpem@0 | 126 | generate |
| philpem@0 | 127 | if (IRQ_MODE == 1 && LEVEL == 1) begin |
| philpem@0 | 128 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 129 | if (RST_I) |
| philpem@0 | 130 | IRQ_TEMP <= #UDLY 0; |
| philpem@0 | 131 | else |
| philpem@0 | 132 | IRQ_TEMP <= #UDLY PIO_IO_I & IRQ_MASK & ~PIO_TRI;//bit-and |
| philpem@0 | 133 | assign IRQ_O = IRQ_TEMP; |
| philpem@0 | 134 | end |
| philpem@0 | 135 | else if (IRQ_MODE == 1 && EDGE == 1) begin |
| philpem@0 | 136 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 137 | if (RST_I) |
| philpem@0 | 138 | PIO_DATA_DLY <= #UDLY 0; |
| philpem@0 | 139 | else |
| philpem@0 | 140 | PIO_DATA_DLY <= PIO_IO_I; |
| philpem@0 | 141 | |
| philpem@0 | 142 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 143 | if (RST_I) |
| philpem@0 | 144 | EDGE_CAPTURE <= #UDLY 0; |
| philpem@0 | 145 | else if ((PIO_IO_I & ~PIO_DATA_DLY & ~PIO_TRI) && POSE_EDGE_IRQ == 1) |
| philpem@0 | 146 | EDGE_CAPTURE <= #UDLY PIO_IO_I & ~PIO_DATA_DLY; |
| philpem@0 | 147 | else if ((~PIO_IO_I & PIO_DATA_DLY & ~PIO_TRI) && NEGE_EDGE_IRQ == 1) |
| philpem@0 | 148 | EDGE_CAPTURE <= #UDLY ~PIO_IO_I & PIO_DATA_DLY; |
| philpem@0 | 149 | else if ((PIO_IO_I & ~PIO_DATA_DLY & ~PIO_TRI) && EITHER_EDGE_IRQ == 1) |
| philpem@0 | 150 | EDGE_CAPTURE <= #UDLY PIO_IO_I & ~PIO_DATA_DLY; |
| philpem@0 | 151 | else if ((~PIO_IO_I & PIO_DATA_DLY & ~PIO_TRI) && EITHER_EDGE_IRQ == 1) |
| philpem@0 | 152 | EDGE_CAPTURE <= #UDLY ~PIO_IO_I & PIO_DATA_DLY; |
| philpem@0 | 153 | else if ( (~IRQ_MASK) & DAT_I & IRQ_MASK_WR_EN ) |
| philpem@0 | 154 | // interrupt mask's being set, so clear edge-capture |
| philpem@0 | 155 | EDGE_CAPTURE <= #UDLY 0; |
| philpem@0 | 156 | else if ( EDGE_CAP_WR_EN ) |
| philpem@0 | 157 | // user's writing to the edge-register, so update edge-capture |
| philpem@0 | 158 | // register |
| philpem@0 | 159 | EDGE_CAPTURE <= #UDLY EDGE_CAPTURE & DAT_I; |
| philpem@0 | 160 | |
| philpem@0 | 161 | assign IRQ_O = |(EDGE_CAPTURE & IRQ_MASK); |
| philpem@0 | 162 | end |
| philpem@0 | 163 | else // IRQ_MODE ==0 |
| philpem@0 | 164 | assign IRQ_O = 0; |
| philpem@0 | 165 | endgenerate |
| philpem@0 | 166 | endmodule |
| philpem@0 | 167 | `endif // TPIO_V |
| philpem@0 | 168 |