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