sayma: support external RTM clocking

This commit is contained in:
Sebastien Bourdeauducq 2018-08-17 22:57:54 +08:00
parent 041dc0f64a
commit 167e97efd2
5 changed files with 44 additions and 16 deletions

View File

@ -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 });
}
}

View File

@ -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(())
}

View File

@ -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);

View File

@ -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();

View File

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