Skip to content

Commit 5126f61

Browse files
author
Sebastien Bourdeauducq
committedMar 18, 2013
dvisampler: use pix5x as IODELAY clock
1 parent 48aae9b commit 5126f61

File tree

3 files changed

+39
-49
lines changed

3 files changed

+39
-49
lines changed
 

‎milkymist/dvisampler/__init__.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,5 @@ def __init__(self, inversions="", debug_data_capture=True):
2525
setattr(self, name, s)
2626
self.comb += [
2727
cap.pad.eq(s),
28-
cap.serdesstrobe.eq(self.clocking.serdesstrobe),
29-
cap.delay_rst.eq(~self.clocking.locked)
28+
cap.serdesstrobe.eq(self.clocking.serdesstrobe)
3029
]

‎milkymist/dvisampler/clocking.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class Clocking(Module, AutoReg):
88
def __init__(self):
99
self.clkin = Signal()
1010

11-
self._r_pll_reset = RegisterField(reset=1)
11+
self._r_pll_reset = RegisterField()
1212
self._r_locked = RegisterField(1, READ_ONLY, WRITE_ONLY)
1313

1414
self.locked = Signal()
@@ -46,15 +46,16 @@ def __init__(self):
4646
self.specials += Instance("BUFPLL",
4747
Instance.Parameter("DIVIDE", 4),
4848
Instance.Input("PLLIN", pll_clk0),
49-
Instance.ClockPort("GCLK", "pix5x"),
49+
Instance.Input("GCLK", ClockSignal("pix5x")),
5050
Instance.Input("LOCKED", pll_locked),
5151
Instance.Output("IOCLK", self._cd_pix20x.clk),
5252
Instance.Output("LOCK", locked_async),
5353
Instance.Output("SERDESSTROBE", self.serdesstrobe)
5454
)
55-
self.specials += MultiReg(locked_async, self.locked, "sys")
56-
self.comb += self._r_locked.field.w.eq(self.locked)
5755
self.specials += Instance("BUFG",
5856
Instance.Input("I", pll_clk1), Instance.Output("O", self._cd_pix5x.clk))
5957
self.specials += Instance("BUFG",
6058
Instance.Input("I", pll_clk2), Instance.Output("O", self._cd_pix.clk))
59+
self.specials += MultiReg(locked_async, self.locked, "sys")
60+
self.specials += MultiReg(~locked_async, self._cd_pix5x.rst, "pix5x")
61+
self.comb += self._r_locked.field.w.eq(self.locked)

‎milkymist/dvisampler/datacapture.py

+33-43
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
from migen.fhdl.structure import *
22
from migen.fhdl.module import Module
33
from migen.fhdl.specials import Instance
4-
from migen.genlib.cdc import PulseSynchronizer
4+
from migen.genlib.cdc import MultiReg, PulseSynchronizer
55
from migen.bank.description import *
66

77
class DataCapture(Module, AutoReg):
88
def __init__(self, ntbits, debug=False):
99
self.pad = Signal()
1010
self.serdesstrobe = Signal()
11-
self.delay_rst = Signal() # system clock domain
1211
self.d0 = Signal() # pix5x clock domain
1312
self.d1 = Signal() # pix5x clock domain
1413

1514
if debug:
16-
self._r_delay_rst = RegisterRaw()
1715
self._r_current_tap = RegisterField(8, READ_ONLY, WRITE_ONLY)
1816

1917
###
@@ -22,31 +20,21 @@ def __init__(self, ntbits, debug=False):
2220
pad_delayed = Signal()
2321
delay_inc = Signal()
2422
delay_ce = Signal()
25-
delay_rst = Signal()
26-
delay_init = Signal()
2723
self.specials += Instance("IODELAY2",
2824
Instance.Parameter("DELAY_SRC", "IDATAIN"),
2925
Instance.Parameter("IDELAY_TYPE", "VARIABLE_FROM_ZERO"),
3026
Instance.Parameter("COUNTER_WRAPAROUND", "STAY_AT_LIMIT"),
3127
Instance.Parameter("DATA_RATE", "SDR"),
3228
Instance.Input("IDATAIN", self.pad),
3329
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")),
3935
Instance.Input("CAL", 0),
4036
Instance.Input("T", 1)
4137
)
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-
)
5038

5139
d0p = Signal()
5240
d1p = Signal()
@@ -62,8 +50,8 @@ def __init__(self, ntbits, debug=False):
6250
Instance.Output("Q1", d1p),
6351
Instance.Input("BITSLIP", 0),
6452
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")),
6755
Instance.Input("D", pad_delayed),
6856
Instance.Input("IOCE", self.serdesstrobe),
6957
Instance.Input("RST", 0)
@@ -107,32 +95,34 @@ def __init__(self, ntbits, debug=False):
10795
)
10896
]
10997

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))
113103
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)
118106
]
119107

120108
# Debug
121109
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)
135128
)
136-
)
137-
else:
138-
self.comb += delay_rst.eq(self.delay_rst)

0 commit comments

Comments
 (0)
Please sign in to comment.