move clocking to zynq_clocking

add clock-switching FSM
restore order
This commit is contained in:
mwojcik 2023-01-16 18:14:56 +08:00
parent b26731d83c
commit 3194b772ae
4 changed files with 146 additions and 66 deletions

View File

@ -24,46 +24,9 @@ import dma
import analyzer
import acpki
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 = {
0: "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.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")
# another hack since ps7 itself does not have cd_sys anymore
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.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.csr_devices.append("rtio_core")
@ -219,8 +182,10 @@ class GenericMaster(SoCCore):
self.csr_devices.append("drtio_transceiver")
self.crg = self.ps7 # HACK for eem_7series to find the clock
self.submodules.rtio_crg = RTIOClockMultiplier(rtio_clk_freq)
self.csr_devices.append("rtio_crg")
self.submodules.sys_crg = zynq_clocking.SYSCRG(self.platform, self.drtio_transceiver.gtps[0].txoutclk)
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["si5324_soft_reset"] = None
@ -239,7 +204,7 @@ class GenericMaster(SoCCore):
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
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 = []
drtioaux_csr_group = []
@ -334,9 +299,8 @@ class GenericSatellite(SoCCore):
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.submodules.rtio_crg = RTIOClockMultiplier(rtio_clk_freq)
self.csr_devices.append("rtio_crg")
self.rustc_cfg["has_rtio_crg"] = None
self.submodules.sys_crg = zynq_clocking.SYSCRG(self.platform, self.drtio_transceiver.gtps[0].txoutclk)
self.csr_devices.append("sys_crg")
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.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_memory_group = []

View File

@ -25,11 +25,14 @@ import dma
import analyzer
import acpki
import drtio_aux_controller
import zynq_clocking
class SYSCRG(Module, AutoCSR):
def __init__(self, platform, main_clk):
def __init__(self, platform, ps7, main_clk):
self.pll_locked = CSRStatus()
self.pll_clksel = CSRStorage()
self.pll_reset = CSRStorage()
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
@ -37,31 +40,35 @@ class SYSCRG(Module, AutoCSR):
sys_clk = Signal()
sys4x_clk = Signal()
fb_clk = Signal()
fclk_buf = Signal()
self.specials += [
Instance("BUFG", i_I=ps7.fclk.clk[0], o_O=fclk_buf),
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=fclk_buf,
i_CLKINSEL=self.pll_clksel.storage,
p_REF_JITTER1=0.01,
p_CLKIN1_PERIOD=8.0,
i_CLKIN1=main_clk,
i_CLKINSEL=1,
# VCO @ 1GHz when using 125MHz input
p_CLKFBOUT_MULT=8, p_DIVCLK_DIVIDE=1,
# VCO @ 1.5GHz when using 125MHz input
p_CLKFBOUT_MULT=12, p_DIVCLK_DIVIDE=1,
i_CLKFBIN=fb_clk,
i_RST=0,
i_RST=self.pll_reset.storage,
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,
p_CLKOUT1_DIVIDE=2, p_CLKOUT1_PHASE=0.0,
p_CLKOUT1_DIVIDE=3, p_CLKOUT1_PHASE=0.0,
o_CLKOUT1=sys4x_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)
platform.add_period_constraint(fclk_buf, 8.)
platform.add_false_path_constraints(self.cd_sys.clk, fclk_buf, main_clk)
class SMAClkinForward(Module):
@ -154,6 +161,7 @@ class ZC706(SoCCore):
platform.add_period_constraint(si5324_out.p, 8.0)
self.specials += [
Instance("IBUFDS_GTE2",
i_CEB=0,
i_I=si5324_out.p, i_IB=si5324_out.n,
o_O=cdr_clk,
p_CLKCM_CFG="0b1",
@ -165,7 +173,7 @@ class ZC706(SoCCore):
self.rustc_cfg["si5324_as_synthesizer"] = 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.platform.add_period_constraint(self.sys_crg.cd_sys.clk, 8.)

View 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)

View File

@ -68,17 +68,16 @@ fn get_rtio_clock_cfg(cfg: &Config) -> RtioClock {
fn init_rtio(timer: &mut GlobalTimer, _clk: RtioClock) {
timer.delay_ms(1);
let locked = unsafe { pl::csr::sys_crg::pll_locked_read() != 0 };
if locked {
info!("RTIO PLL locked");
} else {
panic!("RTIO PLL failed to lock");
info!("Switching SYS clocks...");
unsafe {
pl::csr::sys_crg::clock_switch_write(1);
}
timer.delay_ms(2);
unsafe {
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)]