OpenCores
URL https://opencores.org/ocsvn/ftdi_wb_bridge/ftdi_wb_bridge/trunk

Subversion Repositories ftdi_wb_bridge

[/] [ftdi_wb_bridge/] [trunk/] [rtl/] [ftdi_sync.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ultra_embe
//-----------------------------------------------------------------
2
//                 FTDI Asynchronous FIFO Interface
3
//                              V0.1
4
//                        Ultra-Embedded.com
5
//                          Copyright 2015
6
//
7
//                 Email: admin@ultra-embedded.com
8
//
9
//                         License: GPL
10
// If you would like a version with a more permissive license for
11
// use in closed source commercial applications please contact me
12
// for details.
13
//-----------------------------------------------------------------
14
//
15
// This file is open source HDL; you can redistribute it and/or 
16
// modify it under the terms of the GNU General Public License as 
17
// published by the Free Software Foundation; either version 2 of 
18
// the License, or (at your option) any later version.
19
//
20
// This file is distributed in the hope that it will be useful,
21
// but WITHOUT ANY WARRANTY; without even the implied warranty of
22
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
// GNU General Public License for more details.
24
//
25
// You should have received a copy of the GNU General Public 
26
// License along with this file; if not, write to the Free Software
27
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28
// USA
29
//-----------------------------------------------------------------
30
 
31
//-----------------------------------------------------------------
32
// Module: ftdi_sync - Async FT245 FIFO interface
33
//-----------------------------------------------------------------
34
module ftdi_sync
35
 
36
//-----------------------------------------------------------------
37
// Params
38
//-----------------------------------------------------------------
39
#(
40
    parameter       CLK_DIV = 0    // 0 - X
41
)
42
 
43
//-----------------------------------------------------------------
44
// Ports
45
//-----------------------------------------------------------------
46
(
47
    input           clk_i,
48
    input           rst_i,
49
 
50
    // FTDI (async FIFO interface)
51
    input           ftdi_rxf_i,
52
    input           ftdi_txe_i,
53
    output          ftdi_siwua_o,
54
    output reg      ftdi_wr_o,
55
    output reg      ftdi_rd_o,
56
    inout [7:0]     ftdi_d_io,
57
 
58
    // Synchronous Interface
59
    output [7:0]    data_o,
60
    input [7:0]     data_i,
61
    input           wr_i,
62
    input           rd_i,
63
    output          wr_accept_o,
64
    output reg      rd_ready_o
65
);
66
 
67
//-----------------------------------------------------------------
68
// Defines / Local params
69
//-----------------------------------------------------------------
70
localparam STATE_W           = 2;
71
localparam STATE_IDLE        = 2'd0;
72
localparam STATE_TX_SETUP    = 2'd1;
73
localparam STATE_TX          = 2'd2;
74
localparam STATE_RX          = 2'd3;
75
 
76
//-----------------------------------------------------------------
77
// Registers / Wires
78
//-----------------------------------------------------------------
79
 
80
// Xilinx placement pragmas:
81
//synthesis attribute IOB of tx_data_q is "TRUE"
82
//synthesis attribute IOB of ftdi_rd_o is "TRUE"
83
//synthesis attribute IOB of ftdi_wr_o is "TRUE"
84
 
85
// Current state
86
reg [STATE_W-1:0]      state_q;
87
 
88
reg                    tx_ready_q;
89
 
90
reg                    ftdi_rxf_ms_q;
91
reg                    ftdi_txe_ms_q;
92
reg                    ftdi_rxf_q;
93
reg                    ftdi_txe_q;
94
 
95
reg [7:0]              rx_data_q;
96
reg [7:0]              tx_data_q;
97
 
98
//-----------------------------------------------------------------
99
// Resample async signals
100
//-----------------------------------------------------------------
101
always @ (posedge clk_i or posedge rst_i)
102
if (rst_i)
103
begin
104
    ftdi_rxf_ms_q   <= 1'b1;
105
    ftdi_txe_ms_q   <= 1'b1;
106
    ftdi_rxf_q      <= 1'b1;
107
    ftdi_txe_q      <= 1'b1;
108
end
109
else
110
begin
111
    ftdi_rxf_q      <= ftdi_rxf_ms_q;
112
    ftdi_rxf_ms_q   <= ftdi_rxf_i;
113
 
114
    ftdi_txe_q      <= ftdi_txe_ms_q;
115
    ftdi_txe_ms_q   <= ftdi_txe_i;
116
end
117
 
118
//-----------------------------------------------------------------
119
// Clock divider
120
//-----------------------------------------------------------------
121
reg [CLK_DIV:0] clk_div_q;
122
 
123
always @ (posedge rst_i or posedge clk_i)
124
if (rst_i)
125
    clk_div_q <= {1'b1, {(CLK_DIV){1'b0}}};
126
else if (CLK_DIV > 0)
127
    clk_div_q <= {clk_div_q[0], clk_div_q[CLK_DIV:1]};
128
else
129
    clk_div_q <= ~clk_div_q;
130
 
131
wire clk_en_w = clk_div_q[0];
132
 
