def create_clkout(self, cd, freq, phase=0, buf="bufg", margin=1e-2, with_reset=True, ce=None): assert self.nclkouts < self.nclkouts_max clkout = Signal() self.clkouts[self.nclkouts] = (clkout, freq, phase, margin) if with_reset: self.specials += AsyncResetSynchronizer(cd, ~self.locked | self.reset) if buf is None: self.comb += cd.clk.eq(clkout) else: clkout_buf = Signal() self.comb += cd.clk.eq(clkout_buf) if buf == "bufg": self.specials += Instance("BUFG", i_I=clkout, o_O=clkout_buf) elif buf == "bufr": self.specials += Instance("BUFR", i_I=clkout, o_O=clkout_buf) elif buf == "bufgce": if ce is None: raise ValueError( "BUFGCE requires user to provide a clock enable ce Signal" ) self.specials += Instance("BUFGCE", i_I=clkout, o_O=clkout_buf, i_CE=ce) elif buf == "bufio": self.specials += Instance("BUFIO", i_I=clkout, o_O=clkout_buf) else: raise ValueError("Unsupported clock buffer: {}".format(buf)) create_clkout_log(self.logger, cd.name, freq, margin, self.nclkouts) self.nclkouts += 1
def __init__(self, platform, sys_clk_freq, refclk_from_pll, refclk_freq): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_por = ClockDomain(reset_less=True) self.clock_domains.cd_ref = ClockDomain(reset_less=True) self.phasesel = CSRStorage(2) self.phasedir = CSRStorage() self.phasestep = CSRStorage() self.phaseloadreg = CSRStorage() # # # # clk / rst clk100 = platform.request("clk100") rst_n = platform.request("rst_n") platform.add_period_constraint(clk100, 1e9/100e6) # power on reset por_count = Signal(16, reset=2**16-1) por_done = Signal() self.comb += self.cd_por.clk.eq(ClockSignal()) self.comb += por_done.eq(por_count == 0) self.sync.por += If(~por_done, por_count.eq(por_count - 1)) # pll self.submodules.pll = pll = ECP5PLL() pll.register_clkin(clk100, 100e6) pll.create_clkout(self.cd_sys, sys_clk_freq) if refclk_from_pll: pll.create_clkout(self.cd_ref, refclk_freq) self.specials += AsyncResetSynchronizer( self.cd_sys, ~por_done | ~pll.locked | ~rst_n) self.comb += [ pll.phasesel.eq(self.phasesel.storage), pll.phasedir.eq(self.phasedir.storage), pll.phasestep.eq(self.phasestep.storage), pll.phaseloadreg.eq(self.phaseloadreg.storage), ]
def __init__(self, platform, sys_clk_freq, x5_clk_freq): self.clock_domains.cd_sys = ClockDomain() # self.clock_domains.cd_hr2x = ClockDomain() # self.clock_domains.cd_hr = ClockDomain() # self.clock_domains.cd_hr2x_90 = ClockDomain() # self.clock_domains.cd_hr_90 = ClockDomain() self.clock_domains.cd_adc_bitclk = ClockDomain() self.clock_domains.cd_adc_sampleclk = ClockDomain() # # # adc_clks = platform.request("adc_clks") # clk / rst clk = clk12 = platform.request("clk12") rst_n = platform.request("rst_n") if x5_clk_freq is not None: clk = clk50 = platform.request("ext_clk50") self.comb += platform.request("ext_clk50_en").eq(1) platform.add_period_constraint(clk50, 1e9 / x5_clk_freq) # sysclk pll, also generate sample clock sampleclk_freq = 25e6 self.submodules.pll = pll = ECP5PLL() self.comb += pll.reset.eq(~rst_n) pll.register_clkin(clk, x5_clk_freq or 12e6) pll.create_clkout(self.cd_sys, sys_clk_freq) pll.create_clkout(self.cd_adc_sampleclk, sampleclk_freq) self.comb += adc_clks.sclk.eq(~self.cd_adc_sampleclk.clk) self.specials += AsyncResetSynchronizer(self.cd_sys, ~rst_n) # bitclk pll bitclk_freq = 150e6 self.submodules.bitclk_pll = bitclk_pll = ECP5PLL() platform.add_period_constraint(adc_clks.dclk, 1e9 / bitclk_freq) self.comb += bitclk_pll.reset.eq(~rst_n) bitclk_pll.register_clkin(adc_clks.dclk, bitclk_freq) bitclk_pll.create_clkout(self.cd_adc_bitclk, bitclk_freq, phase=200) #200)
def __init__(self, platform): self.clock_domains.cd_sys = ClockDomain() clk200 = platform.request("clk200") clk200_se = Signal() self.specials += Instance("IBUFDS", i_I=clk200.p, i_IB=clk200.n, o_O=clk200_se) try: cpu_reset = platform.request("cpu_reset") except: cpu_reset = ~platform.request("cpu_reset_n") pll_locked = Signal() pll_fb = Signal() pll_sys = Signal() self.specials += [ Instance("PLLE2_BASE", p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, # VCO @ 1GHz p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=5.0, p_CLKFBOUT_MULT=5, p_DIVCLK_DIVIDE=1, i_CLKIN1=clk200_se, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, # 200MHz p_CLKOUT0_DIVIDE=5, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=pll_sys, p_CLKOUT1_DIVIDE=2, p_CLKOUT1_PHASE=0.0, #o_CLKOUT1=, p_CLKOUT2_DIVIDE=2, p_CLKOUT2_PHASE=0.0, #o_CLKOUT2=, p_CLKOUT3_DIVIDE=2, p_CLKOUT3_PHASE=0.0, #o_CLKOUT3=, p_CLKOUT4_DIVIDE=2, p_CLKOUT4_PHASE=0.0, #o_CLKOUT4= ), Instance("BUFG", i_I=pll_sys, o_O=self.cd_sys.clk), AsyncResetSynchronizer(self.cd_sys, ~pll_locked | cpu_reset), ]
def __init__(self, platform, sys_clk_freq): self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) self.clock_domains.cd_pll4x = ClockDomain(reset_less=True) self.clock_domains.cd_idelay = ClockDomain() # # # self.submodules.pll = pll = USMMCM(speedgrade=-2) self.comb += pll.reset.eq(self.rst) pll.register_clkin(platform.request("clk300", 0), 300e6) pll.create_clkout(self.cd_pll4x, sys_clk_freq * 4, buf=None, with_reset=False) pll.create_clkout(self.cd_idelay, 500e6) platform.add_false_path_constraints( self.cd_sys.clk, pll.clkin ) # Ignore sys_clk to pll.clkin path created by SoC's rst. self.specials += [ Instance("BUFGCE_DIV", name="main_bufgce_div", p_BUFGCE_DIVIDE=4, i_CE=1, i_I=self.cd_pll4x.clk, o_O=self.cd_sys.clk), Instance("BUFGCE", name="main_bufgce", i_CE=1, i_I=self.cd_pll4x.clk, o_O=self.cd_sys4x.clk), AsyncResetSynchronizer(self.cd_idelay, ~pll.locked), ] self.submodules.idelayctrl = USIDELAYCTRL(cd_ref=self.cd_idelay, cd_sys=self.cd_sys)
def __init__(self, platform, f_sys, f_sample, add_rst=[]): ''' The `cursor UP` button resets the sys clock domain! add_rst = additional reset signals for sys_clk must be active high and will be synchronized with sys_clk ''' self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_clk200 = ClockDomain() # # # # self.cd_sys.clk.attr.add('keep') self.submodules.pll = pll = S7MMCM(speedgrade=-1) pll.register_clkin(ClockSignal('sys'), 100e6) self.comb += [pll.reset.eq(ResetSignal('sys'))] pll.create_clkout(self.cd_clk200, 200e6) self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200) # ------------------------------------------ # OR together all RESET sources for cd_sys # ------------------------------------------ # Zynq PS reset signal (bitfile load) add_rst.append(ResetSignal("ps7")) rst_sum = Signal() self.sync += rst_sum.eq(reduce(or_, add_rst)) self.specials += AsyncResetSynchronizer(self.cd_sys, rst_sum) # !!! sys_clk is provided by FCLK_CLK0 from PS7 !!! self.comb += ClockSignal("sys").eq(ClockSignal("ps7")) # Flashy Led blinker for sample_clk bl = LedBlinker( f_sample / 8, Cat([platform.request('user_led', i) for i in range(8)])) self.submodules.sample_blink = ClockDomainsRenamer("sample")(bl)
def __init__(self, platform, sys_clk_freq, x5_clk_freq): self.clock_domains.cd_sys = ClockDomain() # # # self.cd_sys.clk.attr.add("keep") # clk / rst clk = clk12 = platform.request("clk12") rst_n = platform.request("rst_n") platform.add_period_constraint(clk12, 1e9/12e6) if x5_clk_freq is not None: clk = clk50 = platform.request("ext_clk50") self.comb += platform.request("ext_clk50_en").eq(1) platform.add_period_constraint(clk50, 1e9/x5_clk_freq) # pll self.submodules.pll = pll = ECP5PLL() self.comb += pll.reset.eq(~rst_n) pll.register_clkin(clk, x5_clk_freq or 12e6) pll.create_clkout(self.cd_sys, sys_clk_freq) self.specials += AsyncResetSynchronizer(self.cd_sys, ~rst_n) self.comb += self.cd_sys.clk.eq(clk)
def __init__(self, platform, sys_clk_freq): self.clock_domains.cd_sys = ClockDomain() #self.clock_domains.cd_clk125 = ClockDomain() # # # # clk / rst clk25 = platform.request("clk_in") #rst_n = platform.request("rst_n") platform.add_period_constraint(clk25, period_ns(25e6)) # pll self.submodules.pll = pll = ECP5PLL() pll.register_clkin(clk25, 25e6) # pll.create_clkout(self.cd_clk125, 125e6) pll.create_clkout(self.cd_sys, sys_clk_freq) self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll.locked) #self.specials += AsyncResetSynchronizer(self.cd_clk125, ~pll.locked) #platform.add_period_constraint(self.cd_clk125.clk, period_ns(125e6)) platform.add_period_constraint(self.cd_sys.clk, period_ns(sys_clk_freq))
def __init__(self, platform, sys_clk_freq): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_por = ClockDomain(reset_less=True) # # # # Clk / Rst clk27 = platform.request("clk27") platform.add_period_constraint(clk27, 1e9 / 27e6) # Power on reset por_count = Signal(16, reset=2**16 - 1) por_done = Signal() self.comb += self.cd_por.clk.eq(ClockSignal()) self.comb += por_done.eq(por_count == 0) self.sync.por += If(~por_done, por_count.eq(por_count - 1)) # PLL self.submodules.pll = pll = ECP5PLL() pll.register_clkin(clk27, 27e6) pll.create_clkout(self.cd_sys, sys_clk_freq) self.specials += AsyncResetSynchronizer(self.cd_sys, ~por_done | ~pll.locked)
def __init__(self, platform): clk12 = platform.request("clk12") self.clock_domains.cd_sys = ClockDomain() self.reset = Signal() # FIXME: Use PLL, increase system clock to 32 MHz, pending nextpnr # fixes. self.comb += self.cd_sys.clk.eq(clk12) # POR reset logic- POR generated from sys clk, POR logic feeds sys clk # reset. self.clock_domains.cd_por = ClockDomain() reset_delay = Signal(12, reset=4095) self.comb += [ self.cd_por.clk.eq(self.cd_sys.clk), self.cd_sys.rst.eq(reset_delay != 0) ] self.sync.por += \ If(reset_delay != 0, reset_delay.eq(reset_delay - 1) ) self.specials += AsyncResetSynchronizer(self.cd_por, self.reset)
def __init__(self, platform, sys_clk_freq): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True) # # # self.cd_sys.clk.attr.add("keep") self.cd_sys_ps.clk.attr.add("keep") # clk / rst clk8 = platform.request("clk8") rst = Signal() platform.add_period_constraint(clk8, 1e9 / 8e6) # pll self.submodules.pll = pll = ECP5PLL() pll.register_clkin(clk8, 8e6) pll.create_clkout(self.cd_sys, sys_clk_freq, phase=11) pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=20) self.specials += AsyncResetSynchronizer(self.cd_sys, rst) # sdram clock self.comb += platform.request("sdram_clock").eq(self.cd_sys_ps.clk)
def __init__(self, platform, sys_clk_freq): self.clock_domains.cd_por = ClockDomain(reset_less=True) self.clock_domains.cd_sys = ClockDomain() # # # # Clk / Rst clk12 = platform.request("clk12") rst = platform.request("user_btn", 0) # Power on reset por_count = Signal(16, reset=2**16 - 1) por_done = Signal() self.comb += self.cd_por.clk.eq(clk12) self.comb += por_done.eq(por_count == 0) self.sync.por += If(~por_done, por_count.eq(por_count - 1)) # PLL self.submodules.pll = pll = ECP5PLL() pll.register_clkin(clk12, 12e6) pll.create_clkout(self.cd_sys, sys_clk_freq) self.specials += AsyncResetSynchronizer(self.cd_sys, ~por_done | ~pll.locked | rst)
def __init__(self, platform, sys_clk_freq): self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys2x = ClockDomain() # # # # Clk / Rst clk100 = platform.request("clk100") rst_n = platform.request("rst_n") # PLL self.submodules.pll = pll = GW1NPLL(device="GW1N9K") self.comb += pll.reset.eq(~rst_n) pll.register_clkin(clk100, 100e6) pll.create_clkout(self.cd_sys2x, 2*sys_clk_freq, with_reset=False) self.specials += Instance("CLKDIV", p_DIV_MODE= "2", i_RESETN = rst_n, i_HCLKIN = self.cd_sys2x.clk, o_CLKOUT = self.cd_sys.clk ) self.specials += AsyncResetSynchronizer(self.cd_sys, ~rst_n)
def __init__(self): self._pll_reset = CSRStorage(reset=1) self._pll_locked = CSRStatus() self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_rtio = ClockDomain() # self.clock_domains.cd_rtiox4 = ClockDomain(reset_less=True) pll_locked = Signal() rtio_clk = Signal() rtiox4_clk = Signal() self.specials += [ Instance( "PLLE2_ADV", p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, p_REF_JITTER1=0.24, p_CLKIN1_PERIOD=8.0, p_CLKIN2_PERIOD=8.0, i_CLKIN2=self.cd_sys.clk, # Warning: CLKINSEL=0 means CLKIN2 is selected i_CLKINSEL=0, # VCO @ 1GHz when using 125MHz input p_CLKFBOUT_MULT=8, p_DIVCLK_DIVIDE=1, i_CLKFBIN=self.cd_rtio.clk, i_RST=self._pll_reset.storage, o_CLKFBOUT=rtio_clk, # p_CLKOUT0_DIVIDE=2, p_CLKOUT0_PHASE=0.0, # o_CLKOUT0=rtiox4_clk ), Instance("BUFG", i_I=rtio_clk, o_O=self.cd_rtio.clk), # Instance("BUFG", i_I=rtiox4_clk, o_O=self.cd_rtiox4.clk), AsyncResetSynchronizer(self.cd_rtio, ~pll_locked), MultiReg(pll_locked, self._pll_locked.status) ]
def __init__(self, platform, sys_clk_freq): self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) self.clock_domains.cd_pll4x = ClockDomain(reset_less=True) self.clock_domains.cd_idelay = ClockDomain() self.clock_domains.cd_eth = ClockDomain() # # # self.submodules.pll = pll = USMMCM(speedgrade=-2) self.comb += pll.reset.eq(platform.request("cpu_reset") | self.rst) pll.register_clkin(platform.request("clk125"), 125e6) pll.create_clkout(self.cd_pll4x, sys_clk_freq * 4, buf=None, with_reset=False) pll.create_clkout(self.cd_idelay, 200e6, with_reset=False) pll.create_clkout(self.cd_eth, 200e6) self.specials += [ Instance("BUFGCE_DIV", name="main_bufgce_div", p_BUFGCE_DIVIDE=4, i_CE=1, i_I=self.cd_pll4x.clk, o_O=self.cd_sys.clk), Instance("BUFGCE", name="main_bufgce", i_CE=1, i_I=self.cd_pll4x.clk, o_O=self.cd_sys4x.clk), AsyncResetSynchronizer(self.cd_idelay, ~pll.locked), ] self.submodules.idelayctrl = USIDELAYCTRL(cd_ref=self.cd_idelay, cd_sys=self.cd_sys)
def __init__(self, platform, sys_clk_freq, with_usb_pll=False, with_rst=True): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys_ps = ClockDomain() # # # # Clk / Rst clk25 = platform.request("clk25") rst_n = 1 if not with_rst else platform.request("user_btn_n", 0) platform.add_period_constraint(clk25, 1e9 / 25e6) # PLL self.submodules.pll = pll = ECP5PLL() pll.register_clkin(clk25, 25e6) pll.create_clkout(self.cd_sys, sys_clk_freq) pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=180) # Idealy 90° but needs to be increased. self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll.locked | ~rst_n) # USB PLL if with_usb_pll: self.submodules.usb_pll = usb_pll = ECP5PLL() usb_pll.register_clkin(clk25, 25e6) self.clock_domains.cd_usb_12 = ClockDomain() self.clock_domains.cd_usb_48 = ClockDomain() usb_pll.create_clkout(self.cd_usb_12, 12e6, margin=0) usb_pll.create_clkout(self.cd_usb_48, 48e6, margin=0) # SDRAM clock self.specials += DDROutput(1, 0, platform.request("sdram_clock"), ClockSignal("sys_ps"))
def __init__(self, platform, sys_clk_freq): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_por = ClockDomain() # Clocks clk16 = platform.request("clk16") platform.add_period_constraint(clk16, 1e9 / 16e6) if sys_clk_freq == 16e6: self.comb += self.cd_sys.clk.eq(clk16) else: self.submodules.pll = pll = iCE40PLL() pll.register_clkin(clk16, 16e6) pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=False) platform.add_period_constraint(self.cd_sys.clk, 1e9 / sys_clk_freq) # Power On Reset self.reset = Signal() por_cycles = 8 por_counter = Signal(log2_int(por_cycles), reset=por_cycles - 1) self.comb += self.cd_por.clk.eq(self.cd_sys.clk) platform.add_period_constraint(self.cd_por.clk, 1e9 / sys_clk_freq) self.sync.por += If(por_counter != 0, por_counter.eq(por_counter - 1)) self.comb += self.cd_sys.rst.eq(por_counter != 0) self.specials += AsyncResetSynchronizer(self.cd_por, self.reset)
def __init__(self, platform): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) self.clock_domains.cd_clk200 = ClockDomain() self.clock_domains.cd_clk50 = ClockDomain() clk100 = platform.request("clk100") rst = platform.request("user_btn") pll_locked = Signal() pll_fb = Signal() self.pll_sys = Signal() self.specials += [ Instance( "PLLE2_BASE", p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, # VCO @ 1600 MHz p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0, p_CLKFBOUT_MULT=16, p_DIVCLK_DIVIDE=1, i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, # 100 MHz p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=self.pll_sys, ), Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk), AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst), ]
def __init__(self, platform): self.jreset = CSRStorage(reset=1) self.jref = Signal() self.refclk = Signal() refclk2 = Signal() self.clock_domains.cd_jesd = ClockDomain() refclk_pads = platform.request("dac_refclk", 0) platform.add_period_constraint(refclk_pads.p, 1e9/self.refclk_freq) self.specials += [ Instance("IBUFDS_GTE3", i_CEB=self.jreset.storage, p_REFCLK_HROW_CK_SEL=0b00, i_I=refclk_pads.p, i_IB=refclk_pads.n, o_O=self.refclk, o_ODIV2=refclk2), Instance("BUFG_GT", i_I=refclk2, o_O=self.cd_jesd.clk), AsyncResetSynchronizer(self.cd_jesd, self.jreset.storage), ] jref = platform.request("dac_sysref") self.specials += Instance("IBUFDS_IBUFDISABLE", p_USE_IBUFDISABLE="TRUE", p_SIM_DEVICE="ULTRASCALE", i_IBUFDISABLE=self.jreset.storage, i_I=jref.p, i_IB=jref.n, o_O=self.jref)
def __init__(self, platform): self.clock_domains.cd_sys = ClockDomain() pll_fb = Signal() pll_locked = Signal() pll_clk625 = Signal() self.specials += [ Instance( "PLLE2_BASE", p_CLKIN1_PERIOD=20.0, i_CLKIN1=platform.request("clk50"), i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_locked, # VCO @ 1GHz p_CLKFBOUT_MULT=20, p_DIVCLK_DIVIDE=1, p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=pll_clk625, ), Instance("BUFG", i_I=pll_clk625, o_O=self.cd_sys.clk), AsyncResetSynchronizer(self.cd_sys, ~pll_locked) ]
def __init__(self, platform): clk12 = platform.request("clk12") self.clock_domains.cd_sys = ClockDomain() self.reset = Signal() # Fout = Fin x (DIVF + 1) / (2^DIVQ x (DIVR + 1)) self.specials += \ Instance("SB_PLL40_CORE", p_FEEDBACK_PATH="SIMPLE", p_PLLOUT_SELECT="GENCLK", p_DIVR=0, # 0 p_DIVF=7, # 7 p_DIVQ=1, # 1 p_FILTER_RANGE=0b010, i_RESETB=1, i_BYPASS=0, i_REFERENCECLK=clk12, o_PLLOUTCORE=self.cd_sys.clk, # 48MHz ) # POR reset logic- POR generated from sys clk, POR logic feeds sys clk # reset. self.clock_domains.cd_por = ClockDomain() reset_delay = Signal(12, reset=4095) self.comb += [ self.cd_por.clk.eq(self.cd_sys.clk), ] self.sync += [self.cd_sys.rst.eq(reset_delay != 0)] self.sync.por += \ If(reset_delay != 0, reset_delay.eq(reset_delay - 1) ) self.specials += AsyncResetSynchronizer(self.cd_por, self.reset)
def __init__(self, n_bits, n_words): self.data = Signal() self.wck = Signal() self.bck = Signal() layout = [("data", n_bits)] self.clock_domains.cd_decode = ClockDomain() self.specials += AsyncResetSynchronizer(self.cd_decode, ResetSignal("sys")) decoder = ClockDomainsRenamer("decode")(Decoder(n_bits, n_words)) self.submodules.decoder = decoder cdr = ClockDomainsRenamer({"read": "sys", "write": "decode"}) self.submodules.fifo = cdr(stream.AsyncFIFO(layout, 8)) self.source = self.fifo.source self.comb += [ self.cd_decode.clk.eq(self.bck), decoder.wck.eq(self.wck), decoder.data.eq(self.data), decoder.source.connect(self.fifo.sink), ]
def __init__(self, platform, sys_clk_freq): self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_por = ClockDomain(reset_less=True) # # # # Clk/Rst clk12 = platform.request("clk12") # Power On Reset por_count = Signal(16, reset=2**16-1) por_done = Signal() self.comb += self.cd_por.clk.eq(ClockSignal()) self.comb += por_done.eq(por_count == 0) self.sync.por += If(~por_done, por_count.eq(por_count - 1)) # PLL self.submodules.pll = pll = iCE40PLL(primitive="SB_PLL40_PAD") self.comb += pll.reset.eq(self.rst) pll.register_clkin(clk12, 12e6) pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=False) self.specials += AsyncResetSynchronizer(self.cd_sys, ~por_done | ~pll.locked) platform.add_period_constraint(self.cd_sys.clk, 1e9/sys_clk_freq)
def __init__(self, platform, sys_clk_freq): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True) # # # # Clk / Rst clk25 = platform.request("clk25") rst = platform.request("rst") platform.add_period_constraint(clk25, 1e9 / 25e6) # PLL self.submodules.pll = pll = ECP5PLL() self.comb += pll.reset.eq(rst) pll.register_clkin(clk25, 25e6) pll.create_clkout(self.cd_sys, sys_clk_freq, phase=11) pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=20) self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll.locked | rst) # SDRAM clock self.comb += platform.request("sdram_clock").eq(self.cd_sys_ps.clk) # Prevent ESP32 from resetting FPGA self.comb += platform.request("wifi_gpio0").eq(1)
def __init__(self, refclk_or_clk_pads, data_pads, sys_clk_freq): pcs = PCS(lsb_first=True) self.submodules += pcs self.sink = pcs.sink self.source = pcs.source self.link_up = pcs.link_up self.clock_domains.cd_eth_tx = ClockDomain() self.clock_domains.cd_eth_rx = ClockDomain() self.clock_domains.cd_eth_tx_half = ClockDomain(reset_less=True) self.clock_domains.cd_eth_rx_half = ClockDomain(reset_less=True) # for specifying clock constraints. 62.5MHz clocks. self.txoutclk = Signal() self.rxoutclk = Signal() # # # if isinstance(refclk_or_clk_pads, Signal): refclk = refclk_or_clk_pads else: refclk = Signal() self.specials += Instance("IBUFDS_GTE2", i_I=refclk_or_clk_pads.p, i_IB=refclk_or_clk_pads.n, i_CEB=0, o_O=refclk) # GTX transceiver tx_reset = Signal() tx_mmcm_locked = Signal() tx_data = Signal(20) tx_reset_done = Signal() rx_reset = Signal() rx_mmcm_locked = Signal() rx_data = Signal(20) rx_reset_done = Signal() pll = GTXChannelPLL(refclk, 200e6, 1.25e9) self.submodules.pll = pll # Work around Python's 255 argument limitation. gtx_params = dict( # Simulation-Only Attributes p_SIM_RECEIVER_DETECT_PASS="******", p_SIM_TX_EIDLE_DRIVE_LEVEL="X", p_SIM_RESET_SPEEDUP="FALSE", p_SIM_CPLLREFCLK_SEL="FALSE", p_SIM_VERSION="4.0", # RX Byte and Word Alignment Attributes p_ALIGN_COMMA_DOUBLE="FALSE", p_ALIGN_COMMA_ENABLE=0b1111111111, p_ALIGN_COMMA_WORD=2, p_ALIGN_MCOMMA_DET="TRUE", p_ALIGN_MCOMMA_VALUE=0b1010000011, p_ALIGN_PCOMMA_DET="TRUE", p_ALIGN_PCOMMA_VALUE=0b0101111100, p_SHOW_REALIGN_COMMA="TRUE", p_RXSLIDE_AUTO_WAIT=7, p_RXSLIDE_MODE="OFF", p_RX_SIG_VALID_DLY=10, # RX 8B/10B Decoder Attributes p_RX_DISPERR_SEQ_MATCH="TRUE", p_DEC_MCOMMA_DETECT="TRUE", p_DEC_PCOMMA_DETECT="TRUE", p_DEC_VALID_COMMA_ONLY="TRUE", # RX Clock Correction Attributes p_CBCC_DATA_SOURCE_SEL="DECODED", p_CLK_COR_SEQ_2_USE="FALSE", p_CLK_COR_KEEP_IDLE="FALSE", p_CLK_COR_MAX_LAT=9, p_CLK_COR_MIN_LAT=7, p_CLK_COR_PRECEDENCE="TRUE", p_CLK_COR_REPEAT_WAIT=0, p_CLK_COR_SEQ_LEN=1, p_CLK_COR_SEQ_1_ENABLE=0b1111, p_CLK_COR_SEQ_1_1=0b0100000000, p_CLK_COR_SEQ_1_2=0b0000000000, p_CLK_COR_SEQ_1_3=0b0000000000, p_CLK_COR_SEQ_1_4=0b0000000000, p_CLK_CORRECT_USE="FALSE", p_CLK_COR_SEQ_2_ENABLE=0b1111, p_CLK_COR_SEQ_2_1=0b0100000000, p_CLK_COR_SEQ_2_2=0b0000000000, p_CLK_COR_SEQ_2_3=0b0000000000, p_CLK_COR_SEQ_2_4=0b0000000000, # RX Channel Bonding Attributes p_CHAN_BOND_KEEP_ALIGN="FALSE", p_CHAN_BOND_MAX_SKEW=1, p_CHAN_BOND_SEQ_LEN=1, p_CHAN_BOND_SEQ_1_1=0b0000000000, p_CHAN_BOND_SEQ_1_2=0b0000000000, p_CHAN_BOND_SEQ_1_3=0b0000000000, p_CHAN_BOND_SEQ_1_4=0b0000000000, p_CHAN_BOND_SEQ_1_ENABLE=0b1111, p_CHAN_BOND_SEQ_2_1=0b0000000000, p_CHAN_BOND_SEQ_2_2=0b0000000000, p_CHAN_BOND_SEQ_2_3=0b0000000000, p_CHAN_BOND_SEQ_2_4=0b0000000000, p_CHAN_BOND_SEQ_2_ENABLE=0b1111, p_CHAN_BOND_SEQ_2_USE="FALSE", p_FTS_DESKEW_SEQ_ENABLE=0b1111, p_FTS_LANE_DESKEW_CFG=0b1111, p_FTS_LANE_DESKEW_EN="FALSE", # RX Margin Analysis Attributes p_ES_CONTROL=0b000000, p_ES_ERRDET_EN="FALSE", p_ES_EYE_SCAN_EN="TRUE", p_ES_HORZ_OFFSET=0x000, p_ES_PMA_CFG=0b0000000000, p_ES_PRESCALE=0b00000, p_ES_QUALIFIER=0x00000000000000000000, p_ES_QUAL_MASK=0x00000000000000000000, p_ES_SDATA_MASK=0x00000000000000000000, p_ES_VERT_OFFSET=0b000000000, # FPGA RX Interface Attributes p_RX_DATA_WIDTH=20, # PMA Attributes p_OUTREFCLK_SEL_INV=0b11, p_PMA_RSV=0x001e7080, p_PMA_RSV2=0x2050, p_PMA_RSV3=0b00, p_PMA_RSV4=0x00000000, p_RX_BIAS_CFG=0b000000000100, p_DMONITOR_CFG=0x000A00, p_RX_CM_SEL=0b11, p_RX_CM_TRIM=0b010, p_RX_DEBUG_CFG=0b000000000000, p_RX_OS_CFG=0b0000010000000, p_TERM_RCAL_CFG=0b10000, p_TERM_RCAL_OVRD=0b0, p_TST_RSV=0x00000000, p_RX_CLK25_DIV=5, p_TX_CLK25_DIV=5, p_UCODEER_CLR=0b0, # PCI Express Attributes p_PCS_PCIE_EN="FALSE", # PCS Attributes p_PCS_RSVD_ATTR=0x000000000000, # RX Buffer Attributes p_RXBUF_ADDR_MODE="FAST", p_RXBUF_EIDLE_HI_CNT=0b1000, p_RXBUF_EIDLE_LO_CNT=0b0000, p_RXBUF_EN="TRUE", p_RX_BUFFER_CFG=0b000000, p_RXBUF_RESET_ON_CB_CHANGE="TRUE", p_RXBUF_RESET_ON_COMMAALIGN="FALSE", p_RXBUF_RESET_ON_EIDLE="FALSE", p_RXBUF_RESET_ON_RATE_CHANGE="TRUE", p_RXBUFRESET_TIME=0b00001, p_RXBUF_THRESH_OVFLW=61, p_RXBUF_THRESH_OVRD="FALSE", p_RXBUF_THRESH_UNDFLW=4, p_RXDLY_CFG=0x001F, p_RXDLY_LCFG=0x030, p_RXDLY_TAP_CFG=0x0000, p_RXPH_CFG=0x000000, p_RXPHDLY_CFG=0x084020, p_RXPH_MONITOR_SEL=0b00000, p_RX_XCLK_SEL="RXREC", p_RX_DDI_SEL=0b000000, p_RX_DEFER_RESET_BUF_EN="TRUE", # CDR Attributes p_RXCDR_CFG=0x03000023ff10100020, p_RXCDR_FR_RESET_ON_EIDLE=0b0, p_RXCDR_HOLD_DURING_EIDLE=0b0, p_RXCDR_PH_RESET_ON_EIDLE=0b0, p_RXCDR_LOCK_CFG=0b010101, # RX Initialization and Reset Attributes p_RXCDRFREQRESET_TIME=0b00001, p_RXCDRPHRESET_TIME=0b00001, p_RXISCANRESET_TIME=0b00001, p_RXPCSRESET_TIME=0b00001, p_RXPMARESET_TIME=0b00011, # RX OOB Signaling Attributes p_RXOOB_CFG=0b0000110, # RX Gearbox Attributes p_RXGEARBOX_EN="FALSE", p_GEARBOX_MODE=0b000, # PRBS Detection Attribute p_RXPRBS_ERR_LOOPBACK=0b0, # Power-Down Attributes p_PD_TRANS_TIME_FROM_P2=0x03c, p_PD_TRANS_TIME_NONE_P2=0x3c, p_PD_TRANS_TIME_TO_P2=0x64, # RX OOB Signaling Attributes p_SAS_MAX_COM=64, p_SAS_MIN_COM=36, p_SATA_BURST_SEQ_LEN=0b0101, p_SATA_BURST_VAL=0b100, p_SATA_EIDLE_VAL=0b100, p_SATA_MAX_BURST=8, p_SATA_MAX_INIT=21, p_SATA_MAX_WAKE=7, p_SATA_MIN_BURST=4, p_SATA_MIN_INIT=12, p_SATA_MIN_WAKE=4, # RX Fabric Clock Output Control Attributes p_TRANS_TIME_RATE=0x0E, # TX Buffer Attributes p_TXBUF_EN="TRUE", p_TXBUF_RESET_ON_RATE_CHANGE="TRUE", p_TXDLY_CFG=0x001F, p_TXDLY_LCFG=0x030, p_TXDLY_TAP_CFG=0x0000, p_TXPH_CFG=0x0780, p_TXPHDLY_CFG=0x084020, p_TXPH_MONITOR_SEL=0b00000, p_TX_XCLK_SEL="TXOUT", # FPGA TX Interface Attributes p_TX_DATA_WIDTH=20, # TX Configurable Driver Attributes p_TX_DEEMPH0=0b00000, p_TX_DEEMPH1=0b00000, p_TX_EIDLE_ASSERT_DELAY=0b110, p_TX_EIDLE_DEASSERT_DELAY=0b100, p_TX_LOOPBACK_DRIVE_HIZ="FALSE", p_TX_MAINCURSOR_SEL=0b0, p_TX_DRIVE_MODE="DIRECT", p_TX_MARGIN_FULL_0=0b1001110, p_TX_MARGIN_FULL_1=0b1001001, p_TX_MARGIN_FULL_2=0b1000101, p_TX_MARGIN_FULL_3=0b1000010, p_TX_MARGIN_FULL_4=0b1000000, p_TX_MARGIN_LOW_0=0b1000110, p_TX_MARGIN_LOW_1=0b1000100, p_TX_MARGIN_LOW_2=0b1000010, p_TX_MARGIN_LOW_3=0b1000000, p_TX_MARGIN_LOW_4=0b1000000, # TX Gearbox Attributes p_TXGEARBOX_EN="FALSE", # TX Initialization and Reset Attributes p_TXPCSRESET_TIME=0b00001, p_TXPMARESET_TIME=0b00001, # TX Receiver Detection Attributes p_TX_RXDETECT_CFG=0x1832, p_TX_RXDETECT_REF=0b100, # CPLL Attributes p_CPLL_CFG=0xBC07DC, p_CPLL_FBDIV=pll.config["n2"], p_CPLL_FBDIV_45=pll.config["n1"], p_CPLL_INIT_CFG=0x00001E, p_CPLL_LOCK_CFG=0x01E8, p_CPLL_REFCLK_DIV=pll.config["m"], p_RXOUT_DIV=pll.config["d"], p_TXOUT_DIV=pll.config["d"], p_SATA_CPLL_CFG="VCO_3000MHZ", # RX Initialization and Reset Attributes p_RXDFELPMRESET_TIME=0b0001111, # RX Equalizer Attributes p_RXLPM_HF_CFG=0b00000011110000, p_RXLPM_LF_CFG=0b00000011110000, p_RX_DFE_GAIN_CFG=0x020FEA, p_RX_DFE_H2_CFG=0b000000000000, p_RX_DFE_H3_CFG=0b000001000000, p_RX_DFE_H4_CFG=0b00011110000, p_RX_DFE_H5_CFG=0b00011100000, p_RX_DFE_KL_CFG=0b0000011111110, p_RX_DFE_LPM_CFG=0x0954, p_RX_DFE_LPM_HOLD_DURING_EIDLE=0b0, p_RX_DFE_UT_CFG=0b10001111000000000, p_RX_DFE_VP_CFG=0b00011111100000011, # Power-Down Attributes p_RX_CLKMUX_PD=0b1, p_TX_CLKMUX_PD=0b1, # FPGA RX Interface Attribute p_RX_INT_DATAWIDTH=0, # FPGA TX Interface Attribute p_TX_INT_DATAWIDTH=0, # TX Configurable Driver Attributes p_TX_QPI_STATUS_EN=0b0, # RX Equalizer Attributes p_RX_DFE_KL_CFG2=0x301148AC, p_RX_DFE_XYD_CFG=0b0000000000000, # TX Configurable Driver Attributes p_TX_PREDRIVER_MODE=0b0) gtx_params.update( # CPLL Ports #o_CPLLFBCLKLOST =, o_CPLLLOCK=pll.lock, i_CPLLLOCKDETCLK=ClockSignal(), i_CPLLLOCKEN=1, i_CPLLPD=0, #o_CPLLREFCLKLOST =, i_CPLLREFCLKSEL=0b001, i_CPLLRESET=pll.reset, i_GTRSVD=0b0000000000000000, i_PCSRSVDIN=0b0000000000000000, i_PCSRSVDIN2=0b00000, i_PMARSVDIN=0b00000, i_PMARSVDIN2=0b00000, i_TSTIN=0b11111111111111111111, #o_TSTOUT =, # Channel i_CLKRSVD=0b0000, # Channel - Clocking Ports i_GTGREFCLK=0, i_GTNORTHREFCLK0=0, i_GTNORTHREFCLK1=0, i_GTREFCLK0=pll.refclk, i_GTREFCLK1=0, i_GTSOUTHREFCLK0=0, i_GTSOUTHREFCLK1=0, # Channel - DRP Ports i_DRPADDR=0, i_DRPCLK=0, i_DRPDI=0, #o_DRPDO =, i_DRPEN=0, #o_DRPRDY =, i_DRPWE=0, # Clocking Ports #o_GTREFCLKMONITOR =, i_QPLLCLK=0, i_QPLLREFCLK=0, i_RXSYSCLKSEL=0b00, i_TXSYSCLKSEL=0b00, # Digital Monitor Ports #o_DMONITOROUT =, # FPGA TX Interface Datapath Configuration i_TX8B10BEN=0, # Loopback Ports i_LOOPBACK=0b000, # PCI Express Ports #o_PHYSTATUS =, i_RXRATE=0b000, #o_RXVALID =, # Power-Down Ports i_RXPD=0b00, i_TXPD=0b00, # RX 8B/10B Decoder Ports i_SETERRSTATUS=0, # RX Initialization and Reset Ports i_EYESCANRESET=0, i_RXUSERRDY=rx_mmcm_locked, # RX Margin Analysis Ports #o_EYESCANDATAERROR =, i_EYESCANMODE=0, i_EYESCANTRIGGER=0, # Receive Ports - CDR Ports i_RXCDRFREQRESET=0, i_RXCDRHOLD=0, #o_RXCDRLOCK =, i_RXCDROVRDEN=0, i_RXCDRRESET=0, i_RXCDRRESETRSV=0, # Receive Ports - Clock Correction Ports #o_RXCLKCORCNT =, # Receive Ports - FPGA RX Interface Datapath Configuration i_RX8B10BEN=0, # Receive Ports - FPGA RX Interface Ports i_RXUSRCLK=ClockSignal("eth_rx_half"), i_RXUSRCLK2=ClockSignal("eth_rx_half"), # Receive Ports - FPGA RX interface Ports o_RXDATA=Cat(*[rx_data[10 * i:10 * i + 8] for i in range(2)]), # Receive Ports - Pattern Checker Ports #o_RXPRBSERR =, i_RXPRBSSEL=0b000, # Receive Ports - Pattern Checker ports i_RXPRBSCNTRESET=0, # Receive Ports - RX Equalizer Ports i_RXDFEXYDEN=1, i_RXDFEXYDHOLD=0, i_RXDFEXYDOVRDEN=0, # Receive Ports - RX 8B/10B Decoder Ports i_RXDISPERR=Cat(*[rx_data[10 * i + 9] for i in range(2)]), #o_RXNOTINTABLE =, # Receive Ports - RX AFE i_GTXRXP=data_pads.rxp, # Receive Ports - RX AFE Ports i_GTXRXN=data_pads.rxn, # Receive Ports - RX Buffer Bypass Ports i_RXBUFRESET=0, #o_RXBUFSTATUS =, i_RXDDIEN=0, i_RXDLYBYPASS=1, i_RXDLYEN=0, i_RXDLYOVRDEN=0, i_RXDLYSRESET=0, #o_RXDLYSRESETDONE =, i_RXPHALIGN=0, #o_RXPHALIGNDONE =, i_RXPHALIGNEN=0, i_RXPHDLYPD=0, i_RXPHDLYRESET=0, #o_RXPHMONITOR =, i_RXPHOVRDEN=0, #o_RXPHSLIPMONITOR =, #o_RXSTATUS =, # Receive Ports - RX Byte and Word Alignment Ports #o_RXBYTEISALIGNED =, #o_RXBYTEREALIGN =, #o_RXCOMMADET =, i_RXCOMMADETEN=1, i_RXMCOMMAALIGNEN=1, i_RXPCOMMAALIGNEN=1, # Receive Ports - RX Channel Bonding Ports #o_RXCHANBONDSEQ =, i_RXCHBONDEN=0, i_RXCHBONDLEVEL=0b000, i_RXCHBONDMASTER=0, #o_RXCHBONDO =, i_RXCHBONDSLAVE=0, # Receive Ports - RX Channel Bonding Ports #o_RXCHANISALIGNED =, #o_RXCHANREALIGN =, # Receive Ports - RX Equailizer Ports i_RXLPMHFHOLD=0, i_RXLPMHFOVRDEN=0, i_RXLPMLFHOLD=0, # Receive Ports - RX Equalizer Ports i_RXDFEAGCHOLD=0, i_RXDFEAGCOVRDEN=0, i_RXDFECM1EN=0, i_RXDFELFHOLD=0, i_RXDFELFOVRDEN=1, i_RXDFELPMRESET=0, i_RXDFETAP2HOLD=0, i_RXDFETAP2OVRDEN=0, i_RXDFETAP3HOLD=0, i_RXDFETAP3OVRDEN=0, i_RXDFETAP4HOLD=0, i_RXDFETAP4OVRDEN=0, i_RXDFETAP5HOLD=0, i_RXDFETAP5OVRDEN=0, i_RXDFEUTHOLD=0, i_RXDFEUTOVRDEN=0, i_RXDFEVPHOLD=0, i_RXDFEVPOVRDEN=0, i_RXDFEVSEN=0, i_RXLPMLFKLOVRDEN=0, #o_RXMONITOROUT = i_RXMONITORSEL=0, i_RXOSHOLD=0, i_RXOSOVRDEN=0, # Receive Ports - RX Fabric ClocK Output Control Ports #o_RXRATEDONE =, # Receive Ports - RX Fabric Output Control Ports o_RXOUTCLK=self.rxoutclk, #o_RXOUTCLKFABRIC =, #o_RXOUTCLKPCS =, i_RXOUTCLKSEL=0b010, # Receive Ports - RX Gearbox Ports #o_RXDATAVALID =, #o_RXHEADER =, #o_RXHEADERVALID =, #o_RXSTARTOFSEQ =, # Receive Ports - RX Gearbox Ports i_RXGEARBOXSLIP=0, # Receive Ports - RX Initialization and Reset Ports i_GTRXRESET=rx_reset, i_RXOOBRESET=0, i_RXPCSRESET=0, i_RXPMARESET=0, # Receive Ports - RX Margin Analysis ports i_RXLPMEN=0, # Receive Ports - RX OOB Signaling ports #o_RXCOMSASDET =, #o_RXCOMWAKEDET =, # Receive Ports - RX OOB Signaling ports #o_RXCOMINITDET =, # Receive Ports - RX OOB signalling Ports #o_RXELECIDLE =, i_RXELECIDLEMODE=0b11, # Receive Ports - RX Polarity Control Ports i_RXPOLARITY=0, # Receive Ports - RX gearbox ports i_RXSLIDE=0, # Receive Ports - RX8B/10B Decoder Ports #o_RXCHARISCOMMA =, o_RXCHARISK=Cat(*[rx_data[10 * i + 8] for i in range(2)]), # Receive Ports - Rx Channel Bonding Ports i_RXCHBONDI=0b00000, # Receive Ports -RX Initialization and Reset Ports o_RXRESETDONE=rx_reset_done, # Rx AFE Ports i_RXQPIEN=0, #o_RXQPISENN =, #o_RXQPISENP =, # TX Buffer Bypass Ports i_TXPHDLYTSTCLK=0, # TX Configurable Driver Ports i_TXPOSTCURSOR=0b00000, i_TXPOSTCURSORINV=0, i_TXPRECURSOR=0b00000, i_TXPRECURSORINV=0, i_TXQPIBIASEN=0, i_TXQPISTRONGPDOWN=0, i_TXQPIWEAKPUP=0, # TX Initialization and Reset Ports i_CFGRESET=0, i_GTTXRESET=tx_reset, #o_PCSRSVDOUT =, i_TXUSERRDY=tx_mmcm_locked, # Transceiver Reset Mode Operation i_GTRESETSEL=0, i_RESETOVRD=0, # Transmit Ports - 8b10b Encoder Control Ports i_TXCHARDISPMODE=Cat(*[tx_data[10 * i + 9] for i in range(2)]), i_TXCHARDISPVAL=Cat(*[tx_data[10 * i + 8] for i in range(2)]), # Transmit Ports - FPGA TX Interface Ports i_TXUSRCLK=ClockSignal("eth_tx_half"), i_TXUSRCLK2=ClockSignal("eth_tx_half"), # Transmit Ports - PCI Express Ports i_TXELECIDLE=0, i_TXMARGIN=0b000, i_TXRATE=0b000, i_TXSWING=0, # Transmit Ports - Pattern Generator Ports i_TXPRBSFORCEERR=0, # Transmit Ports - TX Buffer Bypass Ports i_TXDLYBYPASS=1, i_TXDLYEN=0, i_TXDLYHOLD=0, i_TXDLYOVRDEN=0, i_TXDLYSRESET=0, #o_TXDLYSRESETDONE =, i_TXDLYUPDOWN=0, i_TXPHALIGN=0, #o_TXPHALIGNDONE =, i_TXPHALIGNEN=0, i_TXPHDLYPD=0, i_TXPHDLYRESET=0, i_TXPHINIT=0, #o_TXPHINITDONE =, i_TXPHOVRDEN=0, # Transmit Ports - TX Buffer Ports #o_TXBUFSTATUS =, # Transmit Ports - TX Configurable Driver Ports i_TXBUFDIFFCTRL=0b100, i_TXDEEMPH=0, i_TXDIFFCTRL=0b1000, i_TXDIFFPD=0, i_TXINHIBIT=0, i_TXMAINCURSOR=0b0000000, i_TXPISOPD=0, # Transmit Ports - TX Data Path interface i_TXDATA=Cat(*[tx_data[10 * i:10 * i + 8] for i in range(2)]), # Transmit Ports - TX Driver and OOB signaling o_GTXTXN=data_pads.txn, o_GTXTXP=data_pads.txp, # Transmit Ports - TX Fabric Clock Output Control Ports o_TXOUTCLK=self.txoutclk, #o_TXOUTCLKFABRIC =, #o_TXOUTCLKPCS =, i_TXOUTCLKSEL=0b010, #o_TXRATEDONE =, # Transmit Ports - TX Gearbox Ports i_TXCHARISK=0b00000000, #o_TXGEARBOXREADY =, i_TXHEADER=0b000, i_TXSEQUENCE=0b0000000, i_TXSTARTSEQ=0, # Transmit Ports - TX Initialization and Reset Ports i_TXPCSRESET=0, i_TXPMARESET=0, o_TXRESETDONE=tx_reset_done, # Transmit Ports - TX OOB signaling Ports #o_TXCOMFINISH =, i_TXCOMINIT=0, i_TXCOMSAS=0, i_TXCOMWAKE=0, i_TXPDELECIDLEMODE=0, # Transmit Ports - TX Polarity Control Ports i_TXPOLARITY=0, # Transmit Ports - TX Receiver Detection Ports i_TXDETECTRX=0, # Transmit Ports - TX8b/10b Encoder Ports i_TX8B10BBYPASS=0b00000000, # Transmit Ports - pattern Generator Ports i_TXPRBSSEL=0b000, # Tx Configurable Driver Ports #o_TXQPISENN =, #o_TXQPISENP =, ) self.specials += Instance("GTXE2_CHANNEL", **gtx_params) # Get 125MHz clocks back - the GTX is outputting 62.5MHz. txoutclk_rebuffer = Signal() self.specials += Instance("BUFH", i_I=self.txoutclk, o_O=txoutclk_rebuffer) rxoutclk_rebuffer = Signal() self.specials += Instance("BUFG", i_I=self.rxoutclk, o_O=rxoutclk_rebuffer) tx_mmcm_fb = Signal() tx_mmcm_reset = Signal(reset=1) clk_tx_unbuf = Signal() clk_tx_half_unbuf = Signal() self.specials += [ Instance( "MMCME2_BASE", p_CLKIN1_PERIOD=16.0, i_CLKIN1=txoutclk_rebuffer, i_RST=tx_mmcm_reset, o_CLKFBOUT=tx_mmcm_fb, i_CLKFBIN=tx_mmcm_fb, p_CLKFBOUT_MULT_F=16, o_LOCKED=tx_mmcm_locked, p_DIVCLK_DIVIDE=1, p_CLKOUT0_DIVIDE_F=16, o_CLKOUT0=clk_tx_half_unbuf, p_CLKOUT1_DIVIDE=8, o_CLKOUT1=clk_tx_unbuf, ), Instance("BUFH", i_I=clk_tx_half_unbuf, o_O=self.cd_eth_tx_half.clk), Instance("BUFH", i_I=clk_tx_unbuf, o_O=self.cd_eth_tx.clk), AsyncResetSynchronizer(self.cd_eth_tx, ~tx_mmcm_locked) ] rx_mmcm_fb = Signal() rx_mmcm_reset = Signal(reset=1) clk_rx_unbuf = Signal() clk_rx_half_unbuf = Signal() self.specials += [ Instance( "MMCME2_BASE", p_CLKIN1_PERIOD=16.0, i_CLKIN1=rxoutclk_rebuffer, i_RST=rx_mmcm_reset, o_CLKFBOUT=rx_mmcm_fb, i_CLKFBIN=rx_mmcm_fb, p_CLKFBOUT_MULT_F=16, o_LOCKED=rx_mmcm_locked, p_DIVCLK_DIVIDE=1, p_CLKOUT0_DIVIDE_F=16, o_CLKOUT0=clk_rx_half_unbuf, p_CLKOUT1_DIVIDE=8, o_CLKOUT1=clk_rx_unbuf, ), Instance("BUFG", i_I=clk_rx_half_unbuf, o_O=self.cd_eth_rx_half.clk), Instance("BUFG", i_I=clk_rx_unbuf, o_O=self.cd_eth_rx.clk), AsyncResetSynchronizer(self.cd_eth_rx, ~rx_mmcm_locked) ] # Transceiver init tx_init = GTXTXInit(sys_clk_freq, buffer_enable=True) self.comb += [ pll.reset.eq(tx_init.pllreset), tx_init.plllock.eq(pll.lock), tx_reset.eq(tx_init.gtXxreset) ] self.sync += tx_mmcm_reset.eq(~pll.lock) tx_mmcm_reset.attr.add("no_retiming") rx_init = ResetInserter()(GTXRXInit(sys_clk_freq, buffer_enable=True)) self.submodules += rx_init self.comb += [ rx_init.reset.eq(~tx_init.done), rx_reset.eq(rx_init.gtXxreset) ] ps_restart = PulseSynchronizer("eth_tx", "sys") self.submodules += ps_restart self.comb += [ ps_restart.i.eq(pcs.restart), rx_init.restart.eq(ps_restart.o) ] # Unlike CDRs from serious vendors, Xilinx CDRs can't tell you # when they are locked. Assume CDR lock time is 50,000 UI, # as per DS183. The Xilinx "wizards" also assume that. cdr_lock_time = round(sys_clk_freq * 50e3 / 1.25e9) cdr_lock_counter = Signal(max=cdr_lock_time + 1) cdr_locked = Signal() self.sync += [ If(rx_reset, cdr_locked.eq(0), cdr_lock_counter.eq(0)).Elif( cdr_lock_counter != cdr_lock_time, cdr_lock_counter.eq(cdr_lock_counter + 1)).Else( cdr_locked.eq(1)), rx_mmcm_reset.eq(~cdr_locked) ] rx_mmcm_reset.attr.add("no_retiming") # Gearbox and PCS connection gearbox = Gearbox() self.submodules += gearbox self.comb += [ tx_data.eq(gearbox.tx_data_half), gearbox.rx_data_half.eq(rx_data), gearbox.tx_data.eq(pcs.tbi_tx), pcs.tbi_rx.eq(gearbox.rx_data) ]
def __init__(self, platform, clk_freq): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys_ps = ClockDomain() f0 = 32 * 1000000 clk32 = platform.request("clk32") clk32a = Signal() self.specials += Instance("IBUFG", i_I=clk32, o_O=clk32a) clk32b = Signal() self.specials += Instance("BUFIO2", p_DIVIDE=1, p_DIVIDE_BYPASS="******", p_I_INVERT="FALSE", i_I=clk32a, o_DIVCLK=clk32b) f = Fraction(int(clk_freq), int(f0)) n, m, p = f.denominator, f.numerator, 8 assert f0 / n * m == clk_freq pll_lckd = Signal() pll_fb = Signal() pll = Signal(6) self.specials.pll = Instance( "PLL_ADV", p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", p_REF_JITTER=.01, p_CLK_FEEDBACK="CLKFBOUT", i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, p_DIVCLK_DIVIDE=1, p_CLKFBOUT_MULT=m * p // n, p_CLKFBOUT_PHASE=0., i_CLKIN1=clk32b, i_CLKIN2=0, i_CLKINSEL=1, p_CLKIN1_PERIOD=1000000000 / f0, p_CLKIN2_PERIOD=0., i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, o_CLKOUT0=pll[0], p_CLKOUT0_DUTY_CYCLE=.5, o_CLKOUT1=pll[1], p_CLKOUT1_DUTY_CYCLE=.5, o_CLKOUT2=pll[2], p_CLKOUT2_DUTY_CYCLE=.5, o_CLKOUT3=pll[3], p_CLKOUT3_DUTY_CYCLE=.5, o_CLKOUT4=pll[4], p_CLKOUT4_DUTY_CYCLE=.5, o_CLKOUT5=pll[5], p_CLKOUT5_DUTY_CYCLE=.5, p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p // 1, p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p // 1, p_CLKOUT2_PHASE=0., p_CLKOUT2_DIVIDE=p // 1, p_CLKOUT3_PHASE=0., p_CLKOUT3_DIVIDE=p // 1, p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p // 1, # sys p_CLKOUT5_PHASE=270., p_CLKOUT5_DIVIDE=p // 1, # sys_ps ) self.specials += Instance("BUFG", i_I=pll[4], o_O=self.cd_sys.clk) self.specials += Instance("BUFG", i_I=pll[5], o_O=self.cd_sys_ps.clk) self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd) self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC", i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, i_C0=self.cd_sys.clk, i_C1=~self.cd_sys.clk, o_Q=platform.request("sdram_clock"))
def __init__(self, qpll_channel, pads, sys_clk_freq, rtio_clk_freq, mode): assert mode in ["single", "master", "slave"] self.mode = mode # # # self.stable_clkin = Signal() self.submodules.encoder = encoder = ClockDomainsRenamer("rtio_tx")( Encoder(2, True)) self.submodules.decoders = decoders = [ ClockDomainsRenamer("rtio_rx")((Decoder(True))) for _ in range(2) ] self.rx_ready = Signal() # transceiver direct clock outputs # useful to specify clock constraints in a way palatable to Vivado self.txoutclk = Signal() self.rxoutclk = Signal() # # # # TX generates RTIO clock, init must be in system domain self.submodules.tx_init = tx_init = GTPTXInit(sys_clk_freq, mode) # RX receives restart commands from RTIO domain rx_init = ClockDomainsRenamer("rtio_tx")(GTPRXInit(rtio_clk_freq)) self.submodules += rx_init self.comb += [ tx_init.stable_clkin.eq(self.stable_clkin), qpll_channel.reset.eq(tx_init.pllreset), tx_init.plllock.eq(qpll_channel.lock) ] txdata = Signal(20) rxdata = Signal(20) rxphaligndone = Signal() gtp_params = dict( # Simulation-Only Attributes p_SIM_RECEIVER_DETECT_PASS="******", p_SIM_TX_EIDLE_DRIVE_LEVEL="X", p_SIM_RESET_SPEEDUP="FALSE", p_SIM_VERSION="2.0", # RX Byte and Word Alignment Attributes p_ALIGN_COMMA_DOUBLE="FALSE", p_ALIGN_COMMA_ENABLE=0b1111111111, p_ALIGN_COMMA_WORD=1, p_ALIGN_MCOMMA_DET="TRUE", p_ALIGN_MCOMMA_VALUE=0b1010000011, p_ALIGN_PCOMMA_DET="TRUE", p_ALIGN_PCOMMA_VALUE=0b0101111100, p_SHOW_REALIGN_COMMA="FALSE", p_RXSLIDE_AUTO_WAIT=7, p_RXSLIDE_MODE="PCS", p_RX_SIG_VALID_DLY=10, # RX 8B/10B Decoder Attributes p_RX_DISPERR_SEQ_MATCH="FALSE", p_DEC_MCOMMA_DETECT="TRUE", p_DEC_PCOMMA_DETECT="TRUE", p_DEC_VALID_COMMA_ONLY="FALSE", # RX Clock Correction Attributes p_CBCC_DATA_SOURCE_SEL="ENCODED", p_CLK_COR_SEQ_2_USE="FALSE", p_CLK_COR_KEEP_IDLE="FALSE", p_CLK_COR_MAX_LAT=9, p_CLK_COR_MIN_LAT=7, p_CLK_COR_PRECEDENCE="TRUE", p_CLK_COR_REPEAT_WAIT=0, p_CLK_COR_SEQ_LEN=1, p_CLK_COR_SEQ_1_ENABLE=0b1111, p_CLK_COR_SEQ_1_1=0b0100000000, p_CLK_COR_SEQ_1_2=0b0000000000, p_CLK_COR_SEQ_1_3=0b0000000000, p_CLK_COR_SEQ_1_4=0b0000000000, p_CLK_CORRECT_USE="FALSE", p_CLK_COR_SEQ_2_ENABLE=0b1111, p_CLK_COR_SEQ_2_1=0b0100000000, p_CLK_COR_SEQ_2_2=0b0000000000, p_CLK_COR_SEQ_2_3=0b0000000000, p_CLK_COR_SEQ_2_4=0b0000000000, # RX Channel Bonding Attributes p_CHAN_BOND_KEEP_ALIGN="FALSE", p_CHAN_BOND_MAX_SKEW=1, p_CHAN_BOND_SEQ_LEN=1, p_CHAN_BOND_SEQ_1_1=0b0000000000, p_CHAN_BOND_SEQ_1_2=0b0000000000, p_CHAN_BOND_SEQ_1_3=0b0000000000, p_CHAN_BOND_SEQ_1_4=0b0000000000, p_CHAN_BOND_SEQ_1_ENABLE=0b1111, p_CHAN_BOND_SEQ_2_1=0b0000000000, p_CHAN_BOND_SEQ_2_2=0b0000000000, p_CHAN_BOND_SEQ_2_3=0b0000000000, p_CHAN_BOND_SEQ_2_4=0b0000000000, p_CHAN_BOND_SEQ_2_ENABLE=0b1111, p_CHAN_BOND_SEQ_2_USE="FALSE", p_FTS_DESKEW_SEQ_ENABLE=0b1111, p_FTS_LANE_DESKEW_CFG=0b1111, p_FTS_LANE_DESKEW_EN="FALSE", # RX Margin Analysis Attributes p_ES_CONTROL=0b000000, p_ES_ERRDET_EN="FALSE", p_ES_EYE_SCAN_EN="FALSE", p_ES_HORZ_OFFSET=0x010, p_ES_PMA_CFG=0b0000000000, p_ES_PRESCALE=0b00000, p_ES_QUALIFIER=0x00000000000000000000, p_ES_QUAL_MASK=0x00000000000000000000, p_ES_SDATA_MASK=0x00000000000000000000, p_ES_VERT_OFFSET=0b000000000, # FPGA RX Interface Attributes p_RX_DATA_WIDTH=20, # PMA Attributes p_OUTREFCLK_SEL_INV=0b11, p_PMA_RSV=0x00000333, p_PMA_RSV2=0x00002040, p_PMA_RSV3=0b00, p_PMA_RSV4=0b0000, p_RX_BIAS_CFG=0b0000111100110011, p_DMONITOR_CFG=0x000A00, p_RX_CM_SEL=0b01, p_RX_CM_TRIM=0b0000, p_RX_DEBUG_CFG=0b00000000000000, p_RX_OS_CFG=0b0000010000000, p_TERM_RCAL_CFG=0b100001000010000, p_TERM_RCAL_OVRD=0b000, p_TST_RSV=0x00000000, p_RX_CLK25_DIV=5, p_TX_CLK25_DIV=5, p_UCODEER_CLR=0b0, # PCI Express Attributes p_PCS_PCIE_EN="FALSE", # PCS Attributes p_PCS_RSVD_ATTR=0x000000000000, # RX Buffer Attributes p_RXBUF_ADDR_MODE="FAST", p_RXBUF_EIDLE_HI_CNT=0b1000, p_RXBUF_EIDLE_LO_CNT=0b0000, p_RXBUF_EN="FALSE", p_RX_BUFFER_CFG=0b000000, p_RXBUF_RESET_ON_CB_CHANGE="TRUE", p_RXBUF_RESET_ON_COMMAALIGN="FALSE", p_RXBUF_RESET_ON_EIDLE="FALSE", p_RXBUF_RESET_ON_RATE_CHANGE="TRUE", p_RXBUFRESET_TIME=0b00001, p_RXBUF_THRESH_OVFLW=61, p_RXBUF_THRESH_OVRD="FALSE", p_RXBUF_THRESH_UNDFLW=4, p_RXDLY_CFG=0x001F, p_RXDLY_LCFG=0x030, p_RXDLY_TAP_CFG=0x0000, p_RXPH_CFG=0xC00002, p_RXPHDLY_CFG=0x084020, p_RXPH_MONITOR_SEL=0b00000, p_RX_XCLK_SEL="RXUSR", p_RX_DDI_SEL=0b000000, p_RX_DEFER_RESET_BUF_EN="TRUE", # CDR Attributes p_RXCDR_CFG=0x0001107FE206021081010, p_RXCDR_FR_RESET_ON_EIDLE=0b0, p_RXCDR_HOLD_DURING_EIDLE=0b0, p_RXCDR_PH_RESET_ON_EIDLE=0b0, p_RXCDR_LOCK_CFG=0b001001, # RX Initialization and Reset Attributes p_RXCDRFREQRESET_TIME=0b00001, p_RXCDRPHRESET_TIME=0b00001, p_RXISCANRESET_TIME=0b00001, p_RXPCSRESET_TIME=0b00001, p_RXPMARESET_TIME=0b00011, # RX OOB Signaling Attributes p_RXOOB_CFG=0b0000110, # RX Gearbox Attributes p_RXGEARBOX_EN="FALSE", p_GEARBOX_MODE=0b000, # PRBS Detection Attribute p_RXPRBS_ERR_LOOPBACK=0b0, # Power-Down Attributes p_PD_TRANS_TIME_FROM_P2=0x03c, p_PD_TRANS_TIME_NONE_P2=0x3c, p_PD_TRANS_TIME_TO_P2=0x64, # RX OOB Signaling Attributes p_SAS_MAX_COM=64, p_SAS_MIN_COM=36, p_SATA_BURST_SEQ_LEN=0b0101, p_SATA_BURST_VAL=0b100, p_SATA_EIDLE_VAL=0b100, p_SATA_MAX_BURST=8, p_SATA_MAX_INIT=21, p_SATA_MAX_WAKE=7, p_SATA_MIN_BURST=4, p_SATA_MIN_INIT=12, p_SATA_MIN_WAKE=4, # RX Fabric Clock Output Control Attributes p_TRANS_TIME_RATE=0x0E, # TX Buffer Attributes p_TXBUF_EN="FALSE", p_TXBUF_RESET_ON_RATE_CHANGE="TRUE", p_TXDLY_CFG=0x001F, p_TXDLY_LCFG=0x030, p_TXDLY_TAP_CFG=0x0000, p_TXPH_CFG=0x0780, p_TXPHDLY_CFG=0x084020, p_TXPH_MONITOR_SEL=0b00000, p_TX_XCLK_SEL="TXUSR", # FPGA TX Interface Attributes p_TX_DATA_WIDTH=20, # TX Configurable Driver Attributes p_TX_DEEMPH0=0b000000, p_TX_DEEMPH1=0b000000, p_TX_EIDLE_ASSERT_DELAY=0b110, p_TX_EIDLE_DEASSERT_DELAY=0b100, p_TX_LOOPBACK_DRIVE_HIZ="FALSE", p_TX_MAINCURSOR_SEL=0b0, p_TX_DRIVE_MODE="DIRECT", p_TX_MARGIN_FULL_0=0b1001110, p_TX_MARGIN_FULL_1=0b1001001, p_TX_MARGIN_FULL_2=0b1000101, p_TX_MARGIN_FULL_3=0b1000010, p_TX_MARGIN_FULL_4=0b1000000, p_TX_MARGIN_LOW_0=0b1000110, p_TX_MARGIN_LOW_1=0b1000100, p_TX_MARGIN_LOW_2=0b1000010, p_TX_MARGIN_LOW_3=0b1000000, p_TX_MARGIN_LOW_4=0b1000000, # TX Gearbox Attributes p_TXGEARBOX_EN="FALSE", # TX Initialization and Reset Attributes p_TXPCSRESET_TIME=0b00001, p_TXPMARESET_TIME=0b00001, # TX Receiver Detection Attributes p_TX_RXDETECT_CFG=0x1832, p_TX_RXDETECT_REF=0b100, # JTAG Attributes p_ACJTAG_DEBUG_MODE=0b0, p_ACJTAG_MODE=0b0, p_ACJTAG_RESET=0b0, # CDR Attributes p_CFOK_CFG=0x49000040E80, p_CFOK_CFG2=0b0100000, p_CFOK_CFG3=0b0100000, p_CFOK_CFG4=0b0, p_CFOK_CFG5=0x0, p_CFOK_CFG6=0b0000, p_RXOSCALRESET_TIME=0b00011, p_RXOSCALRESET_TIMEOUT=0b00000, # PMA Attributes p_CLK_COMMON_SWING=0b0, p_RX_CLKMUX_EN=0b1, p_TX_CLKMUX_EN=0b1, p_ES_CLK_PHASE_SEL=0b0, p_USE_PCS_CLK_PHASE_SEL=0b0, p_PMA_RSV6=0b0, p_PMA_RSV7=0b0, # TX Configuration Driver Attributes p_TX_PREDRIVER_MODE=0b0, p_PMA_RSV5=0b0, p_SATA_PLL_CFG="VCO_3000MHZ", # RX Fabric Clock Output Control Attributes p_RXOUT_DIV=2, # TX Fabric Clock Output Control Attributes p_TXOUT_DIV=2, # RX Phase Interpolator Attributes p_RXPI_CFG0=0b000, p_RXPI_CFG1=0b1, p_RXPI_CFG2=0b1, # RX Equalizer Attributes p_ADAPT_CFG0=0x00000, p_RXLPMRESET_TIME=0b0001111, p_RXLPM_BIAS_STARTUP_DISABLE=0b0, p_RXLPM_CFG=0b0110, p_RXLPM_CFG1=0b0, p_RXLPM_CM_CFG=0b0, p_RXLPM_GC_CFG=0b111100010, p_RXLPM_GC_CFG2=0b001, p_RXLPM_HF_CFG=0b00001111110000, p_RXLPM_HF_CFG2=0b01010, p_RXLPM_HF_CFG3=0b0000, p_RXLPM_HOLD_DURING_EIDLE=0b0, p_RXLPM_INCM_CFG=0b0, p_RXLPM_IPCM_CFG=0b1, p_RXLPM_LF_CFG=0b000000001111110000, p_RXLPM_LF_CFG2=0b01010, p_RXLPM_OSINT_CFG=0b100, # TX Phase Interpolator PPM Controller Attributes p_TXPI_CFG0=0b00, p_TXPI_CFG1=0b00, p_TXPI_CFG2=0b00, p_TXPI_CFG3=0b0, p_TXPI_CFG4=0b0, p_TXPI_CFG5=0b000, p_TXPI_GREY_SEL=0b0, p_TXPI_INVSTROBE_SEL=0b0, p_TXPI_PPMCLK_SEL="TXUSRCLK2", p_TXPI_PPM_CFG=0x00, p_TXPI_SYNFREQ_PPM=0b001, # LOOPBACK Attributes p_LOOPBACK_CFG=0b0, p_PMA_LOOPBACK_CFG=0b0, # RX OOB Signalling Attributes p_RXOOB_CLK_CFG="PMA", # TX OOB Signalling Attributes p_TXOOB_CFG=0b0, # RX Buffer Attributes p_RXSYNC_MULTILANE=0b0, p_RXSYNC_OVRD=0b0, p_RXSYNC_SKIP_DA=0b0, # TX Buffer Attributes p_TXSYNC_MULTILANE=0b0, p_TXSYNC_OVRD=0b1, p_TXSYNC_SKIP_DA=0b0) gtp_params.update( # CPLL Ports i_GTRSVD=0b0000000000000000, i_PCSRSVDIN=0b0000000000000000, i_TSTIN=0b11111111111111111111, # Channel - DRP Ports i_DRPADDR=rx_init.drpaddr, i_DRPCLK=ClockSignal("rtio_tx"), i_DRPDI=rx_init.drpdi, o_DRPDO=rx_init.drpdo, i_DRPEN=rx_init.drpen, o_DRPRDY=rx_init.drprdy, i_DRPWE=rx_init.drpwe, # FPGA TX Interface Datapath Configuration i_TX8B10BEN=0, # Loopback Ports i_LOOPBACK=0, # PCI Express Ports #o_PHYSTATUS =, i_RXRATE=0, #o_RXVALID =, # PMA Reserved Ports i_PMARSVDIN3=0b0, i_PMARSVDIN4=0b0, # Power-Down Ports i_RXPD=Cat(rx_init.gtrxpd, rx_init.gtrxpd), i_TXPD=0b00, # RX 8B/10B Decoder Ports i_SETERRSTATUS=0, # RX Initialization and Reset Ports i_EYESCANRESET=0, i_RXUSERRDY=rx_init.rxuserrdy, # RX Margin Analysis Ports #o_EYESCANDATAERROR =, i_EYESCANMODE=0, i_EYESCANTRIGGER=0, # Receive Ports i_CLKRSVD0=0, i_CLKRSVD1=0, i_DMONFIFORESET=0, i_DMONITORCLK=0, o_RXPMARESETDONE=rx_init.rxpmaresetdone, i_SIGVALIDCLK=0, # Receive Ports - CDR Ports i_RXCDRFREQRESET=0, i_RXCDRHOLD=0, #o_RXCDRLOCK =, i_RXCDROVRDEN=0, i_RXCDRRESET=0, i_RXCDRRESETRSV=0, i_RXOSCALRESET=0, i_RXOSINTCFG=0b0010, #o_RXOSINTDONE =, i_RXOSINTHOLD=0, i_RXOSINTOVRDEN=0, i_RXOSINTPD=0, #o_RXOSINTSTARTED =, i_RXOSINTSTROBE=0, #o_RXOSINTSTROBESTARTED =, i_RXOSINTTESTOVRDEN=0, # Receive Ports - Clock Correction Ports #o_RXCLKCORCNT =, # Receive Ports - FPGA RX Interface Datapath Configuration i_RX8B10BEN=0, # Receive Ports - FPGA RX Interface Ports o_RXDATA=Cat(rxdata[:8], rxdata[10:18]), i_RXUSRCLK=ClockSignal("rtio_rx"), i_RXUSRCLK2=ClockSignal("rtio_rx"), # Receive Ports - Pattern Checker Ports #o_RXPRBSERR =, i_RXPRBSSEL=0, # Receive Ports - Pattern Checker ports i_RXPRBSCNTRESET=0, # Receive Ports - RX 8B/10B Decoder Ports #o_RXCHARISCOMMA =, o_RXCHARISK=Cat(rxdata[8], rxdata[18]), o_RXDISPERR=Cat(rxdata[9], rxdata[19]), #o_RXNOTINTABLE =, # Receive Ports - RX AFE Ports i_GTPRXN=pads.rxn, i_GTPRXP=pads.rxp, i_PMARSVDIN2=0b0, #o_PMARSVDOUT0 =, #o_PMARSVDOUT1 =, # Receive Ports - RX Buffer Bypass Ports i_RXBUFRESET=0, #o_RXBUFSTATUS =, i_RXDDIEN=1, i_RXDLYBYPASS=0, i_RXDLYEN=1, i_RXDLYOVRDEN=0, i_RXDLYSRESET=rx_init.rxdlysreset, o_RXDLYSRESETDONE=rx_init.rxdlysresetdone, i_RXPHALIGN=0, o_RXPHALIGNDONE=rxphaligndone, i_RXPHALIGNEN=0, i_RXPHDLYPD=0, i_RXPHDLYRESET=0, #o_RXPHMONITOR =, i_RXPHOVRDEN=0, #o_RXPHSLIPMONITOR =, #o_RXSTATUS =, i_RXSYNCALLIN=rxphaligndone, o_RXSYNCDONE=rx_init.rxsyncdone, i_RXSYNCIN=0, i_RXSYNCMODE=1, #o_RXSYNCOUT =, # Receive Ports - RX Byte and Word Alignment Ports #o_RXBYTEISALIGNED =, #o_RXBYTEREALIGN =, #o_RXCOMMADET =, i_RXCOMMADETEN=1, i_RXMCOMMAALIGNEN=0, i_RXPCOMMAALIGNEN=0, i_RXSLIDE=0, # Receive Ports - RX Channel Bonding Ports #o_RXCHANBONDSEQ =, i_RXCHBONDEN=0, i_RXCHBONDI=0b0000, i_RXCHBONDLEVEL=0, i_RXCHBONDMASTER=0, #o_RXCHBONDO =, i_RXCHBONDSLAVE=0, # Receive Ports - RX Channel Bonding Ports #o_RXCHANISALIGNED =, #o_RXCHANREALIGN =, # Receive Ports - RX Decision Feedback Equalizer #o_DMONITOROUT =, i_RXADAPTSELTEST=0, i_RXDFEXYDEN=0, i_RXOSINTEN=0b1, i_RXOSINTID0=0, i_RXOSINTNTRLEN=0, #o_RXOSINTSTROBEDONE =, # Receive Ports - RX Driver,OOB signalling,Coupling and Eq.,CDR i_RXLPMLFOVRDEN=0, i_RXLPMOSINTNTRLEN=0, # Receive Ports - RX Equalizer Ports i_RXLPMHFHOLD=0, i_RXLPMHFOVRDEN=0, i_RXLPMLFHOLD=0, i_RXOSHOLD=0, i_RXOSOVRDEN=0, # Receive Ports - RX Fabric ClocK Output Control Ports #o_RXRATEDONE =, # Receive Ports - RX Fabric Clock Output Control Ports i_RXRATEMODE=0b0, # Receive Ports - RX Fabric Output Control Ports o_RXOUTCLK=self.rxoutclk, #o_RXOUTCLKFABRIC =, #o_RXOUTCLKPCS =, i_RXOUTCLKSEL=0b010, # Receive Ports - RX Gearbox Ports #o_RXDATAVALID =, #o_RXHEADER =, #o_RXHEADERVALID =, #o_RXSTARTOFSEQ =, i_RXGEARBOXSLIP=0, # Receive Ports - RX Initialization and Reset Ports i_GTRXRESET=rx_init.gtrxreset, i_RXLPMRESET=0, i_RXOOBRESET=0, i_RXPCSRESET=0, i_RXPMARESET=0, # Receive Ports - RX OOB Signaling ports #o_RXCOMSASDET =, #o_RXCOMWAKEDET =, #o_RXCOMINITDET =, #o_RXELECIDLE =, i_RXELECIDLEMODE=0b11, # Receive Ports - RX Polarity Control Ports i_RXPOLARITY=0, # Receive Ports -RX Initialization and Reset Ports o_RXRESETDONE=rx_init.rxresetdone, # TX Buffer Bypass Ports i_TXPHDLYTSTCLK=0, # TX Configurable Driver Ports i_TXPOSTCURSOR=0b00000, i_TXPOSTCURSORINV=0, i_TXPRECURSOR=0, i_TXPRECURSORINV=0, # TX Fabric Clock Output Control Ports i_TXRATEMODE=0, # TX Initialization and Reset Ports i_CFGRESET=0, i_GTTXRESET=tx_init.gttxreset, #o_PCSRSVDOUT =, i_TXUSERRDY=tx_init.txuserrdy, # TX Phase Interpolator PPM Controller Ports i_TXPIPPMEN=0, i_TXPIPPMOVRDEN=0, i_TXPIPPMPD=0, i_TXPIPPMSEL=0, i_TXPIPPMSTEPSIZE=0, # Transceiver Reset Mode Operation i_GTRESETSEL=0, i_RESETOVRD=0, # Transmit Ports #o_TXPMARESETDONE =, # Transmit Ports - Configurable Driver Ports i_PMARSVDIN0=0b0, i_PMARSVDIN1=0b0, # Transmit Ports - FPGA TX Interface Ports i_TXDATA=Cat(txdata[:8], txdata[10:18]), i_TXUSRCLK=ClockSignal("rtio_tx"), i_TXUSRCLK2=ClockSignal("rtio_tx"), # Transmit Ports - PCI Express Ports i_TXELECIDLE=0, i_TXMARGIN=0, i_TXRATE=0, i_TXSWING=0, # Transmit Ports - Pattern Generator Ports i_TXPRBSFORCEERR=0, # Transmit Ports - TX 8B/10B Encoder Ports i_TX8B10BBYPASS=0, i_TXCHARDISPMODE=Cat(txdata[9], txdata[19]), i_TXCHARDISPVAL=Cat(txdata[8], txdata[18]), i_TXCHARISK=0, # Transmit Ports - TX Buffer Bypass Ports i_TXDLYBYPASS=0, i_TXDLYEN=tx_init.txdlyen, i_TXDLYHOLD=0, i_TXDLYOVRDEN=0, i_TXDLYSRESET=tx_init.txdlysreset, o_TXDLYSRESETDONE=tx_init.txdlysresetdone, i_TXDLYUPDOWN=0, i_TXPHALIGN=tx_init.txphalign, o_TXPHALIGNDONE=tx_init.txphaligndone, i_TXPHALIGNEN=1, i_TXPHDLYPD=0, i_TXPHDLYRESET=0, i_TXPHINIT=tx_init.txphinit, o_TXPHINITDONE=tx_init.txphinitdone, i_TXPHOVRDEN=0, # Transmit Ports - TX Buffer Ports #o_TXBUFSTATUS =, # Transmit Ports - TX Buffer and Phase Alignment Ports i_TXSYNCALLIN=0, #o_TXSYNCDONE =, #i_TXSYNCIN =0, #i_TXSYNCMODE =0, #o_TXSYNCOUT =, # Transmit Ports - TX Configurable Driver Ports o_GTPTXN=pads.txn, o_GTPTXP=pads.txp, i_TXBUFDIFFCTRL=0b100, i_TXDEEMPH=0, i_TXDIFFCTRL=0b1000, i_TXDIFFPD=0, i_TXINHIBIT=0, i_TXMAINCURSOR=0b0000000, i_TXPISOPD=0, # Transmit Ports - TX Fabric Clock Output Control Ports o_TXOUTCLK=self.txoutclk, #o_TXOUTCLKFABRIC =, #o_TXOUTCLKPCS =, i_TXOUTCLKSEL=0b011, #o_TXRATEDONE =, # Transmit Ports - TX Gearbox Ports #o_TXGEARBOXREADY =, i_TXHEADER=0, i_TXSEQUENCE=0, i_TXSTARTSEQ=0, # Transmit Ports - TX Initialization and Reset Ports i_TXPCSRESET=0, i_TXPMARESET=0, o_TXRESETDONE=tx_init.txresetdone, # Transmit Ports - TX OOB signalling Ports #o_TXCOMFINISH =, i_TXCOMINIT=0, i_TXCOMSAS=0, i_TXCOMWAKE=0, i_TXPDELECIDLEMODE=0, # Transmit Ports - TX Polarity Control Ports i_TXPOLARITY=0, # Transmit Ports - TX Receiver Detection Ports i_TXDETECTRX=0, # Transmit Ports - pattern Generator Ports i_TXPRBSSEL=0) if qpll_channel.index == 0: gtp_params.update( i_RXSYSCLKSEL=0b00, i_TXSYSCLKSEL=0b00, i_PLL0CLK=qpll_channel.clk, i_PLL0REFCLK=qpll_channel.refclk, i_PLL1CLK=0, i_PLL1REFCLK=0, ) elif qpll_channel.index == 1: gtp_params.update( i_RXSYSCLKSEL=0b11, i_TXSYSCLKSEL=0b11, i_PLL0CLK=0, i_PLL0REFCLK=0, i_PLL1CLK=qpll_channel.clk, i_PLL1REFCLK=qpll_channel.refclk, ) else: raise ValueError self.specials += Instance("GTPE2_CHANNEL", **gtp_params) # tx clocking tx_reset_deglitched = Signal() tx_reset_deglitched.attr.add("no_retiming") self.sync += tx_reset_deglitched.eq(~tx_init.done) self.clock_domains.cd_rtio_tx = ClockDomain() if mode == "master" or mode == "single": self.specials += Instance("BUFG", i_I=self.txoutclk, o_O=self.cd_rtio_tx.clk) self.specials += AsyncResetSynchronizer(self.cd_rtio_tx, tx_reset_deglitched) # rx clocking rx_reset_deglitched = Signal() rx_reset_deglitched.attr.add("no_retiming") self.sync.rtio_tx += rx_reset_deglitched.eq(~rx_init.done) self.clock_domains.cd_rtio_rx = ClockDomain() self.specials += [ Instance("BUFG", i_I=self.rxoutclk, o_O=self.cd_rtio_rx.clk), AsyncResetSynchronizer(self.cd_rtio_rx, rx_reset_deglitched) ] # tx data self.comb += txdata.eq(Cat(*[encoder.output[i] for i in range(2)])) # rx data for i in range(2): self.comb += decoders[i].input.eq(rxdata[10 * i:10 * (i + 1)]) # clock alignment clock_aligner = BruteforceClockAligner(0b0101111100, rtio_clk_freq, check_period=12e-3) self.submodules += clock_aligner self.comb += [ clock_aligner.rxdata.eq(rxdata), rx_init.restart.eq(clock_aligner.restart), self.rx_ready.eq(clock_aligner.ready) ]
def __init__(self, platform, sys_clk_freq, with_usb_pll=False): self.clock_domains.cd_init = ClockDomain() self.clock_domains.cd_por = ClockDomain(reset_less=True) self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys2x = ClockDomain() self.clock_domains.cd_sys2x_i = ClockDomain(reset_less=True) self.clock_domains.cd_sys2x_eb = ClockDomain(reset_less=True) # # # self.stop = Signal() self.reset = Signal() # Clk / Rst clk48 = platform.request("clk48") rst_n = platform.request("usr_btn") # Power on reset por_count = Signal(16, reset=2**16 - 1) por_done = Signal() self.comb += self.cd_por.clk.eq(clk48) self.comb += por_done.eq(por_count == 0) self.sync.por += If(~por_done, por_count.eq(por_count - 1)) # PLL sys2x_clk_ecsout = Signal() self.submodules.pll = pll = ECP5PLL() self.comb += pll.reset.eq(~por_done | ~rst_n) pll.register_clkin(clk48, 48e6) pll.create_clkout(self.cd_sys2x_i, 2 * sys_clk_freq) pll.create_clkout(self.cd_init, 24e6) self.specials += [ Instance("ECLKBRIDGECS", i_CLK0=self.cd_sys2x_i.clk, i_SEL=0, o_ECSOUT=sys2x_clk_ecsout), Instance("ECLKSYNCB", i_ECLKI=sys2x_clk_ecsout, i_STOP=self.stop, o_ECLKO=self.cd_sys2x.clk), Instance("CLKDIVF", p_DIV="2.0", i_ALIGNWD=0, i_CLKI=self.cd_sys2x.clk, i_RST=self.reset, o_CDIVX=self.cd_sys.clk), AsyncResetSynchronizer(self.cd_sys, ~pll.locked | self.reset), AsyncResetSynchronizer(self.cd_sys2x, ~pll.locked | self.reset), ] # USB PLL if with_usb_pll: self.clock_domains.cd_usb_12 = ClockDomain() self.clock_domains.cd_usb_48 = ClockDomain() usb_pll = ECP5PLL() self.submodules += usb_pll self.comb += usb_pll.reset.eq(~por_done | ~rst_n) usb_pll.register_clkin(clk48, 48e6) usb_pll.create_clkout(self.cd_usb_48, 48e6) usb_pll.create_clkout(self.cd_usb_12, 12e6) # FPGA Reset (press usr_btn for 1 second to fallback to bootlooader) reset_timer = WaitTimer(sys_clk_freq) self.submodules += reset_timer self.comb += reset_timer.wait.eq(~rst_n) self.comb += platform.request("rst_n").eq(~reset_timer.done)
def __init__(self, refclk_or_clk_pads, data_pads, sys_clk_freq): pcs = PCS(lsb_first=True) self.submodules += pcs self.sink = pcs.sink self.source = pcs.source self.link_up = pcs.link_up self.clock_domains.cd_eth_tx = ClockDomain() self.clock_domains.cd_eth_rx = ClockDomain() self.clock_domains.cd_eth_tx_half = ClockDomain(reset_less=True) self.clock_domains.cd_eth_rx_half = ClockDomain(reset_less=True) # for specifying clock constraints. 125MHz clocks. self.txoutclk = Signal() self.rxoutclk = Signal() # # # if isinstance(refclk_or_clk_pads, Signal): refclk = refclk_or_clk_pads else: refclk = Signal() self.specials += Instance( "IBUFDS_GTE3", i_I=refclk_or_clk_pads.p, i_IB=refclk_or_clk_pads.n, i_CEB=0, o_O=refclk, ) gtpowergood = Signal() pll_reset = Signal(reset=1) pll_locked = Signal() tx_reset = Signal() tx_data = Signal(20) tx_reset_done = Signal() rx_reset = Signal() rx_data = Signal(20) rx_reset_done = Signal() gth_params = dict( p_ACJTAG_DEBUG_MODE=0b0, p_ACJTAG_MODE=0b0, p_ACJTAG_RESET=0b0, p_ADAPT_CFG0=0b1111100000000000, p_ADAPT_CFG1=0b0000000000000000, p_ALIGN_COMMA_DOUBLE="FALSE", p_ALIGN_COMMA_ENABLE=0b0000000000, p_ALIGN_COMMA_WORD=1, p_ALIGN_MCOMMA_DET="FALSE", p_ALIGN_MCOMMA_VALUE=0b1010000011, p_ALIGN_PCOMMA_DET="FALSE", p_ALIGN_PCOMMA_VALUE=0b0101111100, p_A_RXOSCALRESET=0b0, p_A_RXPROGDIVRESET=0b0, p_A_TXPROGDIVRESET=0b0, p_CBCC_DATA_SOURCE_SEL="ENCODED", p_CDR_SWAP_MODE_EN=0b0, p_CHAN_BOND_KEEP_ALIGN="FALSE", p_CHAN_BOND_MAX_SKEW=1, p_CHAN_BOND_SEQ_1_1=0b0000000000, p_CHAN_BOND_SEQ_1_2=0b0000000000, p_CHAN_BOND_SEQ_1_3=0b0000000000, p_CHAN_BOND_SEQ_1_4=0b0000000000, p_CHAN_BOND_SEQ_1_ENABLE=0b1111, p_CHAN_BOND_SEQ_2_1=0b0000000000, p_CHAN_BOND_SEQ_2_2=0b0000000000, p_CHAN_BOND_SEQ_2_3=0b0000000000, p_CHAN_BOND_SEQ_2_4=0b0000000000, p_CHAN_BOND_SEQ_2_ENABLE=0b1111, p_CHAN_BOND_SEQ_2_USE="FALSE", p_CHAN_BOND_SEQ_LEN=1, p_CLK_CORRECT_USE="FALSE", p_CLK_COR_KEEP_IDLE="FALSE", p_CLK_COR_MAX_LAT=6, p_CLK_COR_MIN_LAT=4, p_CLK_COR_PRECEDENCE="TRUE", p_CLK_COR_REPEAT_WAIT=0, p_CLK_COR_SEQ_1_1=0b0000000000, p_CLK_COR_SEQ_1_2=0b0000000000, p_CLK_COR_SEQ_1_3=0b0000000000, p_CLK_COR_SEQ_1_4=0b0000000000, p_CLK_COR_SEQ_1_ENABLE=0b1111, p_CLK_COR_SEQ_2_1=0b0000000000, p_CLK_COR_SEQ_2_2=0b0000000000, p_CLK_COR_SEQ_2_3=0b0000000000, p_CLK_COR_SEQ_2_4=0b0000000000, p_CLK_COR_SEQ_2_ENABLE=0b1111, p_CLK_COR_SEQ_2_USE="FALSE", p_CLK_COR_SEQ_LEN=1, p_CPLL_CFG0=0b0110011111111000, p_CPLL_CFG1=0b1010010010101100, p_CPLL_CFG2=0b0000000000000111, p_CPLL_CFG3=0b000000, p_CPLL_FBDIV=5, p_CPLL_FBDIV_45=5, p_CPLL_INIT_CFG0=0b0000001010110010, p_CPLL_INIT_CFG1=0b00000000, p_CPLL_LOCK_CFG=0b0000000111101000, p_CPLL_REFCLK_DIV=2, p_DDI_CTRL=0b00, p_DDI_REALIGN_WAIT=15, p_DEC_MCOMMA_DETECT="FALSE", p_DEC_PCOMMA_DETECT="FALSE", p_DEC_VALID_COMMA_ONLY="FALSE", p_DFE_D_X_REL_POS=0b0, p_DFE_VCM_COMP_EN=0b0, p_DMONITOR_CFG0=0b0000000000, p_DMONITOR_CFG1=0b00000000, p_ES_CLK_PHASE_SEL=0b0, p_ES_CONTROL=0b000000, p_ES_ERRDET_EN="FALSE", p_ES_EYE_SCAN_EN="FALSE", p_ES_HORZ_OFFSET=0b000000000000, p_ES_PMA_CFG=0b0000000000, p_ES_PRESCALE=0b00000, p_ES_QUALIFIER0=0b0000000000000000, p_ES_QUALIFIER1=0b0000000000000000, p_ES_QUALIFIER2=0b0000000000000000, p_ES_QUALIFIER3=0b0000000000000000, p_ES_QUALIFIER4=0b0000000000000000, p_ES_QUAL_MASK0=0b0000000000000000, p_ES_QUAL_MASK1=0b0000000000000000, p_ES_QUAL_MASK2=0b0000000000000000, p_ES_QUAL_MASK3=0b0000000000000000, p_ES_QUAL_MASK4=0b0000000000000000, p_ES_SDATA_MASK0=0b0000000000000000, p_ES_SDATA_MASK1=0b0000000000000000, p_ES_SDATA_MASK2=0b0000000000000000, p_ES_SDATA_MASK3=0b0000000000000000, p_ES_SDATA_MASK4=0b0000000000000000, p_EVODD_PHI_CFG=0b00000000000, p_EYE_SCAN_SWAP_EN=0b0, p_FTS_DESKEW_SEQ_ENABLE=0b1111, p_FTS_LANE_DESKEW_CFG=0b1111, p_FTS_LANE_DESKEW_EN="FALSE", p_GEARBOX_MODE=0b00000, p_GM_BIAS_SELECT=0b0, p_LOCAL_MASTER=0b1, p_OOBDIVCTL=0b00, p_OOB_PWRUP=0b0, p_PCI3_AUTO_REALIGN="OVR_1K_BLK", p_PCI3_PIPE_RX_ELECIDLE=0b0, p_PCI3_RX_ASYNC_EBUF_BYPASS=0b00, p_PCI3_RX_ELECIDLE_EI2_ENABLE=0b0, p_PCI3_RX_ELECIDLE_H2L_COUNT=0b000000, p_PCI3_RX_ELECIDLE_H2L_DISABLE=0b000, p_PCI3_RX_ELECIDLE_HI_COUNT=0b000000, p_PCI3_RX_ELECIDLE_LP4_DISABLE=0b0, p_PCI3_RX_FIFO_DISABLE=0b0, p_PCIE_BUFG_DIV_CTRL=0b0001000000000000, p_PCIE_RXPCS_CFG_GEN3=0b0000001010100100, p_PCIE_RXPMA_CFG=0b0000000000001010, p_PCIE_TXPCS_CFG_GEN3=0b0010110010100100, p_PCIE_TXPMA_CFG=0b0000000000001010, p_PCS_PCIE_EN="FALSE", p_PCS_RSVD0=0b0000000000000000, p_PCS_RSVD1=0b000, p_PD_TRANS_TIME_FROM_P2=0b000000111100, p_PD_TRANS_TIME_NONE_P2=0b00011001, p_PD_TRANS_TIME_TO_P2=0b01100100, p_PLL_SEL_MODE_GEN12=0b00, p_PLL_SEL_MODE_GEN3=0b11, p_PMA_RSV1=0b1111000000000000, p_PROCESS_PAR=0b010, p_RATE_SW_USE_DRP=0b1, p_RESET_POWERSAVE_DISABLE=0b0, ) gth_params.update( p_RXBUFRESET_TIME=0b00011, p_RXBUF_ADDR_MODE="FAST", p_RXBUF_EIDLE_HI_CNT=0b1000, p_RXBUF_EIDLE_LO_CNT=0b0000, p_RXBUF_EN="TRUE", p_RXBUF_RESET_ON_CB_CHANGE="TRUE", p_RXBUF_RESET_ON_COMMAALIGN="FALSE", p_RXBUF_RESET_ON_EIDLE="FALSE", p_RXBUF_RESET_ON_RATE_CHANGE="TRUE", p_RXBUF_THRESH_OVFLW=61, p_RXBUF_THRESH_OVRD="TRUE", p_RXBUF_THRESH_UNDFLW=1, p_RXCDRFREQRESET_TIME=0b00001, p_RXCDRPHRESET_TIME=0b00001, p_RXCDR_CFG0=0b0000000000000000, p_RXCDR_CFG0_GEN3=0b0000000000000000, p_RXCDR_CFG1=0b0000000000000000, p_RXCDR_CFG1_GEN3=0b0000000000000000, p_RXCDR_CFG2=0b0000011111000110, p_RXCDR_CFG2_GEN3=0b0000011111100110, p_RXCDR_CFG3=0b0000000000000000, p_RXCDR_CFG3_GEN3=0b0000000000000000, p_RXCDR_CFG4=0b0000000000000000, p_RXCDR_CFG4_GEN3=0b0000000000000000, p_RXCDR_CFG5=0b0000000000000000, p_RXCDR_CFG5_GEN3=0b0000000000000000, p_RXCDR_FR_RESET_ON_EIDLE=0b0, p_RXCDR_HOLD_DURING_EIDLE=0b0, p_RXCDR_LOCK_CFG0=0b0100010010000000, p_RXCDR_LOCK_CFG1=0b0101111111111111, p_RXCDR_LOCK_CFG2=0b0111011111000011, p_RXCDR_PH_RESET_ON_EIDLE=0b0, p_RXCFOK_CFG0=0b0100000000000000, p_RXCFOK_CFG1=0b0000000001100101, p_RXCFOK_CFG2=0b0000000000101110, p_RXDFELPMRESET_TIME=0b0001111, p_RXDFELPM_KL_CFG0=0b0000000000000000, p_RXDFELPM_KL_CFG1=0b0000000000110010, p_RXDFELPM_KL_CFG2=0b0000000000000000, p_RXDFE_CFG0=0b0000101000000000, p_RXDFE_CFG1=0b0000000000000000, p_RXDFE_GC_CFG0=0b0000000000000000, p_RXDFE_GC_CFG1=0b0111100001110000, p_RXDFE_GC_CFG2=0b0000000000000000, p_RXDFE_H2_CFG0=0b0000000000000000, p_RXDFE_H2_CFG1=0b0000000000000000, p_RXDFE_H3_CFG0=0b0100000000000000, p_RXDFE_H3_CFG1=0b0000000000000000, p_RXDFE_H4_CFG0=0b0010000000000000, p_RXDFE_H4_CFG1=0b0000000000000011, p_RXDFE_H5_CFG0=0b0010000000000000, p_RXDFE_H5_CFG1=0b0000000000000011, p_RXDFE_H6_CFG0=0b0010000000000000, p_RXDFE_H6_CFG1=0b0000000000000000, p_RXDFE_H7_CFG0=0b0010000000000000, p_RXDFE_H7_CFG1=0b0000000000000000, p_RXDFE_H8_CFG0=0b0010000000000000, p_RXDFE_H8_CFG1=0b0000000000000000, p_RXDFE_H9_CFG0=0b0010000000000000, p_RXDFE_H9_CFG1=0b0000000000000000, p_RXDFE_HA_CFG0=0b0010000000000000, p_RXDFE_HA_CFG1=0b0000000000000000, p_RXDFE_HB_CFG0=0b0010000000000000, p_RXDFE_HB_CFG1=0b0000000000000000, p_RXDFE_HC_CFG0=0b0000000000000000, p_RXDFE_HC_CFG1=0b0000000000000000, p_RXDFE_HD_CFG0=0b0000000000000000, p_RXDFE_HD_CFG1=0b0000000000000000, p_RXDFE_HE_CFG0=0b0000000000000000, p_RXDFE_HE_CFG1=0b0000000000000000, p_RXDFE_HF_CFG0=0b0000000000000000, p_RXDFE_HF_CFG1=0b0000000000000000, p_RXDFE_OS_CFG0=0b1000000000000000, p_RXDFE_OS_CFG1=0b0000000000000000, p_RXDFE_UT_CFG0=0b1000000000000000, p_RXDFE_UT_CFG1=0b0000000000000011, p_RXDFE_VP_CFG0=0b1010101000000000, p_RXDFE_VP_CFG1=0b0000000000110011, p_RXDLY_CFG=0b0000000000011111, p_RXDLY_LCFG=0b0000000000110000, p_RXELECIDLE_CFG="Sigcfg_4", p_RXGBOX_FIFO_INIT_RD_ADDR=4, p_RXGEARBOX_EN="FALSE", p_RXISCANRESET_TIME=0b00001, p_RXLPM_CFG=0b0000000000000000, p_RXLPM_GC_CFG=0b0001000000000000, p_RXLPM_KH_CFG0=0b0000000000000000, p_RXLPM_KH_CFG1=0b0000000000000010, p_RXLPM_OS_CFG0=0b1000000000000000, p_RXLPM_OS_CFG1=0b0000000000000010, p_RXOOB_CFG=0b000000110, p_RXOOB_CLK_CFG="PMA", p_RXOSCALRESET_TIME=0b00011, p_RXOUT_DIV=4, p_RXPCSRESET_TIME=0b00011, p_RXPHBEACON_CFG=0b0000000000000000, p_RXPHDLY_CFG=0b0010000000100000, p_RXPHSAMP_CFG=0b0010000100000000, p_RXPHSLIP_CFG=0b0110011000100010, p_RXPH_MONITOR_SEL=0b00000, p_RXPI_CFG0=0b01, p_RXPI_CFG1=0b01, p_RXPI_CFG2=0b01, p_RXPI_CFG3=0b01, p_RXPI_CFG4=0b1, p_RXPI_CFG5=0b1, p_RXPI_CFG6=0b011, p_RXPI_LPM=0b0, p_RXPI_VREFSEL=0b0, p_RXPMACLK_SEL="DATA", p_RXPMARESET_TIME=0b00011, p_RXPRBS_ERR_LOOPBACK=0b0, p_RXPRBS_LINKACQ_CNT=15, p_RXSLIDE_AUTO_WAIT=7, p_RXSLIDE_MODE="OFF", p_RXSYNC_MULTILANE=0b0, p_RXSYNC_OVRD=0b0, p_RXSYNC_SKIP_DA=0b0, p_RX_AFE_CM_EN=0b0, p_RX_BIAS_CFG0=0b0000101010110100, p_RX_BUFFER_CFG=0b000000, p_RX_CAPFF_SARC_ENB=0b0, p_RX_CLK25_DIV=8, p_RX_CLKMUX_EN=0b1, p_RX_CLK_SLIP_OVRD=0b00000, p_RX_CM_BUF_CFG=0b1010, p_RX_CM_BUF_PD=0b0, p_RX_CM_SEL=0b11, p_RX_CM_TRIM=0b1010, p_RX_CTLE3_LPF=0b00000001, p_RX_DATA_WIDTH=20, p_RX_DDI_SEL=0b000000, p_RX_DEFER_RESET_BUF_EN="TRUE", p_RX_DFELPM_CFG0=0b0110, p_RX_DFELPM_CFG1=0b1, p_RX_DFELPM_KLKH_AGC_STUP_EN=0b1, p_RX_DFE_AGC_CFG0=0b10, p_RX_DFE_AGC_CFG1=0b000, p_RX_DFE_KL_LPM_KH_CFG0=0b01, p_RX_DFE_KL_LPM_KH_CFG1=0b000, p_RX_DFE_KL_LPM_KL_CFG0=0b01, p_RX_DFE_KL_LPM_KL_CFG1=0b000, p_RX_DFE_LPM_HOLD_DURING_EIDLE=0b0, p_RX_DISPERR_SEQ_MATCH="TRUE", p_RX_DIVRESET_TIME=0b00001, p_RX_EN_HI_LR=0b0, p_RX_EYESCAN_VS_CODE=0b0000000, p_RX_EYESCAN_VS_NEG_DIR=0b0, p_RX_EYESCAN_VS_RANGE=0b00, p_RX_EYESCAN_VS_UT_SIGN=0b0, p_RX_FABINT_USRCLK_FLOP=0b0, p_RX_INT_DATAWIDTH=0, p_RX_PMA_POWER_SAVE=0b0, p_RX_PROGDIV_CFG=20.0, p_RX_SAMPLE_PERIOD=0b111, p_RX_SIG_VALID_DLY=11, p_RX_SUM_DFETAPREP_EN=0b0, p_RX_SUM_IREF_TUNE=0b1100, p_RX_SUM_RES_CTRL=0b11, p_RX_SUM_VCMTUNE=0b0000, p_RX_SUM_VCM_OVWR=0b0, p_RX_SUM_VREF_TUNE=0b000, p_RX_TUNE_AFE_OS=0b10, p_RX_WIDEMODE_CDR=0b0, p_RX_XCLK_SEL="RXDES", ) gth_params.update( p_SAS_MAX_COM=64, p_SAS_MIN_COM=36, p_SATA_BURST_SEQ_LEN=0b1110, p_SATA_CPLL_CFG="VCO_3000MHZ", p_SATA_MAX_BURST=8, p_SATA_MAX_INIT=21, p_SATA_MAX_WAKE=7, p_SATA_MIN_BURST=4, p_SATA_MIN_INIT=12, p_SATA_MIN_WAKE=4, p_SHOW_REALIGN_COMMA="FALSE", p_SIM_RECEIVER_DETECT_PASS="******", p_SIM_RESET_SPEEDUP="TRUE", p_SIM_TX_EIDLE_DRIVE_LEVEL=0b0, p_SIM_VERSION=2, p_TAPDLY_SET_TX=0b00, p_TEMPERATUR_PAR=0b0010, p_TERM_RCAL_CFG=0b100001000010000, p_TERM_RCAL_OVRD=0b000, p_TRANS_TIME_RATE=0b00001110, p_TST_RSV0=0b00000000, p_TST_RSV1=0b00000000, p_TXBUF_EN="TRUE", p_TXBUF_RESET_ON_RATE_CHANGE="TRUE", p_TXDLY_CFG=0b0000000000001001, p_TXDLY_LCFG=0b0000000001010000, p_TXDRVBIAS_N=0b1010, p_TXDRVBIAS_P=0b1010, p_TXFIFO_ADDR_CFG="LOW", p_TXGBOX_FIFO_INIT_RD_ADDR=4, p_TXGEARBOX_EN="FALSE", p_TXOUT_DIV=4, p_TXPCSRESET_TIME=0b00011, p_TXPHDLY_CFG0=0b0010000000100000, p_TXPHDLY_CFG1=0b0000000001110101, p_TXPH_CFG=0b0000100110000000, p_TXPH_MONITOR_SEL=0b00000, p_TXPI_CFG0=0b01, p_TXPI_CFG1=0b01, p_TXPI_CFG2=0b01, p_TXPI_CFG3=0b1, p_TXPI_CFG4=0b1, p_TXPI_CFG5=0b011, p_TXPI_GRAY_SEL=0b0, p_TXPI_INVSTROBE_SEL=0b0, p_TXPI_LPM=0b0, p_TXPI_PPMCLK_SEL="TXUSRCLK2", p_TXPI_PPM_CFG=0b00000000, p_TXPI_SYNFREQ_PPM=0b001, p_TXPI_VREFSEL=0b0, p_TXPMARESET_TIME=0b00011, p_TXSYNC_MULTILANE=0b0, p_TXSYNC_OVRD=0b0, p_TXSYNC_SKIP_DA=0b0, p_TX_CLK25_DIV=8, p_TX_CLKMUX_EN=0b1, p_TX_DATA_WIDTH=20, p_TX_DCD_CFG=0b000010, p_TX_DCD_EN=0b0, p_TX_DEEMPH0=0b000000, p_TX_DEEMPH1=0b000000, p_TX_DIVRESET_TIME=0b00001, p_TX_DRIVE_MODE="DIRECT", p_TX_EIDLE_ASSERT_DELAY=0b100, p_TX_EIDLE_DEASSERT_DELAY=0b011, p_TX_EML_PHI_TUNE=0b0, p_TX_FABINT_USRCLK_FLOP=0b0, p_TX_IDLE_DATA_ZERO=0b0, p_TX_INT_DATAWIDTH=0, p_TX_LOOPBACK_DRIVE_HIZ="FALSE", p_TX_MAINCURSOR_SEL=0b0, p_TX_MARGIN_FULL_0=0b1001111, p_TX_MARGIN_FULL_1=0b1001110, p_TX_MARGIN_FULL_2=0b1001100, p_TX_MARGIN_FULL_3=0b1001010, p_TX_MARGIN_FULL_4=0b1001000, p_TX_MARGIN_LOW_0=0b1000110, p_TX_MARGIN_LOW_1=0b1000101, p_TX_MARGIN_LOW_2=0b1000011, p_TX_MARGIN_LOW_3=0b1000010, p_TX_MARGIN_LOW_4=0b1000000, p_TX_MODE_SEL=0b000, p_TX_PMADATA_OPT=0b0, p_TX_PMA_POWER_SAVE=0b0, p_TX_PROGCLK_SEL="CPLL", p_TX_PROGDIV_CFG=20.0, p_TX_QPI_STATUS_EN=0b0, p_TX_RXDETECT_CFG=0b00000000110010, p_TX_RXDETECT_REF=0b100, p_TX_SAMPLE_PERIOD=0b111, p_TX_SARC_LPBK_ENB=0b0, p_TX_XCLK_SEL="TXOUT", p_USE_PCS_CLK_PHASE_SEL=0b0, p_WB_MODE=0b00, ) gth_params.update( i_CFGRESET=0b0, i_CLKRSVD0=0b0, i_CLKRSVD1=0b0, i_CPLLLOCKDETCLK=0b0, i_CPLLLOCKEN=0b1, i_CPLLPD=pll_reset, i_CPLLREFCLKSEL=0b001, i_CPLLRESET=0b0, i_DMONFIFORESET=0b0, i_DMONITORCLK=0b0, i_DRPADDR=0b000000000, i_DRPCLK=0b0, i_DRPDI=0b0000000000000000, i_DRPEN=0b0, i_DRPWE=0b0, i_EVODDPHICALDONE=0b0, i_EVODDPHICALSTART=0b0, i_EVODDPHIDRDEN=0b0, i_EVODDPHIDWREN=0b0, i_EVODDPHIXRDEN=0b0, i_EVODDPHIXWREN=0b0, i_EYESCANMODE=0b0, i_EYESCANRESET=0b0, i_EYESCANTRIGGER=0b0, i_GTGREFCLK=0b0, i_GTHRXN=data_pads.rxn, i_GTHRXP=data_pads.rxp, i_GTNORTHREFCLK0=0b0, i_GTNORTHREFCLK1=0b0, i_GTREFCLK0=refclk, i_GTREFCLK1=0b0, i_GTRESETSEL=0b0, i_GTRSVD=0b0000000000000000, i_GTRXRESET=rx_reset, i_GTSOUTHREFCLK0=0b0, i_GTSOUTHREFCLK1=0b0, i_GTTXRESET=tx_reset, i_LOOPBACK=0b000, i_LPBKRXTXSEREN=0b0, i_LPBKTXRXSEREN=0b0, i_PCIEEQRXEQADAPTDONE=0b0, i_PCIERSTIDLE=0b0, i_PCIERSTTXSYNCSTART=0b0, i_PCIEUSERRATEDONE=0b0, i_PCSRSVDIN2=0b00000, i_PCSRSVDIN=0b0000000000000000, i_PMARSVDIN=0b00000, i_QPLL0CLK=0b0, i_QPLL0REFCLK=0b0, i_QPLL1CLK=0b0, i_QPLL1REFCLK=0b0, i_RESETOVRD=0b0, i_RSTCLKENTX=0b0, i_RX8B10BEN=0b0, i_RXBUFRESET=0b0, i_RXCDRFREQRESET=0b0, i_RXCDRHOLD=0b0, i_RXCDROVRDEN=0b0, i_RXCDRRESETRSV=0b0, i_RXCDRRESET=0b0, i_RXCHBONDEN=0b0, i_RXCHBONDI=0b00000, i_RXCHBONDLEVEL=0b000, i_RXCHBONDMASTER=0b0, i_RXCHBONDSLAVE=0b0, i_RXCOMMADETEN=0b0, i_RXDFEAGCCTRL=0b01, i_RXDFEAGCHOLD=0b0, i_RXDFEAGCOVRDEN=0b0, i_RXDFELFHOLD=0b0, i_RXDFELFOVRDEN=0b0, i_RXDFELPMRESET=0b0, i_RXDFETAP10HOLD=0b0, i_RXDFETAP10OVRDEN=0b0, i_RXDFETAP11HOLD=0b0, i_RXDFETAP11OVRDEN=0b0, i_RXDFETAP12HOLD=0b0, i_RXDFETAP12OVRDEN=0b0, i_RXDFETAP13HOLD=0b0, i_RXDFETAP13OVRDEN=0b0, i_RXDFETAP14HOLD=0b0, i_RXDFETAP14OVRDEN=0b0, i_RXDFETAP15HOLD=0b0, i_RXDFETAP15OVRDEN=0b0, i_RXDFETAP2HOLD=0b0, i_RXDFETAP2OVRDEN=0b0, i_RXDFETAP3HOLD=0b0, i_RXDFETAP3OVRDEN=0b0, i_RXDFETAP4HOLD=0b0, i_RXDFETAP4OVRDEN=0b0, i_RXDFETAP5HOLD=0b0, i_RXDFETAP5OVRDEN=0b0, i_RXDFETAP6HOLD=0b0, i_RXDFETAP6OVRDEN=0b0, i_RXDFETAP7HOLD=0b0, i_RXDFETAP7OVRDEN=0b0, i_RXDFETAP8HOLD=0b0, i_RXDFETAP8OVRDEN=0b0, i_RXDFETAP9HOLD=0b0, i_RXDFETAP9OVRDEN=0b0, i_RXDFEUTHOLD=0b0, i_RXDFEUTOVRDEN=0b0, i_RXDFEVPHOLD=0b0, i_RXDFEVPOVRDEN=0b0, i_RXDFEVSEN=0b0, i_RXDFEXYDEN=0b1, i_RXDLYBYPASS=0b1, i_RXDLYEN=0b0, i_RXDLYOVRDEN=0b0, i_RXDLYSRESET=0b0, i_RXELECIDLEMODE=0b11, i_RXGEARBOXSLIP=0b0, i_RXLATCLK=0b0, i_RXLPMEN=0b1, i_RXLPMGCHOLD=0b0, i_RXLPMGCOVRDEN=0b0, i_RXLPMHFHOLD=0b0, i_RXLPMHFOVRDEN=0b0, i_RXLPMLFHOLD=0b0, i_RXLPMLFKLOVRDEN=0b0, i_RXLPMOSHOLD=0b0, i_RXLPMOSOVRDEN=0b0, i_RXMCOMMAALIGNEN=0b0, i_RXMONITORSEL=0b00, i_RXOOBRESET=0b0, i_RXOSCALRESET=0b0, i_RXOSHOLD=0b0, i_RXOSINTCFG=0b1101, i_RXOSINTEN=0b1, i_RXOSINTHOLD=0b0, i_RXOSINTOVRDEN=0b0, i_RXOSINTSTROBE=0b0, i_RXOSINTTESTOVRDEN=0b0, i_RXOSOVRDEN=0b0, i_RXOUTCLKSEL=0b101, i_RXPCOMMAALIGNEN=0b0, i_RXPCSRESET=0b0, i_RXPD=0b00, i_RXPHALIGNEN=0b0, i_RXPHALIGN=0b0, i_RXPHDLYPD=0b1, i_RXPHDLYRESET=0b0, i_RXPHOVRDEN=0b0, i_RXPLLCLKSEL=0b00, i_RXPMARESET=0b0, i_RXPOLARITY=0b0, i_RXPRBSCNTRESET=0b0, i_RXPRBSSEL=0b0000, i_RXPROGDIVRESET=0b0, i_RXQPIEN=0b0, i_RXRATEMODE=0b0, i_RXRATE=0b000, i_RXSLIDE=0b0, i_RXSLIPOUTCLK=0b0, i_RXSLIPPMA=0b0, i_RXSYNCALLIN=0b0, i_RXSYNCIN=0b0, i_RXSYNCMODE=0b0, i_RXSYSCLKSEL=0b00, i_RXUSERRDY=0b1, i_RXUSRCLK2=ClockSignal("eth_rx_half"), i_RXUSRCLK=ClockSignal("eth_rx_half"), #i_SATA_BURST = 0b100, #i_SATA_EIDLE = 0b100, i_SIGVALIDCLK=0b0, i_TSTIN=0b00000000000000000000, i_TX8B10BBYPASS=0b00000000, i_TX8B10BEN=0b0, i_TXBUFDIFFCTRL=0b000, i_TXCOMINIT=0b0, i_TXCOMSAS=0b0, i_TXCOMWAKE=0b0, i_TXCTRL0=Cat(*[tx_data[10 * i + 8] for i in range(2)]), i_TXCTRL1=Cat(*[tx_data[10 * i + 9] for i in range(2)]), i_TXCTRL2=0b00000000, i_TXDATAEXTENDRSVD=0b00000000, i_TXDATA=Cat(*[tx_data[10 * i:10 * i + 8] for i in range(2)]), i_TXDEEMPH=0b0, i_TXDETECTRX=0b0, i_TXDIFFCTRL=0b1100, i_TXDIFFPD=0b0, i_TXDLYBYPASS=0b1, i_TXDLYEN=0b0, i_TXDLYHOLD=0b0, i_TXDLYOVRDEN=0b0, i_TXDLYSRESET=0b0, i_TXDLYUPDOWN=0b0, i_TXELECIDLE=0b0, i_TXHEADER=0b000000, i_TXINHIBIT=0b0, i_TXLATCLK=0b0, i_TXMAINCURSOR=0b1000000, i_TXMARGIN=0b000, i_TXOUTCLKSEL=0b101, i_TXPCSRESET=0b0, i_TXPDELECIDLEMODE=0b0, i_TXPD=0b00, i_TXPHALIGNEN=0b0, i_TXPHALIGN=0b0, i_TXPHDLYPD=0b1, i_TXPHDLYRESET=0b0, i_TXPHDLYTSTCLK=0b0, i_TXPHINIT=0b0, i_TXPHOVRDEN=0b0, i_TXPIPPMEN=0b0, i_TXPIPPMOVRDEN=0b0, i_TXPIPPMPD=0b0, i_TXPIPPMSEL=0b0, i_TXPIPPMSTEPSIZE=0b00000, i_TXPISOPD=0b0, i_TXPLLCLKSEL=0b00, i_TXPMARESET=0b0, i_TXPOLARITY=0b0, i_TXPOSTCURSORINV=0b0, i_TXPOSTCURSOR=0b00000, i_TXPRBSFORCEERR=0b0, i_TXPRBSSEL=0b0000, i_TXPRECURSORINV=0b0, i_TXPRECURSOR=0b00000, i_TXPROGDIVRESET=0b0, i_TXQPIBIASEN=0b0, i_TXQPISTRONGPDOWN=0b0, i_TXQPIWEAKPUP=0b0, i_TXRATEMODE=0b0, i_TXRATE=0b000, i_TXSEQUENCE=0b0000000, i_TXSWING=0b0, i_TXSYNCALLIN=0b0, i_TXSYNCIN=0b0, i_TXSYNCMODE=0b0, i_TXSYSCLKSEL=0b00, i_TXUSERRDY=0b1, i_TXUSRCLK2=ClockSignal("eth_tx_half"), i_TXUSRCLK=ClockSignal("eth_tx_half"), ) gth_params.update( o_BUFGTCE=Open(), o_BUFGTCEMASK=Open(), o_BUFGTDIV=Open(), o_BUFGTRESET=Open(), o_BUFGTRSTMASK=Open(), o_CPLLFBCLKLOST=Open(), o_CPLLLOCK=pll_locked, o_CPLLREFCLKLOST=Open(), o_DMONITOROUT=Open(), o_DRPDO=Open(), o_DRPRDY=Open(), o_EYESCANDATAERROR=Open(), o_GTHTXN=data_pads.txn, o_GTHTXP=data_pads.txp, o_GTPOWERGOOD=gtpowergood, o_GTREFCLKMONITOR=Open(), o_PCIERATEGEN3=Open(), o_PCIERATEIDLE=Open(), o_PCIERATEQPLLPD=Open(), o_PCIERATEQPLLRESET=Open(), o_PCIESYNCTXSYNCDONE=Open(), o_PCIEUSERGEN3RDY=Open(), o_PCIEUSERPHYSTATUSRST=Open(), o_PCIEUSERRATESTART=Open(), o_PCSRSVDOUT=Open(), o_PHYSTATUS=Open(), o_PINRSRVDAS=Open(), o_RESETEXCEPTION=Open(), o_RXBUFSTATUS=Open(), o_RXBYTEISALIGNED=Open(), o_RXBYTEREALIGN=Open(), o_RXCDRLOCK=Open(), o_RXCDRPHDONE=Open(), o_RXCHANBONDSEQ=Open(), o_RXCHANISALIGNED=Open(), o_RXCHANREALIGN=Open(), o_RXCHBONDO=Open(), o_RXCLKCORCNT=Open(), o_RXCOMINITDET=Open(), o_RXCOMMADET=Open(), o_RXCOMSASDET=Open(), o_RXCOMWAKEDET=Open(), o_RXCTRL0=Cat(*[rx_data[10 * i + 8] for i in range(2)]), o_RXCTRL1=Cat(*[rx_data[10 * i + 9] for i in range(2)]), o_RXCTRL2=Open(), o_RXCTRL3=Open(), o_RXDATA=Cat(*[rx_data[10 * i:10 * i + 8] for i in range(2)]), o_RXDATAEXTENDRSVD=Open(), o_RXDATAVALID=Open(), o_RXDLYSRESETDONE=Open(), o_RXELECIDLE=Open(), o_RXHEADER=Open(), o_RXHEADERVALID=Open(), o_RXMONITOROUT=Open(), o_RXOSINTDONE=Open(), o_RXOSINTSTARTED=Open(), o_RXOSINTSTROBEDONE=Open(), o_RXOSINTSTROBESTARTED=Open(), o_RXOUTCLK=self.rxoutclk, o_RXOUTCLKFABRIC=Open(), o_RXOUTCLKPCS=Open(), o_RXPHALIGNDONE=Open(), o_RXPHALIGNERR=Open(), o_RXPMARESETDONE=Open(), o_RXPRBSERR=Open(), o_RXPRBSLOCKED=Open(), o_RXPRGDIVRESETDONE=Open(), o_RXQPISENN=Open(), o_RXQPISENP=Open(), o_RXRATEDONE=Open(), o_RXRECCLKOUT=Open(), o_RXRESETDONE=rx_reset_done, o_RXSLIDERDY=Open(), o_RXSLIPDONE=Open(), o_RXSLIPOUTCLKRDY=Open(), o_RXSLIPPMARDY=Open(), o_RXSTARTOFSEQ=Open(), o_RXSTATUS=Open(), o_RXSYNCDONE=Open(), o_RXSYNCOUT=Open(), o_RXVALID=Open(), o_TXBUFSTATUS=Open(), o_TXCOMFINISH=Open(), o_TXDLYSRESETDONE=Open(), o_TXOUTCLK=self.txoutclk, o_TXOUTCLKFABRIC=Open(), o_TXOUTCLKPCS=Open(), o_TXPHALIGNDONE=Open(), o_TXPHINITDONE=Open(), o_TXPMARESETDONE=Open(), o_TXPRGDIVRESETDONE=Open(), o_TXQPISENN=Open(), o_TXQPISENP=Open(), o_TXRATEDONE=Open(), o_TXRESETDONE=tx_reset_done, o_TXSYNCDONE=Open(), o_TXSYNCOUT=Open(), ) tx_bufg_gt_ce = Signal() tx_bufg_gt_clr = Signal() rx_bufg_gt_ce = Signal() rx_bufg_gt_clr = Signal() self.specials += [ Instance("GTHE3_CHANNEL", **gth_params), Instance( "BUFG_GT", i_DIV=0, i_I=self.txoutclk, o_O=self.cd_eth_tx.clk, ), Instance( "BUFG_GT", i_DIV=1, i_I=self.txoutclk, o_O=self.cd_eth_tx_half.clk, ), Instance( "BUFG_GT", i_DIV=0, i_I=self.rxoutclk, o_O=self.cd_eth_rx.clk, ), Instance( "BUFG_GT", i_DIV=1, i_I=self.rxoutclk, o_O=self.cd_eth_rx_half.clk, ), AsyncResetSynchronizer(self.cd_eth_tx, ~tx_reset_done), AsyncResetSynchronizer(self.cd_eth_rx, ~rx_reset_done), ] # Transceiver reset pll_reset_cycles = round(300000 * sys_clk_freq // 1000000000) reset_counter = Signal(max=pll_reset_cycles + 1) self.sync += [ If(~gtpowergood, pll_reset.eq(1), reset_counter.eq(0)).Else( If(reset_counter == pll_reset_cycles, pll_reset.eq(0)).Else(reset_counter.eq(reset_counter + 1))) ] self.comb += [ tx_reset.eq(pll_reset | ~pll_locked), rx_reset.eq(pll_reset | ~pll_locked | pcs.restart) ] # Gearbox and PCS connection gearbox = Gearbox() self.submodules += gearbox self.comb += [ tx_data.eq(gearbox.tx_data_half), gearbox.rx_data_half.eq(rx_data), gearbox.tx_data.eq(pcs.tbi_tx), pcs.tbi_rx.eq(gearbox.rx_data) ]
def __init__(self, refclk, pads, sys_clk_freq, rtio_clk_freq, dw, mode): assert (dw == 20) or (dw == 40) assert mode in ["single", "master", "slave"] self.mode = mode # phase alignment self.txsyncallin = Signal() self.txphaligndone = Signal() self.txsyncallin = Signal() self.txsyncin = Signal() self.txsyncout = Signal() self.txdlysreset = Signal() # # # nwords = dw//10 self.submodules.encoder = encoder = ClockDomainsRenamer("rtio_tx")( Encoder(nwords, True)) self.submodules.decoders = decoders = [ClockDomainsRenamer("rtio_rx")( (Decoder(True))) for _ in range(nwords)] self.rx_ready = Signal() # transceiver direct clock outputs # useful to specify clock constraints in a way palatable to Vivado self.txoutclk = Signal() self.rxoutclk = Signal() # # # # TX generates RTIO clock, init must be in system domain self.submodules.tx_init = tx_init = GTHInit(sys_clk_freq, False, mode) # RX receives restart commands from RTIO domain rx_init = ClockDomainsRenamer("rtio_tx")(GTHInit(rtio_clk_freq, True)) self.submodules += rx_init cpll_reset = Signal() cpll_lock = Signal() self.comb += [ cpll_reset.eq(tx_init.pllreset), tx_init.plllock.eq(cpll_lock), rx_init.plllock.eq(cpll_lock) ] txdata = Signal(dw) rxdata = Signal(dw) rxphaligndone = Signal() gth_params = dict( p_ACJTAG_DEBUG_MODE =0b0, p_ACJTAG_MODE =0b0, p_ACJTAG_RESET =0b0, p_ADAPT_CFG0 =0b1111100000000000, p_ADAPT_CFG1 =0b0000000000000000, p_ALIGN_COMMA_DOUBLE ="FALSE", p_ALIGN_COMMA_ENABLE =0b0000000000, p_ALIGN_COMMA_WORD =1, p_ALIGN_MCOMMA_DET ="FALSE", p_ALIGN_MCOMMA_VALUE =0b1010000011, p_ALIGN_PCOMMA_DET ="FALSE", p_ALIGN_PCOMMA_VALUE =0b0101111100, p_A_RXOSCALRESET =0b0, p_A_RXPROGDIVRESET =0b0, p_A_TXPROGDIVRESET =0b0, p_CBCC_DATA_SOURCE_SEL ="ENCODED", p_CDR_SWAP_MODE_EN =0b0, p_CHAN_BOND_KEEP_ALIGN ="FALSE", p_CHAN_BOND_MAX_SKEW =1, p_CHAN_BOND_SEQ_1_1 =0b0000000000, p_CHAN_BOND_SEQ_1_2 =0b0000000000, p_CHAN_BOND_SEQ_1_3 =0b0000000000, p_CHAN_BOND_SEQ_1_4 =0b0000000000, p_CHAN_BOND_SEQ_1_ENABLE =0b1111, p_CHAN_BOND_SEQ_2_1 =0b0000000000, p_CHAN_BOND_SEQ_2_2 =0b0000000000, p_CHAN_BOND_SEQ_2_3 =0b0000000000, p_CHAN_BOND_SEQ_2_4 =0b0000000000, p_CHAN_BOND_SEQ_2_ENABLE =0b1111, p_CHAN_BOND_SEQ_2_USE ="FALSE", p_CHAN_BOND_SEQ_LEN =1, p_CLK_CORRECT_USE ="FALSE", p_CLK_COR_KEEP_IDLE ="FALSE", p_CLK_COR_MAX_LAT =20, p_CLK_COR_MIN_LAT =18, p_CLK_COR_PRECEDENCE ="TRUE", p_CLK_COR_REPEAT_WAIT =0, p_CLK_COR_SEQ_1_1 =0b0000000000, p_CLK_COR_SEQ_1_2 =0b0000000000, p_CLK_COR_SEQ_1_3 =0b0000000000, p_CLK_COR_SEQ_1_4 =0b0000000000, p_CLK_COR_SEQ_1_ENABLE =0b1111, p_CLK_COR_SEQ_2_1 =0b0000000000, p_CLK_COR_SEQ_2_2 =0b0000000000, p_CLK_COR_SEQ_2_3 =0b0000000000, p_CLK_COR_SEQ_2_4 =0b0000000000, p_CLK_COR_SEQ_2_ENABLE =0b1111, p_CLK_COR_SEQ_2_USE ="FALSE", p_CLK_COR_SEQ_LEN =1, p_CPLL_CFG0 =0b0110011111111000, p_CPLL_CFG1 =0b1010010010101100, p_CPLL_CFG2 =0b0000000000000111, p_CPLL_CFG3 =0b000000, p_CPLL_FBDIV =5, p_CPLL_FBDIV_45 =4, p_CPLL_INIT_CFG0 =0b0000001010110010, p_CPLL_INIT_CFG1 =0b00000000, p_CPLL_LOCK_CFG =0b0000000111101000, p_CPLL_REFCLK_DIV =1, p_DDI_CTRL =0b00, p_DDI_REALIGN_WAIT =15, p_DEC_MCOMMA_DETECT ="FALSE", p_DEC_PCOMMA_DETECT ="FALSE", p_DEC_VALID_COMMA_ONLY ="FALSE", p_DFE_D_X_REL_POS =0b0, p_DFE_VCM_COMP_EN =0b0, p_DMONITOR_CFG0 =0b0000000000, p_DMONITOR_CFG1 =0b00000000, p_ES_CLK_PHASE_SEL =0b0, p_ES_CONTROL =0b000000, p_ES_ERRDET_EN ="FALSE", p_ES_EYE_SCAN_EN ="FALSE", p_ES_HORZ_OFFSET =0b000000000000, p_ES_PMA_CFG =0b0000000000, p_ES_PRESCALE =0b00000, p_ES_QUALIFIER0 =0b0000000000000000, p_ES_QUALIFIER1 =0b0000000000000000, p_ES_QUALIFIER2 =0b0000000000000000, p_ES_QUALIFIER3 =0b0000000000000000, p_ES_QUALIFIER4 =0b0000000000000000, p_ES_QUAL_MASK0 =0b0000000000000000, p_ES_QUAL_MASK1 =0b0000000000000000, p_ES_QUAL_MASK2 =0b0000000000000000, p_ES_QUAL_MASK3 =0b0000000000000000, p_ES_QUAL_MASK4 =0b0000000000000000, p_ES_SDATA_MASK0 =0b0000000000000000, p_ES_SDATA_MASK1 =0b0000000000000000, p_ES_SDATA_MASK2 =0b0000000000000000, p_ES_SDATA_MASK3 =0b0000000000000000, p_ES_SDATA_MASK4 =0b0000000000000000, p_EVODD_PHI_CFG =0b00000000000, p_EYE_SCAN_SWAP_EN =0b0, p_FTS_DESKEW_SEQ_ENABLE =0b1111, p_FTS_LANE_DESKEW_CFG =0b1111, p_FTS_LANE_DESKEW_EN ="FALSE", p_GEARBOX_MODE =0b00000, p_GM_BIAS_SELECT =0b0, p_LOCAL_MASTER =0b1, p_OOBDIVCTL =0b00, p_OOB_PWRUP =0b0, p_PCI3_AUTO_REALIGN ="OVR_1K_BLK", p_PCI3_PIPE_RX_ELECIDLE =0b0, p_PCI3_RX_ASYNC_EBUF_BYPASS =0b00, p_PCI3_RX_ELECIDLE_EI2_ENABLE =0b0, p_PCI3_RX_ELECIDLE_H2L_COUNT =0b000000, p_PCI3_RX_ELECIDLE_H2L_DISABLE =0b000, p_PCI3_RX_ELECIDLE_HI_COUNT =0b000000, p_PCI3_RX_ELECIDLE_LP4_DISABLE =0b0, p_PCI3_RX_FIFO_DISABLE =0b0, p_PCIE_BUFG_DIV_CTRL =0b0001000000000000, p_PCIE_RXPCS_CFG_GEN3 =0b0000001010100100, p_PCIE_RXPMA_CFG =0b0000000000001010, p_PCIE_TXPCS_CFG_GEN3 =0b0010010010100100, p_PCIE_TXPMA_CFG =0b0000000000001010, p_PCS_PCIE_EN ="FALSE", p_PCS_RSVD0 =0b0000000000000000, p_PCS_RSVD1 =0b000, p_PD_TRANS_TIME_FROM_P2 =0b000000111100, p_PD_TRANS_TIME_NONE_P2 =0b00011001, p_PD_TRANS_TIME_TO_P2 =0b01100100, p_PLL_SEL_MODE_GEN12 =0b00, p_PLL_SEL_MODE_GEN3 =0b11, p_PMA_RSV1 =0b1111000000000000, p_PROCESS_PAR =0b010, p_RATE_SW_USE_DRP =0b1, p_RESET_POWERSAVE_DISABLE =0b0, ) gth_params.update( p_RXBUFRESET_TIME =0b00011, p_RXBUF_ADDR_MODE ="FAST", p_RXBUF_EIDLE_HI_CNT =0b1000, p_RXBUF_EIDLE_LO_CNT =0b0000, p_RXBUF_EN ="FALSE", p_RXBUF_RESET_ON_CB_CHANGE ="TRUE", p_RXBUF_RESET_ON_COMMAALIGN ="FALSE", p_RXBUF_RESET_ON_EIDLE ="FALSE", p_RXBUF_RESET_ON_RATE_CHANGE ="TRUE", p_RXBUF_THRESH_OVFLW =0, p_RXBUF_THRESH_OVRD ="FALSE", p_RXBUF_THRESH_UNDFLW =0, p_RXCDRFREQRESET_TIME =0b00001, p_RXCDRPHRESET_TIME =0b00001, p_RXCDR_CFG0 =0b0000000000000000, p_RXCDR_CFG0_GEN3 =0b0000000000000000, p_RXCDR_CFG1 =0b0000000000000000, p_RXCDR_CFG1_GEN3 =0b0000000000000000, p_RXCDR_CFG2 =0b0000011111010110, p_RXCDR_CFG2_GEN3 =0b0000011111100110, p_RXCDR_CFG3 =0b0000000000000000, p_RXCDR_CFG3_GEN3 =0b0000000000000000, p_RXCDR_CFG4 =0b0000000000000000, p_RXCDR_CFG4_GEN3 =0b0000000000000000, p_RXCDR_CFG5 =0b0000000000000000, p_RXCDR_CFG5_GEN3 =0b0000000000000000, p_RXCDR_FR_RESET_ON_EIDLE =0b0, p_RXCDR_HOLD_DURING_EIDLE =0b0, p_RXCDR_LOCK_CFG0 =0b0100010010000000, p_RXCDR_LOCK_CFG1 =0b0101111111111111, p_RXCDR_LOCK_CFG2 =0b0111011111000011, p_RXCDR_PH_RESET_ON_EIDLE =0b0, p_RXCFOK_CFG0 =0b0100000000000000, p_RXCFOK_CFG1 =0b0000000001100101, p_RXCFOK_CFG2 =0b0000000000101110, p_RXDFELPMRESET_TIME =0b0001111, p_RXDFELPM_KL_CFG0 =0b0000000000000000, p_RXDFELPM_KL_CFG1 =0b0000000000000010, p_RXDFELPM_KL_CFG2 =0b0000000000000000, p_RXDFE_CFG0 =0b0000101000000000, p_RXDFE_CFG1 =0b0000000000000000, p_RXDFE_GC_CFG0 =0b0000000000000000, p_RXDFE_GC_CFG1 =0b0111100001110000, p_RXDFE_GC_CFG2 =0b0000000000000000, p_RXDFE_H2_CFG0 =0b0000000000000000, p_RXDFE_H2_CFG1 =0b0000000000000000, p_RXDFE_H3_CFG0 =0b0100000000000000, p_RXDFE_H3_CFG1 =0b0000000000000000, p_RXDFE_H4_CFG0 =0b0010000000000000, p_RXDFE_H4_CFG1 =0b0000000000000011, p_RXDFE_H5_CFG0 =0b0010000000000000, p_RXDFE_H5_CFG1 =0b0000000000000011, p_RXDFE_H6_CFG0 =0b0010000000000000, p_RXDFE_H6_CFG1 =0b0000000000000000, p_RXDFE_H7_CFG0 =0b0010000000000000, p_RXDFE_H7_CFG1 =0b0000000000000000, p_RXDFE_H8_CFG0 =0b0010000000000000, p_RXDFE_H8_CFG1 =0b0000000000000000, p_RXDFE_H9_CFG0 =0b0010000000000000, p_RXDFE_H9_CFG1 =0b0000000000000000, p_RXDFE_HA_CFG0 =0b0010000000000000, p_RXDFE_HA_CFG1 =0b0000000000000000, p_RXDFE_HB_CFG0 =0b0010000000000000, p_RXDFE_HB_CFG1 =0b0000000000000000, p_RXDFE_HC_CFG0 =0b0000000000000000, p_RXDFE_HC_CFG1 =0b0000000000000000, p_RXDFE_HD_CFG0 =0b0000000000000000, p_RXDFE_HD_CFG1 =0b0000000000000000, p_RXDFE_HE_CFG0 =0b0000000000000000, p_RXDFE_HE_CFG1 =0b0000000000000000, p_RXDFE_HF_CFG0 =0b0000000000000000, p_RXDFE_HF_CFG1 =0b0000000000000000, p_RXDFE_OS_CFG0 =0b1000000000000000, p_RXDFE_OS_CFG1 =0b0000000000000000, p_RXDFE_UT_CFG0 =0b1000000000000000, p_RXDFE_UT_CFG1 =0b0000000000000011, p_RXDFE_VP_CFG0 =0b1010101000000000, p_RXDFE_VP_CFG1 =0b0000000000110011, p_RXDLY_CFG =0b0000000000011111, p_RXDLY_LCFG =0b0000000000110000, p_RXELECIDLE_CFG ="SIGCFG_4", p_RXGBOX_FIFO_INIT_RD_ADDR =4, p_RXGEARBOX_EN ="FALSE", p_RXISCANRESET_TIME =0b00001, p_RXLPM_CFG =0b0000000000000000, p_RXLPM_GC_CFG =0b0001000000000000, p_RXLPM_KH_CFG0 =0b0000000000000000, p_RXLPM_KH_CFG1 =0b0000000000000010, p_RXLPM_OS_CFG0 =0b1000000000000000, p_RXLPM_OS_CFG1 =0b0000000000000010, p_RXOOB_CFG =0b000000110, p_RXOOB_CLK_CFG ="PMA", p_RXOSCALRESET_TIME =0b00011, p_RXOUT_DIV =2, p_RXPCSRESET_TIME =0b00011, p_RXPHBEACON_CFG =0b0000000000000000, p_RXPHDLY_CFG =0b0010000000100000, p_RXPHSAMP_CFG =0b0010000100000000, p_RXPHSLIP_CFG =0b0110011000100010, p_RXPH_MONITOR_SEL =0b00000, p_RXPI_CFG0 =0b00, p_RXPI_CFG1 =0b00, p_RXPI_CFG2 =0b00, p_RXPI_CFG3 =0b00, p_RXPI_CFG4 =0b1, p_RXPI_CFG5 =0b1, p_RXPI_CFG6 =0b000, p_RXPI_LPM =0b0, p_RXPI_VREFSEL =0b0, p_RXPMACLK_SEL ="DATA", p_RXPMARESET_TIME =0b00011, p_RXPRBS_ERR_LOOPBACK =0b0, p_RXPRBS_LINKACQ_CNT =15, p_RXSLIDE_AUTO_WAIT =7, p_RXSLIDE_MODE ="OFF", p_RXSYNC_MULTILANE =0b0, p_RXSYNC_OVRD =0b0, p_RXSYNC_SKIP_DA =0b0, p_RX_AFE_CM_EN =0b0, p_RX_BIAS_CFG0 =0b0000101010110100, p_RX_BUFFER_CFG =0b000000, p_RX_CAPFF_SARC_ENB =0b0, p_RX_CLK25_DIV =6, p_RX_CLKMUX_EN =0b1, p_RX_CLK_SLIP_OVRD =0b00000, p_RX_CM_BUF_CFG =0b1010, p_RX_CM_BUF_PD =0b0, p_RX_CM_SEL =0b11, p_RX_CM_TRIM =0b1010, p_RX_CTLE3_LPF =0b00000001, p_RX_DATA_WIDTH =dw, p_RX_DDI_SEL =0b000000, p_RX_DEFER_RESET_BUF_EN ="TRUE", p_RX_DFELPM_CFG0 =0b0110, p_RX_DFELPM_CFG1 =0b1, p_RX_DFELPM_KLKH_AGC_STUP_EN =0b1, p_RX_DFE_AGC_CFG0 =0b10, p_RX_DFE_AGC_CFG1 =0b100, p_RX_DFE_KL_LPM_KH_CFG0 =0b01, p_RX_DFE_KL_LPM_KH_CFG1 =0b100, p_RX_DFE_KL_LPM_KL_CFG0 =0b01, p_RX_DFE_KL_LPM_KL_CFG1 =0b100, p_RX_DFE_LPM_HOLD_DURING_EIDLE =0b0, p_RX_DISPERR_SEQ_MATCH ="TRUE", p_RX_DIVRESET_TIME =0b00001, p_RX_EN_HI_LR =0b0, p_RX_EYESCAN_VS_CODE =0b0000000, p_RX_EYESCAN_VS_NEG_DIR =0b0, p_RX_EYESCAN_VS_RANGE =0b00, p_RX_EYESCAN_VS_UT_SIGN =0b0, p_RX_FABINT_USRCLK_FLOP =0b0, p_RX_INT_DATAWIDTH =dw==40, p_RX_PMA_POWER_SAVE =0b0, p_RX_PROGDIV_CFG =0.0, p_RX_SAMPLE_PERIOD =0b111, p_RX_SIG_VALID_DLY =11, p_RX_SUM_DFETAPREP_EN =0b0, p_RX_SUM_IREF_TUNE =0b0000, p_RX_SUM_RES_CTRL =0b00, p_RX_SUM_VCMTUNE =0b0000, p_RX_SUM_VCM_OVWR =0b0, p_RX_SUM_VREF_TUNE =0b000, p_RX_TUNE_AFE_OS =0b10, p_RX_WIDEMODE_CDR =0b0, p_RX_XCLK_SEL ="RXUSR", p_SAS_MAX_COM =64, p_SAS_MIN_COM =36, p_SATA_BURST_SEQ_LEN =0b1110, p_SATA_CPLL_CFG ="VCO_3000MHZ", p_SATA_MAX_BURST =8, p_SATA_MAX_INIT =21, p_SATA_MAX_WAKE =7, p_SATA_MIN_BURST =4, p_SATA_MIN_INIT =12, p_SATA_MIN_WAKE =4, p_SHOW_REALIGN_COMMA ="TRUE", p_SIM_RECEIVER_DETECT_PASS ="******", p_SIM_RESET_SPEEDUP ="TRUE", p_SIM_TX_EIDLE_DRIVE_LEVEL =0b0, p_SIM_VERSION =2, p_TAPDLY_SET_TX =0b00, p_TEMPERATUR_PAR =0b0010, p_TERM_RCAL_CFG =0b100001000010000, p_TERM_RCAL_OVRD =0b000, p_TRANS_TIME_RATE =0b00001110, p_TST_RSV0 =0b00000000, p_TST_RSV1 =0b00000000, ) gth_params.update( p_TXBUF_EN ="FALSE", p_TXBUF_RESET_ON_RATE_CHANGE ="TRUE", p_TXDLY_CFG =0b0000000000001001, p_TXDLY_LCFG =0b0000000001010000, p_TXDRVBIAS_N =0b1010, p_TXDRVBIAS_P =0b1010, p_TXFIFO_ADDR_CFG ="LOW", p_TXGBOX_FIFO_INIT_RD_ADDR =4, p_TXGEARBOX_EN ="FALSE", p_TXOUT_DIV =2, p_TXPCSRESET_TIME =0b00011, p_TXPHDLY_CFG0 =0b0010000000100000, p_TXPHDLY_CFG1 =0b0000000001110101, p_TXPH_CFG =0b0000100110000000, p_TXPH_MONITOR_SEL =0b00000, p_TXPI_CFG0 =0b00, p_TXPI_CFG1 =0b00, p_TXPI_CFG2 =0b00, p_TXPI_CFG3 =0b1, p_TXPI_CFG4 =0b1, p_TXPI_CFG5 =0b000, p_TXPI_GRAY_SEL =0b0, p_TXPI_INVSTROBE_SEL =0b0, p_TXPI_LPM =0b0, p_TXPI_PPMCLK_SEL ="TXUSRCLK2", p_TXPI_PPM_CFG =0b00000000, p_TXPI_SYNFREQ_PPM =0b001, p_TXPI_VREFSEL =0b0, p_TXPMARESET_TIME =0b00011, p_TXSYNC_MULTILANE =0 if mode == "single" else 1, p_TXSYNC_OVRD =0b0, p_TXSYNC_SKIP_DA =0b0, p_TX_CLK25_DIV =6, p_TX_CLKMUX_EN =0b1, p_TX_DATA_WIDTH =dw, p_TX_DCD_CFG =0b000010, p_TX_DCD_EN =0b0, p_TX_DEEMPH0 =0b000000, p_TX_DEEMPH1 =0b000000, p_TX_DIVRESET_TIME =0b00001, p_TX_DRIVE_MODE ="DIRECT", p_TX_EIDLE_ASSERT_DELAY =0b100, p_TX_EIDLE_DEASSERT_DELAY =0b011, p_TX_EML_PHI_TUNE =0b0, p_TX_FABINT_USRCLK_FLOP =0b0, p_TX_IDLE_DATA_ZERO =0b0, p_TX_INT_DATAWIDTH =dw==40, p_TX_LOOPBACK_DRIVE_HIZ ="FALSE", p_TX_MAINCURSOR_SEL =0b0, p_TX_MARGIN_FULL_0 =0b1001111, p_TX_MARGIN_FULL_1 =0b1001110, p_TX_MARGIN_FULL_2 =0b1001100, p_TX_MARGIN_FULL_3 =0b1001010, p_TX_MARGIN_FULL_4 =0b1001000, p_TX_MARGIN_LOW_0 =0b1000110, p_TX_MARGIN_LOW_1 =0b1000101, p_TX_MARGIN_LOW_2 =0b1000011, p_TX_MARGIN_LOW_3 =0b1000010, p_TX_MARGIN_LOW_4 =0b1000000, p_TX_MODE_SEL =0b000, p_TX_PMADATA_OPT =0b0, p_TX_PMA_POWER_SAVE =0b0, p_TX_PROGCLK_SEL ="PREPI", p_TX_PROGDIV_CFG =0.0, p_TX_QPI_STATUS_EN =0b0, p_TX_RXDETECT_CFG =0b00000000110010, p_TX_RXDETECT_REF =0b100, p_TX_SAMPLE_PERIOD =0b111, p_TX_SARC_LPBK_ENB =0b0, p_TX_XCLK_SEL ="TXUSR", p_USE_PCS_CLK_PHASE_SEL =0b0, p_WB_MODE =0b00, ) gth_params.update( # Reset modes i_GTRESETSEL=0, i_RESETOVRD=0, i_CPLLRESET=0, i_CPLLPD=cpll_reset, o_CPLLLOCK=cpll_lock, i_CPLLLOCKEN=1, i_CPLLREFCLKSEL=0b001, i_TSTIN=2**20-1, i_GTREFCLK0=refclk, # TX clock o_TXOUTCLK=self.txoutclk, i_TXSYSCLKSEL=0b00, i_TXPLLCLKSEL=0b00, i_TXOUTCLKSEL=0b11, # TX Startup/Reset i_GTTXRESET=tx_init.gtXxreset, o_TXRESETDONE=tx_init.Xxresetdone, i_TXDLYSRESET=tx_init.Xxdlysreset if mode != "slave" else self.txdlysreset, o_TXDLYSRESETDONE=tx_init.Xxdlysresetdone, o_TXPHALIGNDONE=tx_init.Xxphaligndone, i_TXUSERRDY=tx_init.Xxuserrdy, i_TXSYNCMODE=mode != "slave", i_TXSYNCALLIN=self.txsyncallin, i_TXSYNCIN=self.txsyncin, o_TXSYNCOUT=self.txsyncout, # TX data i_TXCTRL0=Cat(*[txdata[10*i+8] for i in range(nwords)]), i_TXCTRL1=Cat(*[txdata[10*i+9] for i in range(nwords)]), i_TXDATA=Cat(*[txdata[10*i:10*i+8] for i in range(nwords)]), i_TXUSRCLK=ClockSignal("rtio_tx"), i_TXUSRCLK2=ClockSignal("rtio_tx"), # TX electrical i_TXPD=0b00, i_TXBUFDIFFCTRL=0b000, i_TXDIFFCTRL=0b1100, # RX Startup/Reset i_GTRXRESET=rx_init.gtXxreset, o_RXRESETDONE=rx_init.Xxresetdone, i_RXDLYSRESET=rx_init.Xxdlysreset, o_RXPHALIGNDONE=rxphaligndone, i_RXSYNCALLIN=rxphaligndone, i_RXUSERRDY=rx_init.Xxuserrdy, i_RXSYNCIN=0, i_RXSYNCMODE=1, o_RXSYNCDONE=rx_init.Xxsyncdone, # RX AFE i_RXDFEAGCCTRL=1, i_RXDFEXYDEN=1, i_RXLPMEN=1, i_RXOSINTCFG=0xd, i_RXOSINTEN=1, # RX clock i_RXRATE=0, i_RXDLYBYPASS=0, i_RXSYSCLKSEL=0b00, i_RXOUTCLKSEL=0b010, i_RXPLLCLKSEL=0b00, o_RXOUTCLK=self.rxoutclk, i_RXUSRCLK=ClockSignal("rtio_rx"), i_RXUSRCLK2=ClockSignal("rtio_rx"), # RX data o_RXCTRL0=Cat(*[rxdata[10*i+8] for i in range(nwords)]), o_RXCTRL1=Cat(*[rxdata[10*i+9] for i in range(nwords)]), o_RXDATA=Cat(*[rxdata[10*i:10*i+8] for i in range(nwords)]), # RX electrical i_RXPD=Replicate(rx_init.restart, 2), i_RXELECIDLEMODE=0b11, # Pads i_GTHRXP=pads.rxp, i_GTHRXN=pads.rxn, o_GTHTXP=pads.txp, o_GTHTXN=pads.txn ) self.specials += Instance("GTHE3_CHANNEL", **gth_params) self.comb += self.txphaligndone.eq(tx_init.Xxphaligndone) self.submodules += [ add_probe_async("drtio_gth", "cpll_lock", cpll_lock), add_probe_async("drtio_gth", "txuserrdy", tx_init.Xxuserrdy), add_probe_async("drtio_gth", "tx_init_done", tx_init.done), add_probe_async("drtio_gth", "rxuserrdy", rx_init.Xxuserrdy), add_probe_async("drtio_gth", "rx_init_done", rx_init.done), add_probe_buffer("drtio_gth", "txdata", txdata, clock_domain="rtio_tx"), add_probe_buffer("drtio_gth", "rxdata", rxdata, clock_domain="rtio_rx") ] # tx clocking tx_reset_deglitched = Signal() tx_reset_deglitched.attr.add("no_retiming") self.sync += tx_reset_deglitched.eq(~tx_init.done) self.clock_domains.cd_rtio_tx = ClockDomain() if mode == "master" or mode == "single": self.specials += \ Instance("BUFG_GT", i_I=self.txoutclk, o_O=self.cd_rtio_tx.clk, i_DIV=0) self.specials += AsyncResetSynchronizer(self.cd_rtio_tx, tx_reset_deglitched) # rx clocking rx_reset_deglitched = Signal() rx_reset_deglitched.attr.add("no_retiming") self.sync.rtio_tx += rx_reset_deglitched.eq(~rx_init.done) self.clock_domains.cd_rtio_rx = ClockDomain() self.specials += [ Instance("BUFG_GT", i_I=self.rxoutclk, o_O=self.cd_rtio_rx.clk), AsyncResetSynchronizer(self.cd_rtio_rx, rx_reset_deglitched) ] # tx data self.comb += txdata.eq(Cat(*[encoder.output[i] for i in range(nwords)])) # rx data for i in range(nwords): self.comb += decoders[i].input.eq(rxdata[10*i:10*(i+1)]) # clock alignment clock_aligner = BruteforceClockAligner(0b0101111100, rtio_clk_freq) self.submodules += clock_aligner self.comb += [ clock_aligner.rxdata.eq(rxdata), rx_init.restart.eq(clock_aligner.restart), self.rx_ready.eq(clock_aligner.ready) ] self.submodules += add_probe_async("drtio_gth", "clock_aligner_ready", clock_aligner.ready)