dvisampler: use pix5x as IODELAY clock
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Mon, 18 Mar 2013 18:03:17 +0000 (19:03 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Mon, 18 Mar 2013 18:03:17 +0000 (19:03 +0100)
milkymist/dvisampler/__init__.py
milkymist/dvisampler/clocking.py
milkymist/dvisampler/datacapture.py

index e0f2fda5f5436cdf0f20f1bc8ae5c27f38b183e9..477585f03b1621241411c65872e092cbf41dec38 100644 (file)
@@ -25,6 +25,5 @@ class DVISampler(Module, AutoReg):
                        setattr(self, name, s)
                        self.comb += [
                                cap.pad.eq(s),
-                               cap.serdesstrobe.eq(self.clocking.serdesstrobe),
-                               cap.delay_rst.eq(~self.clocking.locked)
+                               cap.serdesstrobe.eq(self.clocking.serdesstrobe)
                        ]
index 44dd76ce4a798a00a057d32a338e3507e5b60901..0dbc33e5ad89994db975a06125191791ce1047d7 100644 (file)
@@ -8,7 +8,7 @@ class Clocking(Module, AutoReg):
        def __init__(self):
                self.clkin = Signal()
 
-               self._r_pll_reset = RegisterField(reset=1)
+               self._r_pll_reset = RegisterField()
                self._r_locked = RegisterField(1, READ_ONLY, WRITE_ONLY)
 
                self.locked = Signal()
@@ -46,15 +46,16 @@ class Clocking(Module, AutoReg):
                self.specials += Instance("BUFPLL",
                        Instance.Parameter("DIVIDE", 4),
                        Instance.Input("PLLIN", pll_clk0),
-                       Instance.ClockPort("GCLK", "pix5x"),
+                       Instance.Input("GCLK", ClockSignal("pix5x")),
                        Instance.Input("LOCKED", pll_locked),
                        Instance.Output("IOCLK", self._cd_pix20x.clk),
                        Instance.Output("LOCK", locked_async),
                        Instance.Output("SERDESSTROBE", self.serdesstrobe)
                )
-               self.specials += MultiReg(locked_async, self.locked, "sys")
-               self.comb += self._r_locked.field.w.eq(self.locked)
                self.specials += Instance("BUFG",
                        Instance.Input("I", pll_clk1), Instance.Output("O", self._cd_pix5x.clk))
                self.specials += Instance("BUFG",
                        Instance.Input("I", pll_clk2), Instance.Output("O", self._cd_pix.clk))
+               self.specials += MultiReg(locked_async, self.locked, "sys")
+               self.specials += MultiReg(~locked_async, self._cd_pix5x.rst, "pix5x")
+               self.comb += self._r_locked.field.w.eq(self.locked)
index 5fa883e9d43569a70a143b2ea4eb475227d45d56..6a534987505929b0cafaae426ee1eb48c2b9939f 100644 (file)
@@ -1,19 +1,17 @@
 from migen.fhdl.structure import *
 from migen.fhdl.module import Module
 from migen.fhdl.specials import Instance
-from migen.genlib.cdc import PulseSynchronizer
+from migen.genlib.cdc import MultiReg, PulseSynchronizer
 from migen.bank.description import *
 
 class DataCapture(Module, AutoReg):
        def __init__(self, ntbits, debug=False):
                self.pad = Signal()
                self.serdesstrobe = Signal()
-               self.delay_rst = Signal() # system clock domain
                self.d0 = Signal() # pix5x clock domain
                self.d1 = Signal() # pix5x clock domain
 
                if debug:
-                       self._r_delay_rst = RegisterRaw()
                        self._r_current_tap = RegisterField(8, READ_ONLY, WRITE_ONLY)
 
                ###
@@ -22,8 +20,6 @@ class DataCapture(Module, AutoReg):
                pad_delayed = Signal()
                delay_inc = Signal()
                delay_ce = Signal()
-               delay_rst = Signal()
-               delay_init = Signal()
                self.specials += Instance("IODELAY2",
                        Instance.Parameter("DELAY_SRC", "IDATAIN"),
                        Instance.Parameter("IDELAY_TYPE", "VARIABLE_FROM_ZERO"),
@@ -31,22 +27,14 @@ class DataCapture(Module, AutoReg):
                        Instance.Parameter("DATA_RATE", "SDR"),
                        Instance.Input("IDATAIN", self.pad),
                        Instance.Output("DATAOUT", pad_delayed),
-                       Instance.Input("INC", delay_inc | delay_init),
-                       Instance.Input("CE", delay_ce | delay_init),
-                       Instance.Input("RST", delay_rst),
-                       Instance.ClockPort("CLK"),
-                       Instance.ClockPort("IOCLK0", "pix20x"),
+                       Instance.Input("INC", delay_inc),
+                       Instance.Input("CE", delay_ce),
+                       Instance.Input("RST", ResetSignal("pix5x")),
+                       Instance.Input("CLK", ClockSignal("pix5x")),
+                       Instance.Input("IOCLK0", ClockSignal("pix20x")),
                        Instance.Input("CAL", 0),
                        Instance.Input("T", 1)
                )
-               # initialize delay to 127 taps
-               delay_init_count = Signal(7, reset=127)
-               self.comb += delay_init.eq(delay_init_count != 0)
-               self.sync += If(delay_rst,
-                               delay_init_count.eq(127)
-                       ).Elif(delay_init,
-                               delay_init_count.eq(delay_init_count - 1)
-                       )
 
                d0p = Signal()
                d1p = Signal()
@@ -62,8 +50,8 @@ class DataCapture(Module, AutoReg):
                        Instance.Output("Q1", d1p),
                        Instance.Input("BITSLIP", 0),
                        Instance.Input("CE0", 1),
-                       Instance.ClockPort("CLK0", "pix20x"),
-                       Instance.ClockPort("CLKDIV", "pix5x"),
+                       Instance.Input("CLK0", ClockSignal("pix20x")),
+                       Instance.Input("CLKDIV", ClockSignal("pix5x")),
                        Instance.Input("D", pad_delayed),
                        Instance.Input("IOCE", self.serdesstrobe),
                        Instance.Input("RST", 0)
@@ -107,32 +95,34 @@ class DataCapture(Module, AutoReg):
                        )
                ]
 
