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

Subversion Repositories usb11

[/] [usb11/] [trunk/] [rtl/] [systemc/] [usb_pe_sie.cpp] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfoltran
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  USB Protocol Engine                                        ////
4
////  Performs automatic protocol functions                      ////
5
////                                                             ////
6
////  SystemC Version: usb_pe_sie.cpp                            ////
7
////  Author: Alfredo Luiz Foltran Fialho                        ////
8
////          alfoltran@ig.com.br                                ////
9
////                                                             ////
10
////                                                             ////
11
/////////////////////////////////////////////////////////////////////
12
////                                                             ////
13
//// Verilog Version: usb1_pe.v                                  ////
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
#include "systemc.h"
40
#include "usb_pe_sie.h"
41
 
42
// Endpoint/CSR Decoding
43
void usb_pe_sie::csr_decoder(void) {
44
        IN_ep.write(csr.read()[9]);
45
        OUT_ep.write(csr.read()[10]);
46
        CTRL_ep.write(csr.read()[11]);
47
        txfr_iso.write(csr.read()[12]);
48
        txfr_bulk.write(csr.read()[13]);
49
        txfr_int.write(!csr.read()[12] && !csr.read()[13]);
50
        ep_type.write(csr.read().range(10, 9));
51
        txfr_type.write(csr.read().range(13, 12));
52
}
53
 
54
void usb_pe_sie::match_up(void) {
55
        match_r.write(match.read() && fsel.read());
56
}
57
 
58
// No such endpoint indicator
59
void usb_pe_sie::nse_err_up(void) {
60
        nse_err.write(token_valid.read() && (pid_OUT.read() || pid_IN.read() || pid_SETUP.read()) && !match.read());
61
}
62
 
63
void usb_pe_sie::send_token_up(void) {
64
        send_token.write(send_token_d.read());
65
}
66
 
67
void usb_pe_sie::token_pid_sel_up(void) {
68
        token_pid_sel.write(token_pid_sel_d.read());
69
}
70
 
71
// Data PID storage
72
void usb_pe_sie::ep0_dpid_up(void) {
73
        if (!rst.read())
74
                ep0_dpid.write(0);
75
        else if (uc_dpd_set.read() && (ep_sel.read() == 0))
76
                ep0_dpid.write(next_dpid.read());
77
}
78
 
79
void usb_pe_sie::ep1_dpid_up(void) {
80
        if (!rst.read())
81
                ep1_dpid.write(0);
82
        else if (uc_dpd_set.read() && (ep_sel.read() == 1))
83
                ep1_dpid.write(next_dpid.read());
84
}
85
 
86
void usb_pe_sie::ep2_dpid_up(void) {
87
        if (!rst.read())
88
                ep2_dpid.write(0);
89
        else if (uc_dpd_set.read() && (ep_sel.read() == 2))
90
                ep2_dpid.write(next_dpid.read());
91
}
92
 
93
void usb_pe_sie::ep3_dpid_up(void) {
94
        if (!rst.read())
95
                ep3_dpid.write(0);
96
        else if (uc_dpd_set.read() && (ep_sel.read() == 3))
97
                ep3_dpid.write(next_dpid.read());
98
}
99
 
100
void usb_pe_sie::ep4_dpid_up(void) {
101
        if (!rst.read())
102
                ep4_dpid.write(0);
103
        else if (uc_dpd_set.read() && (ep_sel.read() == 4))
104
                ep4_dpid.write(next_dpid.read());
105
}
106
 
107
void usb_pe_sie::ep5_dpid_up(void) {
108
        if (!rst.read())
109
                ep5_dpid.write(0);
110
        else if (uc_dpd_set.read() && (ep_sel.read() == 5))
111
                ep5_dpid.write(next_dpid.read());
112
}
113
 
114
void usb_pe_sie::ep6_dpid_up(void) {
115
        if (!rst.read())
116
                ep6_dpid.write(0);
117
        else if (uc_dpd_set.read() && (ep_sel.read() == 6))
118
                ep6_dpid.write(next_dpid.read());
119
}
120
 
121
void usb_pe_sie::ep7_dpid_up(void) {
122
        if (!rst.read())
123
                ep7_dpid.write(0);
124
        else if (uc_dpd_set.read() && (ep_sel.read() == 7))
125
                ep7_dpid.write(next_dpid.read());
126
}
127
 