133
//-----------------------------------------------------------------
134
// Sample flag
135
//-----------------------------------------------------------------
136
// Sample read data when both RD# and RXF# are low
137
wire rx_sample_w = (state_q == STATE_RX) & clk_en_w;
138
 
139
// Target accepts data when WR# and TXE# are low
140
wire tx_sent_w   = (state_q == STATE_TX) & clk_en_w;
141
 
142
wire rx_ready_w = ~ftdi_rxf_q & clk_en_w;
143
wire tx_space_w = ~ftdi_txe_q & clk_en_w;
144
 
145
wire rx_start_w  = (state_q == STATE_IDLE) & rx_ready_w & !rd_ready_o;
146
wire tx_start_w  = (state_q == STATE_IDLE) & tx_space_w & tx_ready_q;
147
 
148
//-----------------------------------------------------------------
149
// Next State Logic
150
//-----------------------------------------------------------------
151
reg [STATE_W-1:0] next_state_r;
152
always @ *
153
begin
154
    next_state_r = state_q;
155
 
156
    case (state_q)
157
    //-----------------------------------------
158
    // STATE_IDLE
159
    //-----------------------------------------
160
    STATE_IDLE :
161
    begin
162
        if (rx_start_w)
163
            next_state_r    = STATE_RX;
164
        else if (tx_start_w)
165
            next_state_r    = STATE_TX_SETUP;
166
    end
167
    //-----------------------------------------
168
    // STATE_RX
169
    //-----------------------------------------
170
    STATE_RX :
171
    begin
172
        if (clk_en_w)
173
            next_state_r  = STATE_IDLE;
174
    end
175
    //-----------------------------------------
176
    // STATE_TX_SETUP
177
    //-----------------------------------------
178
    STATE_TX_SETUP :
179
    begin
180
        if (clk_en_w)
181
            next_state_r  = STATE_TX;
182
    end
183
    //-----------------------------------------
184
    // STATE_TX
185
    //-----------------------------------------
186
    STATE_TX :
187
    begin
188
        if (clk_en_w)
189
            next_state_r  = STATE_IDLE;
190
    end
191
    default:
192
        ;
193
   endcase
194
end
195
 
196
// Update state
197
always @ (posedge rst_i or posedge clk_i)
198
if (rst_i)
199
    state_q   <= STATE_IDLE;
200
else
201
    state_q   <= next_state_r;
202
 
203
//-----------------------------------------------------------------
204
// rd_ready_o
205
//-----------------------------------------------------------------
206
always @ (posedge rst_i or posedge clk_i)
207
if (rst_i)
208
    rd_ready_o <= 1'b0;
209
else if (rx_sample_w)
210
    rd_ready_o <= 1'b1;
211
else if (rd_i)
212
    rd_ready_o <= 1'b0;
213
 
214
//-----------------------------------------------------------------
215
// tx_ready_q
216
//-----------------------------------------------------------------
217
always @ (posedge rst_i or posedge clk_i)
218
if (rst_i)
219
    tx_ready_q <= 1'b0;
220
else if (tx_sent_w)
221
    tx_ready_q <= 1'b0;
222
else if (wr_i)
223
    tx_ready_q <= 1'b1;
224
 
225
assign wr_accept_o = !tx_ready_q;
226
 
227
//-----------------------------------------------------------------
228
// RD#
229
//-----------------------------------------------------------------
230
always @ (posedge rst_i or posedge clk_i)
231
if (rst_i)
232
    ftdi_rd_o <= 1'b1;
233
else if (rx_start_w)
234
    ftdi_rd_o <= 1'b0;
235
else if (rx_sample_w)
236
    ftdi_rd_o <= 1'b1;
237
 
238
//-----------------------------------------------------------------
239
// WR#
240
//-----------------------------------------------------------------
241
always @ (posedge rst_i or posedge clk_i)
242
if (rst_i)
243
    ftdi_wr_o <= 1'b1;
244
else if ((state_q == STATE_TX_SETUP) && clk_en_w)
245
    ftdi_wr_o <= 1'b0;
246
else if (tx_sent_w)
247
    ftdi_wr_o <= 1'b1;
248
 
249
//-----------------------------------------------------------------
250
// Rx Data
251
//-----------------------------------------------------------------
252
always @ (posedge rst_i or posedge clk_i)
253
if (rst_i)
254
    rx_data_q <= 8'b0;
255
else if (rx_sample_w)
256
    rx_data_q <= ftdi_d_io;
257
 
258
//-----------------------------------------------------------------
259
// Tx Data
260
//-----------------------------------------------------------------
261
always @ (posedge rst_i or posedge clk_i)
262
if (rst_i)
263
    tx_data_q <= 8'b0;
264
else if (wr_i && wr_accept_o)
265
    tx_data_q <= data_i;
266
 
267
//-----------------------------------------------------------------
268
// Outputs
269
//-----------------------------------------------------------------
270
 
271
// Tristate output
272
assign ftdi_d_io    = (state_q == STATE_TX_SETUP || state_q == STATE_TX) ? tx_data_q : 8'hzz;
273
assign ftdi_siwua_o = 1'b1;
274
 
275
assign data_o       = rx_data_q;
276
 
277
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.