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

Subversion Repositories ftdi_wb_bridge

[/] [ftdi_wb_bridge/] [trunk/] [rtl/] [ftdi_if.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_if - Async FT245 FIFO interface
33
//-----------------------------------------------------------------
34
module ftdi_if
35
 
36
//-----------------------------------------------------------------
37
// Params
38
//-----------------------------------------------------------------
39
#(
40
    parameter                   CLK_DIV             = 2,    // 2 - X
41
    parameter                   LITTLE_ENDIAN       = 1,    // 0 or 1
42
    parameter                   ADDR_W              = 32,
43
    parameter                   GP_OUTPUTS          = 8,    // 1 - 8
44
    parameter                   GP_INPUTS           = 8,    // 1 - 8
45
    parameter                   GP_IN_EVENT_MASK    = 8'h00
46
)
47
 
48
//-----------------------------------------------------------------
49
// Ports
50
//-----------------------------------------------------------------
51
(
52
    input                       clk_i,
53
    input                       rst_i,
54
 
55
    // FTDI (async FIFO interface)
56
    input                       ftdi_rxf_i,
57
    input                       ftdi_txe_i,
58
    output                      ftdi_siwua_o,
59
    output                      ftdi_wr_o,
60
    output                      ftdi_rd_o,
61
    inout [7:0]                 ftdi_d_io,
62
 
63
    // General Purpose IO
64
    output [GP_OUTPUTS-1:0]     gp_o,
65
    input  [GP_INPUTS-1:0]      gp_i,
66
 
67
    // Wishbone Interface (Master)
68
    output [ADDR_W-1:0]         mem_addr_o,
69
    output [31:0]               mem_data_o,
70
    input [31:0]                mem_data_i,
71
    output [3:0]                mem_sel_o,
72
    output reg                  mem_we_o,
73
    output reg                  mem_stb_o,
74
    output                      mem_cyc_o,
75
    input                       mem_ack_i,
76
    input                       mem_stall_i
77
);
78
 
79
//-----------------------------------------------------------------
80
// Defines / Local params
81
//-----------------------------------------------------------------
82
localparam CMD_NOP          = 4'd0;
83
localparam CMD_WR           = 4'd1;
84
localparam CMD_RD           = 4'd2;
85
localparam CMD_GP_WR        = 4'd3;
86
localparam CMD_GP_RD        = 4'd4;
87
localparam CMD_GP_RD_CLR    = 4'd5;
88
 
89
`define CMD_R               3:0
90
`define LEN_UPPER_R         7:4
91
`define LEN_LOWER_R         7:0
92
 
93
localparam LEN_W            = 12;
94
 
95
localparam DATA_W           = 8;
96
 
97
localparam STATE_W          = 4;
98
localparam STATE_IDLE       = 4'd0;
99
localparam STATE_CMD        = 4'd1;
100
localparam STATE_LEN        = 4'd2;
101
localparam STATE_ADDR0      = 4'd3;
102
localparam STATE_ADDR1      = 4'd4;
103
localparam STATE_ADDR2      = 4'd5;
104
localparam STATE_ADDR3      = 4'd6;
105
localparam STATE_WRITE      = 4'd7;
106
localparam STATE_READ       = 4'd8;
107
localparam STATE_DATA0      = 4'd9;
108
localparam STATE_DATA1      = 4'd10;
109
localparam STATE_DATA2      = 4'd11;
110
localparam STATE_DATA3      = 4'd12;
111
localparam STATE_GP_WR      = 4'd13;
112
localparam STATE_GP_RD      = 4'd14;
113
 
114
//-----------------------------------------------------------------
115
// Registers / Wires
116
//-----------------------------------------------------------------
117
 
118
// Async I/F <-> sync I/F
119
wire [DATA_W-1:0]   data_tx_w;
120
wire [DATA_W-1:0]   data_rx_w;
121
wire                wr_w;
122
wire                rd_w;
123
wire                wr_accept_w;
124
wire                rx_ready_w;
125
 
126
// Current state
127
reg [STATE_W-1:0]   state_q;
128
 
129
// Transfer length (for WB read / writes)
130
reg [LEN_W-1:0]     len_q;
131
 
132
// Mem address (some bits might be unused if ADDR_W < 32)
133
reg [31:0]          mem_addr_q;
134
reg                 mem_cyc_q;
135
 
136
// Byte Index
137
reg [1:0]           data_idx_q;
138
 
139
// Word storage
140
reg [31:0]          data_q;
141
 
142
// GPIO Output Flops
143
reg [GP_OUTPUTS-1:0] gp_out_q;
144
 
145
// GPIO Input Flops
146
reg [GP_INPUTS-1:0]  gp_in_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_ready_w)
163
            next_state_r    = STATE_CMD;
164
    end
165
    //-----------------------------------------
166
    // STATE_CMD
167
    //-----------------------------------------
168
    STATE_CMD :
169
    begin
170
        if (data_rx_w[`CMD_R] == CMD_NOP)