128
void usb_pe_sie::uc_dpd_up(void) {
129
        switch (ep_sel.read()) {
130
                case 0:  uc_dpd.write(ep0_dpid.read()); break;
131
                case 1: uc_dpd.write(ep1_dpid.read()); break;
132
                case 2: uc_dpd.write(ep2_dpid.read()); break;
133
                case 3: uc_dpd.write(ep3_dpid.read()); break;
134
                case 4: uc_dpd.write(ep4_dpid.read()); break;
135
                case 5: uc_dpd.write(ep5_dpid.read()); break;
136
                case 6: uc_dpd.write(ep6_dpid.read()); break;
137
                case 7: uc_dpd.write(ep7_dpid.read()); break;
138
        }
139
}
140
 
141
// Data PID sequencer
142
void usb_pe_sie::sq_statemachine(void) {
143
        sc_uint<8> sel1;
144
        sc_uint<5> sel2;
145
        sc_uint<2> sel_d1, sel_d2;
146
 
147
        // tr/mf:ep/type:tr/type:last dpd
148
        sel1 = ((sc_uint<2>)tr_fr_d.read(), (sc_uint<2>)ep_type.read(), (sc_uint<2>)txfr_type.read(), (sc_uint<2>)uc_dpd.read());
149
 
150
        // CTRL Endpoint Selector
151
        sel2 = ((sc_uint<1>)setup_token.read(), (sc_uint<1>)in_op.read(), (sc_uint<1>)out_op.read(), (sc_uint<2>)uc_dpd.read());
152
 
153
        // Sync1 Selector
154
        sel_d1 = ((sc_uint<1>)pid_MDATA.read(), (sc_uint<1>)pid_DATA1.read());
155
 
156
        // Sync2 Selector
157
        sel_d2 = ((sc_uint<1>)pid_MDATA.read(), (sc_uint<1>)pid_DATA2.read());
158
 
159
        switch (sel1) {// synopsys full_case parallel_case
160
 
161
                // 0X_01_01_XX -> ISO txfr. IN, 1 tr/mf
162
                case 0x14:
163
                case 0x15:
164
                case 0x16:
165
                case 0x17:
166
                case 0x54:
167
                case 0x55:
168
                case 0x56:
169
                case 0x57:      next_dpid.write(0);
170
                                        break;
171
 
172
                // 10_01_01_X0 -> ISO txfr. IN, 2 tr/mf
173
                case 0x94:
174
                case 0x96:      next_dpid.write(1);
175
                                        break;
176
 
177
                // 10_01_01_X1 -> ISO txfr. IN, 2 tr/mf
178
                case 0x95:
179
                case 0x97:      next_dpid.write(0);
180
                                        break;
181
 
182
                // 11_01_01_00 -> ISO txfr. IN, 3 tr/mf
183
                case 0xd4:      next_dpid.write(1);
184
                                        break;
185
 
186
                // 11_01_01_01 -> ISO txfr. IN, 3 tr/mf
187
                case 0xd5:      next_dpid.write(2);
188
                                        break;
189
 
190
                // 11_01_01_10 -> ISO txfr. IN, 3 tr/mf
191
                case 0xd6:      next_dpid.write(0);
192
                                        break;
193
 
194
                // 0X_10_01_XX -> ISO txfr. OUT, 1 tr/mf
195
                case 0x24:
196
                case 0x25:
197
                case 0x26:
198
                case 0x27:
199
                case 0x64:
200
                case 0x65:
201
                case 0x66:
202
                case 0x67:      next_dpid.write(0);
203
                                        break;
204
 
205
                // 10_10_01_XX -> ISO txfr. OUT, 2 tr/mf
206
                case 0xa4:
207
                case 0xa5:
208
                case 0xa6:      // Resynchronize in case of PID error
209
                case 0xa7:      switch (sel_d1) {// synopsys full_case parallel_case
210
                                                case 2: next_dpid.write(1); break;
211
                                                case 1: next_dpid.write(0); break;
212
                                        }
213
                                        break;
214
 
215
                // 11_10_01_00 -> ISO txfr. OUT, 3 tr/mf
216
                case 0xe4:      // Resynchronize in case of PID error
217
                                        switch (sel_d2) {// synopsys full_case parallel_case
218
                                                case 2: next_dpid.write(1); break;
219
                                                case 1: next_dpid.write(0); break;
220
                                        }
221
                                        break;
222
 
223
                // 11_10_01_01 -> ISO txfr. OUT, 3 tr/mf
224
                case 0xe5:      // Resynchronize in case of PID error
225
                                        switch (sel_d2) {// synopsys full_case parallel_case
226
                                                case 2: next_dpid.write(2); break;
227
                                                case 1: next_dpid.write(0); break;
228
                                        }
229
                                        break;
230
 
231
                // 11_10_01_10 -> ISO txfr. OUT, 3 tr/mf
232
                case 0xe6:      // Resynchronize in case of PID error
233
                                        switch (sel_d2) {// synopsys full_case parallel_case
234
                                                case 2: next_dpid.write(1); break;
235
                                                case 1: next_dpid.write(0); break;
236
                                        }
237
                                        break;
238
 
239
                // XX_01_00_X0 or XX_10_00_X0 -> IN/OUT endpoint only
240
                case 0x10:
241
                case 0x12:
242
                case 0x50:
243
                case 0x52:
244
                case 0x90:
245
                case 0x92:
246
                case 0xd0:
247
                case 0xd2:
248
                case 0x20:
249
                case 0x22:
250
                case 0x60:
251
                case 0x62:
252
                case 0xa0:
253
                case 0xa2:
254
                case 0xe0:
255
                case 0xe2:      next_dpid.write(1);     // INT transfers
256
                                        break;
257
 
258
                // XX_01_00_X1 or XX_10_00_X1 -> IN/OUT endpoint only
259
                case 0x11:
260
                case 0x13:
261
                case 0x51:
262
                case 0x53:
263
                case 0x91:
264
                case 0x93:
265
                case 0xd1:
266
                case 0xd3:
267
                case 0x21:
268
                case 0x23:
269
                case 0x61:
270
                case 0x63:
271
                case 0xa1:
272
                case 0xa3:
273
                case 0xe1:
274
                case 0xe3:      next_dpid.write(0);      // INT transfers
275
                                        break;
276
 
277
                // XX_01_10_X0 or XX_10_10_X0 -> IN/OUT endpoint only
278
                case 0x18:
279
                case 0x1a:
280
                case 0x58:
281
                case 0x5a:
282
                case 0x98:
283
                case 0x9a:
284
                case 0xd8:
285
                case 0xda:
286
                case 0x28:
287
                case 0x2a:
288
                case 0x68:
289
                case 0x6a:
290
                case 0xa8:
291
                case 0xaa:
292
                case 0xe8:
293
                case 0xea:      next_dpid.write(1);     // BULK transfers
294
                                        break;
295
 
296
                // XX_01_10_X1 or XX_10_10_X1 -> IN/OUT endpoint only
297
                case 0x19:
298
                case 0x1b:
299
                case 0x59:
300
                case 0x5b:
301
                case 0x99:
302
                case 0x9b:
303
                case 0xd9:
304
                case 0xdb:
305
                case 0x29:
306
                case 0x2b:
307
                case 0x69:
308
                case 0x6b:
309
                case 0xa9:
310
                case 0xab:
311
                case 0xe9:
312
                case 0xeb:      next_dpid.write(0);      // BULK transfers
313
                                        break;
314
 
315
                // XX_00_XX_XX -> CTRL Endpoint
316
                case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
317
                case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
318
                case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
319
                case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
320
                case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
321
                case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
322
                case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
323
                case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
324
                                        switch (sel2) {// synopsys full_case parallel_case
325
 
326
                                                // 1_XX_XX -> SETUP operation
327
                                                case 0x10:
328
                                                case 0x11:
329
                                                case 0x12:
330
                                                case 0x13:
331
                                                case 0x14:
332
                                                case 0x15:
333
                                                case 0x16:
334
                                                case 0x17:
335
                                                case 0x18:
336
                                                case 0x19:
337
                                                case 0x1a:
338
                                                case 0x1b:
339
                                                case 0x1c:
340
                                                case 0x1d:
341
                                                case 0x1e:
342
                                                case 0x1f:      next_dpid.write(3);
343
                                                                        break;
344
 
345
                                                // 0_10_0X -> IN operation
346
                                                case 0x08:
347
                                                case 0x09:      next_dpid.write(3);
348
                                                                        break;
349
 
350
                                                // 0_10_1X -> IN operation
351
                                                case 0x0a:
352
                                                case 0x0b:      next_dpid.write(1);
353
                                                                        break;
354
 
355
                                                // 0_01_X0 -> OUT operation
356
                                                case 0x04:
357
                                                case 0x06:      next_dpid.write(3);
358
                                                                        break;
359
 
360
                                                // 0_01_X1 -> OUT operation
361
                                                case 0x05:
362
                                                case 0x07:      next_dpid.write(2);
363
                                                                        break;
364
                                        }
365
                                        break;
366
        }
367
}
368
 
