Exemplo n.º 1
0
Arquivo: clock.py Projeto: blazra/tdr
 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
Exemplo n.º 2
0
    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),
        ]
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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),
        ]
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
    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))
Exemplo n.º 9
0
    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)
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
    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)
Exemplo n.º 12
0
    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)
Exemplo n.º 13
0
    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)
Exemplo n.º 14
0
    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)
        ]
Exemplo n.º 15
0
    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)
Exemplo n.º 16
0
    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"))
Exemplo n.º 17
0
    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)
Exemplo n.º 18
0
    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),
        ]
Exemplo n.º 19
0
    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)
Exemplo n.º 20
0
    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)
        ]
Exemplo n.º 21
0
    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)
Exemplo n.º 22
0
    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),
        ]
Exemplo n.º 23
0
    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)
Exemplo n.º 24
0
    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)
Exemplo n.º 25
0
    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)
        ]
Exemplo n.º 26
0
    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"))
Exemplo n.º 27
0
    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)
        ]
Exemplo n.º 28
0
    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)
Exemplo n.º 29
0
    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)
        ]
Exemplo n.º 30
0
    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)