diff --git a/milkymist/dvisampler/__init__.py b/milkymist/dvisampler/__init__.py index e0f2fda5f..477585f03 100644 --- a/milkymist/dvisampler/__init__.py +++ b/milkymist/dvisampler/__init__.py @@ -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) ] diff --git a/milkymist/dvisampler/clocking.py b/milkymist/dvisampler/clocking.py index 44dd76ce4..0dbc33e5a 100644 --- a/milkymist/dvisampler/clocking.py +++ b/milkymist/dvisampler/clocking.py @@ -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) diff --git a/milkymist/dvisampler/datacapture.py b/milkymist/dvisampler/datacapture.py index 5fa883e9d..6a5349875 100644 --- a/milkymist/dvisampler/datacapture.py +++ b/milkymist/dvisampler/datacapture.py @@ -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)