369
// Current PID decoder
370
// Allow any PID for ISO transfers when mode full speed or tr_fr is zero
371
void usb_pe_sie::allow_pid_up(void) {
372
        sc_uint<4> sel;
373
 
374
        sel = ((sc_uint<1>)pid_DATA0.read(), (sc_uint<1>)pid_DATA1.read(), (sc_uint<1>)pid_DATA2.read(), (sc_uint<1>)pid_MDATA.read());
375
 
376
        switch (sel) {// synopsys full_case parallel_case
377
                // 1000
378
                case 8: allow_pid.write(0); break;
379
                // 0100
380
                case 4: allow_pid.write(1); break;
381
                // 0010
382
                case 2: allow_pid.write(2); break;
383
                // 0001
384
                case 1: allow_pid.write(3); break;
385
        }
386
}
387
 
388
void usb_pe_sie::this_dpid_up(void) {
389
        sc_uint<8> sel1;
390
        sc_uint<5> sel2;
391
 
392
        // tr/mf:ep/type:tr/type:last dpd
393
        sel1 = ((sc_uint<2>)tr_fr_d.read(), (sc_uint<2>)ep_type.read(), (sc_uint<2>)txfr_type.read(), (sc_uint<2>)uc_dpd.read());
394
 
395
        // CTRL Endpoint Selector
396
        sel2 = ((sc_uint<1>)setup_token.read(), (sc_uint<1>)in_op.read(), (sc_uint<1>)out_op.read(), (sc_uint<2>)uc_dpd.read());
397
 
398
        switch (sel1) {// synopsys full_case parallel_case
399
 
400
                // 0X_01_01_XX -> ISO txfr. IN, 1 tr/mf
401
                case 0x14:
402
                case 0x15:
403
                case 0x16:
404
                case 0x17:
405
                case 0x54:
406
                case 0x55:
407
                case 0x56:
408
                case 0x57:      this_dpid.write(0);
409
                                        break;
410
 
411
                // 10_01_01_X0 -> ISO txfr. IN, 2 tr/mf
412
                case 0x94:
413
                case 0x96:      this_dpid.write(1);
414
                                        break;
415
 
416
                // 10_01_01_X1 -> ISO txfr. IN, 2 tr/mf
417
                case 0x95:
418
                case 0x97:      this_dpid.write(0);
419
                                        break;
420
 
421
                // 11_01_01_00 -> ISO txfr. IN, 3 tr/mf
422
                case 0xd4:      this_dpid.write(2);
423
                                        break;
424
 
425
                // 11_01_01_01 -> ISO txfr. IN, 3 tr/mf
426
                case 0xd5:      this_dpid.write(1);
427
                                        break;
428
 
429
                // 11_01_01_10 -> ISO txfr. IN, 3 tr/mf
430
                case 0xd6:      this_dpid.write(0);
431
                                        break;
432
 
433
                // 00_10_01_XX -> ISO txfr. OUT, 0 tr/mf
434
                case 0x24:
435
                case 0x25:
436
                case 0x26:
437
                case 0x27:      this_dpid.write(allow_pid.read());
438
                                        break;
439
 
440
                // 01_10_01_XX -> ISO txfr. OUT, 1 tr/mf
441
                case 0x64:
442
                case 0x65:
443
                case 0x66:
444
                case 0x67:      this_dpid.write(0);
445
                                        break;
446
 
447
                // 10_10_01_X0 -> ISO txfr. OUT, 2 tr/mf
448
                case 0xa4:
449
                case 0xa6:      this_dpid.write(3);
450
                                        break;
451
 
452
                // 10_10_01_X1 -> ISO txfr. OUT, 2 tr/mf
453
                case 0xa5:
454
                case 0xa7:      this_dpid.write(1);
455
                                        break;
456
 
457
                // 11_10_01_00 -> ISO txfr. OUT, 3 tr/mf
458
                case 0xe4:      this_dpid.write(3);
459
                                        break;
460
 
461
                // 11_10_01_01 -> ISO txfr. OUT, 3 tr/mf
462
                case 0xe5:      this_dpid.write(3);
463
                                        break;
464
 
465
                // 11_10_01_10 -> ISO txfr. OUT, 3 tr/mf
466
                case 0xe6:      this_dpid.write(2);
467
                                        break;
468
 
469
                // XX_01_00_X0 or XX_10_00_X0 -> IN/OUT endpoint only
470
                case 0x10:
471
                case 0x12:
472
                case 0x50:
473
                case 0x52:
474
                case 0x90:
475
                case 0x92:
476
                case 0xd0:
477
                case 0xd2:
478
                case 0x20:
479
                case 0x22:
480
                case 0x60:
481
                case 0x62:
482
                case 0xa0:
483
                case 0xa2:
484
                case 0xe0:
485
                case 0xe2:      this_dpid.write(0);      // INT transfers
486
                                        break;
487
 
488
                // XX_01_00_X1 or XX_10_00_X1 -> IN/OUT endpoint only
489
                case 0x11:
490
                case 0x13:
491
                case 0x51:
492
                case 0x53:
493
                case 0x91:
494
                case 0x93:
495
                case 0xd1:
496
                case 0xd3:
497
                case 0x21:
498
                case 0x23:
499
                case 0x61:
500
                case 0x63:
501
                case 0xa1:
502
                case 0xa3:
503
                case 0xe1:
504
                case 0xe3:      this_dpid.write(1);     // INT transfers
505
                                        break;
506
 
507
                // XX_01_10_X0 or XX_10_10_X0 -> IN/OUT endpoint only
508
                case 0x18:
509
                case 0x1a:
510
                case 0x58:
511
                case 0x5a:
512
                case 0x98:
513
                case 0x9a:
514
                case 0xd8:
515
                case 0xda:
516
                case 0x28:
517
                case 0x2a:
518
                case 0x68:
519
                case 0x6a:
520
                case 0xa8:
521
                case 0xaa:
522
                case 0xe8:
523
                case 0xea:      this_dpid.write(0);      // BULK transfers
524
                                        break;
525
 
526
                // XX_01_10_X1 or XX_10_10_X1 -> IN/OUT endpoint only
527
                case 0x19:
528
                case 0x1b:
529
                case 0x59:
530
                case 0x5b:
531
                case 0x99:
532
                case 0x9b:
533
                case 0xd9:
534
                case 0xdb:
535
                case 0x29:
536
                case 0x2b:
537
                case 0x69:
538
                case 0x6b:
539
                case 0xa9:
540
                case 0xab:
541
                case 0xe9:
542
                case 0xeb:      this_dpid.write(1);     // BULK transfers
543
                                        break;
544
 
545
                // XX_00_XX_XX -> CTRL Endpoint
546
                case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
547
                case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
548
                case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
549
                case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
550
                case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
551
                case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
552
                case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
553
                case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
554
                                        switch (sel2) {// synopsys full_case parallel_case
555
 
556
                                                // 1_XX_XX -> SETUP operation
557
                                                case 0x10:
558
                                                case 0x11:
559
                                                case 0x12:
560
                                                case 0x13:
561
                                                case 0x14:
562
                                                case 0x15:
563
                                                case 0x16:
564
                                                case 0x17:
565
                                                case 0x18:
566
                                                case 0x19:
567
                                                case 0x1a:
568
                                                case 0x1b:
569
                                                case 0x1c:
570
                                                case 0x1d:
571
                                                case 0x1e:
572
                                                case 0x1f:      this_dpid.write(0);
573
                                                                        break;
574
 
575
                                                // 0_10_0X -> IN operation
576
                                                case 0x08:
577
                                                case 0x09:      this_dpid.write(0);
578
                                                                        break;
579
 
580
                                                // 0_10_1X -> IN operation
581
                                                case 0x0a:
582
                                                case 0x0b:      this_dpid.write(1);
583
                                                                        break;
584
 
585
                                                // 0_01_X0 -> OUT operation
586
                                                case 0x04:
587
                                                case 0x06:      this_dpid.write(0);
588
                                                                        break;
589
 
590
                                                // 0_01_X1 -> OUT operation
591
                                                case 0x05:
592
                                                case 0x07:      this_dpid.write(1);
593
                                                                        break;
594
                                        }
595
                                        break;
596
        }
597
}
598
 
