RTIO/SYS Clock merge #212
@ -24,44 +24,7 @@ import dma
|
||||
import analyzer
|
||||
import acpki
|
||||
import drtio_aux_controller
|
||||
|
||||
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)
|
||||
import zynq_clocking
|
||||
|
||||
|
||||
eem_iostandard_dict = {
|
||||
@ -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 = []
|
||||
|
@ -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.)
|
||||
|
||||
|
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) {
|
||||
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)]
|
||||
|
Loading…
Reference in New Issue
Block a user