Sat, 06 Aug 2011 01:43:24 +0100
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 | // FILE DETAILS |
| philpem@0 | 39 | // Project : GPIO for LM32 |
| philpem@0 | 40 | // File : tpio.v |
| philpem@0 | 41 | // Title : Tri State IO control |
| philpem@0 | 42 | // Dependencies : system_conf.v |
| philpem@0 | 43 | // Description : Implements the logic to interface tri-state IO with |
| philpem@0 | 44 | // Wishbone bus. |
| philpem@0 | 45 | // ============================================================================= |
| philpem@0 | 46 | // REVISION HISTORY |
| philpem@0 | 47 | // Version : 7.0 |
| philpem@0 | 48 | // Mod. Date : Jun 27, 2005 |
| philpem@0 | 49 | // Changes Made : Initial Creation |
| philpem@0 | 50 | // |
| philpem@0 | 51 | // Version : 7.0SP2, 3.0 |
| philpem@0 | 52 | // Mod. Date : 20 Nov. 2007 |
| philpem@0 | 53 | // Changes Made : Code clean up and add the BB for the inout port. |
| philpem@0 | 54 | // |
| philpem@0 | 55 | // Version : 3.1 |
| philpem@0 | 56 | // Mod. Date : 11 Oct. 2008 |
| philpem@0 | 57 | // Changes Made : Update the Edge Capture Register clean method |
| philpem@0 | 58 | // Make IRQ Mask register readable |
| philpem@0 | 59 | // ============================================================================= |
| philpem@0 | 60 | `ifndef TPIO_V |
| philpem@0 | 61 | `define TPIO_V |
| philpem@0 | 62 | `timescale 1ns/100 ps |
| philpem@0 | 63 | `include "system_conf.v" |
| philpem@0 | 64 | module TRI_PIO #(parameter DATA_WIDTH = 16, |
| philpem@0 | 65 | parameter IRQ_MODE = 1, |
| philpem@0 | 66 | parameter LEVEL = 0, |
| philpem@0 | 67 | parameter EDGE = 1, |
| philpem@0 | 68 | parameter POSE_EDGE_IRQ = 1, |
| philpem@0 | 69 | parameter NEGE_EDGE_IRQ = 0, |
| philpem@0 | 70 | parameter EITHER_EDGE_IRQ = 0) |
| philpem@0 | 71 | (RST_I, |
| philpem@0 | 72 | CLK_I, |
| philpem@0 | 73 | DAT_I, |
| philpem@0 | 74 | DAT_O, |
| philpem@0 | 75 | PIO_IO, |
| philpem@0 | 76 | IRQ_O, |
| philpem@0 | 77 | PIO_TRI_WR_EN, |
| philpem@0 | 78 | PIO_TRI_RE_EN, |
| philpem@0 | 79 | PIO_DATA_RE_EN, |
| philpem@0 | 80 | PIO_DATA_WR_EN, |
| philpem@0 | 81 | IRQ_MASK_RE_EN, |
| philpem@0 | 82 | IRQ_MASK_WR_EN, |
| philpem@0 | 83 | EDGE_CAP_WR_EN); |
| philpem@0 | 84 | |
| philpem@0 | 85 | parameter UDLY = 1;//user delay |
| philpem@0 | 86 | |
| philpem@0 | 87 | input RST_I; |
| philpem@0 | 88 | input CLK_I; |
| philpem@0 | 89 | input DAT_I; |
| philpem@0 | 90 | input PIO_TRI_RE_EN; |
| philpem@0 | 91 | input PIO_TRI_WR_EN; |
| philpem@0 | 92 | input PIO_DATA_RE_EN; |
| philpem@0 | 93 | input PIO_DATA_WR_EN; |
| philpem@0 | 94 | output DAT_O; |
| philpem@0 | 95 | input IRQ_MASK_RE_EN; |
| philpem@0 | 96 | input IRQ_MASK_WR_EN; |
| philpem@0 | 97 | input EDGE_CAP_WR_EN; |
| philpem@0 | 98 | output IRQ_O; |
| philpem@0 | 99 | inout PIO_IO; |
| philpem@0 | 100 | |
| philpem@0 | 101 | wire PIO_IO_I; |
| philpem@0 | 102 | wire DAT_O; |
| philpem@0 | 103 | wire IRQ_O; |
| philpem@0 | 104 | reg PIO_DATA_O; |
| philpem@0 | 105 | reg PIO_DATA_I; |
| philpem@0 | 106 | reg PIO_TRI; |
| philpem@0 | 107 | reg IRQ_MASK; |
| philpem@0 | 108 | reg IRQ_TEMP; |
| philpem@0 | 109 | reg EDGE_CAPTURE; |
| philpem@0 | 110 | reg PIO_DATA_DLY; |
| philpem@0 | 111 | |
| philpem@0 | 112 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 113 | if (RST_I) |
| philpem@0 | 114 | PIO_TRI <= #UDLY 0; |
| philpem@0 | 115 | else if (PIO_TRI_WR_EN) |
| philpem@0 | 116 | PIO_TRI <= #UDLY DAT_I; |
| philpem@0 | 117 | |
| philpem@0 | 118 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 119 | if (RST_I) |
| philpem@0 | 120 | PIO_DATA_O <= #UDLY 0; |
| philpem@0 | 121 | else if (PIO_DATA_WR_EN) |
| philpem@0 | 122 | PIO_DATA_O <= #UDLY DAT_I; |
| philpem@0 | 123 | |
| philpem@0 | 124 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 125 | if (RST_I) |
| philpem@0 | 126 | PIO_DATA_I <= #UDLY 0; |
| philpem@0 | 127 | else if (PIO_DATA_RE_EN) |
| philpem@0 | 128 | PIO_DATA_I <= #UDLY PIO_IO_I; |
| philpem@0 | 129 | |
| philpem@0 | 130 | BB tpio_inst(.I(PIO_DATA_O), .T(~PIO_TRI), .O(PIO_IO_I), .B(PIO_IO)); |
| philpem@0 | 131 | assign DAT_O = PIO_TRI_RE_EN ? PIO_TRI : |
| philpem@0 | 132 | IRQ_MASK_RE_EN ? IRQ_MASK : PIO_DATA_I; |
| philpem@0 | 133 | |
| philpem@0 | 134 | //IRQ_MODE |
| philpem@0 | 135 | |
| philpem@0 | 136 | generate |
| philpem@0 | 137 | if (IRQ_MODE == 1) begin |
| philpem@0 | 138 | //CONFIG THE IRQ_MASK REG. |
| philpem@0 | 139 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 140 | if (RST_I) |
| philpem@0 | 141 | IRQ_MASK <= #UDLY 0; |
| philpem@0 | 142 | else if (IRQ_MASK_WR_EN) |
| philpem@0 | 143 | IRQ_MASK <= #UDLY DAT_I; |
| philpem@0 | 144 | end |
| philpem@0 | 145 | endgenerate |
| philpem@0 | 146 | |
| philpem@0 | 147 | generate |
| philpem@0 | 148 | if (IRQ_MODE == 1 && LEVEL == 1) begin |
| philpem@0 | 149 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 150 | if (RST_I) |
| philpem@0 | 151 | IRQ_TEMP <= #UDLY 0; |
| philpem@0 | 152 | else |
| philpem@0 | 153 | IRQ_TEMP <= #UDLY PIO_IO_I & IRQ_MASK & ~PIO_TRI;//bit-and |
| philpem@0 | 154 | assign IRQ_O = IRQ_TEMP; |
| philpem@0 | 155 | end |
| philpem@0 | 156 | else if (IRQ_MODE == 1 && EDGE == 1) begin |
| philpem@0 | 157 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 158 | if (RST_I) |
| philpem@0 | 159 | PIO_DATA_DLY <= #UDLY 0; |
| philpem@0 | 160 | else |
| philpem@0 | 161 | PIO_DATA_DLY <= PIO_IO_I; |
| philpem@0 | 162 | |
| philpem@0 | 163 | always @(posedge CLK_I or posedge RST_I) |
| philpem@0 | 164 | if (RST_I) |
| philpem@0 | 165 | EDGE_CAPTURE <= #UDLY 0; |
| philpem@0 | 166 | else if ((PIO_IO_I & ~PIO_DATA_DLY & ~PIO_TRI) && POSE_EDGE_IRQ == 1) |
| philpem@0 | 167 | EDGE_CAPTURE <= #UDLY PIO_IO_I & ~PIO_DATA_DLY; |
| philpem@0 | 168 | else if ((~PIO_IO_I & PIO_DATA_DLY & ~PIO_TRI) && NEGE_EDGE_IRQ == 1) |
| philpem@0 | 169 | EDGE_CAPTURE <= #UDLY ~PIO_IO_I & PIO_DATA_DLY; |
| philpem@0 | 170 | else if ((PIO_IO_I & ~PIO_DATA_DLY & ~PIO_TRI) && EITHER_EDGE_IRQ == 1) |
| philpem@0 | 171 | EDGE_CAPTURE <= #UDLY PIO_IO_I & ~PIO_DATA_DLY; |
| philpem@0 | 172 | else if ((~PIO_IO_I & PIO_DATA_DLY & ~PIO_TRI) && EITHER_EDGE_IRQ == 1) |
| philpem@0 | 173 | EDGE_CAPTURE <= #UDLY ~PIO_IO_I & PIO_DATA_DLY; |
| philpem@0 | 174 | else if ( (~IRQ_MASK) & DAT_I & IRQ_MASK_WR_EN ) |
| philpem@0 | 175 | // interrupt mask's being set, so clear edge-capture |
| philpem@0 | 176 | EDGE_CAPTURE <= #UDLY 0; |
| philpem@0 | 177 | else if ( EDGE_CAP_WR_EN ) |
| philpem@0 | 178 | // user's writing to the edge-register, so update edge-capture |
| philpem@0 | 179 | // register |
| philpem@0 | 180 | EDGE_CAPTURE <= #UDLY EDGE_CAPTURE & DAT_I; |
| philpem@0 | 181 | |
| philpem@0 | 182 | assign IRQ_O = |(EDGE_CAPTURE & IRQ_MASK); |
| philpem@0 | 183 | end |
| philpem@0 | 184 | else // IRQ_MODE ==0 |
| philpem@0 | 185 | assign IRQ_O = 0; |
| philpem@0 | 186 | endgenerate |
| philpem@0 | 187 | endmodule |
| philpem@0 | 188 | `endif // TPIO_V |
| philpem@0 | 189 |