599
// Assign PID for outgoing packets
600
void usb_pe_sie::data_pid_sel_up(void) {
601
        data_pid_sel.write(this_dpid.read());
602
}
603
 
604
// Verify PID for incoming data packets
605
void usb_pe_sie::pid_seq_err_up(void) {
606
        pid_seq_err.write(!(((this_dpid.read() == 0) && pid_DATA0.read()) ||
607
                        ((this_dpid.read() == 1) && pid_DATA1.read()) ||
608
                        ((this_dpid.read() == 2) && pid_DATA2.read()) ||
609
                        ((this_dpid.read() == 3) && pid_MDATA.read())));
610
}
611
 
612
// IDMA Setup and SRC/DEST Buffer Select
613
// For Control Endpoint things are different:
614
// buffer0 is used for OUT (incoming) data packets
615
// buffer1 is used for IN (outgoing) data packets
616
 
617
// Keep track of last token for control endpoints
618
void usb_pe_sie::in_token_up(void) {
619
        if (!rst.read())
620
                in_token.write(false);
621
        else if (pid_IN.read())
622
                in_token.write(true);
623
        else if (pid_OUT.read() || pid_SETUP.read())
624
                in_token.write(false);
625
}
626
 
627
void usb_pe_sie::out_token_up(void) {
628
        if (!rst.read())
629
                out_token.write(false);
630
        else if (pid_OUT.read() || pid_SETUP.read())
631
                out_token.write(true);
632
        else if (pid_IN.read())
633
                out_token.write(false);
634
}
635
 