-               # Send delay update commands to system (IDELAY) clock domain
-               self.submodules.xf_inc = PulseSynchronizer("pix5x", "sys")
-               self.submodules.xf_dec = PulseSynchronizer("pix5x", "sys")
+               # Drive IODELAY controls
+               delay_init = Signal()
+               delay_init_count = Signal(7, reset=127)
+               self.comb += delay_init.eq(delay_init_count != 0)
+               self.sync.pix5x += If(delay_init, delay_init_count.eq(delay_init_count - 1))
                self.comb += [
-                       self.xf_inc.i.eq(pulse_inc),
-                       delay_inc.eq(self.xf_inc.o),
-                       self.xf_dec.i.eq(pulse_dec),
-                       delay_ce.eq(self.xf_inc.o | self.xf_dec.o)
+                       delay_ce.eq(delay_init | pulse_inc | pulse_dec),
+                       delay_inc.eq(delay_init | pulse_inc)
                ]
 
                # Debug
                if debug:
-                       self.comb += delay_rst.eq(self.delay_rst | self._r_delay_rst.re)
-                       current_tap = self._r_current_tap.field.w
-                       self.sync += If(delay_rst,
-                               current_tap.eq(0)
-                       ).Elif(delay_ce,
-                               If(delay_inc,
-                                       If(current_tap != 0xff,
-                                               current_tap.eq(current_tap + 1)
-                                       )
-                               ).Else(
-                                       If(current_tap != 0,
-                                               current_tap.eq(current_tap - 1)
-                                       )
+                       # Transfer delay update commands to system clock domain
+                       pix5x_reset_sys = Signal()
+                       self.specials += MultiReg(ResetSignal("pix5x"), pix5x_reset_sys, "sys")
+                       self.submodules.xf_inc = PulseSynchronizer("pix5x", "sys")
+                       self.submodules.xf_dec = PulseSynchronizer("pix5x", "sys")
+                       self.comb += [
+                               self.xf_inc.i.eq(pulse_inc),
+                               self.xf_dec.i.eq(pulse_dec)
+                       ]
+                       # Update tap count in system clock domain
+                       current_tap = Signal(8, reset=127)
+                       self.comb += self._r_current_tap.field.w.eq(current_tap)
+                       self.sync += If(pix5x_reset_sys,
+                                       current_tap.eq(127)
+                               ).Elif(self.xf_inc.o & (current_tap != 0xff),
+                                       current_tap.eq(current_tap + 1)
+                               ).Elif(self.xf_dec.o & (current_tap != 0),
+                                       current_tap.eq(current_tap - 1)
                                )
-                       )
-               else:
-                       self.comb += delay_rst.eq(self.delay_rst)