vusb_dpllnrzi.v
41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
/*******************************************************************************
-- File Type: Verilog HDL
-- Tool Version: VHDL2verilog v4.4 Tue Sep 19 10:06:32 EDT 2000 SunOS 5.5.1
-- Input file was: vusb_dpllnrzi
-- Date Created: Tue Jul 16 13:59:29 2002
*******************************************************************************/
`timescale 1 ns / 1 ns // timescale for following modules
// ------------------------------------------------------------------------------
// Copyright 1997 VAutomation Inc. Nashua NH (603)882-2282 ALL RIGHTS RESERVED.
// This software is provided under license and contains proprietary and
// confidential material which is the property of VAutomation Inc.
//
// File: vusb_dpllnrzi.vhd Digital PLL with NRZI decode and clock enable generator.
//
// Revision: $Revision: 1.1.1.1 $
//
// Description:
// This is a Digital Phase Locked loop that extracts data and clock
// from the incoming NRZI encoded DATAIN signal. DATAIN should be
// a sharp, noise-free signal. It should come from an input
// buffer with plenty of hysteresis. The CLK signal input to this
// block must be 4X the data rate of of the serial stream. The
// Phase locked clock enable sigal (UCLK_EN) is always high for
// one CLKs and may be low from 2 to 4 CLK
// If DATAIN has noise on it, the DPLL will constantly run in "early"
// mode with UCLK_EN high for 1 CLK and low for 2. DATAOUT
// transitions 1 CLK after UCLK_EN pulse. This allows plenty of hold
// time for DATAOUT relative to the clock enabled edge.
// The USB DPLUS and DMINUS differential signals are processed here
// to insure clean and correct Single Ended Zero (SE0) and EOP detection.
// If this code is used in a slow speed device, then the EOP detection
// logic will need to have the DPLUS and DMINUS polarities reversed.
// DPLUS and DMINUS must be low for 2 48Mhz clocks before a SE0 is recognized.
//
// When a SE0 is detected, transistions on the DATAIN signal are ignored.
// This keeps the PLL locked during the SE0 when it is probable that
// the DATAIN line will be noisy when used with a simple Differential
// OPAMP. This is because both inputs to the OPAMP will be close to ground.
// Theory of Operation:
// The PLL looks at K to J transition on the incoming data stream and adujusts
// the CLKEN_DPLL signal so that the transitions are centered between
// enable pulses. Because of the USB signal transition skew specification,
// and the USB hub idle to K timing specification only K to J signal
// transitions will be used. The PLL is built using a 4 bit shift register
// which is shifting at the incoming 4X oversampling clock CLK. This shift
// register is free running and develops 4 phases of CLKEN_DPLL. Another 4
// bit shift register is used to select which of the 4 phases we want. The
// phase of CLKEN_DPLL is adjusted only on the 2nd CLK when CLKEN_DPLL is
// is low. Under normal operation CLKEN_DPLL is low for 3 cycles then high
// for one cycle. If a transition has been detected earlier than expected,
// then the next UCLK_EN will be low for only two CLKs. If a transition is
// detected during the late window, then UCLK_EN low for 4 CLKs before the
// next enable. If the transition is in the proper place or there was no
// transition, then no adjustments are made to the phase.
//
// Timing Diagram:
// If a transition is detected during clocks 1 or 2, then it is early
// and our next CLKEN_DPLL will be low for only 2 CLKs. If a transition
// occurs during clock 7, then it is late and the next CLKEN_DPLL will
// be low for 4 CLKs. Note that CLKEN_DPLL is alway high for 1 CLK and
// low for 2 to 4 CLKS.
//
// __ 1__ 2__ 3__ 4__ 5__ 6__ 7__ 8__ 9__ 10__ 11__
// CLK | |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |
// _____ _____ _____
// SHIFTER(3) ____/ \_________________/ \_________________/ \________
// _____ _____ _____
// SHIFTER(2) __________/ \_________________/ \_________________/ \__
// _____ _____ __
// SHIFTER(1) ________________/ \_________________/ \__________________/
// ____ _____ _____
// SHIFTER(0) \_________________/ \_________________/ \_______________
// _____ ______ _____
// PHASE _______/ \___________X___________/ \__________X \_________
// ___________ __________
// EARLY_WINDOW ________/ \__________________/ \_______________
// _____ ______ _____
// LATE_WINDOW ___/ \___________X___________/ \__________X \_________
// ___ ________________________________ ________________
// K_TO_J_TRANS___XXXXXX________________________________XXXXXXXXXX________________
// ________Late____________________________________Early__________________
// STATE __________________3______X___________2_________________X______3________
//
// CLKEN_DPLL output:
// The CLKEN_DPLL clock enable output from the the DPLL is intented to be
// used as a clock enable signal used in conjunction with the 48MHz input
// clock to clock the registers in the VUSB design. It can, however, be
// used directly as a clock to the the VUSB. The Clock enable is alligned
// with the dataout, seo and eop signals to select a 48MHz rising edge
// that is centered in the data. As a result the rising edge of the clock
// enable falls less than one 48MHz cycle before the center of any data
// transitions.
//
// NRZI encoding:
// NRZI encoding is a popular method of encoding serial data
// in relatively noise-free environments. The basic concept is that
// every time a 0 is transmitted, the state of the line is reversed.
// RESET: Note that CLKEN_DPLL is active while RESET is asserted. Typically
// RESET is connected to the DPLL from a power-on-reset cell. Alternatively
// the reset sent to circuitry clocked by CLKEN_DPLL must be stretched for
// some number of CLKEN_DPLL pulses.
// Signals ending in _n are active low.
//
// ------------------------------------------------------------------------------
// This product is licensed to:
// John Princen of RouteFree
// for use at site(s):
// broadon
// ------------------------------------------------------------------------------
// Revision History
// $Log:
// 62 VUSB 1.61 7/5/02 2:00:54 PM Will Sanborn Removed
// hub signals, which were not used.
// 61 VUSB 1.60 6/27/02 6:04:05 PM Will Sanborn Doc
// Change Only: replacing "synopsysTM" in comments with "_synopsysTMTM" to
// prevent error with compiler interpreting those comments as pragmas.
// 60 VUSB 1.59 4/11/02 2:49:09 PM Patrick Koran all
// checked in from pats pc, week of Starteam upgrade 4.6 to 5.1
// 59 VUSB 1.58 2/11/02 3:39:20 PM Tom Frechette making
// clocks and resets uniform.
// 58 VUSB 1.57 2/11/02 2:15:39 PM Tom Frechette Fixing
// resets for changereset script.
// 57 VUSB 1.56 2/11/02 1:37:09 PM Tom Frechette Fixed
// sync resets for changereset script.
// 56 VUSB 1.55 2/7/02 4:45:53 PM Tom Frechette Fixed
// reset names.
// 55 VUSB 1.54 11/29/01 5:21:37 PM Tom Frechette Still
// missed _synopsysTMTM comment
// 54 VUSB 1.53 11/29/01 5:09:56 PM Tom Frechette Missed
// _synopsysTMTM comment.
// 53 VUSB 1.52 11/29/01 4:53:06 PM Tom Frechette Changed
// comments to _synopsysTMTM.
// 52 VUSB 1.51 11/29/01 2:54:28 PM Tom Frechette
// Re-ordered lines to get rif of the _synopsysTM(TM) Warning.
// 51 VUSB 1.50 10/30/01 11:00:03 AM Monika Leary Fixed a
// synthesis warning
// 50 VUSB 1.49 8/23/01 9:49:11 AM Tom Frechette
// 49 VUSB 1.48 6/22/01 9:06:56 AM Tom Frechette Changed
// name of config.
// 48 VUSB 1.47 6/21/01 10:00:08 AM Tom Frechette Changed
// the name
// 47 VUSB 1.46 6/21/01 9:51:39 AM Tom Frechette
// 46 VUSB 1.45 5/15/01 3:41:48 PM Monika Leary Added
// async reset.
// 45 VUSB 1.44 1/22/01 2:38:55 PM Chris Kolb Commented
// out unused very_early_transition signal.
// 44 VUSB 1.43 1/19/01 9:59:05 AM Grace LaRocque cleaning
// up exemplar warnings
// 43 VUSB 1.42 12/14/00 8:42:30 AM Christopher Meyers RCS
// Keyword To StarTeam Keyword Translation
// 42 VUSB 1.41 12/13/00 8:05:32 PM Mark Pettigrew # removed
// 'verbose' signal - no longer used
// 41 VUSB 1.40 12/13/00 8:05:26 PM Mark Pettigrew yanked
// out extraneous comments
// 40 VUSB 1.39 12/13/00 8:05:22 PM Mark Pettigrew #
// commented out assert statements
// 39 VUSB 1.38 12/13/00 8:05:16 PM Chris Kolb Changed
// host_wo_hub from a generic to a signal. Changed architecture name to
// rtl.
// 38 VUSB 1.37 12/13/00 8:05:06 PM Gregory Recupero Removed
// ^M's
// 37 VUSB 1.36 12/13/00 8:05:01 PM Mark Pettigrew
// ulogicified source - no functional changes
// 36 VUSB 1.35 12/13/00 8:04:56 PM Chris Kolb Added
// ASCII schematic.
// 35 VUSB 1.34 12/13/00 8:04:52 PM Chris Kolb Added
// logic to sample the dpll inputs at the falling edge of clock inorder
// to increase the DPLL's tolerance to jitter and frequency variation
// (See the table at the end of the file).
// 34 VUSB 1.33 12/13/00 8:04:45 PM Gregory Recupero Fixed
// dpll_clk_en for conversion to verilog and gate level simulations
// 33 VUSB 1.32 12/13/00 8:04:41 PM Chris Kolb Added
// host_wo_hub generic for host without hub to allow different instances
// of the vusb core to set the constant differently.
// 32 VUSB 1.31 12/13/00 8:04:36 PM Chris Kolb Changed
// low speed signalling to allow the host speed to switch on the fly to
// support low speed devices thru a hub.
// 31 VUSB 1.30 12/13/00 8:04:29 PM Chris Kolb Added
// generic lsdev to support dynamic Low to Full speed switching. Fixed
// keyword case and indentation for readability.
// 30 VUSB 1.29 12/13/00 8:04:18 PM Chris Kolb Added
// eop_48_out signal to perform async clear function in HUB.
// 29 VUSB 1.28 12/13/00 8:04:12 PM Chris Kolb Qualified
// the SE0 sampling with an SE0 pulse width of at least two samples.
// 28 VUSB 1.27 12/13/00 8:04:05 PM Chris Kolb Fixed
// reset polarity on datain filter.
// 27 VUSB 1.26 12/13/00 8:04:00 PM Chris Kolb Added one
// more cycle of reset delay on transition filter. Added reset filter
// on datain to supress X's on input.
// 26 VUSB 1.25 12/13/00 8:03:56 PM Chris Kolb Reordered
// _synopsysTM(TM) syn_set_reset comment so it would survive translation
// to verilog.
// 25 VUSB 1.24 12/13/00 8:03:51 PM Chris Kolb Recoded
// processes using _synopsysTM(TM) style synchronous reset syntax.
// 24 VUSB 1.23 12/13/00 8:03:47 PM Chris Kolb Added
// more robust metability protection. Cleaned up the EOP detection to
// decouple the detection from the phase lock loop function. Removed a
// layer of synchronization uncertainty from the EOP detects that are
// provided to the Hub logic.
// 23 VUSB 1.22 12/13/00 8:03:40 PM Chris Kolb Added a
// 20ns delay to sie_eop_out to move that pulse farther away from the
// SE0 to J transition on the bus.
// 22 VUSB 1.21 12/13/00 8:03:36 PM Chris Kolb Combined
// sie_eop_out input into fseop_det, and synchronized it to the 12MHz
// clock domain.
// 21 VUSB 1.20 12/13/00 8:03:29 PM Chris Kolb Fixed Low
// Speed EOP detection.
// 20 VUSB 1.19 12/13/00 8:03:22 PM Chris Kolb Add 1
// additional clock delay to reset_after_clks to support verilog.
// 19 VUSB 1.18 12/13/00 8:03:16 PM Eric Ryherd Added the
// flops to hold SE0 active until we have output a couple of clocks
// after reset. Get Xes fed in via dplus/dminus without these.
// 18 VUSB 1.17 12/13/00 8:03:11 PM Chris Kolb Added
// logic for Low Speed EOP detection.
// 17 VUSB 1.16 12/13/00 8:03:06 PM Chris Kolb Added
// signals for hub.
// 16 VUSB 1.15 12/13/00 8:02:56 PM Gregory Recupero Added
// _synopsysTM(TM) reset attributes
// 15 VUSB 1.14 12/13/00 8:02:49 PM Chris Kolb Stubbed
// out low speed support. Centered rising edge of the clock enable pulse
// in the output siganls.
// 14 VUSB 1.13 12/13/00 8:02:42 PM Chris Kolb Added
// support for low speed single port root hub.
// 13 VUSB 1.12 12/13/00 8:02:34 PM Chris Kolb Added
// synchronized reset generation logic.
// 12 VUSB 1.11 12/13/00 8:02:29 PM Chris Kolb Rewritten
// to support clock enable pulses.
// 11 VUSB 1.10 12/13/00 8:02:20 PM Eric Ryherd fixed the
// EOP pipelining of DPLUS and DMINUS...
// 10 VUSB 1.9 12/13/00 8:02:14 PM Eric Ryherd Aligned
// se0 with the data, se0 had 1 extra pipe stage in it which caused
// det_se0 to come out 1 bit late in some cases.
// 9 VUSB 1.8 12/13/00 8:02:09 PM Eric Ryherd Inverted
// reset_f so the DPLL will start after config in a xilinx FPGA.
// 8 VUSB 1.7 12/13/00 8:02:04 PM Eric Ryherd Added
// EOP.
// 7 VUSB 1.6 12/13/00 8:01:59 PM Eric Ryherd Added SE0
// output.
// 6 VUSB 1.5 12/13/00 8:01:53 PM Eric Ryherd Incorrect
// data when DATAIN is asymetric causing pairs of late/early - fixed.
// 5 VUSB 1.4 12/13/00 8:01:49 PM Eric Ryherd Changed
// to 4 bit DPLL and removed resetout.
// 4 VUSB 1.3 12/13/00 8:01:43 PM Gregory Recupero Move
// reset counter external to DPLL
// 3 VUSB 1.2 12/13/00 8:01:38 PM Eric Ryherd
// Simplified to logic a bit to meet timing.
// 2 VUSB 1.1 12/13/00 8:01:32 PM Eric Ryherd RESET now
// runs thru the DPLL so the clockout will run while reset asserted.
// 1 VUSB 1.0 12/13/00 8:01:28 PM Chris Kolb initial
// revision
// $
// ------------------------------------------------------------------------------
// USE ieee.std_logic_arith.ALL; -- we use the IEEE standard 1164 arithmetic
// ------------------------------------------------------------------------------
// Copyright 1995 VAutomation Inc. Nashua NH (603)882-2282 ALL RIGHTS RESERVED.
// This software is provided under license and contains proprietary and
// confidential material which is the property of VAutomation Inc.
//
// File: vusb_cfg.vhd USB Configuration file.
//
// Revision: $Revision: 1.1.1.1 $
//
// Description: A Package file for the usb core that defines global usb constants
// that contol how the VUSB core is synthesised.
//
// ---------------------------------------------------------------------------
// This product is licensed to:
// $name$ of $company$
// for use at site(s):
// $site$
// ------------------------------------------------------------------------------
// Revision History
// $Log:
// 32 VUSB 1.31 7/5/02 9:15:50 AM Chris Kolb Moved
// VUSB build configruation Revision constant to vusb_cfg, and updated
// the rev number to 3.0.
// 31 VUSB 1.30 4/11/02 2:49:09 PM Patrick Koran all
// checked in from pats pc, week of Starteam upgrade 4.6 to 5.1
// 30 VUSB 1.29 3/18/02 10:52:11 AM Tom Frechette Changed
// IRQ_NUM default to 0x0.
// 29 VUSB 1.28 3/15/02 2:39:08 PM Tom Frechette Added
// Interupt info into add_info register.
// 28 VUSB 1.27 2/7/02 4:49:00 PM Tom Frechette Removed
// sync config variable.
// 27 VUSB 1.26 8/23/01 9:48:58 AM Tom Frechette
// 26 VUSB 1.25 7/25/01 3:41:35 PM Tom Frechette Changed
// FIFO Parameter Names.
// 25 VUSB 1.24 7/10/01 3:03:41 PM Tom Frechette Moved
// HOST comment for verilog.
// 24 VUSB 1.23 7/6/01 7:44:00 AM Tom Frechette Added
// host comments around host constant to make it look like vusb_sie.
// 23 VUSB 1.22 7/6/01 7:34:33 AM Tom Frechette Added
// device constant comment for ARC.
// 22 VUSB 1.21 7/3/01 4:42:08 PM Tom Frechette Changed
// mode to a constant in vusb_cfg.
// 21 VUSB 1.20 6/22/01 3:09:48 PM Tom Frechette Changed
// endpoint number.
// 20 VUSB 1.19 6/21/01 9:59:56 AM Tom Frechette Changed
// the name and added fifo constants
// 19 VUSB 1.18 6/21/01 9:51:24 AM Tom Frechette
// 18 VUSB 1.17 5/25/01 10:25:08 AM Monika Leary Set
// synchronous reset constant to '1'
// 17 VUSB 1.16 5/17/01 2:52:48 PM Monika Leary Added
// USE_SYNC_RESET constant
// 16 VUSB 1.15 12/14/00 8:42:11 AM Christopher Meyers RCS
// Keyword To StarTeam Keyword Translation
// 15 VUSB 1.14 12/13/00 7:58:39 PM Chris Kolb Removed
// the HOST_WITHOUT_HUB constant. This control is now a Endpt0 control
// register bit in up_int.vhd.
// 14 VUSB 1.13 12/13/00 7:58:31 PM Gregory Recupero Removed
// ^M's
// 13 VUSB 1.12 12/13/00 7:58:26 PM Mark Pettigrew
// ulogicified source - no functional changes
// 12 VUSB 1.11 12/13/00 7:58:19 PM Chris Kolb Change
// type of HOST_WITHOUT_HUB from std_logic to integer so that it could
// be used to initialize a _synopsysTM(TM) compatible generic.
// 11 VUSB 1.10 12/13/00 7:58:14 PM Chris Kolb Set
// constant to support Host to Low Speed device thru a hub.
// 10 VUSB 1.9 12/13/00 7:58:07 PM Chris Kolb Changed
// LOW_SPEED_DEV constant to type integer to support generics.
// 9 VUSB 1.8 12/13/00 7:57:58 PM Christopher Meyers
// removed ASIC_IMPLEMENTATION constant
// 8 VUSB 1.7 12/13/00 7:57:46 PM Chris Kolb Remove
// ^M's. No functional changes.
// 7 VUSB 1.6 12/13/00 7:57:39 PM Chris Kolb Added
// HOST_WITHOUT_HUB constant to support new code in the DPLLNRZI.
// 6 VUSB 1.5 12/13/00 7:57:19 PM Chris Kolb Turned
// host mode back on.
// 5 VUSB 1.4 12/13/00 7:57:12 PM Chris Kolb Reverted
// to device only implementation.
// 4 VUSB 1.3 12/13/00 7:57:08 PM Chris Kolb Added
// revision string.
// 3 VUSB 1.2 12/13/00 7:57:03 PM Chris Kolb Enabled
// implementation of embedded host functions.
// 2 VUSB 1.1 12/13/00 7:56:58 PM Chris Kolb Added
// IMPLEMENT_EMBEDED_HOST constant.
// 1 VUSB 1.0 12/13/00 7:56:51 PM Chris Kolb initial
// revision
// $
//
//
// ------------------------------------------------------------------------------
module vusb_dpllnrzi (usb_clk48,
datain,
dplus,
dminus,
usb_rst48,
usb_rst48_a,
low_speed_en,
host_wo_hub,
clken_dpll,
clken_12,
dataout,
eop,
rcvout,
se0,
out180);
// file containing translation of VHDL package 'vusb_cfg'
parameter lsdev = 0;
`include "vusb_cfg.v"
input usb_clk48; // high speed clock - 4x data rate
input datain; // NRZI encoded serial data/clock in
input dplus; // USB positive data
input dminus; // USB negative data
input usb_rst48; // reset the PLL. CLKEN_DPLL stops.
input usb_rst48_a; // reset the PLL. CLKEN_DPLL stops.
input low_speed_en; // USB speed control
input host_wo_hub; // USB host without hub
output clken_dpll; // clock enable output
output clken_12; // fixed clock divided by 4 clock enable.
output dataout; // NRZ serial data out
output eop; // End Of Packet detected
output rcvout; // synchronized jstate signal
output se0; // single ended zero out
output out180;
reg clken_dpll;
wire clken_12;
wire dataout;
wire eop;
wire rcvout;
wire se0;
//
wire out180;
wire check_sync; // time to check if we are in sync
reg [2:0] clk12_cnt; // clock divide by 8 counter.
reg clk_slow_en; // clock divided by 8 (single pulse)
reg clkneg_slow_en; // clock divided by 8 (single pulse)
reg clken_12l; // clock divided by 4 local copy
reg datain_r1; // synchronization register
reg datain_r2; // synchronization register
reg datain_delayed; // synchronization register
reg datain_delayed_r1; // synchronization register
reg datain_delayed_r2; // synchronization register
reg dataoutl; // local versions
reg dminus_r1;
reg dminus_r2;
reg dminus_r3; // Data synchronizers
reg dminus_late_r1;
reg dminus_late_r2; // Data synchronizers
wire dpll_clk_en; // DPLL input clock enable
wire dpll_clkneg_en; // DPLL input clock enable
reg dplus_r1;
reg dplus_r2;
reg dplus_r3; // Data synchronizers
reg dplus_late_r1;
reg dplus_late_r2; // Data synchronizers
reg early; // flag indicating the transition was early
wire early_window; // timing window for detecting early transitions
reg eopl; // local version
reg eop_dpll; // EOP held for DPLL clock
wire j_delayed_in_r2;
reg j_delayed_in_r3;
reg j_delayed_in_r4; // Data synchronizers
wire j_state_in_r2;
reg j_state_in_r3;
reg j_state_in_r4; // Data synchronizers
wire k_to_j_trans; // K to J transistion on DATAIN
wire k_to_j_trans_dly; // K to J transistion on DATAIN
wire out180_window; // timing window for detecting 180 degree
reg late; // flag indicating the transition was late
wire late_window; // timing window for detecting late transitions
wire low_speed_signaling; // USB speed signal
wire phase; // D input to the CLKEN DFF
reg phase_r1;
reg phase_r2;
reg phase_r3; // flopped version of phase
reg pre_data; // data before clocked with clken_dpll
reg rcvoutl; // local version
reg reset_after_clks;
reg reset_after_clks_r1;
reg reset_after_clks_r2;
reg reset_after_clks_r3;
reg reset_after_clks_r4; // delayed reset
wire se0_blanking; // Single Ended Zero synchronizers
wire se0_r2; // Single Ended Zero synchronizers
wire se0_r3;
reg se0_r4;
reg se0_r5; // Single Ended Zero synchronizers
wire se0_late_r2;
reg se0_late_r3; // Single Ended Zero synchronizers
reg se0l; // local versions
reg [3:0] shifter; // 4 phase clock generator
wire [3:0] shifter_d; // D inputs to SR flops.
reg [3:0] state; // selects which phase we want
wire [3:0] state_d; // D inputs to SR flops.
wire transition; // any transistion on DATAIN
// signal very_early_transition : std_ulogic;
wire very_late_transition;
reg very_late_transition_r1;
// The following line is used when translating to Verilog...
// _synopsys sync_set_reset "usb_rst48"
assign low_speed_signaling = lsdev == 1 ? 1'b 1 :
host_wo_hub == 1'b 1 ? low_speed_en :
1'b 0;
// If this is a low speed device, or it is a high speed device that
// is transmitting a low speed packet directly to a low speed
// device without an interviening hub then invert the j/k state
// polarity.
assign k_to_j_trans = ~j_state_in_r4 & j_state_in_r3 & ~se0_blanking; // ignore transitions into and out of SE0.
// K to J transition
// detected on datain.
assign se0_blanking = se0_r2 & se0_r3 | se0_r3 & se0_r4 |
se0l;
assign transition = (j_state_in_r4 ^ j_state_in_r3) & ~se0l; // ignore transitions out of SE0.
// transition
// detected on datain.
assign shifter_d = {shifter[0], shifter[3:1]}; // normally we just shift
assign state_d = early == 1'b 1 | (k_to_j_trans & ~k_to_j_trans_dly) ==
1'b 1 ? {state[2:0], state[3]} :
late == 1'b 1 | (k_to_j_trans & k_to_j_trans_dly) ==
1'b 1 ? {state[0], state[3:1]} :
state;
assign phase = shifter[0] & state[0] | shifter[1] & state[1] |
shifter[2] & state[2] | shifter[3] & state[3];
assign early_window = phase_r3; // and the check_sync time
assign late_window = phase_r1;
assign check_sync = phase_r2;
assign out180_window = phase_r2;
assign out180 = out180_window & k_to_j_trans;
assign dataout = dataoutl; // connect local copies to outputs
assign se0 = se0l;
assign eop = eopl;
assign rcvout = rcvoutl;
assign clken_12 = clken_12l;
assign dpll_clk_en = clk_slow_en | ~low_speed_en;
assign dpll_clkneg_en = clkneg_slow_en | ~low_speed_en;
always @(posedge usb_clk48 or posedge usb_rst48_a)
begin : flops_usb_rst48
if (usb_rst48_a == 1'b 1)
begin
shifter <= 4'b 1000;
state <= 4'b 1000;
early <= 1'b 0;
late <= 1'b 0;
eop_dpll <= 1'b 0;
pre_data <= 1'b 0;
dataoutl <= 1'b 0;
eopl <= 1'b 0;
se0l <= 1'b 1;
rcvoutl <= 1'b 0;
end
else
begin
if (usb_rst48 == 1'b 1)
begin
shifter <= 4'b 1000;
state <= 4'b 1000;
early <= 1'b 0;
late <= 1'b 0;
eop_dpll <= 1'b 0;
pre_data <= 1'b 0;
dataoutl <= 1'b 0;
eopl <= 1'b 0;
se0l <= 1'b 1;
rcvoutl <= 1'b 0;
end
// vsync_usb_rst48
else
begin
if (dpll_clk_en == 1'b 1)
begin
shifter <= shifter_d; // 4 phase free running clock
if (check_sync == 1'b 1)
begin
state <= state_d; // using the state register
end
// select which phase we want
if (check_sync == 1'b 1)
begin
early <= k_to_j_trans & ~k_to_j_trans_dly;
end
else if (early_window == 1'b 1 )
begin
early <= early | k_to_j_trans;
end
if (check_sync == 1'b 1)
begin
late <= 1'b 0;
end
else if (late_window == 1'b 1 )
begin
late <= k_to_j_trans;
// Capture the EOP event for the DPLL clock domain 3 cycles of SE0
// followed by a J-state.
end
if (late_window == 1'b 1)
begin
eop_dpll <= (dplus_r2 & ~low_speed_signaling | dminus_r2 & low_speed_signaling) &
(se0_r3 & se0_r4 & se0_r5); // 3 cycles of SE0
end
else
begin
eop_dpll <= eop_dpll | (dplus_r2 & ~low_speed_signaling | dminus_r2 &
low_speed_signaling) & (se0_r3 & se0_r4 & se0_r5); // 3 cycles of SE0
// Capture any transitions that occure between this late window and the next.
end
if (reset_after_clks_r3 == 1'b 1 | late_window == 1'b 1)
begin
pre_data <= 1'b 1;
end
// preset the pre-data bit,
else if ((transition & ~very_late_transition_r1) == 1'b 1 )
begin
pre_data <= 1'b 0;
end
// if there is a transition, then the bit is a 0.
if (reset_after_clks_r4 == 1'b 1)
begin
dataoutl <= 1'b 0;
eopl <= 1'b 0;
se0l <= 1'b 1; // force se0 to ignore D+/D- until stable
rcvoutl <= 1'b 0;
end
else if (late_window == 1'b 1 )
begin
dataoutl <= pre_data & ~transition & ~very_late_transition; // late transition means the data
// a late transition or a very
// bit is a zero
// An eop is detected if 3 cycles of se0 are followed by a J-state
eopl <= eop_dpll;
se0l <= se0_late_r2 & se0_late_r3 | se0_r2 & se0_r3 |
se0_r3 & se0_r4;
rcvoutl <= j_state_in_r3;
end
else
begin
dataoutl <= dataoutl;
eopl <= eopl;
se0l <= se0l;
rcvoutl <= rcvoutl;
end
end
end
// reset --vsync_usb_rst48
end
// clk / reset
end
always @(posedge usb_clk48 or posedge usb_rst48_a)
begin : flops
if (usb_rst48_a == 1'b 1)
begin
phase_r3 <= 1'b 0;
phase_r2 <= 1'b 0;
phase_r1 <= 1'b 0;
clken_dpll <= 1'b 0;
j_state_in_r4 <= 1'b 0;
j_state_in_r3 <= 1'b 0;
datain_r2 <= 1'b 0;
datain_r1 <= 1'b 0;
dplus_r3 <= 1'b 0;
dplus_r2 <= 1'b 0;
dplus_r1 <= 1'b 0;
dminus_r3 <= 1'b 0;
dminus_r2 <= 1'b 0;
dminus_r1 <= 1'b 0;
se0_r5 <= 1'b 0;
se0_r4 <= 1'b 0;
end
else
begin
if (usb_rst48 == 1'b 1)
begin
phase_r3 <= 1'b 0;
phase_r2 <= 1'b 0;
phase_r1 <= 1'b 0;
clken_dpll <= 1'b 0;
j_state_in_r4 <= 1'b 0;
j_state_in_r3 <= 1'b 0;
datain_r2 <= 1'b 0;
datain_r1 <= 1'b 0;
dplus_r3 <= 1'b 0;
dplus_r2 <= 1'b 0;
dplus_r1 <= 1'b 0;
dminus_r3 <= 1'b 0;
dminus_r2 <= 1'b 0;
dminus_r1 <= 1'b 0;
se0_r5 <= 1'b 0;
se0_r4 <= 1'b 0;
end
else
begin
if (dpll_clk_en == 1'b 1)
begin
phase_r3 <= phase_r2;
phase_r2 <= phase_r1;
phase_r1 <= phase;
clken_dpll <= phase;
// Synchronize the DATAIN signal to remove metastability.
j_state_in_r4 <= j_state_in_r3; // Fourth stage synchronizer
j_state_in_r3 <= j_state_in_r2; // Third stage synchronizer
datain_r2 <= datain_r1; // Second stage synchronizer
datain_r1 <= datain | reset_after_clks_r4; // filtered with reset
// Fiusb_rst48 stage synchronizer
// Synchronize the D+ and D- to remove metastability.
dplus_r3 <= dplus_r2;
dplus_r2 <= dplus_r1;
dplus_r1 <= dplus;
dminus_r3 <= dminus_r2;
dminus_r2 <= dminus_r1;
dminus_r1 <= dminus;
se0_r5 <= se0_r4; // Save some history on se0 so that
se0_r4 <= se0_r3; // a detect circuit can be
// impelemented for either clock enable.
end
else
begin
clken_dpll <= 1'b 0;
end
end
// clock enable
end
// clock = '1'
end
// create the flip-flops that don't need reset.
assign j_state_in_r2 = datain_r2 ^ low_speed_signaling;
assign se0_r2 = ~dplus_r2 & ~dminus_r2;
assign se0_r3 = ~dplus_r3 & ~dminus_r3;
always @(posedge usb_clk48 or posedge usb_rst48_a)
begin : fixed_frequency
if (usb_rst48_a == 1'b 1)
begin
clk12_cnt <= 3'b 000;
clk_slow_en <= 1'b 0;
clkneg_slow_en <= 1'b 0;
clken_12l <= 1'b 0;
end
else
begin
if (usb_rst48 == 1'b 1)
begin
clk12_cnt <= 3'b 000;
clk_slow_en <= 1'b 0;
clkneg_slow_en <= 1'b 0;
clken_12l <= 1'b 0;
end
else
begin
clk12_cnt <= clk12_cnt + 1'b 1;
if (clk12_cnt[1:0] == 2'b 11)
begin
clken_12l <= 1'b 1;
end
else
begin
clken_12l <= 1'b 0;
end
if (clk12_cnt == 3'b 111)
begin
clk_slow_en <= 1'b 1;
end
else
begin
clk_slow_en <= 1'b 0;
end
if (clk12_cnt == 3'b 011)
begin
clkneg_slow_en <= 1'b 1;
end
else
begin
clkneg_slow_en <= 1'b 0;
end
end
// reset --vsync_usb_rst48
end
// clk / reset
end
// fixed_frequency
always @(posedge usb_clk48 or posedge usb_rst48_a)
begin : usb_rst48_vauto
if (usb_rst48_a == 1'b 1)
begin
reset_after_clks <= 1'b 1;
reset_after_clks_r1 <= 1'b 1;
reset_after_clks_r2 <= 1'b 1;
reset_after_clks_r3 <= 1'b 1;
reset_after_clks_r4 <= 1'b 1;
end
else
begin
if (usb_rst48 == 1'b 1)
begin
reset_after_clks <= 1'b 1;
reset_after_clks_r1 <= 1'b 1;
reset_after_clks_r2 <= 1'b 1;
reset_after_clks_r3 <= 1'b 1;
reset_after_clks_r4 <= 1'b 1;
end
else
begin
if (clk12_cnt[1:0] == 2'b 11)
begin
reset_after_clks_r4 <= reset_after_clks_r3;
reset_after_clks_r3 <= reset_after_clks_r2;
reset_after_clks_r2 <= reset_after_clks_r1;
reset_after_clks_r1 <= reset_after_clks;
reset_after_clks <= 1'b 0;
end
// clk12_cnt
end
// vsync_usb_rst48
end
// clk/reset
end
// The logic below this point has been added to increase the jitter
// tolerance of the phase lock loop beyond the +/-9ns paired edge jitter
// specification in the USB 1.1 specification. This logic requires 3 negitive
// edge triggered flip flops to gain additional resolution on the position of
// an incomming transition relative to the current DPLL output clock.
// Because These negative edge flops may cause a problem for automatic
// test insertion or other areas of your tool chain we have grouped
// the logic together so that it maybe easily removed from your
// design. This logic may be removed by uncommenting the following 4
// lines, and then commenting out or deleteting the lines between
// "JITTER HARDENNING REMOVE ON" and "JITTER HARDENNING REMOVE OFF"
// k_to_j_trans_dly <= '0'; -- treat the 180 out of sync window as
// very_late_transition <= '0'; -- a second early window.
// very_late_transition_f <= '0'; -- a second early window.
// se0_late_ff <= '0'; se0_late_fff <= '0';
// The following ASCII schematic shows the connections to and from the negative
// edge flip flops.
//
// ----- -----
// | | | |
// dplus | | dplus_late_f | | dplus_late_ff
// +-------------| |----------------| |---------------
// | | neg | | pos |
// | +--o> clk | +---> clk |
// | | ----- | -----
// | clk | |
// | +----------------------+
// | |
// vp | \ | | ----- -----
// ---|+ \-+ | | | | |
// | \ datain | | | datain_delayed | | datain_delayed_f
// | >-------------| |----------------| |------------------
// vm | / | | neg | | pos |
// ---|- /-+ +--o> clk | +---> clk |
// | / | | ----- | -----
// | clk | |
// | +----------------------+
// | |
// | | ----- -----
// | | | | | |
// | dminus | | | dminus_late_f | | dminus_late_ff
// +-------------| |----------------| |----------------
// | | neg | | pos |
// +--o> clk | +---> clk |
// | ----- | -----
// clk | |
// ------------------+----------------------+
//
// dplus, dminus and datain should come directly from the USB
// transciver I/O cells.
//
// This table characterizes the performance of the DPLL under ideal (unit delay
// simulation) conditions to random jitter on paired transitions of the inputs
// to the DPLL for the DPLL design with and without the addition of the jitter
// hardenning logic.
// Note: The USB specification for Jitter is +/-9ns with a frequency tollerance
// of +/-209 ps per bit for the paired transitions that are used to adjust the
// DPLL. No time budget has been made for the analog receiver circuits in this
// analysis.
// Total JITTER Frequency Tolerance Frequency Tolerance
// Unimproved Design Jitter Hardenned design
// ---------- ---------- ----------
// +/- 0 ns +/- 1.4 ns +/- 1.4 ns
// +/- 5 ns +/- 800 ps +/- 1.4 ns
// +/- 9 ns +/- 210 ps +/- 800 ps
// +/- 10 ns +/- 0 ps +/- 700 ps
// +/- 11 ns can not track +/- 600 ps
// +/- 12 ns can not track +/- 400 ps
// +/- 13 ns can not track +/- 200 ps
// +/- 14.75 ns can not track +/- 100 ps
//
// JITTER HARDENNING REMOVE ON
// create the reset DFFs
// create the reset DFFs
// These flops hold the DPLL in SE0 which in turn ignores D+/D-
// for 3 bit times which allows these lines to stablize.
// Without this, you often get Xes in the gate level simulations.
assign k_to_j_trans_dly = ~j_delayed_in_r4 & j_delayed_in_r3; // K to J
// transition present on faling edge of clock prior to transition
assign very_late_transition = (j_state_in_r3 ^ j_state_in_r2) & (j_delayed_in_r3 ^ j_delayed_in_r2) &
late_window; // late window or the half cycle after it.
// very_early_transition <= k_to_j_trans and not k_to_j_trans_dly and check_sync;
// This signal is not used but can be displayed in simulation to watch for
// early adjustments in the 180 degree out of phase window.
always @(posedge usb_clk48 or posedge usb_rst48_a)
begin : jitter_flops
if (usb_rst48_a == 1'b 1)
begin
j_delayed_in_r4 <= 1'b 0;
j_delayed_in_r3 <= 1'b 0;
datain_delayed_r2 <= 1'b 0;
datain_delayed_r1 <= 1'b 0;
se0_late_r3 <= 1'b 0;
dplus_late_r2 <= 1'b 0;
dminus_late_r2 <= 1'b 0;
very_late_transition_r1 <= 1'b 0;
end
else
begin
if (usb_rst48 == 1'b 1)
begin
j_delayed_in_r4 <= 1'b 0;
j_delayed_in_r3 <= 1'b 0;
datain_delayed_r2 <= 1'b 0;
datain_delayed_r1 <= 1'b 0;
se0_late_r3 <= 1'b 0;
dplus_late_r2 <= 1'b 0;
dminus_late_r2 <= 1'b 0;
very_late_transition_r1 <= 1'b 0;
end
else
begin
if (dpll_clk_en == 1'b 1)
begin
j_delayed_in_r4 <= j_delayed_in_r3; // Fourth stage synchronizer
j_delayed_in_r3 <= j_delayed_in_r2; // Third stage synchronizer
datain_delayed_r2 <= datain_delayed_r1; // Second stage synchronizer
datain_delayed_r1 <= datain_delayed | reset_after_clks_r4; // filtered with reset
// Fiusb_rst48 stage synchronizer
se0_late_r3 <= se0_late_r2; // used to capture late SE0 events.
dplus_late_r2 <= dplus_late_r1;
dminus_late_r2 <= dminus_late_r1;
very_late_transition_r1 <= very_late_transition;
end
// DATAIN delayed has been sampled on the negative edge of clock.
end
end
end
always @(negedge usb_clk48 or posedge usb_rst48_a)
begin : neg_flop
if (usb_rst48_a == 1'b 1)
begin
datain_delayed <= 1'b 0;
dplus_late_r1 <= 1'b 0;
dminus_late_r1 <= 1'b 0;
end
else
begin
if (usb_rst48 == 1'b 1)
begin
datain_delayed <= 1'b 0;
dplus_late_r1 <= 1'b 0;
dminus_late_r1 <= 1'b 0;
end
else
begin
if (dpll_clkneg_en == 1'b 1)
begin
datain_delayed <= datain;
dplus_late_r1 <= dplus;
dminus_late_r1 <= dminus;
end
end
end
end
// create the negative edge flip-flop
assign j_delayed_in_r2 = datain_delayed_r2 ^ low_speed_signaling;
assign se0_late_r2 = ~dplus_late_r2 & ~dminus_late_r2;
// JITTER HARDENNING REMOVE OFF
// --------------Architecture rtl-----------
endmodule // module vusb_dpllnrzi