1 from migen
.fhdl
.structure
import *
2 from migen
.fhdl
.module
import Module
3 from migen
.fhdl
.specials
import Instance
4 from migen
.genlib
.cdc
import PulseSynchronizer
5 from migen
.bank
.description
import *
7 class DataCapture(Module
, AutoReg
):
8 def __init__(self
, ntbits
, debug
=False):
10 self
.serdesstrobe
= Signal()
11 self
.delay_rst
= Signal() # system clock domain
12 self
.d0
= Signal() # pix5x clock domain
13 self
.d1
= Signal() # pix5x clock domain
16 self
._r
_delay
_rst
= RegisterRaw()
17 self
._r
_current
_tap
= RegisterField(8, READ_ONLY
, WRITE_ONLY
)
22 pad_delayed
= Signal()
27 self
.specials
+= Instance("IODELAY2",
28 Instance
.Parameter("DELAY_SRC", "IDATAIN"),
29 Instance
.Parameter("IDELAY_TYPE", "VARIABLE_FROM_ZERO"),
30 Instance
.Parameter("COUNTER_WRAPAROUND", "STAY_AT_LIMIT"),
31 Instance
.Input("IDATAIN", self
.pad
),
32 Instance
.Output("DATAOUT", pad_delayed
),
33 Instance
.Input("INC", delay_inc | delay_init
),
34 Instance
.Input("CE", delay_ce | delay_init
),
35 Instance
.Input("RST", delay_rst
),
36 Instance
.ClockPort("CLK"),
37 Instance
.Input("CAL", 0),
38 Instance
.Input("T", 1)
40 # initialize delay to 127 taps
41 delay_init_count
= Signal(7, reset
=127)
42 self
.comb
+= delay_init
.eq(delay_init_count
!= 0)
43 self
.sync
+= If(delay_rst
,
44 delay_init_count
.eq(127)
46 delay_init_count
.eq(delay_init_count
- 1)
51 self
.specials
+= Instance("ISERDES2",
52 Instance
.Parameter("BITSLIP_ENABLE", "FALSE"),
53 Instance
.Parameter("DATA_RATE", "SDR"),
54 Instance
.Parameter("DATA_WIDTH", 4),
55 Instance
.Parameter("INTERFACE_TYPE", "RETIMED"),
56 Instance
.Parameter("SERDES_MODE", "NONE"),
57 Instance
.Output("Q4", self
.d0
),
58 Instance
.Output("Q3", d0p
),
59 Instance
.Output("Q2", self
.d1
),
60 Instance
.Output("Q1", d1p
),
61 Instance
.Input("BITSLIP", 0),
62 Instance
.Input("CE0", 1),
63 Instance
.ClockPort("CLK0", "pix20x"),
64 Instance
.ClockPort("CLKDIV", "pix5x"),
65 Instance
.Input("D", pad_delayed
),
66 Instance
.Input("IOCE", self
.serdesstrobe
),
67 Instance
.Input("RST", 0)
71 transitions
= Signal(ntbits
)
72 lateness
= Signal((ntbits
+ 1, True))
78 If(transitions
== 2**ntbits
- 1,
86 ).Elif(self
.d0
!= self
.d1
,
91 lateness
.eq(lateness
- 1)
93 lateness
.eq(lateness
+ 1)
99 lateness
.eq(lateness
+ 1)
101 lateness
.eq(lateness
- 1)
104 transitions
.eq(transitions
+ 1)
108 # Send delay update commands to system (IDELAY) clock domain
109 self
.submodules
.xf_inc
= PulseSynchronizer("pix5x", "sys")
110 self
.submodules
.xf_dec
= PulseSynchronizer("pix5x", "sys")
112 self
.xf_inc
.i
.eq(pulse_inc
),
113 delay_inc
.eq(self
.xf_inc
.o
),
114 self
.xf_dec
.i
.eq(pulse_dec
),
115 delay_ce
.eq(self
.xf_inc
.o | self
.xf_dec
.o
)
120 self
.comb
+= delay_rst
.eq(self
.delay_rst | self
._r
_delay
_rst
.re
)
121 current_tap
= self
._r
_current
_tap
.field
.w
122 self
.sync
+= If(delay_rst
,
126 If(current_tap
!= 0xff,
127 current_tap
.eq(current_tap
+ 1)
131 current_tap
.eq(current_tap
- 1)
136 self
.comb
+= delay_rst
.eq(self
.delay_rst
)