diff --git a/artiq/gateware/drtio/xilinx_rx_synchronizer.py b/artiq/gateware/drtio/xilinx_rx_synchronizer.py new file mode 100644 index 000000000..d6bdfa0aa --- /dev/null +++ b/artiq/gateware/drtio/xilinx_rx_synchronizer.py @@ -0,0 +1,38 @@ +from migen import * + + +class XilinxRXSynchronizer(Module): + """Deterministic RX synchronizer using a relatively placed macro + to put the clock-domain-crossing FFs right next to each other. + + To meet setup/hold constraints receiving FFs, adjust the phase shift + of the Si5324. + + We assume that FPGA routing variations are small enough to be negligible. + """ + def __init__(self): + self.signals = [] + + def resync(self, signal): + synchronized = Signal.like(signal, related=signal) + self.signals.append((signal, synchronized)) + return synchronized + + def do_finalize(self): + l = sum(len(s[0]) for s in self.signals) + din = Signal(l) + inter = Signal(l) + dout = Signal(l) + self.comb += [ + din.eq(Cat(*[s[0] for s in self.signals])), + Cat(*[s[1] for s in self.signals]).eq(dout) + ] + + for i in range(l): + hu_set = ("HU_SET", "drtio_rx_synchronizer") + self.specials += [ + Instance("FD", i_C=ClockSignal("rtio_rx"), i_D=din[i], o_Q=inter[i], + attr={hu_set, ("RLOC", "X0Y{}".format(i))}), + Instance("FD", i_C=ClockSignal("rtio"), i_D=inter[i], o_Q=dout[i], + attr={hu_set, ("RLOC", "X1Y{}".format(i))}) + ]