forked from M-Labs/artiq
sayma: support external RTM clocking
This commit is contained in:
parent
041dc0f64a
commit
167e97efd2
|
@ -33,10 +33,9 @@ fn read(addr: u16) -> u8 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jesd_unreset() {
|
pub fn jesd_reset(reset: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::ad9154_crg::ibuf_disable_write(0);
|
csr::ad9154_crg::jreset_write(if reset { 1 } else { 0 });
|
||||||
csr::ad9154_crg::jreset_write(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -367,6 +367,18 @@ pub mod hmc7043 {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn enable_fpga_ibuf() {
|
||||||
|
/*
|
||||||
|
* Never missing an opportunity to be awful, the HMC7043 produces broadband noise
|
||||||
|
* prior to intialization, which can upset the FPGA.
|
||||||
|
* One mitigation technique is to disable the input buffer until the HMC7043 is
|
||||||
|
* slightly better behaved.
|
||||||
|
*/
|
||||||
|
unsafe {
|
||||||
|
csr::ad9154_crg::ibuf_disable_write(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sysref_offset_dac(dacno: u8, phase_offset: u16) {
|
pub fn sysref_offset_dac(dacno: u8, phase_offset: u16) {
|
||||||
/* Analog delay resolution: 25ps
|
/* Analog delay resolution: 25ps
|
||||||
* Digital delay resolution: 1/2 input clock cycle = 416ps for 1.2GHz
|
* Digital delay resolution: 1/2 input clock cycle = 416ps for 1.2GHz
|
||||||
|
@ -427,6 +439,7 @@ pub fn init() -> Result<(), &'static str> {
|
||||||
hmc7043::init();
|
hmc7043::init();
|
||||||
hmc7043::test_gpo()?;
|
hmc7043::test_gpo()?;
|
||||||
hmc7043::check_phased()?;
|
hmc7043::check_phased()?;
|
||||||
|
hmc7043::enable_fpga_ibuf();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ fn startup() {
|
||||||
board_artiq::hmc830_7043::init().expect("cannot initialize HMC830/7043");
|
board_artiq::hmc830_7043::init().expect("cannot initialize HMC830/7043");
|
||||||
#[cfg(has_ad9154)]
|
#[cfg(has_ad9154)]
|
||||||
{
|
{
|
||||||
board_artiq::ad9154::jesd_unreset();
|
board_artiq::ad9154::jesd_reset(false);
|
||||||
board_artiq::ad9154::init();
|
board_artiq::ad9154::init();
|
||||||
if let Err(e) = board_artiq::jesd204sync::sysref_auto_rtio_align() {
|
if let Err(e) = board_artiq::jesd204sync::sysref_auto_rtio_align() {
|
||||||
error!("failed to align SYSREF at FPGA: {}", e);
|
error!("failed to align SYSREF at FPGA: {}", e);
|
||||||
|
|
|
@ -273,11 +273,6 @@ pub extern fn main() -> i32 {
|
||||||
csr::drtio_transceiver::stable_clkin_write(1);
|
csr::drtio_transceiver::stable_clkin_write(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_ad9154)]
|
|
||||||
{
|
|
||||||
board_artiq::ad9154::jesd_unreset();
|
|
||||||
board_artiq::ad9154::init();
|
|
||||||
}
|
|
||||||
#[cfg(has_allaki_atts)]
|
#[cfg(has_allaki_atts)]
|
||||||
board_artiq::hmc542::program_all(8/*=4dB*/);
|
board_artiq::hmc542::program_all(8/*=4dB*/);
|
||||||
|
|
||||||
|
@ -285,12 +280,34 @@ pub extern fn main() -> i32 {
|
||||||
while !drtio_link_rx_up() {
|
while !drtio_link_rx_up() {
|
||||||
process_errors();
|
process_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("link is up, switching to recovered clock");
|
info!("link is up, switching to recovered clock");
|
||||||
si5324::siphaser::select_recovered_clock(true).expect("failed to switch clocks");
|
si5324::siphaser::select_recovered_clock(true).expect("failed to switch clocks");
|
||||||
si5324::siphaser::calibrate_skew(SIPHASER_PHASE).expect("failed to calibrate skew");
|
si5324::siphaser::calibrate_skew(SIPHASER_PHASE).expect("failed to calibrate skew");
|
||||||
|
|
||||||
|
#[cfg(has_ad9154)]
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* One side of the JESD204 elastic buffer is clocked by the Si5324, the other
|
||||||
|
* by the RTM.
|
||||||
|
* The elastic buffer can operate only when those two clocks are derived from
|
||||||
|
* the same oscillator.
|
||||||
|
* This is the case when either of those conditions is true:
|
||||||
|
* (1) The DRTIO master and the RTM are clocked directly from a common external
|
||||||
|
* source, *and* the Si5324 has locked to the recovered clock.
|
||||||
|
* This clocking scheme provides less noise and phase drift at the DACs.
|
||||||
|
* (2) The RTM clock is connected to the Si5324 output.
|
||||||
|
* To handle those cases, we simply keep the JESD204 core in reset unless the
|
||||||
|
* Si5324 is locked to the recovered clock.
|
||||||
|
*/
|
||||||
|
board_artiq::ad9154::jesd_reset(false);
|
||||||
|
board_artiq::ad9154::init();
|
||||||
|
}
|
||||||
|
|
||||||
drtioaux::reset(0);
|
drtioaux::reset(0);
|
||||||
drtio_reset(false);
|
drtio_reset(false);
|
||||||
drtio_reset_phy(false);
|
drtio_reset_phy(false);
|
||||||
|
|
||||||
while drtio_link_rx_up() {
|
while drtio_link_rx_up() {
|
||||||
process_errors();
|
process_errors();
|
||||||
process_aux_packets();
|
process_aux_packets();
|
||||||
|
@ -309,6 +326,10 @@ pub extern fn main() -> i32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(has_ad9154)]
|
||||||
|
board_artiq::ad9154::jesd_reset(true);
|
||||||
|
|
||||||
drtio_reset_phy(true);
|
drtio_reset_phy(true);
|
||||||
drtio_reset(true);
|
drtio_reset(true);
|
||||||
drtio_tsc_loaded();
|
drtio_tsc_loaded();
|
||||||
|
|
|
@ -577,7 +577,7 @@ class Satellite(BaseSoC, RTMCommon):
|
||||||
|
|
||||||
self.comb += platform.request("sfp_tx_disable", 0).eq(0)
|
self.comb += platform.request("sfp_tx_disable", 0).eq(0)
|
||||||
self.submodules.drtio_transceiver = gth_ultrascale.GTH(
|
self.submodules.drtio_transceiver = gth_ultrascale.GTH(
|
||||||
clock_pads=self.ad9154_crg.refclk,
|
clock_pads=platform.request("si5324_clkout"),
|
||||||
data_pads=[platform.request("sfp", 0)],
|
data_pads=[platform.request("sfp", 0)],
|
||||||
sys_clk_freq=self.clk_freq,
|
sys_clk_freq=self.clk_freq,
|
||||||
rtio_clk_freq=rtio_clk_freq)
|
rtio_clk_freq=rtio_clk_freq)
|
||||||
|
@ -599,7 +599,7 @@ class Satellite(BaseSoC, RTMCommon):
|
||||||
self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6)
|
self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6)
|
||||||
self.submodules.siphaser = SiPhaser7Series(
|
self.submodules.siphaser = SiPhaser7Series(
|
||||||
si5324_clkin=platform.request("si5324_clkin"),
|
si5324_clkin=platform.request("si5324_clkin"),
|
||||||
si5324_clkout_fabric=platform.request("adc_sysref"))
|
si5324_clkout_fabric=platform.request("si5324_clkout_fabric"))
|
||||||
platform.add_platform_command("set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets {mmcm_ps}]",
|
platform.add_platform_command("set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets {mmcm_ps}]",
|
||||||
mmcm_ps=self.siphaser.mmcm_ps_output)
|
mmcm_ps=self.siphaser.mmcm_ps_output)
|
||||||
platform.add_false_path_constraints(
|
platform.add_false_path_constraints(
|
||||||
|
@ -612,11 +612,6 @@ class Satellite(BaseSoC, RTMCommon):
|
||||||
self.csr_devices.append("i2c")
|
self.csr_devices.append("i2c")
|
||||||
self.config["I2C_BUS_COUNT"] = 1
|
self.config["I2C_BUS_COUNT"] = 1
|
||||||
self.config["HAS_SI5324"] = None
|
self.config["HAS_SI5324"] = None
|
||||||
# ensure pins are properly biased and terminated
|
|
||||||
si5324_clkout = platform.request("si5324_clkout", 0)
|
|
||||||
self.specials += Instance(
|
|
||||||
"IBUFDS_GTE3", i_CEB=0, i_I=si5324_clkout.p, i_IB=si5324_clkout.n,
|
|
||||||
attr={("DONT_TOUCH", "true")})
|
|
||||||
|
|
||||||
self.submodules.sysref_sampler = jesd204_tools.SysrefSampler(
|
self.submodules.sysref_sampler = jesd204_tools.SysrefSampler(
|
||||||
self.drtio0.coarse_ts, self.ad9154_crg.jref)
|
self.drtio0.coarse_ts, self.ad9154_crg.jref)
|
||||||
|
|
Loading…
Reference in New Issue