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

Subversion Repositories usb2uart

[/] [usb2uart/] [trunk/] [rtl/] [usb1_core/] [usb1_pe.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dinesha
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  Protocol Engine                                            ////
4
////  Performs automatic protocol functions                      ////
5
////                                                             ////
6
////  Author: Rudolf Usselmann                                   ////
7
////          rudi@asics.ws                                      ////
8
////                                                             ////
9
////                                                             ////
10
////  Downloaded from: http://www.opencores.org/cores/usb1_funct/////
11
////                                                             ////
12
/////////////////////////////////////////////////////////////////////
13
////                                                             ////
14
//// Copyright (C) 2000-2002 Rudolf Usselmann                    ////
15
////                         www.asics.ws                        ////
16
////                         rudi@asics.ws                       ////
17
////                                                             ////
18
//// This source file may be used and distributed without        ////
19
//// restriction provided that this copyright statement is not   ////
20
//// removed from the file and that any derivative work contains ////
21
//// the original copyright notice and the associated disclaimer.////
22
////                                                             ////
23
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
24
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
25
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
26
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
27
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
28
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
29
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
30
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
31
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
32
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
33
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
34
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
35
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
36
////                                                             ////
37
/////////////////////////////////////////////////////////////////////
38
 
39
//  CVS Log
40
//
41
//  $Id: usb1_pe.v,v 1.1.1.1 2002-09-19 12:07:24 rudi Exp $
42
//
43
//  $Date: 2002-09-19 12:07:24 $
44
//  $Revision: 1.1.1.1 $
45
//  $Author: rudi $
46
//  $Locker:  $
47
//  $State: Exp $
48
//
49
// Change History:
50
//               $Log: not supported by cvs2svn $
51
//
52
//
53
//
54
//
55
//
56
//
57
 
58
`include "usb1_defines.v"
59
 
60
module usb1_pe( clk, rst,
61
 
62
                // UTMI Interfaces
63
                tx_valid, rx_active,
64
 
65
                // PID Information
66
                pid_OUT, pid_IN, pid_SOF, pid_SETUP,
67
                pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA,
68
                pid_ACK, pid_PING,
69
 
70
                // Token Information
71
                token_valid,
72
 
73
                // Receive Data Output
74
                rx_data_done, crc16_err,
75
 
76
                // Packet Assembler Interface
77
                send_token, token_pid_sel,
78
                data_pid_sel,
79
 
80
                // IDMA Interface
81
                rx_dma_en, tx_dma_en,
82
                abort,
83
                idma_done,
84
 
85
                // Register File Interface
86
 
87
                fsel,
88
                ep_sel, match, nse_err,
89
                ep_full, ep_empty,
90
 
91
                int_upid_set, int_crc16_set, int_to_set, int_seqerr_set,
92
                csr,
93
                send_stall
94
 
95
                );
96
 
97
input           clk, rst;
98
input           tx_valid, rx_active;
99
 
100
// Packet Disassembler Interface
101
                // Decoded PIDs (used when token_valid is asserted)
102
input           pid_OUT, pid_IN, pid_SOF, pid_SETUP;
103
input           pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA;
104
input           pid_ACK, pid_PING;
105
 
106
input           token_valid;            // Token is valid
107
 
108
input           rx_data_done;           // Indicates end of a transfer
109
input           crc16_err;              // Data packet CRC 16 error
110
 
111
// Packet Assembler Interface
112
output          send_token;
113
output  [1:0]    token_pid_sel;
114
output  [1:0]    data_pid_sel;
115
 
116
// IDMA Interface
117
output          rx_dma_en;      // Allows the data to be stored
118
output          tx_dma_en;      // Allows for data to be retrieved
119
output          abort;          // Abort Transfer (time_out, crc_err or rx_error)
120
input           idma_done;      // DMA is done indicator
121
 
122
input           ep_full;        // Indicates the endpoints fifo is full
123
input           ep_empty;       // Indicates the endpoints fifo is empty
124
 
125
// Register File interface
126
input           fsel;           // This function is selected
127
input   [3:0]    ep_sel;         // Endpoint Number Input
128
input           match;          // Endpoint Matched
129
output          nse_err;        // no such endpoint error
130
 
131
output          int_upid_set;   // Set unsupported PID interrupt
132
output          int_crc16_set;  // Set CRC16 error interrupt
133
output          int_to_set;     // Set time out interrupt
134
output          int_seqerr_set; // Set PID sequence error interrupt
135
 
136
input   [13:0]   csr;            // Internal CSR Output
137
 
138
input           send_stall;     // Force sending a STALL during setup
139
 
140
 
141
///////////////////////////////////////////////////////////////////
142
//
143
// Local Wires and Registers
144
//
145
 
146
// tx token decoding
147
parameter       ACK   = 0,
148
                NACK  = 1,
149
                STALL = 2,
150
                NYET  = 3;
151
 
152
// State decoding
153
parameter       [9:0]    // synopsys enum state
154
                IDLE    = 10'b000000_0001,
155
                TOKEN   = 10'b000000_0010,
156
                IN      = 10'b000000_0100,
157
                IN2     = 10'b000000_1000,
158
                OUT     = 10'b000001_0000,
159
                OUT2A   = 10'b000010_0000,
160
                OUT2B   = 10'b000100_0000,
161
                UPDATEW = 10'b001000_0000,
162
                UPDATE  = 10'b010000_0000,
163
                UPDATE2 = 10'b100000_0000;
164
 
165
reg     [1:0]    token_pid_sel;
166
reg     [1:0]    token_pid_sel_d;
167
reg             send_token;
168
reg             send_token_d;
169
reg             rx_dma_en, tx_dma_en;
170
reg             int_seqerr_set_d;
171
reg             int_seqerr_set;
172
reg             int_upid_set;
173
 
174
reg             match_r;
175
 
176
// Endpoint Decoding
177
wire            IN_ep, OUT_ep, CTRL_ep;         // Endpoint Types
178
wire            txfr_iso, txfr_bulk, txfr_int;  // Transfer Types
179
 
180
reg     [1:0]    uc_dpd;
181
 
182
// Buffer checks
183
reg     [9:0]    /* synopsys enum state */ state, next_state;
184
// synopsys state_vector state
185
 
186
// PID next and current decoders
187
reg     [1:0]    next_dpid;
188
reg     [1:0]    this_dpid;
189
reg             pid_seq_err;
190
wire    [1:0]    tr_fr_d;
191
 
192
wire    [13:0]   size_next;
193
wire            buf_smaller;
194
 
195
// After sending Data in response to an IN token from host, the
196
// host must reply with an ack. The host has XXXnS to reply.
197
// "rx_ack_to" indicates when this time has expired.
198
// rx_ack_to_clr, clears the timer
199
reg             rx_ack_to_clr;
200
reg             rx_ack_to_clr_d;
201
reg             rx_ack_to;
202
reg     [7:0]    rx_ack_to_cnt;
203
 
204
// After sending a OUT token the host must send a data packet.
205
// The host has XX nS to send the packet. "tx_data_to" indicates
206
// when this time has expired.
207
// tx_data_to_clr, clears the timer
208
wire            tx_data_to_clr;
209
reg             tx_data_to;
210
reg     [7:0]    tx_data_to_cnt;
211
 
212
wire    [7:0]    rx_ack_to_val, tx_data_to_val;
213
 
214
 
215
wire    [1:0]    next_bsel;
216
reg             uc_stat_set_d;
217
reg             uc_dpd_set;
218
 
219
reg             in_token;
220
reg             out_token;
221
reg             setup_token;
222
 
223
wire            in_op, out_op;  // Indicate a IN or OUT operation
224
 
225
reg     [1:0]    allow_pid;
226
 
227
reg             nse_err;
228
reg             abort;
229
 
230
wire    [1:0]    ep_type, txfr_type;
231
 
232
///////////////////////////////////////////////////////////////////
233
//
234
// Misc Logic
235
//
236
 
237
// Endpoint/CSR Decoding
238
assign IN_ep   = csr[9];
239
assign OUT_ep  = csr[10];
240
assign CTRL_ep = csr[11];
241
 
242
assign txfr_iso  = csr[12];
243
assign txfr_bulk = csr[13];
244
assign txfr_int = !csr[12] & !csr[13];
245
 
246
assign ep_type = csr[10:9];
247
assign txfr_type = csr[13:12];
248
 
249
always @(posedge clk)
250
        match_r <= #1 match  & fsel;
251
 
252
// No Such Endpoint Indicator
253
always @(posedge clk)
254
        nse_err <= #1 token_valid & (pid_OUT | pid_IN | pid_SETUP) & !match;
255
 
256
always @(posedge clk)
257
        send_token <= #1 send_token_d;
258
 
259
always @(posedge clk)
260
        token_pid_sel <= #1 token_pid_sel_d;
261
 
262
///////////////////////////////////////////////////////////////////
263
//
264
// Data Pid Storage
265
//
266
 
267
reg     [1:0]    ep0_dpid, ep1_dpid, ep2_dpid, ep3_dpid;
268
reg     [1:0]    ep4_dpid, ep5_dpid, ep6_dpid, ep7_dpid;
269
 
270
always @(posedge clk or negedge rst)
271
        if(!rst)                                ep0_dpid <= 2'b00;
272
        else
273
        if(uc_dpd_set & (ep_sel == 4'h0))       ep0_dpid <= next_dpid;
274
 
275
always @(posedge clk or negedge rst)
276
        if(!rst)                                ep1_dpid <= 2'b00;
277
        else
278
        if(uc_dpd_set & (ep_sel == 4'h1))       ep1_dpid <= next_dpid;
279
 
280
always @(posedge clk or negedge rst)
281
        if(!rst)                                ep2_dpid <= 2'b00;
282
        else
283
        if(uc_dpd_set & (ep_sel == 4'h2))       ep2_dpid <= next_dpid;
284
 
285
always @(posedge clk or negedge rst)
286
        if(!rst)                                ep3_dpid <= 2'b00;
287
        else
288
        if(uc_dpd_set & (ep_sel == 4'h3))       ep3_dpid <= next_dpid;
289
 
290
always @(posedge clk or negedge rst)
291
        if(!rst)                                ep4_dpid <= 2'b00;
292
        else
293
        if(uc_dpd_set & (ep_sel == 4'h4))       ep4_dpid <= next_dpid;
294
 
295
always @(posedge clk or negedge rst)
296
        if(!rst)                                ep5_dpid <= 2'b00;
297
        else
298
        if(uc_dpd_set & (ep_sel == 4'h5))       ep5_dpid <= next_dpid;
299
 
300
always @(posedge clk or negedge rst)
301
        if(!rst)                                ep6_dpid <= 2'b00;
302
        else
303
        if(uc_dpd_set & (ep_sel == 4'h6))       ep6_dpid <= next_dpid;
304
 
305
always @(posedge clk or negedge rst)
306
        if(!rst)                                ep7_dpid <= 2'b00;
307
        else
308
        if(uc_dpd_set & (ep_sel == 4'h7))       ep7_dpid <= next_dpid;
309
 
310
always @(posedge clk)
311
        case(ep_sel)
312
           4'h0: uc_dpd <= ep0_dpid;
313
           4'h1: uc_dpd <= ep1_dpid;
314
           4'h2: uc_dpd <= ep2_dpid;
315
           4'h3: uc_dpd <= ep3_dpid;
316
           4'h4: uc_dpd <= ep4_dpid;
317
           4'h5: uc_dpd <= ep5_dpid;
318
           4'h6: uc_dpd <= ep6_dpid;
319
           4'h7: uc_dpd <= ep7_dpid;
320
        endcase
321
 
322
///////////////////////////////////////////////////////////////////
323
//
324
// Data Pid Sequencer
325
//
326
 
327
assign tr_fr_d = 2'h0;
328
 
329
always @(posedge clk)   // tr/mf:ep/type:tr/type:last dpd
330
        casex({tr_fr_d,ep_type,txfr_type,uc_dpd})       // synopsys full_case parallel_case
331
           8'b0?_01_01_??: next_dpid <= #1 2'b00;       // ISO txfr. IN, 1 tr/mf
332
 
333
           8'b10_01_01_?0: next_dpid <= #1 2'b01;        // ISO txfr. IN, 2 tr/mf
334
           8'b10_01_01_?1: next_dpid <= #1 2'b00;       // ISO txfr. IN, 2 tr/mf
335
 
336
           8'b11_01_01_00: next_dpid <= #1 2'b01;       // ISO txfr. IN, 3 tr/mf
337
           8'b11_01_01_01: next_dpid <= #1 2'b10;       // ISO txfr. IN, 3 tr/mf
338
           8'b11_01_01_10: next_dpid <= #1 2'b00;       // ISO txfr. IN, 3 tr/mf
339
 
340
           8'b0?_10_01_??: next_dpid <= #1 2'b00;       // ISO txfr. OUT, 1 tr/mf
341
 
342
           8'b10_10_01_??:                              // ISO txfr. OUT, 2 tr/mf
343
                           begin        // Resynchronize in case of PID error
344
                                case({pid_MDATA, pid_DATA1})    // synopsys full_case parallel_case
345
                                  2'b10: next_dpid <= #1 2'b01;
346
                                  2'b01: next_dpid <= #1 2'b00;
347
                                endcase
348
                           end
349
 
350
           8'b11_10_01_00:                              // ISO txfr. OUT, 3 tr/mf
351
                           begin        // Resynchronize in case of PID error
352
                                case({pid_MDATA, pid_DATA2})    // synopsys full_case parallel_case
353
                                  2'b10: next_dpid <= #1 2'b01;
354
                                  2'b01: next_dpid <= #1 2'b00;
355
                                endcase
356
                           end
357
           8'b11_10_01_01:                              // ISO txfr. OUT, 3 tr/mf
358
                           begin        // Resynchronize in case of PID error
359
                                case({pid_MDATA, pid_DATA2})    // synopsys full_case parallel_case
360
                                  2'b10: next_dpid <= #1 2'b10;
361
                                  2'b01: next_dpid <= #1 2'b00;
362
                                endcase
363
                           end
364
           8'b11_10_01_10:                              // ISO txfr. OUT, 3 tr/mf
365
                           begin        // Resynchronize in case of PID error
366
                                case({pid_MDATA, pid_DATA2})    // synopsys full_case parallel_case
367
                                  2'b10: next_dpid <= #1 2'b01;
368
                                  2'b01: next_dpid <= #1 2'b00;
369
                                endcase
370
                           end
371
 
372
           8'b??_01_00_?0,                               // IN/OUT endpoint only
373
           8'b??_10_00_?0: next_dpid <= #1 2'b01;        // INT transfers
374
 
375
           8'b??_01_00_?1,                              // IN/OUT endpoint only
376
           8'b??_10_00_?1: next_dpid <= #1 2'b00;       // INT transfers
377
 
378
           8'b??_01_10_?0,                               // IN/OUT endpoint only
379
           8'b??_10_10_?0: next_dpid <= #1 2'b01;        // BULK transfers
380
 
381
           8'b??_01_10_?1,                              // IN/OUT endpoint only
382
           8'b??_10_10_?1: next_dpid <= #1 2'b00;       // BULK transfers
383
 
384
           8'b??_00_??_??:                              // CTRL Endpoint
385
                casex({setup_token, in_op, out_op, uc_dpd})     // synopsys full_case parallel_case
386
                   5'b1_??_??: next_dpid <= #1 2'b11;   // SETUP operation
387
                   5'b0_10_0?: next_dpid <= #1 2'b11;   // IN operation
388
                   5'b0_10_1?: next_dpid <= #1 2'b01;   // IN operation
389
                   5'b0_01_?0: next_dpid <= #1 2'b11;    // OUT operation
390
                   5'b0_01_?1: next_dpid <= #1 2'b10;   // OUT operation
391
                endcase
392
 
393
        endcase
394
 
395
// Current PID decoder
396
 
397
// Allow any PID for ISO. transfers when mode full speed or tr_fr is zero
398
always @(pid_DATA0 or pid_DATA1 or pid_DATA2 or pid_MDATA)
399
        case({pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA} ) // synopsys full_case parallel_case
400
           4'b1000: allow_pid = 2'b00;
401
           4'b0100: allow_pid = 2'b01;
402
           4'b0010: allow_pid = 2'b10;
403
           4'b0001: allow_pid = 2'b11;
404
        endcase
405
 
406
always @(posedge clk)   // tf/mf:ep/type:tr/type:last dpd
407
        casex({tr_fr_d,ep_type,txfr_type,uc_dpd})       // synopsys full_case parallel_case
408
           8'b0?_01_01_??: this_dpid <= #1 2'b00;       // ISO txfr. IN, 1 tr/mf
409
 
410
           8'b10_01_01_?0: this_dpid <= #1 2'b01;        // ISO txfr. IN, 2 tr/mf
411
           8'b10_01_01_?1: this_dpid <= #1 2'b00;       // ISO txfr. IN, 2 tr/mf
412
 
413
           8'b11_01_01_00: this_dpid <= #1 2'b10;       // ISO txfr. IN, 3 tr/mf
414
           8'b11_01_01_01: this_dpid <= #1 2'b01;       // ISO txfr. IN, 3 tr/mf
415
           8'b11_01_01_10: this_dpid <= #1 2'b00;       // ISO txfr. IN, 3 tr/mf
416
 
417
           8'b00_10_01_??: this_dpid <= #1 allow_pid;   // ISO txfr. OUT, 0 tr/mf
418
           8'b01_10_01_??: this_dpid <= #1 2'b00;       // ISO txfr. OUT, 1 tr/mf
419
 
420
           8'b10_10_01_?0: this_dpid <= #1 2'b11;        // ISO txfr. OUT, 2 tr/mf
421
           8'b10_10_01_?1: this_dpid <= #1 2'b01;       // ISO txfr. OUT, 2 tr/mf
422
 
423
           8'b11_10_01_00: this_dpid <= #1 2'b11;       // ISO txfr. OUT, 3 tr/mf
424
           8'b11_10_01_01: this_dpid <= #1 2'b11;       // ISO txfr. OUT, 3 tr/mf
425
           8'b11_10_01_10: this_dpid <= #1 2'b10;       // ISO txfr. OUT, 3 tr/mf
426
 
427
           8'b??_01_00_?0,                               // IN/OUT endpoint only
428
           8'b??_10_00_?0: this_dpid <= #1 2'b00;        // INT transfers
429
           8'b??_01_00_?1,                              // IN/OUT endpoint only
430
           8'b??_10_00_?1: this_dpid <= #1 2'b01;       // INT transfers
431
 
432
           8'b??_01_10_?0,                               // IN/OUT endpoint only
433
           8'b??_10_10_?0: this_dpid <= #1 2'b00;        // BULK transfers
434
           8'b??_01_10_?1,                              // IN/OUT endpoint only
435
           8'b??_10_10_?1: this_dpid <= #1 2'b01;       // BULK transfers
436
 
437
           8'b??_00_??_??:                              // CTRL Endpoint
438
                casex({setup_token,in_op, out_op, uc_dpd})      // synopsys full_case parallel_case
439
                   5'b1_??_??: this_dpid <= #1 2'b00;   // SETUP operation
440
                   5'b0_10_0?: this_dpid <= #1 2'b00;   // IN operation
441
                   5'b0_10_1?: this_dpid <= #1 2'b01;   // IN operation
442
                   5'b0_01_?0: this_dpid <= #1 2'b00;    // OUT operation
443
                   5'b0_01_?1: this_dpid <= #1 2'b01;   // OUT operation
444
                endcase
445
        endcase
446
 
447
// Assign PID for outgoing packets
448
assign data_pid_sel = this_dpid;
449
 
450
// Verify PID for incoming data packets
451
always @(posedge clk)
452
        pid_seq_err <= #1 !(    (this_dpid==2'b00 & pid_DATA0) |
453
                                (this_dpid==2'b01 & pid_DATA1) |
454
                                (this_dpid==2'b10 & pid_DATA2) |
455
                                (this_dpid==2'b11 & pid_MDATA)  );
456
 
457
///////////////////////////////////////////////////////////////////
458
//
459
// IDMA Setup & src/dst buffer select
460
//
461
 
462
// For Control endpoints things are different:
463
// buffer0 is used for OUT (incoming) data packets
464
// buffer1 is used for IN (outgoing) data packets
465
 
466
// Keep track of last token for control endpoints
467
always @(posedge clk or negedge rst)
468
        if(!rst)                in_token <= #1 1'b0;
469
        else
470
        if(pid_IN)              in_token <= #1 1'b1;
471
        else
472
        if(pid_OUT | pid_SETUP) in_token <= #1 1'b0;
473
 
474
always @(posedge clk or negedge rst)
475
        if(!rst)                out_token <= #1 1'b0;
476
        else
477
        if(pid_OUT | pid_SETUP) out_token <= #1 1'b1;
478
        else
479
        if(pid_IN)              out_token <= #1 1'b0;
480
 
481
always @(posedge clk or negedge rst)
482
        if(!rst)                setup_token <= #1 1'b0;
483
        else
484
        if(pid_SETUP)           setup_token <= #1 1'b1;
485
        else
486
        if(pid_OUT | pid_IN)    setup_token <= #1 1'b0;
487
 
488
// Indicates if we are performing an IN operation
489
assign  in_op = IN_ep | (CTRL_ep & in_token);
490
 
491
// Indicates if we are performing an OUT operation
492
assign  out_op = OUT_ep | (CTRL_ep & out_token);
493
 
494
 
495
///////////////////////////////////////////////////////////////////
496
//
497
// Determine if packet is to small or to large
498
// This is used to NACK and ignore packet for OUT endpoints
499
//
500
 
501
 
502
///////////////////////////////////////////////////////////////////
503
//
504
// Register File Update Logic
505
//
506
 
507
always @(posedge clk)
508
        uc_dpd_set <= #1 uc_stat_set_d;
509
 
510
// Abort signal
511
always @(posedge clk)
512
        abort <= #1 match & fsel & (state != IDLE);
513
 
514
///////////////////////////////////////////////////////////////////
515
//
516
// TIME OUT TIMERS
517
//
518
 
519
// After sending Data in response to an IN token from host, the
520
// host must reply with an ack. The host has 622nS in Full Speed
521
// mode and 400nS in High Speed mode to reply.
522
// "rx_ack_to" indicates when this time has expired.
523
// rx_ack_to_clr, clears the timer
524
 
525
always @(posedge clk)
526
        rx_ack_to_clr <= #1 tx_valid | rx_ack_to_clr_d;
527
 
528
always @(posedge clk)
529
        if(rx_ack_to_clr)       rx_ack_to_cnt <= #1 8'h0;
530
        else                    rx_ack_to_cnt <= #1 rx_ack_to_cnt + 8'h1;
531
 
532
always @(posedge clk)
533
        rx_ack_to <= #1 (rx_ack_to_cnt == rx_ack_to_val);
534
 
535
assign rx_ack_to_val = `USBF_RX_ACK_TO_VAL_FS;
536
 
537
// After sending a OUT token the host must send a data packet.
538
// The host has 622nS in Full Speed mode and 400nS in High Speed
539
// mode to send the data packet.
540
// "tx_data_to" indicates when this time has expired.
541
// "tx_data_to_clr" clears the timer
542
 
543
assign  tx_data_to_clr = rx_active;
544
 
545
always @(posedge clk)
546
        if(tx_data_to_clr)      tx_data_to_cnt <= #1 8'h0;
547
        else                    tx_data_to_cnt <= #1 tx_data_to_cnt + 8'h1;
548
 
549
always @(posedge clk)
550
        tx_data_to <= #1 (tx_data_to_cnt == tx_data_to_val);
551
 
552
assign tx_data_to_val = `USBF_TX_DATA_TO_VAL_FS;
553
 
554
///////////////////////////////////////////////////////////////////
555
//
556
// Interrupts
557
//
558
reg     pid_OUT_r, pid_IN_r, pid_PING_r, pid_SETUP_r;
559
 
560
always @(posedge clk)
561
        pid_OUT_r <= #1 pid_OUT;
562
 
563
always @(posedge clk)
564
        pid_IN_r <= #1 pid_IN;
565
 
566
always @(posedge clk)
567
        pid_PING_r <= #1 pid_PING;
568
 
569
always @(posedge clk)
570
        pid_SETUP_r <= #1 pid_SETUP;
571
 
572
always @(posedge clk)
573
        int_upid_set <= #1 match_r & !pid_SOF & (
574
                                ( OUT_ep & !(pid_OUT_r | pid_PING_r))           |
575
                                (  IN_ep &  !pid_IN_r)                          |
576
                                (CTRL_ep & !(pid_IN_r | pid_OUT_r | pid_PING_r | pid_SETUP_r))
577
                                        );
578
 
579
 
580
assign int_to_set  = ((state == IN2) & rx_ack_to) | ((state == OUT) & tx_data_to);
581
 
582
assign int_crc16_set = rx_data_done & crc16_err;
583
 
584
always @(posedge clk)
585
        int_seqerr_set <= #1 int_seqerr_set_d;
586
 
587
reg     send_stall_r;
588
 
589
always @(posedge clk or negedge rst)
590
        if(!rst)        send_stall_r <= #1 1'b0;
591
        else
592
        if(send_stall)  send_stall_r <= #1 1'b1;
593
        else
594
        if(send_token)  send_stall_r <= #1 1'b0;
595
 
596
///////////////////////////////////////////////////////////////////
597
//
598
// Main Protocol State Machine
599
//
600
 
601
always @(posedge clk or negedge rst)
602
        if(!rst)        state <= #1 IDLE;
603
        else
604
        if(match)       state <= #1 IDLE;
605
        else            state <= #1 next_state;
606
 
607
always @(state or
608
        pid_seq_err or idma_done or ep_full or ep_empty or
609
        token_valid or pid_ACK or rx_data_done or
610
        tx_data_to or crc16_err or
611
        rx_ack_to or pid_PING or txfr_iso or txfr_int or
612
        CTRL_ep or pid_IN or pid_OUT or IN_ep or OUT_ep or pid_SETUP or pid_SOF
613
        or match_r or abort or send_stall_r
614
        )
615
   begin
616
        next_state = state;
617
        token_pid_sel_d = ACK;
618
        send_token_d = 1'b0;
619
        rx_dma_en = 1'b0;
620
        tx_dma_en = 1'b0;
621
        uc_stat_set_d = 1'b0;
622
        rx_ack_to_clr_d = 1'b1;
623
        int_seqerr_set_d = 1'b0;
624
 
625
        case(state)     // synopsys full_case parallel_case
626
           IDLE:
627
                   begin
628
// synopsys translate_off
629
`ifdef USBF_VERBOSE_DEBUG
630
                $display("PE: Entered state IDLE (%t)", $time);
631
`endif
632
`ifdef USBF_DEBUG
633
                if(rst & match_r & !pid_SOF)
634
                begin
635
                if(match_r === 1'bx)    $display("ERROR: IDLE: match_r is unknown. (%t)", $time);
636
                if(pid_SOF === 1'bx)    $display("ERROR: IDLE: pid_SOF is unknown. (%t)", $time);
637
                if(CTRL_ep === 1'bx)    $display("ERROR: IDLE: CTRL_ep is unknown. (%t)", $time);
638
                if(pid_IN === 1'bx)     $display("ERROR: IDLE: pid_IN is unknown. (%t)", $time);
639
                if(pid_OUT === 1'bx)    $display("ERROR: IDLE: pid_OUT is unknown. (%t)", $time);
640
                if(pid_SETUP === 1'bx)  $display("ERROR: IDLE: pid_SETUP is unknown. (%t)", $time);
641
                if(pid_PING === 1'bx)   $display("ERROR: IDLE: pid_PING is unknown. (%t)", $time);
642
                if(IN_ep === 1'bx)      $display("ERROR: IDLE: IN_ep is unknown. (%t)", $time);
643
                if(OUT_ep === 1'bx)     $display("ERROR: IDLE: OUT_ep is unknown. (%t)", $time);
644
                end
645
`endif
646
// synopsys translate_on
647
 
648
                        if(match_r & !pid_SOF)
649
                           begin
650
/*
651
                                if(ep_stall)            // Halt Forced send STALL
652
                                   begin
653
                                        token_pid_sel_d = STALL;
654
                                        send_token_d = 1'b1;
655
                                        next_state = TOKEN;
656
                                   end
657
                                else
658
*/
659
                                if(IN_ep | (CTRL_ep & pid_IN))
660
                                   begin
661
                                        if(txfr_int & ep_empty)
662
                                           begin
663
                                                token_pid_sel_d = NACK;
664
                                                send_token_d = 1'b1;
665
                                                next_state = TOKEN;
666
                                           end
667
                                        else
668
                                           begin
669
                                                tx_dma_en = 1'b1;
670
                                                next_state = IN;
671
                                           end
672
                                   end
673
                                else
674
                                if(OUT_ep | (CTRL_ep & (pid_OUT | pid_SETUP)))
675
                                   begin
676
                                        rx_dma_en = 1'b1;
677
                                        next_state = OUT;
678
                                   end
679
                           end
680
                   end
681
 
682
           TOKEN:
683
                   begin
684
// synopsys translate_off
685
`ifdef USBF_VERBOSE_DEBUG
686
                $display("PE: Entered state TOKEN (%t)", $time);
687
`endif
688
// synopsys translate_on
689
                        next_state = IDLE;
690
                   end
691
 
692
           IN:
693
                   begin
694
// synopsys translate_off
695
`ifdef USBF_VERBOSE_DEBUG
696
                $display("PE: Entered state IN (%t)", $time);
697
`endif
698
`ifdef USBF_DEBUG
699
                if(idma_done === 1'bx)  $display("ERROR: IN: idma_done is unknown. (%t)", $time);
700
                if(txfr_iso === 1'bx)   $display("ERROR: IN: txfr_iso is unknown. (%t)", $time);
701
`endif
702
// synopsys translate_on
703
                        rx_ack_to_clr_d = 1'b0;
704
                        if(idma_done)
705
                           begin
706
                                if(txfr_iso)    next_state = UPDATE;
707
                                else            next_state = IN2;
708
                           end
709
 
710
                   end
711
           IN2:
712
                   begin
713
// synopsys translate_off
714
`ifdef USBF_VERBOSE_DEBUG
715
                $display("PE: Entered state IN2 (%t)", $time);
716
`endif
717
`ifdef USBF_DEBUG
718
                if(rx_ack_to === 1'bx)  $display("ERROR: IN2: rx_ack_to is unknown. (%t)", $time);
719
                if(token_valid === 1'bx)$display("ERROR: IN2: token_valid is unknown. (%t)", $time);
720
                if(pid_ACK === 1'bx)    $display("ERROR: IN2: pid_ACK is unknown. (%t)", $time);
721
`endif
722
// synopsys translate_on
723
                        rx_ack_to_clr_d = 1'b0;
724
                        // Wait for ACK from HOST or Timeout
725
                        if(rx_ack_to)   next_state = IDLE;
726
                        else
727
                        if(token_valid & pid_ACK)
728
                           begin
729
                                next_state = UPDATE;
730
                           end
731
                   end
732
 
733
           OUT:
734
                   begin
735
// synopsys translate_off
736
`ifdef USBF_VERBOSE_DEBUG
737
                $display("PE: Entered state OUT (%t)", $time);
738
`endif
739
`ifdef USBF_DEBUG
740
                if(tx_data_to === 1'bx) $display("ERROR: OUT: tx_data_to is unknown. (%t)", $time);
741
                if(crc16_err === 1'bx)  $display("ERROR: OUT: crc16_err is unknown. (%t)", $time);
742
                if(abort === 1'bx)      $display("ERROR: OUT: abort is unknown. (%t)", $time);
743
                if(rx_data_done === 1'bx)$display("ERROR: OUT: rx_data_done is unknown. (%t)", $time);
744
                if(txfr_iso === 1'bx)   $display("ERROR: OUT: txfr_iso is unknown. (%t)", $time);
745
                if(pid_seq_err === 1'bx)$display("ERROR: OUT: rx_data_done is unknown. (%t)", $time);
746
`endif
747
// synopsys translate_on
748
                        if(tx_data_to | crc16_err | abort )
749
                                next_state = IDLE;
750
                        else
751
                        if(rx_data_done)
752
                           begin                // Send Ack
753
                                if(txfr_iso)
754
                                   begin
755
                                        if(pid_seq_err)         int_seqerr_set_d = 1'b1;
756
                                        next_state = UPDATEW;
757
                                   end
758
                                else            next_state = OUT2A;
759
                           end
760
                   end
761
 
762
           OUT2B:
763
                   begin        // This is a delay State to NACK to small or to
764
                                // large packets. this state could be skipped
765
// synopsys translate_off
766
`ifdef USBF_VERBOSE_DEBUG
767
                $display("PE: Entered state OUT2B (%t)", $time);
768
`endif
769
`ifdef USBF_DEBUG
770
                if(abort === 1'bx)      $display("ERROR: OUT2A: abort is unknown. (%t)", $time);
771
`endif
772
// synopsys translate_on
773
                        if(abort)       next_state = IDLE;
774
                        else            next_state = OUT2B;
775
                   end
776
           OUT2A:
777
                   begin        // Send ACK/NACK/NYET
778
// synopsys translate_off
779
`ifdef USBF_VERBOSE_DEBUG
780
                $display("PE: Entered state OUT2A (%t)", $time);
781
`endif
782
`ifdef USBF_DEBUG
783
                if(abort === 1'bx)      $display("ERROR: OUT2A: abort is unknown. (%t)", $time);
784
                if(pid_seq_err === 1'bx)$display("ERROR: OUT2A: rx_data_done is unknown. (%t)", $time);
785
`endif
786
// synopsys translate_on
787
                        if(abort)       next_state = IDLE;
788
                        else
789
 
790
                        if(send_stall_r)
791
                           begin
792
                                token_pid_sel_d = STALL;
793
                                send_token_d = 1'b1;
794
                                next_state = IDLE;
795
                           end
796
                        else
797
                        if(ep_full)
798
                           begin
799
                                token_pid_sel_d = NACK;
800
                                send_token_d = 1'b1;
801
                                next_state = IDLE;
802
                           end
803
                        else
804
                           begin
805
                                token_pid_sel_d = ACK;
806
                                send_token_d = 1'b1;
807
                                if(pid_seq_err) next_state = IDLE;
808
                                else            next_state = UPDATE;
809
                           end
810
                   end
811
 
812
           UPDATEW:
813
                   begin
814
// synopsys translate_off
815
`ifdef USBF_VERBOSE_DEBUG
816
                $display("PE: Entered state UPDATEW (%t)", $time);
817
`endif
818
// synopsys translate_on
819
                        next_state = UPDATE;
820
                   end
821
 
822
           UPDATE:
823
                   begin
824
// synopsys translate_off
825
`ifdef USBF_VERBOSE_DEBUG
826
                $display("PE: Entered state UPDATE (%t)", $time);
827
`endif
828
// synopsys translate_on
829
                        uc_stat_set_d = 1'b1;
830
                        next_state = IDLE;
831
                   end
832
        endcase
833
   end
834
 
835
endmodule
836
 

powered by: WebSVN 2.1.0

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