zynq_clocking: add enable_sys5x option, IDELAYCTRL

- Port from artiq repo
- If enable_sys5x,
    - add one PLL thats generate 200MHz IDELAYCTRL ref clock
    - add a IDELAYCTRL instance for EEM Serdes
    - add sys5x for EEM Serdes
linuswck 2023-10-05 11:28:45 +08:00
parent 8eb359ee42
commit d4e8dd1554
1 changed files with 99 additions and 28 deletions

View File

@ -65,10 +65,13 @@ class ClockSwitchFSM(Module):
class SYSCRG(Module, AutoCSR):
def __init__(self, platform, ps7, main_clk, clk_sw=None, freq=125e6):
def __init__(self, platform, ps7, main_clk, clk_sw=None, freq=125e6, enable_sys5x=False):
# assumes bootstrap clock is same freq as main and sys output
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
if enable_sys5x:
self.clock_domains.cd_clk200 = ClockDomain()
self.clock_domains.cd_sys5x = ClockDomain(reset_less=True)
self.current_clock = CSRStatus()
@ -78,11 +81,6 @@ class SYSCRG(Module, AutoCSR):
period = 1e9/freq
pll_locked = Signal()
pll_sys = Signal()
pll_sys4x = Signal()
fb_clk = Signal()
self.submodules.clk_sw_fsm = ClockSwitchFSM()
if clk_sw is None:
@ -91,32 +89,105 @@ class SYSCRG(Module, AutoCSR):
else:
self.comb += self.clk_sw_fsm.i_clk_sw.eq(clk_sw)
self.specials += [
Instance("PLLE2_ADV",
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
p_BANDWIDTH="HIGH",
p_REF_JITTER1=0.001,
p_CLKIN1_PERIOD=period, i_CLKIN1=main_clk,
p_CLKIN2_PERIOD=period, i_CLKIN2=bootstrap_clk,
i_CLKINSEL=self.clk_sw_fsm.o_clk_sw,
if enable_sys5x:
pll_clk200 = Signal()
pll_fb_clk = Signal()
pll_locked = Signal()
self.specials += [
Instance("PLLE2_BASE",
p_CLKIN1_PERIOD=8.0,
i_CLKIN1=bootstrap_clk,
# VCO @ 1.5GHz when using 125MHz input
# 1.2GHz for 100MHz (zc706)
p_CLKFBOUT_MULT=12, p_DIVCLK_DIVIDE=1,
i_CLKFBIN=fb_clk,
i_RST=self.clk_sw_fsm.o_reset,
i_CLKFBIN=pll_fb_clk,
o_CLKFBOUT=pll_fb_clk,
o_LOCKED=pll_locked,
o_CLKFBOUT=fb_clk,
# VCO @ 1GHz
p_CLKFBOUT_MULT=8, p_DIVCLK_DIVIDE=1,
p_CLKOUT0_DIVIDE=3, p_CLKOUT0_PHASE=0.0,
o_CLKOUT0=pll_sys4x,
# 200MHz for IDELAYCTRL
p_CLKOUT0_DIVIDE=5, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=pll_clk200,
),
Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk),
AsyncResetSynchronizer(self.cd_clk200, ~pll_locked),
]
p_CLKOUT1_DIVIDE=12, p_CLKOUT1_PHASE=0.0,
o_CLKOUT1=pll_sys),
Instance("BUFG", i_I=pll_sys, o_O=self.cd_sys.clk),
Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk),
reset_counter = Signal(4, reset=15)
ic_reset = Signal(reset=1)
self.sync.clk200 += \
If(reset_counter != 0,
reset_counter.eq(reset_counter - 1)
).Else(
ic_reset.eq(0)
)
self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset)
AsyncResetSynchronizer(self.cd_sys, ~pll_locked),
]
mmcm_locked = Signal()
mmcm_sys = Signal()
mmcm_sys4x = Signal()
mmcm_sys5x = Signal()
mmcm_fb_clk = Signal()
self.specials += [
Instance("MMCME2_ADV",
p_STARTUP_WAIT="FALSE", o_LOCKED=mmcm_locked,
p_BANDWIDTH="HIGH",
p_REF_JITTER1=0.001,
p_CLKIN1_PERIOD=period, i_CLKIN1=main_clk,
p_CLKIN2_PERIOD=period, i_CLKIN2=bootstrap_clk,
i_CLKINSEL=self.clk_sw_fsm.o_clk_sw,
# VCO @ 1.25GHz with MULT=10
p_CLKFBOUT_MULT_F=10, p_DIVCLK_DIVIDE=1,
i_CLKFBIN=mmcm_fb_clk,
i_RST=self.clk_sw_fsm.o_reset,
o_CLKFBOUT=mmcm_fb_clk,
# 500MHz. Must be more than 400MHz as per DDR3 specs.
p_CLKOUT0_DIVIDE_F=2.5, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=mmcm_sys4x,
# 125MHz
p_CLKOUT1_DIVIDE=10, p_CLKOUT1_PHASE=0.0, o_CLKOUT1=mmcm_sys,
# 625MHz
p_CLKOUT2_DIVIDE=2, p_CLKOUT2_PHASE=0.0, o_CLKOUT2=mmcm_sys5x,
),
Instance("BUFG", i_I=mmcm_sys5x, o_O=self.cd_sys5x.clk),
Instance("BUFG", i_I=mmcm_sys, o_O=self.cd_sys.clk),
Instance("BUFG", i_I=mmcm_sys4x, o_O=self.cd_sys4x.clk),
AsyncResetSynchronizer(self.cd_sys, ~mmcm_locked),
]
else:
pll_locked = Signal()
pll_sys = Signal()
pll_sys4x = Signal()
fb_clk = Signal()
self.specials += [
Instance("PLLE2_ADV",
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
p_BANDWIDTH="HIGH",
p_REF_JITTER1=0.001,
p_CLKIN1_PERIOD=period, i_CLKIN1=main_clk,
p_CLKIN2_PERIOD=period, i_CLKIN2=bootstrap_clk,
i_CLKINSEL=self.clk_sw_fsm.o_clk_sw,
# VCO @ 1.5GHz when using 125MHz input
# 1.2GHz for 100MHz (zc706)
p_CLKFBOUT_MULT=12, p_DIVCLK_DIVIDE=1,
i_CLKFBIN=fb_clk,
i_RST=self.clk_sw_fsm.o_reset,
o_CLKFBOUT=fb_clk,
p_CLKOUT0_DIVIDE=3, p_CLKOUT0_PHASE=0.0,
o_CLKOUT0=pll_sys4x,
p_CLKOUT1_DIVIDE=12, p_CLKOUT1_PHASE=0.0,
o_CLKOUT1=pll_sys),
Instance("BUFG", i_I=pll_sys, o_O=self.cd_sys.clk),
Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk),
AsyncResetSynchronizer(self.cd_sys, ~pll_locked),
]
self.comb += self.current_clock.status.eq(self.clk_sw_fsm.o_clk_sw)