diff --git a/src/gateware/zynq_clocking.py b/src/gateware/zynq_clocking.py index 72bb894..f7b341f 100644 --- a/src/gateware/zynq_clocking.py +++ b/src/gateware/zynq_clocking.py @@ -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)