move clocking to zynq_clocking
add clock-switching FSM restore order
This commit is contained in:
parent
b26731d83c
commit
3194b772ae
@ -24,46 +24,9 @@ import dma
|
|||||||
import analyzer
|
import analyzer
|
||||||
import acpki
|
import acpki
|
||||||
import drtio_aux_controller
|
import drtio_aux_controller
|
||||||
|
import zynq_clocking
|
||||||
|
|
||||||
class SYSCRG(Module, AutoCSR):
|
|
||||||
def __init__(self, platform, main_clk):
|
|
||||||
self.pll_locked = CSRStatus()
|
|
||||||
self.clock_domains.cd_sys = ClockDomain()
|
|
||||||
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
|
|
||||||
|
|
||||||
pll_locked = Signal()
|
|
||||||
sys_clk = Signal()
|
|
||||||
sys4x_clk = 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=8.0,
|
|
||||||
i_CLKIN1=main_clk,
|
|
||||||
i_CLKINSEL=1,
|
|
||||||
|
|
||||||
# VCO @ 1.5GHz when using 125MHz input
|
|
||||||
p_CLKFBOUT_MULT=12, p_DIVCLK_DIVIDE=1,
|
|
||||||
i_CLKFBIN=fb_clk,
|
|
||||||
i_RST=0,
|
|
||||||
|
|
||||||
o_CLKFBOUT=fb_clk,
|
|
||||||
|
|
||||||
p_CLKOUT0_DIVIDE=3, p_CLKOUT0_PHASE=0.0,
|
|
||||||
o_CLKOUT0=sys4x_clk,
|
|
||||||
|
|
||||||
p_CLKOUT1_DIVIDE=12, p_CLKOUT1_PHASE=0.0,
|
|
||||||
o_CLKOUT1=sys_clk),
|
|
||||||
Instance("BUFG", i_I=sys_clk, o_O=self.cd_sys.clk),
|
|
||||||
Instance("BUFG", i_I=sys4x_clk, o_O=self.cd_sys4x.clk),
|
|
||||||
|
|
||||||
AsyncResetSynchronizer(self.cd_sys, ~pll_locked),
|
|
||||||
]
|
|
||||||
self.comb += self.pll_locked.status.eq(pll_locked)
|
|
||||||
|
|
||||||
|
|
||||||
eem_iostandard_dict = {
|
eem_iostandard_dict = {
|
||||||
0: "LVDS_25",
|
0: "LVDS_25",
|
||||||
1: "LVDS_25",
|
1: "LVDS_25",
|
||||||
@ -129,7 +92,7 @@ class GenericStandalone(SoCCore):
|
|||||||
]
|
]
|
||||||
|
|
||||||
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
||||||
self.submodules.sys_crg = SYSCRG(self.platform, clk_synth_se)
|
self.submodules.sys_crg = zynq_clocking.SYSCRG(self.platform, self.ps7, clk_synth_se)
|
||||||
self.csr_devices.append("sys_crg")
|
self.csr_devices.append("sys_crg")
|
||||||
# another hack since ps7 itself does not have cd_sys anymore
|
# another hack since ps7 itself does not have cd_sys anymore
|
||||||
self.crg.cd_sys = self.sys_crg.cd_sys
|
self.crg.cd_sys = self.sys_crg.cd_sys
|
||||||
@ -149,7 +112,7 @@ class GenericStandalone(SoCCore):
|
|||||||
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
|
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
|
||||||
self.rtio_channels.append(rtio.LogChannel())
|
self.rtio_channels.append(rtio.LogChannel())
|
||||||
|
|
||||||
self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3)
|
self.submodules.rtio_tsc = rtio.TSC(glbl_fine_ts_width=3)
|
||||||
self.submodules.rtio_core = rtio.Core(self.rtio_tsc, self.rtio_channels)
|
self.submodules.rtio_core = rtio.Core(self.rtio_tsc, self.rtio_channels)
|
||||||
self.csr_devices.append("rtio_core")
|
self.csr_devices.append("rtio_core")
|
||||||
|
|
||||||
@ -219,8 +182,10 @@ class GenericMaster(SoCCore):
|
|||||||
self.csr_devices.append("drtio_transceiver")
|
self.csr_devices.append("drtio_transceiver")
|
||||||
|
|
||||||
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
||||||
self.submodules.rtio_crg = RTIOClockMultiplier(rtio_clk_freq)
|
self.submodules.sys_crg = zynq_clocking.SYSCRG(self.platform, self.drtio_transceiver.gtps[0].txoutclk)
|
||||||
self.csr_devices.append("rtio_crg")
|
self.csr_devices.append("sys_crg")
|
||||||
|
# another hack since ps7 itself does not have cd_sys anymore
|
||||||
|
self.crg.cd_sys = self.sys_crg.cd_sys
|
||||||
|
|
||||||
self.rustc_cfg["has_si5324"] = None
|
self.rustc_cfg["has_si5324"] = None
|
||||||
self.rustc_cfg["si5324_soft_reset"] = None
|
self.rustc_cfg["si5324_soft_reset"] = None
|
||||||
@ -239,7 +204,7 @@ class GenericMaster(SoCCore):
|
|||||||
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
|
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
|
||||||
self.rtio_channels.append(rtio.LogChannel())
|
self.rtio_channels.append(rtio.LogChannel())
|
||||||
|
|
||||||
self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3)
|
self.submodules.rtio_tsc = rtio.TSC(glbl_fine_ts_width=3)
|
||||||
|
|
||||||
drtio_csr_group = []
|
drtio_csr_group = []
|
||||||
drtioaux_csr_group = []
|
drtioaux_csr_group = []
|
||||||
@ -334,9 +299,8 @@ class GenericSatellite(SoCCore):
|
|||||||
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
||||||
|
|
||||||
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
||||||
self.submodules.rtio_crg = RTIOClockMultiplier(rtio_clk_freq)
|
self.submodules.sys_crg = zynq_clocking.SYSCRG(self.platform, self.drtio_transceiver.gtps[0].txoutclk)
|
||||||
self.csr_devices.append("rtio_crg")
|
self.csr_devices.append("sys_crg")
|
||||||
self.rustc_cfg["has_rtio_crg"] = None
|
|
||||||
|
|
||||||
data_pads = [platform.request("sfp", i) for i in range(4)]
|
data_pads = [platform.request("sfp", i) for i in range(4)]
|
||||||
|
|
||||||
@ -360,7 +324,7 @@ class GenericSatellite(SoCCore):
|
|||||||
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
|
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
|
||||||
self.rtio_channels.append(rtio.LogChannel())
|
self.rtio_channels.append(rtio.LogChannel())
|
||||||
|
|
||||||
self.submodules.rtio_tsc = rtio.TSC("sync", glbl_fine_ts_width=3)
|
self.submodules.rtio_tsc = rtio.TSC(glbl_fine_ts_width=3)
|
||||||
|
|
||||||
drtioaux_csr_group = []
|
drtioaux_csr_group = []
|
||||||
drtioaux_memory_group = []
|
drtioaux_memory_group = []
|
||||||
|
@ -25,11 +25,14 @@ import dma
|
|||||||
import analyzer
|
import analyzer
|
||||||
import acpki
|
import acpki
|
||||||
import drtio_aux_controller
|
import drtio_aux_controller
|
||||||
|
import zynq_clocking
|
||||||
|
|
||||||
|
|
||||||
class SYSCRG(Module, AutoCSR):
|
class SYSCRG(Module, AutoCSR):
|
||||||
def __init__(self, platform, main_clk):
|
def __init__(self, platform, ps7, main_clk):
|
||||||
self.pll_locked = CSRStatus()
|
self.pll_locked = CSRStatus()
|
||||||
|
self.pll_clksel = CSRStorage()
|
||||||
|
self.pll_reset = CSRStorage()
|
||||||
self.clock_domains.cd_sys = ClockDomain()
|
self.clock_domains.cd_sys = ClockDomain()
|
||||||
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
|
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
|
||||||
|
|
||||||
@ -37,31 +40,35 @@ class SYSCRG(Module, AutoCSR):
|
|||||||
sys_clk = Signal()
|
sys_clk = Signal()
|
||||||
sys4x_clk = Signal()
|
sys4x_clk = Signal()
|
||||||
fb_clk = Signal()
|
fb_clk = Signal()
|
||||||
|
fclk_buf = Signal()
|
||||||
self.specials += [
|
self.specials += [
|
||||||
|
Instance("BUFG", i_I=ps7.fclk.clk[0], o_O=fclk_buf),
|
||||||
Instance("PLLE2_ADV",
|
Instance("PLLE2_ADV",
|
||||||
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
|
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
|
||||||
|
p_BANDWIDTH="HIGH",
|
||||||
|
p_REF_JITTER1=0.001,
|
||||||
|
p_CLKIN1_PERIOD=8.0, i_CLKIN1=main_clk,
|
||||||
|
p_CLKIN2_PERIOD=8.0, i_CLKIN2=fclk_buf,
|
||||||
|
i_CLKINSEL=self.pll_clksel.storage,
|
||||||
|
|
||||||
p_REF_JITTER1=0.01,
|
# VCO @ 1.5GHz when using 125MHz input
|
||||||
p_CLKIN1_PERIOD=8.0,
|
p_CLKFBOUT_MULT=12, p_DIVCLK_DIVIDE=1,
|
||||||
i_CLKIN1=main_clk,
|
|
||||||
i_CLKINSEL=1,
|
|
||||||
|
|
||||||
# VCO @ 1GHz when using 125MHz input
|
|
||||||
p_CLKFBOUT_MULT=8, p_DIVCLK_DIVIDE=1,
|
|
||||||
i_CLKFBIN=fb_clk,
|
i_CLKFBIN=fb_clk,
|
||||||
i_RST=0,
|
i_RST=self.pll_reset.storage,
|
||||||
|
|
||||||
o_CLKFBOUT=fb_clk,
|
o_CLKFBOUT=fb_clk,
|
||||||
|
|
||||||
p_CLKOUT0_DIVIDE=8, p_CLKOUT0_PHASE=0.0,
|
p_CLKOUT0_DIVIDE=12, p_CLKOUT0_PHASE=0.0,
|
||||||
o_CLKOUT0=sys_clk,
|
o_CLKOUT0=sys_clk,
|
||||||
p_CLKOUT1_DIVIDE=2, p_CLKOUT1_PHASE=0.0,
|
p_CLKOUT1_DIVIDE=3, p_CLKOUT1_PHASE=0.0,
|
||||||
o_CLKOUT1=sys4x_clk),
|
o_CLKOUT1=sys4x_clk),
|
||||||
Instance("BUFG", i_I=sys_clk, o_O=self.cd_sys.clk),
|
Instance("BUFG", i_I=sys_clk, o_O=self.cd_sys.clk),
|
||||||
Instance("BUFG", i_I=sys4x_clk, o_O=self.cd_sys4x.clk),
|
Instance("BUFG", i_I=sys4x_clk, o_O=self.cd_sys4x.clk),
|
||||||
AsyncResetSynchronizer(self.cd_sys, ~pll_locked)
|
AsyncResetSynchronizer(self.cd_sys, ~pll_locked)
|
||||||
]
|
]
|
||||||
self.comb += self.pll_locked.status.eq(pll_locked)
|
self.comb += self.pll_locked.status.eq(pll_locked)
|
||||||
|
platform.add_period_constraint(fclk_buf, 8.)
|
||||||
|
platform.add_false_path_constraints(self.cd_sys.clk, fclk_buf, main_clk)
|
||||||
|
|
||||||
|
|
||||||
class SMAClkinForward(Module):
|
class SMAClkinForward(Module):
|
||||||
@ -154,6 +161,7 @@ class ZC706(SoCCore):
|
|||||||
platform.add_period_constraint(si5324_out.p, 8.0)
|
platform.add_period_constraint(si5324_out.p, 8.0)
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance("IBUFDS_GTE2",
|
Instance("IBUFDS_GTE2",
|
||||||
|
i_CEB=0,
|
||||||
i_I=si5324_out.p, i_IB=si5324_out.n,
|
i_I=si5324_out.p, i_IB=si5324_out.n,
|
||||||
o_O=cdr_clk,
|
o_O=cdr_clk,
|
||||||
p_CLKCM_CFG="0b1",
|
p_CLKCM_CFG="0b1",
|
||||||
@ -165,7 +173,7 @@ class ZC706(SoCCore):
|
|||||||
self.rustc_cfg["si5324_as_synthesizer"] = None
|
self.rustc_cfg["si5324_as_synthesizer"] = None
|
||||||
self.rustc_cfg["si5324_soft_reset"] = None
|
self.rustc_cfg["si5324_soft_reset"] = None
|
||||||
|
|
||||||
self.submodules.sys_crg = SYSCRG(self.platform, cdr_clk_buf)
|
self.submodules.sys_crg = SYSCRG(self.platform, self.ps7, cdr_clk_buf)
|
||||||
self.csr_devices.append("sys_crg")
|
self.csr_devices.append("sys_crg")
|
||||||
self.platform.add_period_constraint(self.sys_crg.cd_sys.clk, 8.)
|
self.platform.add_period_constraint(self.sys_crg.cd_sys.clk, 8.)
|
||||||
|
|
||||||
|
109
src/gateware/zynq_clocking.py
Normal file
109
src/gateware/zynq_clocking.py
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
from migen import *
|
||||||
|
from migen.genlib.cdc import MultiReg
|
||||||
|
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||||
|
from misoc.interconnect.csr import *
|
||||||
|
|
||||||
|
|
||||||
|
class ClockSwitchFSM(Module):
|
||||||
|
def __init__(self):
|
||||||
|
self.i_clk_sw = Signal()
|
||||||
|
|
||||||
|
self.o_clk_sw = Signal()
|
||||||
|
self.o_reset = Signal()
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
i_switch = Signal()
|
||||||
|
o_switch = Signal()
|
||||||
|
reset = Signal()
|
||||||
|
|
||||||
|
# at 125MHz bootstrap cd, will get around 0.5ms
|
||||||
|
delay_counter = Signal(16, reset=0xFFFF)
|
||||||
|
|
||||||
|
# register to prevent glitches
|
||||||
|
self.sync.bootstrap += [
|
||||||
|
self.o_clk_sw.eq(o_switch),
|
||||||
|
self.o_reset.eq(reset),
|
||||||
|
]
|
||||||
|
|
||||||
|
self.o_clk_sw.attr.add("no_retiming")
|
||||||
|
self.o_reset.attr.add("no_retiming")
|
||||||
|
self.i_clk_sw.attr.add("no_retiming")
|
||||||
|
i_switch.attr.add("no_retiming")
|
||||||
|
|
||||||
|
self.specials += MultiReg(self.i_clk_sw, i_switch, "bootstrap")
|
||||||
|
|
||||||
|
fsm = ClockDomainsRenamer("bootstrap")(FSM(reset_state="START"))
|
||||||
|
|
||||||
|
self.submodules += fsm
|
||||||
|
|
||||||
|
fsm.act("START",
|
||||||
|
If(i_switch & ~o_switch,
|
||||||
|
NextState("RESET_START"))
|
||||||
|
)
|
||||||
|
|
||||||
|
fsm.act("RESET_START",
|
||||||
|
reset.eq(1),
|
||||||
|
If(delay_counter == 0,
|
||||||
|
NextValue(delay_counter, 0xFFFF),
|
||||||
|
NextState("CLOCK_SWITCH")
|
||||||
|
).Else(
|
||||||
|
NextValue(delay_counter, delay_counter-1),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fsm.act("CLOCK_SWITCH",
|
||||||
|
reset.eq(1),
|
||||||
|
NextValue(o_switch, 1),
|
||||||
|
NextValue(delay_counter, delay_counter-1),
|
||||||
|
If(delay_counter == 0,
|
||||||
|
NextState("START"))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SYSCRG(Module, AutoCSR):
|
||||||
|
def __init__(self, platform, ps7, main_clk):
|
||||||
|
self.clock_switch = CSRStorage()
|
||||||
|
self.clock_domains.cd_bootstrap = ClockDomain(reset_less=True)
|
||||||
|
self.clock_domains.cd_sys = ClockDomain()
|
||||||
|
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
|
||||||
|
|
||||||
|
pll_locked = Signal()
|
||||||
|
sys_clk = Signal()
|
||||||
|
sys4x_clk = Signal()
|
||||||
|
fb_clk = Signal()
|
||||||
|
fclk_buf = Signal()
|
||||||
|
|
||||||
|
self.submodules.clk_sw_fsm = ClockSwitchFSM()
|
||||||
|
|
||||||
|
self.comb += self.clk_sw_fsm.i_clk_sw.eq(self.clock_switch.storage)
|
||||||
|
|
||||||
|
self.specials += [
|
||||||
|
Instance("BUFG", i_I=ps7.fclk.clk[0], o_O=self.cd_bootstrap.clk),
|
||||||
|
Instance("PLLE2_ADV",
|
||||||
|
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
|
||||||
|
p_BANDWIDTH="HIGH",
|
||||||
|
p_REF_JITTER1=0.001,
|
||||||
|
p_CLKIN1_PERIOD=8.0, i_CLKIN1=main_clk,
|
||||||
|
p_CLKIN2_PERIOD=8.0, i_CLKIN2=self.cd_bootstrap.clk,
|
||||||
|
i_CLKINSEL=self.clk_sw_fsm.o_clk_sw,
|
||||||
|
|
||||||
|
# VCO @ 1.5GHz when using 125MHz input
|
||||||
|
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=sys4x_clk,
|
||||||
|
|
||||||
|
p_CLKOUT1_DIVIDE=12, p_CLKOUT1_PHASE=0.0,
|
||||||
|
o_CLKOUT1=sys_clk),
|
||||||
|
Instance("BUFG", i_I=sys_clk, o_O=self.cd_sys.clk),
|
||||||
|
Instance("BUFG", i_I=sys4x_clk, o_O=self.cd_sys4x.clk),
|
||||||
|
|
||||||
|
AsyncResetSynchronizer(self.cd_sys, ~pll_locked | ~ps7.fclk.reset_n[0]),
|
||||||
|
]
|
||||||
|
platform.add_period_constraint(self.cd_bootstrap.clk, 8.)
|
||||||
|
platform.add_false_path_constraints(self.cd_sys.clk, self.cd_bootstrap.clk, main_clk)
|
@ -68,17 +68,16 @@ fn get_rtio_clock_cfg(cfg: &Config) -> RtioClock {
|
|||||||
|
|
||||||
|
|
||||||
fn init_rtio(timer: &mut GlobalTimer, _clk: RtioClock) {
|
fn init_rtio(timer: &mut GlobalTimer, _clk: RtioClock) {
|
||||||
timer.delay_ms(1);
|
info!("Switching SYS clocks...");
|
||||||
let locked = unsafe { pl::csr::sys_crg::pll_locked_read() != 0 };
|
unsafe {
|
||||||
if locked {
|
pl::csr::sys_crg::clock_switch_write(1);
|
||||||
info!("RTIO PLL locked");
|
|
||||||
} else {
|
|
||||||
panic!("RTIO PLL failed to lock");
|
|
||||||
}
|
}
|
||||||
|
timer.delay_ms(2);
|
||||||
unsafe {
|
unsafe {
|
||||||
pl::csr::rtio_core::reset_phy_write(1);
|
pl::csr::rtio_core::reset_phy_write(1);
|
||||||
}
|
}
|
||||||
|
// if it's not locked, it will hang at the CSR.
|
||||||
|
info!("SYS PLL locked");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
|
Loading…
Reference in New Issue
Block a user