rtl/verilog/tpio.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 // 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