runtime: clock input specification improvements

closes #1735
pull/1773/head^2
Spaqin 2021-10-28 16:21:51 +08:00 committed by GitHub
parent 21b07dc667
commit 9b1d7e297d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 183 additions and 104 deletions

View File

@ -26,6 +26,8 @@ Highlights:
TTL device (e.g. ``"ttl_0_counter"`` for the edge counter on TTL device``"ttl_0"``)
* ``artiq_master`` now has an ``--experiment-subdir`` option to scan only a subdirectory of the
repository when building the list of experiments.
* The configuration entry ``rtio_clock`` supports multiple clocking settings, deprecating the usage
of compile-time options.
Breaking changes:

View File

@ -4,29 +4,66 @@ use board_artiq::si5324;
#[cfg(has_drtio)]
use board_misoc::{csr, clock};
#[derive(Debug)]
#[derive(Debug, PartialEq)]
#[allow(non_camel_case_types)]
pub enum RtioClock {
Internal = 0,
External = 1
Default,
Int_125,
Int_100,
Int_150,
Ext0_Bypass,
Ext0_Synth0_10to125,
Ext0_Synth0_100to125,
Ext0_Synth0_125to125,
}
#[allow(unreachable_code)]
fn get_rtio_clock_cfg() -> RtioClock {
config::read("rtio_clock", |result| {
match result {
Ok(b"i") => {
info!("using internal RTIO clock");
RtioClock::Internal
config::read_str("rtio_clock", |result| {
let res = match result {
Ok("int_125") => RtioClock::Int_125,
Ok("int_100") => RtioClock::Int_100,
Ok("int_150") => RtioClock::Int_150,
Ok("ext0_bypass") => RtioClock::Ext0_Bypass,
Ok("ext0_bypass_125") => RtioClock::Ext0_Bypass,
Ok("ext0_bypass_100") => RtioClock::Ext0_Bypass,
Ok("ext0_synth0_10to125") => RtioClock::Ext0_Synth0_10to125,
Ok("ext0_synth0_100to125") => RtioClock::Ext0_Synth0_100to125,
Ok("ext0_synth0_125to125") => RtioClock::Ext0_Synth0_125to125,
Ok("i") => {
warn!("Using legacy rtio_clock setting ('i'). Falling back to default. This will be deprecated.");
RtioClock::Default
},
Ok(b"e") => {
info!("using external RTIO clock");
RtioClock::External
Ok("e") => {
warn!("Using legacy rtio_clock setting ('e'). This will be deprecated.");
RtioClock::Ext0_Bypass
},
_ => {
info!("using internal RTIO clock (by default)");
RtioClock::Internal
},
warn!("rtio_clock setting not recognised. Falling back to default.");
RtioClock::Default
}
};
if res == RtioClock::Default {
#[cfg(any(si5324_ext_ref, ext_ref_frequency))]
warn!("si5324_ext_ref and ext_ref_frequency compile-time options are deprecated. Please use the rtio_clock coreconfig settings instead.");
#[cfg(all(rtio_frequency = "125.0", si5324_ext_ref, ext_ref_frequency = "10.0"))]
return RtioClock::Ext0_Synth0_10to125;
#[cfg(all(rtio_frequency = "125.0", si5324_ext_ref, ext_ref_frequency = "100.0"))]
return RtioClock::Ext0_Synth0_100to125;
#[cfg(all(rtio_frequency = "125.0", si5324_ext_ref, ext_ref_frequency = "125.0"))]
return RtioClock::Ext0_Synth0_125to125;
#[cfg(all(rtio_frequency = "125.0", not(si5324_ext_ref)))]
return RtioClock::Int_125;
#[cfg(all(rtio_frequency = "150.0", not(si5324_ext_ref)))]
return RtioClock::Int_150;
#[cfg(all(rtio_frequency = "100.0", not(si5324_ext_ref)))]
return RtioClock::Int_100;
//in case nothing is set
return RtioClock::Int_125;
}
})
res
})
}
#[cfg(has_rtio_crg)]
@ -41,9 +78,19 @@ pub mod crg {
#[cfg(has_rtio_clock_switch)]
pub fn init(clk: RtioClock) -> bool {
let clk_sel: u8 = match clk {
RtioClock::Ext0_Bypass => {
info!("Using external clock");
1
},
_ => {
info!("Using internal RTIO clock");
0
}
};
unsafe {
csr::rtio_crg::pll_reset_write(1);
csr::rtio_crg::clock_sel_write(clk as u8);
csr::rtio_crg::clock_sel_write(clk_sel);
csr::rtio_crg::pll_reset_write(0);
}
clock::spin_us(150);
@ -52,6 +99,7 @@ pub mod crg {
#[cfg(not(has_rtio_clock_switch))]
pub fn init() -> bool {
info!("Using internal RTIO clock");
unsafe {
csr::rtio_crg::pll_reset_write(0);
}
@ -66,84 +114,86 @@ pub mod crg {
}
#[cfg(si5324_as_synthesizer)]
fn setup_si5324_as_synthesizer() {
// 125 MHz output from 10 MHz CLKINx reference, 504 Hz BW
#[cfg(all(rtio_frequency = "125.0", si5324_ext_ref, ext_ref_frequency = "10.0"))]
const SI5324_SETTINGS: si5324::FrequencySettings
= si5324::FrequencySettings {
n1_hs : 10,
nc1_ls : 4,
n2_hs : 10,
n2_ls : 300,
n31 : 6,
n32 : 6,
bwsel : 4,
crystal_ref: false
};
// 125MHz output, from 100MHz CLKINx reference, 586 Hz loop bandwidth
#[cfg(all(rtio_frequency = "125.0", si5324_ext_ref, ext_ref_frequency = "100.0"))]
const SI5324_SETTINGS: si5324::FrequencySettings
= si5324::FrequencySettings {
n1_hs : 10,
nc1_ls : 4,
n2_hs : 10,
n2_ls : 260,
n31 : 52,
n32 : 52,
bwsel : 4,
crystal_ref: false
};
// 125MHz output, from 125MHz CLKINx reference, 606 Hz loop bandwidth
#[cfg(all(rtio_frequency = "125.0", si5324_ext_ref, ext_ref_frequency = "125.0"))]
const SI5324_SETTINGS: si5324::FrequencySettings
= si5324::FrequencySettings {
n1_hs : 5,
nc1_ls : 8,
n2_hs : 7,
n2_ls : 360,
n31 : 63,
n32 : 63,
bwsel : 4,
crystal_ref: false
};
// 125MHz output, from crystal, 7 Hz
#[cfg(all(rtio_frequency = "125.0", not(si5324_ext_ref)))]
const SI5324_SETTINGS: si5324::FrequencySettings
= si5324::FrequencySettings {
n1_hs : 10,
nc1_ls : 4,
n2_hs : 10,
n2_ls : 19972,
n31 : 4565,
n32 : 4565,
bwsel : 4,
crystal_ref: true
};
// 150MHz output, from crystal
#[cfg(all(rtio_frequency = "150.0", not(si5324_ext_ref)))]
const SI5324_SETTINGS: si5324::FrequencySettings
= si5324::FrequencySettings {
n1_hs : 9,
nc1_ls : 4,
n2_hs : 10,
n2_ls : 33732,
n31 : 7139,
n32 : 7139,
bwsel : 3,
crystal_ref: true
};
// 100MHz output, from crystal. Also used as reference for Sayma HMC830.
#[cfg(all(rtio_frequency = "100.0", not(si5324_ext_ref)))]
const SI5324_SETTINGS: si5324::FrequencySettings
= si5324::FrequencySettings {
n1_hs : 9,
nc1_ls : 6,
n2_hs : 10,
n2_ls : 33732,
n31 : 7139,
n32 : 7139,
bwsel : 3,
crystal_ref: true
fn setup_si5324_as_synthesizer(cfg: RtioClock) {
let si5324_settings = match cfg {
RtioClock::Ext0_Synth0_10to125 => { // 125 MHz output from 10 MHz CLKINx reference, 504 Hz BW
info!("using 10MHz reference to make 125MHz RTIO clock with PLL");
si5324::FrequencySettings {
n1_hs : 10,
nc1_ls : 4,
n2_hs : 10,
n2_ls : 300,
n31 : 6,
n32 : 6,
bwsel : 4,
crystal_ref: false
}
},
RtioClock::Ext0_Synth0_100to125 => { // 125MHz output, from 100MHz CLKINx reference, 586 Hz loop bandwidth
info!("using 10MHz reference to make 125MHz RTIO clock with PLL");
si5324::FrequencySettings {
n1_hs : 10,
nc1_ls : 4,
n2_hs : 10,
n2_ls : 260,
n31 : 52,
n32 : 52,
bwsel : 4,
crystal_ref: false
}
},
RtioClock::Ext0_Synth0_125to125 => { // 125MHz output, from 125MHz CLKINx reference, 606 Hz loop bandwidth
info!("using 10MHz reference to make 125MHz RTIO clock with PLL");
si5324::FrequencySettings {
n1_hs : 5,
nc1_ls : 8,
n2_hs : 7,
n2_ls : 360,
n31 : 63,
n32 : 63,
bwsel : 4,
crystal_ref: false
}
},
RtioClock::Int_150 => { // 150MHz output, from crystal
info!("using internal 150MHz RTIO clock");
si5324::FrequencySettings {
n1_hs : 9,
nc1_ls : 4,
n2_hs : 10,
n2_ls : 33732,
n31 : 7139,
n32 : 7139,
bwsel : 3,
crystal_ref: true
}
},
RtioClock::Int_100 => { // 100MHz output, from crystal. Also used as reference for Sayma HMC830.
info!("using internal 100MHz RTIO clock");
si5324::FrequencySettings {
n1_hs : 9,
nc1_ls : 6,
n2_hs : 10,
n2_ls : 33732,
n31 : 7139,
n32 : 7139,
bwsel : 3,
crystal_ref: true
}
},
_ => { // 125MHz output, from crystal, 7 Hz, default (if chosen option is not supported)
info!("using internal 125MHz RTIO clock"); // covers also RtioClock::Int_125
si5324::FrequencySettings {
n1_hs : 10,
nc1_ls : 4,
n2_hs : 10,
n2_ls : 19972,
n31 : 4565,
n32 : 4565,
bwsel : 4,
crystal_ref: true
}
}
};
#[cfg(all(soc_platform = "kasli", hw_rev = "v2.0", not(si5324_ext_ref)))]
let si5324_ref_input = si5324::Input::Ckin2;
@ -155,10 +205,11 @@ fn setup_si5324_as_synthesizer() {
let si5324_ref_input = si5324::Input::Ckin2;
#[cfg(soc_platform = "kc705")]
let si5324_ref_input = si5324::Input::Ckin2;
si5324::setup(&SI5324_SETTINGS, si5324_ref_input).expect("cannot initialize Si5324");
si5324::setup(&si5324_settings, si5324_ref_input).expect("cannot initialize Si5324");
}
pub fn init() {
let clock_cfg = get_rtio_clock_cfg();
#[cfg(si5324_as_synthesizer)]
{
#[cfg(all(soc_platform = "kasli", hw_rev = "v2.0"))]
@ -169,9 +220,12 @@ pub fn init() {
let si5324_ext_input = si5324::Input::Ckin2;
#[cfg(soc_platform = "kc705")]
let si5324_ext_input = si5324::Input::Ckin2;
match get_rtio_clock_cfg() {
RtioClock::Internal => setup_si5324_as_synthesizer(),
RtioClock::External => si5324::bypass(si5324_ext_input).expect("cannot bypass Si5324")
match clock_cfg {
RtioClock::Ext0_Bypass => {
info!("using external RTIO clock with PLL bypass");
si5324::bypass(si5324_ext_input).expect("cannot bypass Si5324")
},
_ => setup_si5324_as_synthesizer(clock_cfg),
}
}
@ -189,7 +243,7 @@ pub fn init() {
#[cfg(has_rtio_crg)]
{
#[cfg(has_rtio_clock_switch)]
let result = crg::init(get_rtio_clock_cfg());
let result = crg::init(clock_cfg);
#[cfg(not(has_rtio_clock_switch))]
let result = crg::init();
if !result {

View File

@ -164,6 +164,19 @@ See :mod:`artiq.coredevice.i2c` for more details.
Clocking
++++++++
The KC705 supports an internal 125 MHz RTIO clock (based on its crystal oscillator) and an external clock, that can be selected using the ``rtio_clock`` configuration entry. Valid values are ``i`` and ``e``, and the default is ``i``. The selected option can be observed in the core device boot logs.
The KC705 in standalone variants supports an internal 125 MHz RTIO clock (based on its crystal oscillator, or external reference for PLL for DRTIO variants) and an external clock, that can be selected using the ``rtio_clock`` configuration entry. Valid values are:
* ``int_125`` - internal crystal oscillator, 125 MHz output (default),
* ``ext0_bypass`` - external clock.
On Kasli, ``rtio_clock=i`` is the default and generates the RTIO clock using a PLL locked either to an internal crystal or to an external frequency reference (variant-dependent). ``rtio_clock=e`` bypasses that PLL and the user must supply the RTIO clock (typically 125 MHz) at the Kasli front panel SMA input. Bypassing the PLL ensures the skews between input clock, Kasli downstream clock outputs, and RTIO clock are deterministic accross reboots of the system. This is useful when phase determinism is required in situtations where the reference clock fans out to other devices before reaching Kasli.
KC705 in DRTIO variants and Kasli generates the RTIO clock using a PLL locked either to an internal crystal or to an external frequency reference. Valid values are:
* ``int_125`` - internal crystal oscillator using PLL, 125 MHz output (default),
* ``int_100`` - internal crystal oscillator using PLL, 100 MHz output,
* ``int_150`` - internal crystal oscillator using PLL, 150 MHz output,
* ``ext0_synth0_10to125`` - external 10 MHz reference using PLL, 125 MHz output,
* ``ext0_synth0_100to125`` - external 100 MHz reference using PLL, 125 MHz output,
* ``ext0_synth0_125to125`` - external 125 MHz reference using PLL, 125 MHz output,
* ``ext0_bypass``, ``ext0_bypass_125``, ``ext0_bypass_100`` - external clock - with explicit aliases available.
The selected option can be observed in the core device boot logs.
Options ``rtio_clock=int_XXX`` and ``rtio_clock=ext0_synth0_XXXXX`` generate the RTIO clock using a PLL locked either to an internal crystal or to an external frequency reference (depending on exact option). ``rtio_clock=ext0_bypass`` bypasses that PLL and the user must supply the RTIO clock (typically 125 MHz) at the Kasli front panel SMA input. Bypassing the PLL ensures the skews between input clock, Kasli downstream clock outputs, and RTIO clock are deterministic accross reboots of the system. This is useful when phase determinism is required in situtations where the reference clock fans out to other devices before reaching Kasli.

View File

@ -288,7 +288,17 @@ If you are using DRTIO and the default routing table (for a star topology) is no
* Select the RTIO clock source (KC705 and Kasli)
The KC705 may use either an external clock signal or its internal clock. The clock is selected at power-up. For Kasli, setting the RTIO clock source to "external" would bypass the Si5324 synthesiser, requiring that an input clock be present. To select the source, use one of these commands: ::
The KC705 may use either an external clock signal, or its internal clock with external frequency or internal crystal reference. The clock is selected at power-up. Setting the RTIO clock source to "ext0_bypass" would bypass the Si5324 synthesiser, requiring that an input clock be present. To select the source, use one of these commands: ::
$ artiq_coremgmt config write -s rtio_clock i # internal clock (default)
$ artiq_coremgmt config write -s rtio_clock e # external clock
$ artiq_coremgmt config write -s rtio_clock int_125 # internal 125MHz clock (default)
$ artiq_coremgmt config write -s rtio_clock ext0_bypass # external clock (bypass)
Other options include:
- ``ext0_synth0_10to125`` - external 10MHz reference clock used by Si5324 to synthesize a 125MHz RTIO clock,
- ``ext0_synth0_100to125`` - exteral 100MHz reference clock used by Si5324 to synthesize a 125MHz RTIO clock,
- ``ext0_synth0_125to125`` - exteral 125MHz reference clock used by Si5324 to synthesize a 125MHz RTIO clock,
- ``int_100`` - internal crystal reference is used by Si5324 to synthesize a 100MHz RTIO clock,
- ``int_150`` - internal crystal reference is used by Si5324 to synthesize a 150MHz RTIO clock.
- ``ext0_bypass_125`` and ``ext0_bypass_100`` - explicit aliases for ``ext0_bypass``.
Availability of these options depends on the board and their configuration - specific setting may or may not be supported.