171
            next_state_r  = STATE_IDLE;
172
        else if (data_rx_w[`CMD_R] == CMD_WR || data_rx_w[`CMD_R] == CMD_RD)
173
            next_state_r  = STATE_LEN;
174
        else if (data_rx_w[`CMD_R] == CMD_GP_WR)
175
            next_state_r  = STATE_GP_WR;
176
        else if (data_rx_w[`CMD_R] == CMD_GP_RD)
177
            next_state_r  = STATE_GP_RD;
178
        else
179
            next_state_r  = STATE_IDLE;
180
    end
181
    //-----------------------------------------
182
    // STATE_LEN
183
    //-----------------------------------------
184
    STATE_LEN :
185
    begin
186
        if (rx_ready_w)
187
            next_state_r  = STATE_ADDR0;
188
    end
189
    //-----------------------------------------
190
    // STATE_ADDR
191
    //-----------------------------------------
192
    STATE_ADDR0 : if (rx_ready_w) next_state_r  = STATE_ADDR1;
193
    STATE_ADDR1 : if (rx_ready_w) next_state_r  = STATE_ADDR2;
194
    STATE_ADDR2 : if (rx_ready_w) next_state_r  = STATE_ADDR3;
195
    STATE_ADDR3 :
196
    begin
197
        if (rx_ready_w && mem_we_o)
198
            next_state_r  = STATE_WRITE;
199
        else if (rx_ready_w)
200
            next_state_r  = STATE_READ;
201
    end
202
    //-----------------------------------------
203
    // STATE_WRITE
204
    //-----------------------------------------
205
    STATE_WRITE :
206
    begin
