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 {
|
||||
csr::ad9154_crg::ibuf_disable_write(0);
|
||||
csr::ad9154_crg::jreset_write(0);
|
||||
csr::ad9154_crg::jreset_write(if reset { 1 } else { 0 });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -367,6 +367,18 @@ pub mod hmc7043 {
|
|||
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) {
|
||||
/* Analog delay resolution: 25ps
|
||||
* 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::test_gpo()?;
|
||||
hmc7043::check_phased()?;
|
||||
hmc7043::enable_fpga_ibuf();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ fn startup() {
|
|||
board_artiq::hmc830_7043::init().expect("cannot initialize HMC830/7043");
|
||||
#[cfg(has_ad9154)]
|
||||
{
|
||||
board_artiq::ad9154::jesd_unreset();
|
||||
board_artiq::ad9154::jesd_reset(false);
|
||||
board_artiq::ad9154::init();
|
||||
if let Err(e) = board_artiq::jesd204sync::sysref_auto_rtio_align() {
|
||||
error!("failed to align SYSREF at FPGA: {}", e);
|
||||
|
|
|
@ -273,11 +273,6 @@ pub extern fn main() -> i32 {
|
|||
csr::drtio_transceiver::stable_clkin_write(1);
|
||||
}
|
||||
|
||||
#[cfg(has_ad9154)]
|
||||
{
|
||||
board_artiq::ad9154::jesd_unreset();
|
||||
board_artiq::ad9154::init();
|
||||
}
|
||||
#[cfg(has_allaki_atts)]
|
||||
board_artiq::hmc542::program_all(8/*=4dB*/);
|
||||
|
||||
|
@ -285,12 +280,34 @@ pub extern fn main() -> i32 {
|
|||
while !drtio_link_rx_up() {
|
||||
process_errors();
|
||||
}
|
||||
|
||||
info!("link is up, switching to recovered clock");
|
||||
si5324::siphaser::select_recovered_clock(true).expect("failed to switch clocks");
|
||||
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);
|
||||
drtio_reset(false);
|
||||
drtio_reset_phy(false);
|
||||
|
||||
while drtio_link_rx_up() {
|
||||
process_errors();
|
||||
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(true);
|
||||
drtio_tsc_loaded();
|
||||
|
|
|
@ -577,7 +577,7 @@ class Satellite(BaseSoC, RTMCommon):
|
|||
|
||||
self.comb += platform.request("sfp_tx_disable", 0).eq(0)
|
||||
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)],
|
||||
sys_clk_freq=self.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.submodules.siphaser = SiPhaser7Series(
|
||||
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}]",
|
||||
mmcm_ps=self.siphaser.mmcm_ps_output)
|
||||
platform.add_false_path_constraints(
|
||||
|
@ -612,11 +612,6 @@ class Satellite(BaseSoC, RTMCommon):
|
|||
self.csr_devices.append("i2c")
|
||||
self.config["I2C_BUS_COUNT"] = 1
|
||||
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.drtio0.coarse_ts, self.ad9154_crg.jref)
|
||||
|
|
Loading…
Reference in New Issue