636
void usb_pe_sie::setup_token_up(void) {
637
        if (!rst.read())
638
                setup_token.write(false);
639
        else if (pid_SETUP.read())
640
                setup_token.write(true);
641
        else if (pid_OUT.read() || pid_IN.read())
642
                setup_token.write(false);
643
}
644
 
645
// Indicates if we are performing an IN operation
646
void usb_pe_sie::in_op_up(void) {
647
        in_op.write(IN_ep.read() || (CTRL_ep.read() && in_token.read()));
648
}
649
 
650
// Indicates if we are performing an OUT operation
651
void usb_pe_sie::out_op_up(void) {
652
        out_op.write(OUT_ep.read() || (CTRL_ep.read() && out_token.read()));
653
}
654
 
655
// Determine if packet is to small or to large
656
// This is used to NACK and ignore packet for OUT endpoints
657
 
658
// Register File Update Logic
659
 
660
void usb_pe_sie::uc_dpd_set_up(void) {
661
        uc_dpd_set.write(uc_stat_set_d.read());
662
}
663
 
664
// Abort signal
665
void usb_pe_sie::abort_up(void) {
666
        abort.write(match.read() && fsel.read() && (state.read() != PE_IDLE));
667
}
668
 
669
// Time Out Timers
670
 
671
// After sending data in response to an IN token from host, the
672
// host must reply with an ack. The host has 622nS in Full Speed
673
// mode and 400nS in High Speed mode to reply.
674
// "rx_ack_to" indicates when this time has expired and
675
// rx_ack_to_clr clears the timer
676
void usb_pe_sie::rx_ack_up1(void) {
677
        rx_ack_to_clr.write(tx_valid.read() || rx_ack_to_clr_d.read());
678
}
679
 