207
        if (len_q == {LEN_W{1'b0}} && mem_ack_i)
208
            next_state_r  = STATE_IDLE;
209
        else
210
            next_state_r  = STATE_WRITE;
211
    end
212
    //-----------------------------------------
213
    // STATE_READ
214
    //-----------------------------------------
215
    STATE_READ :
216
    begin
217
        // Data ready
218
        if (mem_ack_i)
219
            next_state_r  = STATE_DATA0;
220
    end
221
    //-----------------------------------------
222
    // STATE_DATA
223
    //-----------------------------------------
224
    STATE_DATA0 :
225
    begin
226
        if (wr_accept_w)
227
            next_state_r  = STATE_DATA1;
228
    end
229
    STATE_DATA1 :
230
    begin
231
        if (wr_accept_w)
232
            next_state_r  = STATE_DATA2;
233
    end
234
    STATE_DATA2 :
235
    begin
236
        if (wr_accept_w)
237
            next_state_r  = STATE_DATA3;
238
    end
239
    STATE_DATA3 :
240
    begin
241
        if (wr_accept_w && (len_q != {LEN_W{1'b0}}))
242
            next_state_r  = STATE_READ;
243
        else if (wr_accept_w)
244
            next_state_r  = STATE_IDLE;
245
    end
246
    //-----------------------------------------
247
    // STATE_GP_WR
248
    //-----------------------------------------
249
    STATE_GP_WR :
250
    begin
251
        if (rx_ready_w)
252
            next_state_r  = STATE_IDLE;
253
    end
254
    //-----------------------------------------
255
    // STATE_GP_RD
256
    //-----------------------------------------
257
    STATE_GP_RD :
258
    begin
259
        if (wr_accept_w)
260
            next_state_r  = STATE_IDLE;
261
    end
262
    default:
263
        ;
264
   endcase
265
end
266
 
267
// Update state
268
always @ (posedge rst_i or posedge clk_i)
269
if (rst_i)
270
    state_q   <= STATE_IDLE;
271
else
272
    state_q   <= next_state_r;
273
 
274
//-----------------------------------------------------------------
275
// Async -> Sync I/O
276
//-----------------------------------------------------------------
277
ftdi_sync
278
#( .CLK_DIV(CLK_DIV) )
279
u_sync
280
(
281
    .clk_i(clk_i),
282
    .rst_i(rst_i),
283
 
284
    // FTDI (async FIFO interface)
285
    .ftdi_rxf_i(ftdi_rxf_i),
286
    .ftdi_txe_i(ftdi_txe_i),
287
    .ftdi_siwua_o(ftdi_siwua_o),
288
    .ftdi_wr_o(ftdi_wr_o),
289
    .ftdi_rd_o(ftdi_rd_o),
290
    .ftdi_d_io(ftdi_d_io),
291
 
292
    // Synchronous Interface
293
    .data_o(data_rx_w),
294
    .data_i(data_tx_w),
295
    .wr_i(wr_w),
296
    .rd_i(rd_w),
297
    .wr_accept_o(wr_accept_w),
298
    .rd_ready_o(rx_ready_w)
299
);
300
 
301
//-----------------------------------------------------------------
302
// RD/WR to and from async FTDI I/F
303
//-----------------------------------------------------------------
304
 
305
// Write to FTDI interface in the following states
306
assign wr_w = (state_q == STATE_DATA0) |
307
              (state_q == STATE_DATA1) |
308
              (state_q == STATE_DATA2) |
309
              (state_q == STATE_DATA3) |
310
              (state_q == STATE_GP_RD);
311
 
312
// Accept data in the following states
313
assign rd_w = (state_q == STATE_CMD) |
314
              (state_q == STATE_LEN) |
315
              (state_q == STATE_ADDR0) |
316
              (state_q == STATE_ADDR1) |
317
              (state_q == STATE_ADDR2) |
318
              (state_q == STATE_ADDR3) |
319
              (state_q == STATE_WRITE && !mem_cyc_o) |
320
              (state_q == STATE_GP_WR);
321
 
322
//-----------------------------------------------------------------
323
// Capture length
324
//-----------------------------------------------------------------
325
always @ (posedge rst_i or posedge clk_i)
326
if (rst_i)
327
    len_q       <= {LEN_W{1'b0}};
328
else if (state_q == STATE_CMD && rx_ready_w)
329
    len_q[11:8] <= data_rx_w[`LEN_UPPER_R];
330
else if (state_q == STATE_LEN && rx_ready_w)
331
    len_q[7:0]  <= data_rx_w[`LEN_LOWER_R];
332
else if (state_q == STATE_WRITE && rx_ready_w && !mem_cyc_o)
333
    len_q       <= len_q - {{(LEN_W-1){1'b0}}, 1'b1};
334
else if (state_q == STATE_READ && (mem_cyc_o && mem_ack_i))
335
    len_q       <= len_q - {{(LEN_W-1){1'b0}}, 1'b1};
336
else if (((state_q == STATE_DATA0) || (state_q == STATE_DATA1) || (state_q == STATE_DATA2)) && wr_accept_w)
337
    len_q       <= len_q - {{(LEN_W-1){1'b0}}, 1'b1};
338
 
339
//-----------------------------------------------------------------
340
// Capture addr
341
//-----------------------------------------------------------------
342
always @ (posedge rst_i or posedge clk_i)
343
if (rst_i)
344
    mem_addr_q        <= 'd0;
345
else if (state_q == STATE_ADDR0 && rx_ready_w)
346
    mem_addr_q[31:24] <= data_rx_w;
347
else if (state_q == STATE_ADDR1 && rx_ready_w)
348
    mem_addr_q[23:16] <= data_rx_w;
349
else if (state_q == STATE_ADDR2 && rx_ready_w)
350
    mem_addr_q[15:8]  <= data_rx_w;
351
else if (state_q == STATE_ADDR3 && rx_ready_w)
352
    mem_addr_q[7:0]   <= data_rx_w;
353
// Address increment on every access issued
354
else if (state_q == STATE_WRITE && (mem_cyc_o && mem_ack_i))
355
    mem_addr_q        <= {mem_addr_q[31:2], 2'b0} + 'd4;
356
else if (state_q == STATE_READ && (mem_cyc_o && mem_ack_i))
357
    mem_addr_q        <= {mem_addr_q[31:2], 2'b0} + 'd4;
358
 
359
assign mem_addr_o = {mem_addr_q[ADDR_W-1:2], 2'b0};
360
 
361
//-----------------------------------------------------------------
362
// Data Index
363
//-----------------------------------------------------------------
364
always @ (posedge rst_i or posedge clk_i)
365
if (rst_i)
366
    data_idx_q <= 2'b0;
367
else if (state_q == STATE_ADDR3)
368
    data_idx_q <= data_rx_w[1:0];
369
else if (state_q == STATE_WRITE && rx_ready_w && !mem_cyc_o)
370
    data_idx_q <= data_idx_q + 2'd1;
371
 
372
//-----------------------------------------------------------------
373
// Data Sample
374
//-----------------------------------------------------------------
375
always @ (posedge rst_i or posedge clk_i)
376
if (rst_i)
377
    data_q <= 32'b0;
378
// In idle state, just sample GPIO inputs flops in-case of reads
379
else if (state_q == STATE_IDLE)
380
    data_q <= {{(32-GP_INPUTS){1'b0}}, gp_in_q};
381
// Write to memory
382
else if (state_q == STATE_WRITE && rx_ready_w && !mem_cyc_o)
383
begin
384
    if (LITTLE_ENDIAN)
385
    begin
386
        case (data_idx_q)
387
            2'd0: data_q[7:0]   <= data_rx_w;
388
            2'd1: data_q[15:8]  <= data_rx_w;
389
            2'd2: data_q[23:16] <= data_rx_w;
390
            2'd3: data_q[31:24] <= data_rx_w;
391
        endcase
392
    end
393
    else
394
    begin
395
        case (data_idx_q)
396
            2'd3: data_q[7:0]   <= data_rx_w;
397
            2'd2: data_q[15:8]  <= data_rx_w;
398
            2'd1: data_q[23:16] <= data_rx_w;
399
            2'd0: data_q[31:24] <= data_rx_w;
400
        endcase
401
    end
402
end
403
// Read from memory
404
else if (state_q == STATE_READ && mem_ack_i)
405
begin
406
    if (LITTLE_ENDIAN)
407
        data_q <= mem_data_i;
408
    else
409
        data_q <= {mem_data_i[7:0], mem_data_i[15:8], mem_data_i[23:16], mem_data_i[31:24]};
410
end
411
// Shift data out (read response -> FTDI)
412
else if (((state_q == STATE_DATA0) || (state_q == STATE_DATA1) || (state_q == STATE_DATA2)) && wr_accept_w)
413
begin
414
    data_q <= {8'b0, data_q[31:8]};
415
end
416
 
417
assign data_tx_w  = data_q[7:0];
418
 
419
assign mem_data_o = data_q;
420
 
421
//-----------------------------------------------------------------
422
// Wishbone: STB
423
//-----------------------------------------------------------------
424
always @ (posedge rst_i or posedge clk_i)
425
if (rst_i)
426
    mem_stb_o    <= 1'b0;
427
else if (mem_stb_o)
428
begin
429
    if (!mem_stall_i)
430
        mem_stb_o    <= 1'b0;
431
end
432
// Every 4th byte, issue bus access
433
else if (state_q == STATE_WRITE && rx_ready_w && (data_idx_q == 2'd3 || len_q == 1))
434
    mem_stb_o   <= 1'b1;
435
// Read request
436
else if (state_q == STATE_READ && !mem_cyc_o)
437
    mem_stb_o   <= 1'b1;
438
 
439
//-----------------------------------------------------------------
440
// Wishbone: SEL
441
//-----------------------------------------------------------------
442
reg [3:0] mem_sel_q;
443
reg [3:0] mem_sel_r;
444
 
445
always @ *
446
begin
447
    mem_sel_r = 4'b1111;
448
 
449
    case (data_idx_q)
450
    2'd0: mem_sel_r = 4'b0001;
451
    2'd1: mem_sel_r = 4'b0011;
452
    2'd2: mem_sel_r = 4'b0111;
453
    2'd3: mem_sel_r = 4'b1111;
454
    endcase
455
 
456
    case (mem_addr_q[1:0])
457
    2'd0: mem_sel_r = mem_sel_r & 4'b1111;
458
    2'd1: mem_sel_r = mem_sel_r & 4'b1110;
459
    2'd2: mem_sel_r = mem_sel_r & 4'b1100;
460
    2'd3: mem_sel_r = mem_sel_r & 4'b1000;
461
    endcase
462
end
463
 
464
always @ (posedge rst_i or posedge clk_i)
465
if (rst_i)
466
    mem_sel_q    <= 4'b0;
467
// Idle - reset for read requests
468
else if (state_q == STATE_IDLE)
469
    mem_sel_q   <= 4'b1111;
470
// Every 4th byte, issue bus access
471
else if (state_q == STATE_WRITE && rx_ready_w && (data_idx_q == 2'd3 || len_q == 1))
472
    mem_sel_q   <= mem_sel_r;
473
 
474
assign mem_sel_o  = LITTLE_ENDIAN ? mem_sel_q : {mem_sel_q[0], mem_sel_q[1], mem_sel_q[2], mem_sel_q[3]};
475
 
476
//-----------------------------------------------------------------
477
// Wishbone: WE
478
//-----------------------------------------------------------------
479
always @ (posedge rst_i or posedge clk_i)
480
if (rst_i)
481
    mem_we_o    <= 1'b0;
482
else if (state_q == STATE_CMD && rx_ready_w)
483
    mem_we_o    <= (data_rx_w[`CMD_R] == CMD_WR);
484
 
485
//-----------------------------------------------------------------
486
// Wishbone: CYC
487
//-----------------------------------------------------------------
488
always @ (posedge clk_i or posedge rst_i)
489
if (rst_i == 1'b1)
490
    mem_cyc_q <= 1'b0;
491
else if (mem_stb_o)
492
    mem_cyc_q <= 1'b1;
493
else if (mem_ack_i)
494
    mem_cyc_q <= 1'b0;
495
 
496
assign mem_cyc_o  = mem_stb_o | mem_cyc_q;
497
 
498
//-----------------------------------------------------------------
499
// General Purpose Outputs
500
//-----------------------------------------------------------------
501
always @ (posedge rst_i or posedge clk_i)
502
if (rst_i)
503
    gp_out_q <= {(GP_OUTPUTS){1'b0}};
504
else if (state_q == STATE_GP_WR && rx_ready_w)
505
    gp_out_q <= data_rx_w[GP_OUTPUTS-1:0];
506
 
507
assign gp_o = gp_out_q;
508
 
509
//-----------------------------------------------------------------
510
// General Purpose Inputs
511
//-----------------------------------------------------------------
512
reg [GP_INPUTS-1:0]  gp_in_r;
513
always @ *
514
begin
515
    // GPIO inputs can be normal or pulse capture with clear on read.
516
    // GP_IN_EVENT_MASK indicates which are 'pulse capture' ones.
517
    if ((state_q == STATE_GP_RD) && wr_accept_w)
518
        gp_in_r = gp_i;
519
    else
520
        gp_in_r = (gp_in_q & GP_IN_EVENT_MASK) | gp_i;
521
end
522
 
523
always @ (posedge rst_i or posedge clk_i)
524
if (rst_i)
525
    gp_in_q <= {(GP_INPUTS){1'b0}};
526
else
527
    gp_in_q <= gp_in_r;
528
 
529
endmodule

powered by: WebSVN 2.1.0

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