diff --git a/src/gateware/kasli_soc.py b/src/gateware/kasli_soc.py index fe526be..c4aeeab 100755 --- a/src/gateware/kasli_soc.py +++ b/src/gateware/kasli_soc.py @@ -182,11 +182,13 @@ class GenericMaster(SoCCore): self.csr_devices.append("drtio_transceiver") txout_buf = Signal() - txout_buf.attr.add("keep") - self.specials += Instance("BUFG", i_I=self.drtio_transceiver.gtxs[0].txoutclk, o_O=txout_buf) - self.submodules.sys_crg = zynq_clocking.SYSCRG(self.platform, - self.ps7, - txout_buf) + gtx0 = self.drtio_transceiver.gtxs[0] + self.specials += Instance("BUFG", i_I=gtx0.txoutclk, o_O=txout_buf) + self.submodules.sys_crg = zynq_clocking.SYSCRG( + self.platform, + self.ps7, + txout_buf, + clk_sw=gtx0.tx_init.done) self.csr_devices.append("sys_crg") self.crg = self.ps7 # HACK for eem_7series to find the clock # another hack since ps7 itself does not have cd_sys anymore @@ -314,11 +316,13 @@ class GenericSatellite(SoCCore): self.csr_devices.append("drtio_transceiver") txout_buf = Signal() - txout_buf.attr.add("keep") - self.specials += Instance("BUFG", i_I=self.drtio_transceiver.gtxs[0].txoutclk, o_O=txout_buf) - self.submodules.sys_crg = zynq_clocking.SYSCRG(self.platform, - self.ps7, - txout_buf) + gtx0 = self.drtio_transceiver.gtxs[0] + self.specials += Instance("BUFG", i_I=gtx0.txoutclk, o_O=txout_buf) + self.submodules.sys_crg = zynq_clocking.SYSCRG( + self.platform, + self.ps7, + txout_buf, + clk_sw=gtx0.tx_init.done) self.csr_devices.append("sys_crg") self.crg.cd_sys = self.sys_crg.cd_sys diff --git a/src/gateware/zc706.py b/src/gateware/zc706.py index 8a808f2..6b2ebfe 100755 --- a/src/gateware/zc706.py +++ b/src/gateware/zc706.py @@ -199,14 +199,13 @@ class _MasterBase(SoCCore): self.submodules.rtio_tsc = rtio.TSC(glbl_fine_ts_width=3) txout_buf = Signal() - self.specials += Instance( - "BUFG", - i_I=self.drtio_transceiver.gtxs[0].txoutclk, - o_O=txout_buf) + gtx0 = self.drtio_transceiver.gtxs[0] + self.specials += Instance("BUFG", i_I=gtx0.txoutclk, o_O=txout_buf) self.submodules.sys_crg = zynq_clocking.SYSCRG( self.platform, self.ps7, - txout_buf) + txout_buf, + clk_sw=gtx0.tx_init.done) self.csr_devices.append("sys_crg") drtio_csr_group = [] @@ -252,7 +251,6 @@ class _MasterBase(SoCCore): # Constrain TX & RX timing for the first transceiver channel # (First channel acts as master for phase alignment for all channels' TX) - gtx0 = self.drtio_transceiver.gtxs[0] platform.add_false_path_constraints( gtx0.txoutclk, gtx0.rxoutclk) # Constrain RX timing for the each transceiver channel @@ -334,14 +332,16 @@ class _SatelliteBase(SoCCore): txout_buf = Signal() txout_buf.attr.add("keep") + gtx0 = self.drtio_transceiver.gtxs[0] self.specials += Instance( "BUFG", - i_I=self.drtio_transceiver.gtxs[0].txoutclk, + i_I=gtx0.txoutclk, o_O=txout_buf) self.submodules.sys_crg = zynq_clocking.SYSCRG( self.platform, self.ps7, - txout_buf) + txout_buf, + clk_sw=gtx0.tx_init.done) self.csr_devices.append("sys_crg") drtioaux_csr_group = [] @@ -411,7 +411,6 @@ class _SatelliteBase(SoCCore): rtio_clk_period = 1e9/self.drtio_transceiver.rtio_clk_freq # Constrain TX & RX timing for the first transceiver channel # (First channel acts as master for phase alignment for all channels' TX) - gtx0 = self.drtio_transceiver.gtxs[0] platform.add_false_path_constraints( gtx0.txoutclk, gtx0.rxoutclk) # Constrain RX timing for the each transceiver channel diff --git a/src/gateware/zynq_clocking.py b/src/gateware/zynq_clocking.py index c7b93ca..baed5e8 100644 --- a/src/gateware/zynq_clocking.py +++ b/src/gateware/zynq_clocking.py @@ -57,13 +57,15 @@ class ClockSwitchFSM(Module): NextValue(o_switch, 1), NextValue(delay_counter, delay_counter-1), If(delay_counter == 0, - NextState("START")) + NextState("END")) ) + fsm.act("END", + NextValue(o_switch, 1), + reset.eq(0)) class SYSCRG(Module, AutoCSR): - def __init__(self, platform, ps7, main_clk): - self.clock_switch = CSRStorage() + def __init__(self, platform, ps7, main_clk, clk_sw=None): self.clock_domains.cd_bootstrap = ClockDomain(reset_less=True) self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) @@ -79,10 +81,15 @@ class SYSCRG(Module, AutoCSR): self.submodules.clk_sw_fsm = ClockSwitchFSM() - self.comb += self.clk_sw_fsm.i_clk_sw.eq(self.clock_switch.storage) + if clk_sw is None: + self.clock_switch = CSRStorage() + self.comb += self.clk_sw_fsm.i_clk_sw.eq(self.clock_switch.storage) + else: + self.comb += self.clk_sw_fsm.i_clk_sw.eq(clk_sw) self.specials += [ Instance("BUFG", i_I=ps7.fclk.clk[0], o_O=self.cd_bootstrap.clk), + # Instance("BUFG", i_I=ps7.fclk.clk[0], o_O=self.cd_sys.clk), Instance("PLLE2_ADV", p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, p_BANDWIDTH="HIGH", @@ -106,6 +113,6 @@ class SYSCRG(Module, AutoCSR): 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 | ~ps7.fclk.reset_n[0]), + AsyncResetSynchronizer(self.cd_sys, ~ps7.fclk.reset_n[0]), ] platform.add_false_path_constraints(self.cd_bootstrap.clk, main_clk) diff --git a/src/runtime/src/rtio_clocking.rs b/src/runtime/src/rtio_clocking.rs index 4e15347..d9b37d3 100644 --- a/src/runtime/src/rtio_clocking.rs +++ b/src/runtime/src/rtio_clocking.rs @@ -66,13 +66,12 @@ fn get_rtio_clock_cfg(cfg: &Config) -> RtioClock { res } - -fn init_rtio(timer: &mut GlobalTimer, _clk: RtioClock) { +#[cfg(not(has_drtio))] +fn init_rtio(timer: &mut GlobalTimer) { info!("Switching SYS clocks..."); unsafe { pl::csr::sys_crg::clock_switch_write(1); } - timer.delay_ms(10); // if it's not locked, it will hang at the CSR. unsafe { pl::csr::rtio_core::reset_phy_write(1); @@ -87,8 +86,10 @@ fn init_drtio(timer: &mut GlobalTimer) unsafe { pl::csr::drtio_transceiver::stable_clkin_write(1); } - timer.delay_ms(2); // wait for CPLL/QPLL lock + + timer.delay_ms(20); // wait for CPLL/QPLL/MMCM lock unsafe { + pl::csr::rtio_core::reset_phy_write(1); pl::csr::drtio_transceiver::txenable_write(0xffffffffu32 as _); } } @@ -228,8 +229,9 @@ pub fn init(timer: &mut GlobalTimer, cfg: &Config) { } } - init_rtio(timer, clk); - #[cfg(has_drtio)] init_drtio(timer); + + #[cfg(not(has_drtio))] + init_rtio(timer); } \ No newline at end of file diff --git a/src/satman/src/main.rs b/src/satman/src/main.rs index d8a42b6..c1f70ef 100644 --- a/src/satman/src/main.rs +++ b/src/satman/src/main.rs @@ -390,25 +390,6 @@ fn drtiosat_process_errors() { } } - -#[cfg(has_rtio_crg)] -fn init_rtio_crg(timer: &mut GlobalTimer) { - unsafe { - csr::rtio_crg::pll_reset_write(0); - } - timer.delay_us(150); - let locked = unsafe { csr::rtio_crg::pll_locked_read() != 0 }; - if !locked { - error!("RTIO clock failed"); - } - else { - info!("RTIO PLL locked"); - } -} - -#[cfg(not(has_rtio_crg))] -fn init_rtio_crg(_timer: &mut GlobalTimer) { } - fn hardware_tick(ts: &mut u64, timer: &mut GlobalTimer) { let now = timer.get_time(); let mut ts_ms = Milliseconds(*ts); @@ -472,22 +453,15 @@ pub extern fn main_core0() -> i32 { #[cfg(has_si5324)] si5324::setup(&mut i2c, &SI5324_SETTINGS, si5324::Input::Ckin1, &mut timer).expect("cannot initialize Si5324"); + info!("Switching SYS clocks..."); unsafe { csr::drtio_transceiver::stable_clkin_write(1); } - timer.delay_us(1500); // wait for CPLL/QPLL lock - - info!("Switching SYS clocks..."); - unsafe { - csr::sys_crg::clock_switch_write(1); - } - - timer.delay_us(10_000); // wait for SYS PLL lock + timer.delay_us(20_000); // wait for CPLL/QPLL/MMCM lock unsafe { csr::drtio_transceiver::txenable_write(0xffffffffu32 as _); } - init_rtio_crg(&mut timer); #[cfg(has_drtio_routing)] let mut repeaters = [repeater::Repeater::default(); csr::DRTIOREP.len()];