680
void usb_pe_sie::rx_ack_up2(void) {
681
        if (rx_ack_to_clr.read())
682
                rx_ack_to_cnt.write(0);
683
        else
684
                rx_ack_to_cnt.write(rx_ack_to_cnt.read() + 1);
685
}
686
 
687
void usb_pe_sie::rx_ack_up3(void) {
688
        rx_ack_to.write(rx_ack_to_cnt.read() == rx_ack_to_val.read());
689
}
690
 
691
// After sending a OUT token the host must send a data packet.
692
// The host has 622nS in Full Speed mode and 400nS in High Speed
693
// mode to send the data packet.
694
// "tx_data_to" indicates when this time has expired and
695
// "tx_data_to_clr" clears the timer
696
void usb_pe_sie::tx_data_up1(void) {
697
        tx_data_to_clr.write(rx_active.read());
698
}
699
 
700
void usb_pe_sie::tx_data_up2(void) {
701
        if (tx_data_to_clr.read())
702
                tx_data_to_cnt.write(0);
703
        else
704
                tx_data_to_cnt.write(tx_data_to_cnt.read() + 1);
705
}
706
 
707
void usb_pe_sie::tx_data_up3(void) {
708
        tx_data_to.write(tx_data_to_cnt.read() == tx_data_to_val.read());
709
}
710
 
711
// Interrupts
712
void usb_pe_sie::pid_OUT_up(void) {
713
        pid_OUT_r.write(pid_OUT.read());
714
}
715
 
716
void usb_pe_sie::pid_IN_up(void) {
717
        pid_IN_r.write(pid_IN.read());
718
}
719
 
720
void usb_pe_sie::pid_PING_up(void) {
721
        pid_PING_r.write(pid_PING.read());
722
}
723
 
724
void usb_pe_sie::pid_SETUP_up(void) {
725
        pid_SETUP_r.write(pid_SETUP.read());
726
}
727
 
728
void usb_pe_sie::int_upid_up(void) {
729
        int_upid_set.write(match_r.read() && !pid_SOF.read() &&
730
                        ((OUT_ep.read() && !(pid_OUT_r.read() || pid_PING_r.read())) ||
731
                        (IN_ep.read() && !pid_IN_r.read()) ||
732
                        (CTRL_ep.read() && !(pid_IN_r.read() || pid_OUT_r.read() || pid_PING_r.read() || pid_SETUP_r.read()))));
733
}
734
 
735
void usb_pe_sie::int_to_up(void) {
736
        int_to_set.write(((state.read() == PE_IN2) && rx_ack_to.read()) ||
737
                        ((state.read() == PE_OUT) && tx_data_to.read()));
738
}
739
 
740
void usb_pe_sie::int_crc16_up(void) {
741
        int_crc16_set.write(rx_data_done.read() && crc16_err.read());
742
}
743
 
