rtl/verilog/tpio.v

Fri, 13 Aug 2010 10:41:29 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Fri, 13 Aug 2010 10:41:29 +0100
changeset 0
267b5a25932f
child 1
dfc32cad81ba
permissions
-rw-r--r--

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