from migen import * from migen.genlib.cdc import PulseSynchronizer, MultiReg from migen.genlib.fsm import FSM from misoc.interconnect.csr import * class DDMTDSamplerGTX(Module): def __init__(self, gtx, main_xo_pads): self.gtx_beating = Signal() self.main_beating = Signal() # # # main_clk_se = Signal() gtx_beating_FF = Signal() main_beating_FF = Signal() self.specials += [ Instance("IBUFDS", i_I=main_xo_pads.p, i_IB=main_xo_pads.n, o_O=main_clk_se), # Two back to back FFs are used to prevent metastability Instance("FD", i_C=ClockSignal("helper"), i_D=gtx.cd_rtio_rx0.clk, o_Q=gtx_beating_FF), Instance("FD", i_C=ClockSignal("helper"), i_D=gtx_beating_FF, o_Q=self.gtx_beating), Instance("FD", i_C=ClockSignal("helper"), i_D=main_clk_se, o_Q=main_beating_FF,), Instance("FD", i_C=ClockSignal("helper"), i_D=main_beating_FF, o_Q=self.main_beating,) ] class DDMTDDeglitcherFirstEdge(Module): def __init__(self, input_signal, blind_period=200): self.detect = Signal() rising = Signal() input_signal_r = Signal() # # # self.sync.helper += [ input_signal_r.eq(input_signal), rising.eq(input_signal & ~input_signal_r) ] blind_counter = Signal(max=blind_period) self.sync.helper += [ If(blind_counter != 0, blind_counter.eq(blind_counter - 1)), If(input_signal_r, blind_counter.eq(blind_period - 1)), self.detect.eq(rising & (blind_counter == 0)) ] class DDMTD(Module): def __init__(self, counter, input_signal): # in helper clock domain self.h_tag = Signal(len(counter)) self.h_tag_update = Signal() # # # deglitcher = DDMTDDeglitcherFirstEdge(input_signal) self.submodules += deglitcher self.sync.helper += [ self.h_tag_update.eq(0), If(deglitcher.detect, self.h_tag_update.eq(1), self.h_tag.eq(counter) ) ]