744
void usb_pe_sie::int_seqerr_up(void) {
745
        int_seqerr_set.write(int_seqerr_set_d.read());
746
}
747
 
748
void usb_pe_sie::send_stall_up(void) {
749
        if (!rst.read())
750
                send_stall_r.write(false);
751
        else if (send_stall.read())
752
                send_stall_r.write(true);
753
        else if (send_token.read())
754
                send_stall_r.write(false);
755
}
756
 
757
void usb_pe_sie::state_up(void) {
758
        if (!rst.read())
759
                state.write(PE_IDLE);
760
        else if (match.read())
761
                state.write(PE_IDLE);
762
        else
763
                state.write(next_state.read());
764
}
765
 
766
void usb_pe_sie::pe_statemachine(void) {
767
        next_state.write(state.read());
768
        token_pid_sel_d.write(PE_ACK);
769
        send_token_d.write(false);
770
        rx_dma_en.write(false);
771
        tx_dma_en.write(false);
772
        uc_stat_set_d.write(false);
773
        rx_ack_to_clr_d.write(true);
774
        int_seqerr_set_d.write(false);
775
 
776
        switch (state.read()) {// synopsys full_case parallel_case
777
                case PE_IDLE:
778
 
779
///////////////////////////////////////////////////////////////////////
780
//
781
// DEBUG INFORMATIONS
782
//
783
///////////////////////////////////////////////////////////////////////
784
 
785
#ifdef USBF_VERBOSE_DEBUG
786
        cout << "SIE -> PE: Entered state IDLE (" << sc_simulation_time() << ")" << endl;
787
#endif
788
 
789
///////////////////////////////////////////////////////////////////////
790
 
791
                                        if (match_r.read() && !pid_SOF.read()) {
792
                                                if (send_stall.read()) {                                // Halt Forced send STALL
793
                                                        token_pid_sel_d.write(PE_STALL);
794
                                                        send_token_d.write(true);
795
                                                        next_state.write(PE_TOKEN);
796
                                                } else if (IN_ep.read() || (CTRL_ep.read() && pid_IN.read())) {
797
                                                        if (txfr_int.read() && ep_empty.read()) {
798
                                                                token_pid_sel_d.write(PE_NACK);
799
                                                                send_token_d.write(true);
800
                                                                next_state.write(PE_TOKEN);
801
                                                        } else {
802
                                                                tx_dma_en.write(true);
803
                                                                next_state.write(PE_IN);
804
                                                        }
805
                                                } else if (OUT_ep.read() || (CTRL_ep.read() && (pid_OUT.read() || pid_SETUP.read()))) {
806
                                                        rx_dma_en.write(true);
807
                                                        next_state.write(PE_OUT);
808
                                                }
809
                                        }
810
                                        break;
811
 
812
                case PE_TOKEN:
813
 
814
///////////////////////////////////////////////////////////////////////
815
//
816
// DEBUG INFORMATIONS
817
//
818
///////////////////////////////////////////////////////////////////////
819
 
820
#ifdef USBF_VERBOSE_DEBUG
821
        cout << "SIE -> PE: Entered state TOKEN (" << sc_simulation_time() << ")" << endl;
822
#endif
823
 
824
///////////////////////////////////////////////////////////////////////
825
 
826
                                        next_state.write(PE_IDLE);
827
                                        break;
828
 
829
                case PE_IN:
830
 
831
///////////////////////////////////////////////////////////////////////
832
//
833
// DEBUG INFORMATIONS
834
//
835
///////////////////////////////////////////////////////////////////////
836
 
837
#ifdef USBF_VERBOSE_DEBUG
838
        cout << "SIE -> PE: Entered state IN (" << sc_simulation_time() << ")" << endl;
839
#endif
840
 
841
///////////////////////////////////////////////////////////////////////
842
 
843
                                        rx_ack_to_clr_d.write(false);
844
                                        if (idma_done.read())
845
                                                if (txfr_iso.read())
846
                                                        next_state.write(PE_UPDATE);
847
                                                else
848
                                                        next_state.write(PE_IN2);
849
                                        break;
850
 
851
                case PE_IN2:
852
 
853
///////////////////////////////////////////////////////////////////////
854
//
855
// DEBUG INFORMATIONS
856
//
857
///////////////////////////////////////////////////////////////////////
858
 
859
#ifdef USBF_VERBOSE_DEBUG
860
        cout << "SIE -> PE: Entered state IN2 (" << sc_simulation_time() << ")" << endl;
861
#endif
862
 
863
///////////////////////////////////////////////////////////////////////
864
 
865
                                        rx_ack_to_clr_d.write(false);
866
                                        // Wait for ACK from host or time out
867
                                        if (rx_ack_to.read())
868
                                                next_state.write(PE_IDLE);
869
                                        else if (token_valid.read() && pid_ACK.read())
870
                                                next_state.write(PE_UPDATE);
871
                                        break;
872
 
873
                case PE_OUT:
874
 
875
///////////////////////////////////////////////////////////////////////
876
//
877
// DEBUG INFORMATIONS
878
//
879
///////////////////////////////////////////////////////////////////////
880
 
881
#ifdef USBF_VERBOSE_DEBUG
882
        cout << "SIE -> PE: Entered state OUT (" << sc_simulation_time() << ")" << endl;
883
#endif
884
 
885
///////////////////////////////////////////////////////////////////////
886
 
887
                                        if (tx_data_to.read() || crc16_err.read() || abort.read())
888
                                                next_state.write(PE_IDLE);
889
                                        else if (rx_data_done.read()) { // Send ACK
890
                                                if (txfr_iso.read()) {
891
                                                        if (pid_seq_err.read())
892
                                                                int_seqerr_set_d.write(true);
893
                                                        next_state.write(PE_UPDATEW);
894
                                                } else {
895
                                                        next_state.write(PE_OUT2A);
896
                                                }
897
                                        }
898
                                        break;
899
 
900
                case PE_OUT2B:  // This is a delay state to NACK to small or
901
                                                // to large packets. This state could be skipped
902
 
903
///////////////////////////////////////////////////////////////////////
904
//
905
// DEBUG INFORMATIONS
906
//
907
///////////////////////////////////////////////////////////////////////
908
 
909
#ifdef USBF_VERBOSE_DEBUG
910
        cout << "SIE -> PE: Entered state OUT2B (" << sc_simulation_time() << ")" << endl;
911
#endif
912
 
913
///////////////////////////////////////////////////////////////////////
914
 
915
                                        if (abort.read())
916
                                                next_state.write(PE_IDLE);
917
                                        else
918
                                                next_state.write(PE_OUT2B);
919
                                        break;
920
 
921
                case PE_OUT2A:  // Send ACK/NACK/NYET
922
 
923
///////////////////////////////////////////////////////////////////////
924
//
925
// DEBUG INFORMATIONS
926
//
927
///////////////////////////////////////////////////////////////////////
928
 
929
#ifdef USBF_VERBOSE_DEBUG
930
        cout << "SIE -> PE: Entered state OUT2A (" << sc_simulation_time() << ")" << endl;
931
#endif
932
 
933
///////////////////////////////////////////////////////////////////////
934
 
935
                                        if (abort.read())
936
                                                next_state.write(PE_IDLE);
937
                                        else if (send_stall_r.read()) {
938
                                                token_pid_sel_d.write(PE_STALL);
939
                                                send_token_d.write(true);
940
                                                next_state.write(PE_IDLE);
941
                                        } else if (ep_full.read()) {
942
                                                token_pid_sel_d.write(PE_NACK);
943
                                                send_token_d.write(true);
944
                                                next_state.write(PE_IDLE);
945
                                        } else {
946
                                                token_pid_sel_d.write(PE_ACK);
947
                                                send_token_d.write(true);
948
                                                if (pid_seq_err.read())
949
                                                        next_state.write(PE_IDLE);
950
                                                else
951
                                                        next_state.write(PE_UPDATE);
952
                                        }
953
                                        break;
954
 
955
                case PE_UPDATEW:
956
 
957
///////////////////////////////////////////////////////////////////////
958
//
959
// DEBUG INFORMATIONS
960
//
961
///////////////////////////////////////////////////////////////////////
962
 
963
#ifdef USBF_VERBOSE_DEBUG
964
        cout << "SIE -> PE: Entered state UPDATEW (" << sc_simulation_time() << ")" << endl;
965
#endif
966
 
967
///////////////////////////////////////////////////////////////////////
968
 
969
                                        next_state.write(PE_UPDATE);
970
                                        break;
971
 
972
                case PE_UPDATE:
973
 
974
///////////////////////////////////////////////////////////////////////
975
//
976
// DEBUG INFORMATIONS
977
//
978
///////////////////////////////////////////////////////////////////////
979
 
980
#ifdef USBF_VERBOSE_DEBUG
981
        cout << "SIE -> PE: Entered state UPDATE (" << sc_simulation_time() << ")" << endl;
982
#endif
983
 
984
///////////////////////////////////////////////////////////////////////
985
 
986
                                        uc_stat_set_d.write(true);
987
                                        next_state.write(PE_IDLE);
988
                                        break;
989
        }
990
}
991
 

powered by: WebSVN 2.1.0

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