1
1
from migen .fhdl .structure import *
2
2
from migen .fhdl .module import Module
3
3
from migen .fhdl .specials import Instance
4
- from migen .genlib .cdc import PulseSynchronizer
4
+ from migen .genlib .cdc import MultiReg , PulseSynchronizer
5
5
from migen .bank .description import *
6
6
7
7
class DataCapture (Module , AutoReg ):
8
8
def __init__ (self , ntbits , debug = False ):
9
9
self .pad = Signal ()
10
10
self .serdesstrobe = Signal ()
11
- self .delay_rst = Signal () # system clock domain
12
11
self .d0 = Signal () # pix5x clock domain
13
12
self .d1 = Signal () # pix5x clock domain
14
13
15
14
if debug :
16
- self ._r_delay_rst = RegisterRaw ()
17
15
self ._r_current_tap = RegisterField (8 , READ_ONLY , WRITE_ONLY )
18
16
19
17
###
@@ -22,31 +20,21 @@ def __init__(self, ntbits, debug=False):
22
20
pad_delayed = Signal ()
23
21
delay_inc = Signal ()
24
22
delay_ce = Signal ()
25
- delay_rst = Signal ()
26
- delay_init = Signal ()
27
23
self .specials += Instance ("IODELAY2" ,
28
24
Instance .Parameter ("DELAY_SRC" , "IDATAIN" ),
29
25
Instance .Parameter ("IDELAY_TYPE" , "VARIABLE_FROM_ZERO" ),
30
26
Instance .Parameter ("COUNTER_WRAPAROUND" , "STAY_AT_LIMIT" ),
31
27
Instance .Parameter ("DATA_RATE" , "SDR" ),
32
28
Instance .Input ("IDATAIN" , self .pad ),
33
29
Instance .Output ("DATAOUT" , pad_delayed ),
34
- Instance .Input ("INC" , delay_inc | delay_init ),
35
- Instance .Input ("CE" , delay_ce | delay_init ),
36
- Instance .Input ("RST" , delay_rst ),
37
- Instance .ClockPort ("CLK" ),
38
- Instance .ClockPort ("IOCLK0" , "pix20x" ),
30
+ Instance .Input ("INC" , delay_inc ),
31
+ Instance .Input ("CE" , delay_ce ),
32
+ Instance .Input ("RST" , ResetSignal ( "pix5x" ) ),
33
+ Instance .Input ("CLK" , ClockSignal ( "pix5x" ) ),
34
+ Instance .Input ("IOCLK0" , ClockSignal ( "pix20x" ) ),
39
35
Instance .Input ("CAL" , 0 ),
40
36
Instance .Input ("T" , 1 )
41
37
)
42
- # initialize delay to 127 taps
43
- delay_init_count = Signal (7 , reset = 127 )
44
- self .comb += delay_init .eq (delay_init_count != 0 )
45
- self .sync += If (delay_rst ,
46
- delay_init_count .eq (127 )
47
- ).Elif (delay_init ,
48
- delay_init_count .eq (delay_init_count - 1 )
49
- )
50
38
51
39
d0p = Signal ()
52
40
d1p = Signal ()
@@ -62,8 +50,8 @@ def __init__(self, ntbits, debug=False):
62
50
Instance .Output ("Q1" , d1p ),
63
51
Instance .Input ("BITSLIP" , 0 ),
64
52
Instance .Input ("CE0" , 1 ),
65
- Instance .ClockPort ("CLK0" , "pix20x" ),
66
- Instance .ClockPort ("CLKDIV" , "pix5x" ),
53
+ Instance .Input ("CLK0" , ClockSignal ( "pix20x" ) ),
54
+ Instance .Input ("CLKDIV" , ClockSignal ( "pix5x" ) ),
67
55
Instance .Input ("D" , pad_delayed ),
68
56
Instance .Input ("IOCE" , self .serdesstrobe ),
69
57
Instance .Input ("RST" , 0 )
@@ -107,32 +95,34 @@ def __init__(self, ntbits, debug=False):
107
95
)
108
96
]
109
97
110
- # Send delay update commands to system (IDELAY) clock domain
111
- self .submodules .xf_inc = PulseSynchronizer ("pix5x" , "sys" )
112
- self .submodules .xf_dec = PulseSynchronizer ("pix5x" , "sys" )
98
+ # Drive IODELAY controls
99
+ delay_init = Signal ()
100
+ delay_init_count = Signal (7 , reset = 127 )
101
+ self .comb += delay_init .eq (delay_init_count != 0 )
102
+ self .sync .pix5x += If (delay_init , delay_init_count .eq (delay_init_count - 1 ))
113
103
self .comb += [
114
- self .xf_inc .i .eq (pulse_inc ),
115
- delay_inc .eq (self .xf_inc .o ),
116
- self .xf_dec .i .eq (pulse_dec ),
117
- delay_ce .eq (self .xf_inc .o | self .xf_dec .o )
104
+ delay_ce .eq (delay_init | pulse_inc | pulse_dec ),
105
+ delay_inc .eq (delay_init | pulse_inc )
118
106
]
119
107
120
108
# Debug
121
109
if debug :
122
- self .comb += delay_rst .eq (self .delay_rst | self ._r_delay_rst .re )
123
- current_tap = self ._r_current_tap .field .w
124
- self .sync += If (delay_rst ,
125
- current_tap .eq (0 )
126
- ).Elif (delay_ce ,
127
- If (delay_inc ,
128
- If (current_tap != 0xff ,
129
- current_tap .eq (current_tap + 1 )
130
- )
131
- ).Else (
132
- If (current_tap != 0 ,
133
- current_tap .eq (current_tap - 1 )
134
- )
110
+ # Transfer delay update commands to system clock domain
111
+ pix5x_reset_sys = Signal ()
112
+ self .specials += MultiReg (ResetSignal ("pix5x" ), pix5x_reset_sys , "sys" )
113
+ self .submodules .xf_inc = PulseSynchronizer ("pix5x" , "sys" )
114
+ self .submodules .xf_dec = PulseSynchronizer ("pix5x" , "sys" )
115
+ self .comb += [
116
+ self .xf_inc .i .eq (pulse_inc ),
117
+ self .xf_dec .i .eq (pulse_dec )
118
+ ]
119
+ # Update tap count in system clock domain
120
+ current_tap = Signal (8 , reset = 127 )
121
+ self .comb += self ._r_current_tap .field .w .eq (current_tap )
122
+ self .sync += If (pix5x_reset_sys ,
123
+ current_tap .eq (127 )
124
+ ).Elif (self .xf_inc .o & (current_tap != 0xff ),
125
+ current_tap .eq (current_tap + 1 )
126
+ ).Elif (self .xf_dec .o & (current_tap != 0 ),
127
+ current_tap .eq (current_tap - 1 )
135
128
)
136
- )
137
- else :
138
- self .comb += delay_rst .eq (self .delay_rst )
0 commit comments