forked from M-Labs/artiq
sayma: move SYSREF DDMTD to RTM (#795)
This commit is contained in:
parent
8f608fa2fa
commit
ffd3172e02
|
@ -154,15 +154,15 @@ pub mod hmc7043 {
|
||||||
(true, DAC_CLK_DIV, 0x08, false), // 2: DAC0_CLK
|
(true, DAC_CLK_DIV, 0x08, false), // 2: DAC0_CLK
|
||||||
(true, SYSREF_DIV, 0x01, true), // 3: DAC0_SYSREF
|
(true, SYSREF_DIV, 0x01, true), // 3: DAC0_SYSREF
|
||||||
(true, SYSREF_DIV, 0x10, true), // 4: AMC_FPGA_SYSREF0
|
(true, SYSREF_DIV, 0x10, true), // 4: AMC_FPGA_SYSREF0
|
||||||
(true, FPGA_CLK_DIV, 0x10, true), // 5: AMC_FPGA_SYSREF1
|
(false, FPGA_CLK_DIV, 0x10, true), // 5: AMC_FPGA_SYSREF1
|
||||||
(false, 0, 0x10, false), // 6: unused
|
(false, 0, 0x10, false), // 6: unused
|
||||||
(true, SYSREF_DIV, 0x10, true), // 7: RTM_FPGA_SYSREF0
|
(true, FPGA_CLK_DIV, 0x10, true), // 7: RTM_FPGA_SYSREF0
|
||||||
(true, FPGA_CLK_DIV, 0x08, false), // 8: GTP_CLK0_IN
|
(true, FPGA_CLK_DIV, 0x08, false), // 8: GTP_CLK0_IN
|
||||||
(false, 0, 0x10, false), // 9: unused
|
(false, 0, 0x10, false), // 9: unused
|
||||||
(false, 0, 0x10, false), // 10: unused
|
(false, 0, 0x10, false), // 10: unused
|
||||||
(false, 0, 0x08, false), // 11: unused / uFL
|
(false, 0, 0x08, false), // 11: unused / uFL
|
||||||
(false, 0, 0x10, false), // 12: unused
|
(false, 0, 0x10, false), // 12: unused
|
||||||
(false, SYSREF_DIV, 0x10, true), // 13: RTM_FPGA_SYSREF1
|
(false, FPGA_CLK_DIV, 0x10, true), // 13: RTM_FPGA_SYSREF1
|
||||||
];
|
];
|
||||||
|
|
||||||
fn spi_setup() {
|
fn spi_setup() {
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
pub const INIT: u8 = 0x00;
|
||||||
|
pub const PRINT_STATUS: u8 = 0x01;
|
||||||
|
pub const PRBS: u8 = 0x02;
|
||||||
|
pub const STPL: u8 = 0x03;
|
||||||
|
|
||||||
|
pub const SYSREF_DELAY_DAC: u8 = 0x10;
|
||||||
|
pub const SYSREF_SLIP: u8 = 0x11;
|
||||||
|
pub const SYNC: u8 = 0x12;
|
||||||
|
|
||||||
|
pub const DDMTD_SYSREF_RAW: u8 = 0x20;
|
||||||
|
pub const DDMTD_SYSREF: u8 = 0x21;
|
||||||
|
|
||||||
|
|
||||||
|
fn average_2phases(a: i32, b: i32, modulo: i32) -> i32 {
|
||||||
|
let diff = ((a - b + modulo/2 + modulo) % modulo) - modulo/2;
|
||||||
|
return (modulo + b + diff/2) % modulo;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn average_phases(phases: &[i32], modulo: i32) -> i32 {
|
||||||
|
if phases.len() == 1 {
|
||||||
|
panic!("input array length must be a power of 2");
|
||||||
|
} else if phases.len() == 2 {
|
||||||
|
average_2phases(phases[0], phases[1], modulo)
|
||||||
|
} else {
|
||||||
|
let cut = phases.len()/2;
|
||||||
|
average_2phases(
|
||||||
|
average_phases(&phases[..cut], modulo),
|
||||||
|
average_phases(&phases[cut..], modulo),
|
||||||
|
modulo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const RAW_DDMTD_N_SHIFT: i32 = 6;
|
||||||
|
pub const RAW_DDMTD_N: i32 = 1 << RAW_DDMTD_N_SHIFT;
|
||||||
|
pub const DDMTD_DITHER_BITS: i32 = 1;
|
||||||
|
pub const DDMTD_N_SHIFT: i32 = RAW_DDMTD_N_SHIFT + DDMTD_DITHER_BITS;
|
||||||
|
pub const DDMTD_N: i32 = 1 << DDMTD_N_SHIFT;
|
||||||
|
|
||||||
|
#[cfg(has_ad9154)]
|
||||||
|
use board_misoc::{clock, csr};
|
||||||
|
|
||||||
|
#[cfg(has_ad9154)]
|
||||||
|
pub fn init_ddmtd() -> Result<(), &'static str> {
|
||||||
|
unsafe {
|
||||||
|
csr::sysref_ddmtd::reset_write(1);
|
||||||
|
clock::spin_us(1);
|
||||||
|
csr::sysref_ddmtd::reset_write(0);
|
||||||
|
clock::spin_us(100);
|
||||||
|
if csr::sysref_ddmtd::locked_read() != 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err("DDMTD helper PLL failed to lock")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(has_ad9154)]
|
||||||
|
pub fn measure_ddmdt_phase_raw() -> i32 {
|
||||||
|
unsafe { csr::sysref_ddmtd::dt_read() as i32 }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(has_ad9154)]
|
||||||
|
pub fn measure_ddmdt_phase() -> i32 {
|
||||||
|
const AVG_PRECISION_SHIFT: i32 = 6;
|
||||||
|
const AVG_PRECISION: i32 = 1 << AVG_PRECISION_SHIFT;
|
||||||
|
const AVG_MOD: i32 = 1 << (RAW_DDMTD_N_SHIFT + AVG_PRECISION_SHIFT + DDMTD_DITHER_BITS);
|
||||||
|
|
||||||
|
let mut measurements = [0; AVG_PRECISION as usize];
|
||||||
|
for i in 0..AVG_PRECISION {
|
||||||
|
measurements[i as usize] = measure_ddmdt_phase_raw() << (AVG_PRECISION_SHIFT + DDMTD_DITHER_BITS);
|
||||||
|
clock::spin_us(10);
|
||||||
|
}
|
||||||
|
average_phases(&measurements, AVG_MOD) >> AVG_PRECISION_SHIFT
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
pub const INIT: u8 = 0x00;
|
|
||||||
pub const PRINT_STATUS: u8 = 0x01;
|
|
||||||
pub const PRBS: u8 = 0x02;
|
|
||||||
pub const STPL: u8 = 0x03;
|
|
||||||
|
|
||||||
pub const SYSREF_DELAY_DAC: u8 = 0x10;
|
|
||||||
pub const SYSREF_SLIP: u8 = 0x11;
|
|
||||||
pub const SYNC: u8 = 0x12;
|
|
|
@ -51,7 +51,7 @@ pub mod jdac {
|
||||||
use board_artiq::drtioaux;
|
use board_artiq::drtioaux;
|
||||||
|
|
||||||
use super::jesd;
|
use super::jesd;
|
||||||
use super::super::jdac_requests;
|
use super::super::jdac_common;
|
||||||
|
|
||||||
pub fn basic_request(dacno: u8, reqno: u8, param: u8) -> Result<u8, &'static str> {
|
pub fn basic_request(dacno: u8, reqno: u8, param: u8) -> Result<u8, &'static str> {
|
||||||
if let Err(e) = drtioaux::send(1, &drtioaux::Packet::JdacBasicRequest {
|
if let Err(e) = drtioaux::send(1, &drtioaux::Packet::JdacBasicRequest {
|
||||||
|
@ -95,24 +95,24 @@ pub mod jdac {
|
||||||
return Err("JESD core PHY not done");
|
return Err("JESD core PHY not done");
|
||||||
}
|
}
|
||||||
|
|
||||||
basic_request(dacno, jdac_requests::INIT, 0)?;
|
basic_request(dacno, jdac_common::INIT, 0)?;
|
||||||
|
|
||||||
// JESD ready depends on JSYNC being valid, so DAC init needs to happen first
|
// JESD ready depends on JSYNC being valid, so DAC init needs to happen first
|
||||||
if !jesd::ready(dacno) {
|
if !jesd::ready(dacno) {
|
||||||
error!("JESD core reported not ready, sending DAC status print request");
|
error!("JESD core reported not ready, sending DAC status print request");
|
||||||
basic_request(dacno, jdac_requests::PRINT_STATUS, 0)?;
|
basic_request(dacno, jdac_common::PRINT_STATUS, 0)?;
|
||||||
return Err("JESD core reported not ready");
|
return Err("JESD core reported not ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
jesd::prbs(dacno, true);
|
jesd::prbs(dacno, true);
|
||||||
basic_request(dacno, jdac_requests::PRBS, 0)?;
|
basic_request(dacno, jdac_common::PRBS, 0)?;
|
||||||
jesd::prbs(dacno, false);
|
jesd::prbs(dacno, false);
|
||||||
|
|
||||||
jesd::stpl(dacno, true);
|
jesd::stpl(dacno, true);
|
||||||
basic_request(dacno, jdac_requests::STPL, 0)?;
|
basic_request(dacno, jdac_common::STPL, 0)?;
|
||||||
jesd::stpl(dacno, false);
|
jesd::stpl(dacno, false);
|
||||||
|
|
||||||
basic_request(dacno, jdac_requests::INIT, 0)?;
|
basic_request(dacno, jdac_common::INIT, 0)?;
|
||||||
clock::spin_us(5000);
|
clock::spin_us(5000);
|
||||||
|
|
||||||
if !jesd::jsync(dacno) {
|
if !jesd::jsync(dacno) {
|
||||||
|
@ -130,7 +130,7 @@ pub mod jesd204sync {
|
||||||
use board_misoc::{csr, clock, config};
|
use board_misoc::{csr, clock, config};
|
||||||
|
|
||||||
use super::jdac;
|
use super::jdac;
|
||||||
use super::super::jdac_requests;
|
use super::super::jdac_common;
|
||||||
|
|
||||||
const HMC7043_ANALOG_DELAY_RANGE: u8 = 24;
|
const HMC7043_ANALOG_DELAY_RANGE: u8 = 24;
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ pub mod jesd204sync {
|
||||||
const SYSREF_DIV: u16 = 256; // Keep in sync with hmc830_7043.rs
|
const SYSREF_DIV: u16 = 256; // Keep in sync with hmc830_7043.rs
|
||||||
|
|
||||||
fn hmc7043_sysref_delay_dac(dacno: u8, phase_offset: u8) -> Result<(), &'static str> {
|
fn hmc7043_sysref_delay_dac(dacno: u8, phase_offset: u8) -> Result<(), &'static str> {
|
||||||
match jdac::basic_request(dacno, jdac_requests::SYSREF_DELAY_DAC, phase_offset) {
|
match jdac::basic_request(dacno, jdac_common::SYSREF_DELAY_DAC, phase_offset) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(e) => Err(e)
|
Err(e) => Err(e)
|
||||||
}
|
}
|
||||||
|
@ -146,90 +146,43 @@ pub mod jesd204sync {
|
||||||
|
|
||||||
|
|
||||||
fn hmc7043_sysref_slip() -> Result<(), &'static str> {
|
fn hmc7043_sysref_slip() -> Result<(), &'static str> {
|
||||||
match jdac::basic_request(0, jdac_requests::SYSREF_SLIP, 0) {
|
match jdac::basic_request(0, jdac_common::SYSREF_SLIP, 0) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(e) => Err(e)
|
Err(e) => Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ad9154_sync(dacno: u8) -> Result<bool, &'static str> {
|
fn ad9154_sync(dacno: u8) -> Result<bool, &'static str> {
|
||||||
match jdac::basic_request(dacno, jdac_requests::SYNC, 0) {
|
match jdac::basic_request(dacno, jdac_common::SYNC, 0) {
|
||||||
Ok(0) => Ok(false),
|
Ok(0) => Ok(false),
|
||||||
Ok(_) => Ok(true),
|
Ok(_) => Ok(true),
|
||||||
Err(e) => Err(e)
|
Err(e) => Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn average_2phases(a: i32, b: i32, modulo: i32) -> i32 {
|
|
||||||
let diff = ((a - b + modulo/2 + modulo) % modulo) - modulo/2;
|
fn measure_ddmdt_phase_raw() -> Result<i32, &'static str> {
|
||||||
return (modulo + b + diff/2) % modulo;
|
Ok(jdac::basic_request(0, jdac_common::DDMTD_SYSREF_RAW, 0)? as i32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn average_phases(phases: &[i32], modulo: i32) -> i32 {
|
fn measure_ddmdt_phase() -> Result<i32, &'static str> {
|
||||||
if phases.len() == 1 {
|
Ok(jdac::basic_request(0, jdac_common::DDMTD_SYSREF, 0)? as i32)
|
||||||
panic!("input array length must be a power of 2");
|
|
||||||
} else if phases.len() == 2 {
|
|
||||||
average_2phases(phases[0], phases[1], modulo)
|
|
||||||
} else {
|
|
||||||
let cut = phases.len()/2;
|
|
||||||
average_2phases(
|
|
||||||
average_phases(&phases[..cut], modulo),
|
|
||||||
average_phases(&phases[cut..], modulo),
|
|
||||||
modulo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const RAW_DDMTD_N_SHIFT: i32 = 6;
|
|
||||||
const RAW_DDMTD_N: i32 = 1 << RAW_DDMTD_N_SHIFT;
|
|
||||||
const DDMTD_DITHER_BITS: i32 = 1;
|
|
||||||
const DDMTD_N_SHIFT: i32 = RAW_DDMTD_N_SHIFT + DDMTD_DITHER_BITS;
|
|
||||||
const DDMTD_N: i32 = 1 << DDMTD_N_SHIFT;
|
|
||||||
|
|
||||||
fn init_ddmtd() -> Result<(), &'static str> {
|
|
||||||
unsafe {
|
|
||||||
csr::sysref_ddmtd::reset_write(1);
|
|
||||||
clock::spin_us(1);
|
|
||||||
csr::sysref_ddmtd::reset_write(0);
|
|
||||||
clock::spin_us(100);
|
|
||||||
if csr::sysref_ddmtd::locked_read() != 0 {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err("DDMTD helper PLL failed to lock")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn measure_ddmdt_phase_raw() -> i32 {
|
|
||||||
unsafe { csr::sysref_ddmtd::dt_read() as i32 }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn measure_ddmdt_phase() -> i32 {
|
|
||||||
const AVG_PRECISION_SHIFT: i32 = 6;
|
|
||||||
const AVG_PRECISION: i32 = 1 << AVG_PRECISION_SHIFT;
|
|
||||||
const AVG_MOD: i32 = 1 << (RAW_DDMTD_N_SHIFT + AVG_PRECISION_SHIFT + DDMTD_DITHER_BITS);
|
|
||||||
|
|
||||||
let mut measurements = [0; AVG_PRECISION as usize];
|
|
||||||
for i in 0..AVG_PRECISION {
|
|
||||||
measurements[i as usize] = measure_ddmdt_phase_raw() << (AVG_PRECISION_SHIFT + DDMTD_DITHER_BITS);
|
|
||||||
clock::spin_us(10);
|
|
||||||
}
|
|
||||||
average_phases(&measurements, AVG_MOD) >> AVG_PRECISION_SHIFT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_ddmtd_stability(raw: bool, tolerance: i32) -> Result<(), &'static str> {
|
fn test_ddmtd_stability(raw: bool, tolerance: i32) -> Result<(), &'static str> {
|
||||||
info!("testing DDMTD stability (raw={}, tolerance={})...", raw, tolerance);
|
info!("testing DDMTD stability (raw={}, tolerance={})...", raw, tolerance);
|
||||||
|
|
||||||
let modulo = if raw { RAW_DDMTD_N } else { DDMTD_N };
|
let modulo = if raw { jdac_common::RAW_DDMTD_N } else { jdac_common::DDMTD_N };
|
||||||
let measurement = if raw { measure_ddmdt_phase_raw } else { measure_ddmdt_phase };
|
let measurement = if raw { measure_ddmdt_phase_raw } else { measure_ddmdt_phase };
|
||||||
let ntests = if raw { 15000 } else { 150 };
|
let ntests = if raw { 150 } else { 15 };
|
||||||
|
|
||||||
let mut max_pkpk = 0;
|
let mut max_pkpk = 0;
|
||||||
for _ in 0..32 {
|
for _ in 0..32 {
|
||||||
// If we are near the edges, wraparound can throw off the simple min/max computation.
|
// If we are near the edges, wraparound can throw off the simple min/max computation.
|
||||||
// In this case, add an offset to get near the center.
|
// In this case, add an offset to get near the center.
|
||||||
let quadrant = measure_ddmdt_phase();
|
let quadrant = measure_ddmdt_phase()?;
|
||||||
let center_offset =
|
let center_offset =
|
||||||
if quadrant < DDMTD_N/4 || quadrant > 3*DDMTD_N/4 {
|
if quadrant < jdac_common::DDMTD_N/4 || quadrant > 3*jdac_common::DDMTD_N/4 {
|
||||||
modulo/2
|
modulo/2
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
|
@ -238,7 +191,7 @@ pub mod jesd204sync {
|
||||||
let mut min = modulo;
|
let mut min = modulo;
|
||||||
let mut max = 0;
|
let mut max = 0;
|
||||||
for _ in 0..ntests {
|
for _ in 0..ntests {
|
||||||
let m = (measurement() + center_offset) % modulo;
|
let m = (measurement()? + center_offset) % modulo;
|
||||||
if m < min {
|
if m < min {
|
||||||
min = m;
|
min = m;
|
||||||
}
|
}
|
||||||
|
@ -268,11 +221,11 @@ pub mod jesd204sync {
|
||||||
let tolerance = 1;
|
let tolerance = 1;
|
||||||
|
|
||||||
info!("testing HMC7043 SYSREF slip against DDMTD...");
|
info!("testing HMC7043 SYSREF slip against DDMTD...");
|
||||||
let mut old_phase = measure_ddmdt_phase();
|
let mut old_phase = measure_ddmdt_phase()?;
|
||||||
for _ in 0..1024 {
|
for _ in 0..1024 {
|
||||||
hmc7043_sysref_slip();
|
hmc7043_sysref_slip();
|
||||||
let phase = measure_ddmdt_phase();
|
let phase = measure_ddmdt_phase()?;
|
||||||
let step = (DDMTD_N + old_phase - phase) % DDMTD_N;
|
let step = (jdac_common::DDMTD_N + old_phase - phase) % jdac_common::DDMTD_N;
|
||||||
if (step - expected_step).abs() > tolerance {
|
if (step - expected_step).abs() > tolerance {
|
||||||
error!(" ...got unexpected step: {} ({} -> {})", step, old_phase, phase);
|
error!(" ...got unexpected step: {} ({} -> {})", step, old_phase, phase);
|
||||||
return Err("HMC7043 SYSREF slip produced unexpected DDMTD step");
|
return Err("HMC7043 SYSREF slip produced unexpected DDMTD step");
|
||||||
|
@ -295,7 +248,7 @@ pub mod jesd204sync {
|
||||||
|
|
||||||
const SYSREF_SH_PRECISION_SHIFT: i32 = 5;
|
const SYSREF_SH_PRECISION_SHIFT: i32 = 5;
|
||||||
const SYSREF_SH_PRECISION: i32 = 1 << SYSREF_SH_PRECISION_SHIFT;
|
const SYSREF_SH_PRECISION: i32 = 1 << SYSREF_SH_PRECISION_SHIFT;
|
||||||
const SYSREF_SH_MOD: i32 = 1 << (DDMTD_N_SHIFT + SYSREF_SH_PRECISION_SHIFT);
|
const SYSREF_SH_MOD: i32 = 1 << (jdac_common::DDMTD_N_SHIFT + SYSREF_SH_PRECISION_SHIFT);
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct SysrefShLimits {
|
struct SysrefShLimits {
|
||||||
|
@ -318,7 +271,7 @@ pub mod jesd204sync {
|
||||||
}
|
}
|
||||||
|
|
||||||
let current = sysref_sh_error();
|
let current = sysref_sh_error();
|
||||||
let phase = measure_ddmdt_phase();
|
let phase = measure_ddmdt_phase()?;
|
||||||
if current && !previous && rising_n < SYSREF_SH_PRECISION {
|
if current && !previous && rising_n < SYSREF_SH_PRECISION {
|
||||||
ret.rising_phases[rising_n as usize] = phase << SYSREF_SH_PRECISION_SHIFT;
|
ret.rising_phases[rising_n as usize] = phase << SYSREF_SH_PRECISION_SHIFT;
|
||||||
rising_n += 1;
|
rising_n += 1;
|
||||||
|
@ -335,7 +288,7 @@ pub mod jesd204sync {
|
||||||
fn max_phase_deviation(average: i32, phases: &[i32]) -> i32 {
|
fn max_phase_deviation(average: i32, phases: &[i32]) -> i32 {
|
||||||
let mut ret = 0;
|
let mut ret = 0;
|
||||||
for phase in phases.iter() {
|
for phase in phases.iter() {
|
||||||
let deviation = (phase - average + DDMTD_N) % DDMTD_N;
|
let deviation = (phase - average + jdac_common::DDMTD_N) % jdac_common::DDMTD_N;
|
||||||
if deviation > ret {
|
if deviation > ret {
|
||||||
ret = deviation;
|
ret = deviation;
|
||||||
}
|
}
|
||||||
|
@ -345,7 +298,7 @@ pub mod jesd204sync {
|
||||||
|
|
||||||
fn reach_sysref_ddmtd_target(target: i32, tolerance: i32) -> Result<i32, &'static str> {
|
fn reach_sysref_ddmtd_target(target: i32, tolerance: i32) -> Result<i32, &'static str> {
|
||||||
for _ in 0..1024 {
|
for _ in 0..1024 {
|
||||||
let delta = (measure_ddmdt_phase() - target + DDMTD_N) % DDMTD_N;
|
let delta = (measure_ddmdt_phase()? - target + jdac_common::DDMTD_N) % jdac_common::DDMTD_N;
|
||||||
if delta <= tolerance {
|
if delta <= tolerance {
|
||||||
return Ok(delta)
|
return Ok(delta)
|
||||||
}
|
}
|
||||||
|
@ -360,11 +313,11 @@ pub mod jesd204sync {
|
||||||
if rising_average < falling_average {
|
if rising_average < falling_average {
|
||||||
(rising_average + falling_average)/2
|
(rising_average + falling_average)/2
|
||||||
} else {
|
} else {
|
||||||
((falling_average - (DDMTD_N - rising_average))/2 + DDMTD_N) % DDMTD_N
|
((falling_average - (jdac_common::DDMTD_N - rising_average))/2 + jdac_common::DDMTD_N) % jdac_common::DDMTD_N
|
||||||
};
|
};
|
||||||
info!(" SYSREF calibration coarse target: {}", coarse_target);
|
info!(" SYSREF calibration coarse target: {}", coarse_target);
|
||||||
reach_sysref_ddmtd_target(coarse_target, 8)?;
|
reach_sysref_ddmtd_target(coarse_target, 8)?;
|
||||||
let target = measure_ddmdt_phase();
|
let target = measure_ddmdt_phase()?;
|
||||||
info!(" ...done, target={}", target);
|
info!(" ...done, target={}", target);
|
||||||
Ok(target)
|
Ok(target)
|
||||||
}
|
}
|
||||||
|
@ -447,15 +400,14 @@ pub mod jesd204sync {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sysref_auto_rtio_align() -> Result<(), &'static str> {
|
pub fn sysref_auto_rtio_align() -> Result<(), &'static str> {
|
||||||
init_ddmtd()?;
|
|
||||||
test_ddmtd_stability(true, 4)?;
|
test_ddmtd_stability(true, 4)?;
|
||||||
test_ddmtd_stability(false, 1)?;
|
test_ddmtd_stability(false, 1)?;
|
||||||
test_slip_ddmtd()?;
|
test_slip_ddmtd()?;
|
||||||
|
|
||||||
info!("determining SYSREF S/H limits...");
|
info!("determining SYSREF S/H limits...");
|
||||||
let sysref_sh_limits = measure_sysref_sh_limits()?;
|
let sysref_sh_limits = measure_sysref_sh_limits()?;
|
||||||
let rising_average = average_phases(&sysref_sh_limits.rising_phases, SYSREF_SH_MOD);
|
let rising_average = jdac_common::average_phases(&sysref_sh_limits.rising_phases, SYSREF_SH_MOD);
|
||||||
let falling_average = average_phases(&sysref_sh_limits.falling_phases, SYSREF_SH_MOD);
|
let falling_average = jdac_common::average_phases(&sysref_sh_limits.falling_phases, SYSREF_SH_MOD);
|
||||||
let rising_max_deviation = max_phase_deviation(rising_average, &sysref_sh_limits.rising_phases);
|
let rising_max_deviation = max_phase_deviation(rising_average, &sysref_sh_limits.rising_phases);
|
||||||
let falling_max_deviation = max_phase_deviation(falling_average, &sysref_sh_limits.falling_phases);
|
let falling_max_deviation = max_phase_deviation(falling_average, &sysref_sh_limits.falling_phases);
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ mod repeater;
|
||||||
#[cfg(has_jdcg)]
|
#[cfg(has_jdcg)]
|
||||||
mod jdcg;
|
mod jdcg;
|
||||||
#[cfg(any(has_ad9154, has_jdcg))]
|
#[cfg(any(has_ad9154, has_jdcg))]
|
||||||
pub mod jdac_requests;
|
pub mod jdac_common;
|
||||||
|
|
||||||
fn drtiosat_reset(reset: bool) {
|
fn drtiosat_reset(reset: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -306,13 +306,13 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
#[cfg(rtio_frequency = "150.0")]
|
#[cfg(rtio_frequency = "150.0")]
|
||||||
const LINERATE: u64 = 6_000_000_000;
|
const LINERATE: u64 = 6_000_000_000;
|
||||||
match _reqno {
|
match _reqno {
|
||||||
jdac_requests::INIT => (board_artiq::ad9154::setup(_dacno, LINERATE).is_ok(), 0),
|
jdac_common::INIT => (board_artiq::ad9154::setup(_dacno, LINERATE).is_ok(), 0),
|
||||||
jdac_requests::PRINT_STATUS => { board_artiq::ad9154::status(_dacno); (true, 0) },
|
jdac_common::PRINT_STATUS => { board_artiq::ad9154::status(_dacno); (true, 0) },
|
||||||
jdac_requests::PRBS => (board_artiq::ad9154::prbs(_dacno).is_ok(), 0),
|
jdac_common::PRBS => (board_artiq::ad9154::prbs(_dacno).is_ok(), 0),
|
||||||
jdac_requests::STPL => (board_artiq::ad9154::stpl(_dacno, 4, 2).is_ok(), 0),
|
jdac_common::STPL => (board_artiq::ad9154::stpl(_dacno, 4, 2).is_ok(), 0),
|
||||||
jdac_requests::SYSREF_DELAY_DAC => { board_artiq::hmc830_7043::hmc7043::sysref_delay_dac(_dacno, _param); (true, 0) },
|
jdac_common::SYSREF_DELAY_DAC => { board_artiq::hmc830_7043::hmc7043::sysref_delay_dac(_dacno, _param); (true, 0) },
|
||||||
jdac_requests::SYSREF_SLIP => { board_artiq::hmc830_7043::hmc7043::sysref_slip(); (true, 0) },
|
jdac_common::SYSREF_SLIP => { board_artiq::hmc830_7043::hmc7043::sysref_slip(); (true, 0) },
|
||||||
jdac_requests::SYNC => {
|
jdac_common::SYNC => {
|
||||||
match board_artiq::ad9154::sync(_dacno) {
|
match board_artiq::ad9154::sync(_dacno) {
|
||||||
Ok(false) => (true, 0),
|
Ok(false) => (true, 0),
|
||||||
Ok(true) => (true, 1),
|
Ok(true) => (true, 1),
|
||||||
|
@ -321,7 +321,9 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
(false, 0)
|
(false, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
jdac_common::DDMTD_SYSREF_RAW => (true, jdac_common::measure_ddmdt_phase_raw() as u8),
|
||||||
|
jdac_common::DDMTD_SYSREF => (true, jdac_common::measure_ddmdt_phase() as u8),
|
||||||
_ => (false, 0)
|
_ => (false, 0)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -472,6 +474,7 @@ pub extern fn main() -> i32 {
|
||||||
hmc830_7043::init().expect("cannot initialize HMC830/7043");
|
hmc830_7043::init().expect("cannot initialize HMC830/7043");
|
||||||
#[cfg(has_ad9154)]
|
#[cfg(has_ad9154)]
|
||||||
{
|
{
|
||||||
|
jdac_common::init_ddmtd().expect("failed to initialize SYSREF DDMTD core");
|
||||||
for dacno in 0..csr::CONFIG_AD9154_COUNT {
|
for dacno in 0..csr::CONFIG_AD9154_COUNT {
|
||||||
board_artiq::ad9154::reset_and_detect(dacno as u8).expect("AD9154 DAC not detected");
|
board_artiq::ad9154::reset_and_detect(dacno as u8).expect("AD9154 DAC not detected");
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,12 +311,6 @@ class Satellite(SatelliteBase):
|
||||||
self.jdcg_0.jesd.core.register_jref(self.sysref_sampler.jref)
|
self.jdcg_0.jesd.core.register_jref(self.sysref_sampler.jref)
|
||||||
self.jdcg_1.jesd.core.register_jref(self.sysref_sampler.jref)
|
self.jdcg_1.jesd.core.register_jref(self.sysref_sampler.jref)
|
||||||
|
|
||||||
# DDMTD
|
|
||||||
# https://github.com/sinara-hw/Sayma_RTM/issues/68
|
|
||||||
sysref_pads = platform.request("amc_fpga_sysref", 1)
|
|
||||||
self.submodules.sysref_ddmtd = jesd204_tools.DDMTD(sysref_pads, self.rtio_clk_freq)
|
|
||||||
self.csr_devices.append("sysref_ddmtd")
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleSatellite(SatelliteBase):
|
class SimpleSatellite(SatelliteBase):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
|
|
@ -16,6 +16,7 @@ from misoc.targets.sayma_rtm import BaseSoC, soc_sayma_rtm_args, soc_sayma_rtm_a
|
||||||
from misoc.integration.builder import Builder, builder_args, builder_argdict
|
from misoc.integration.builder import Builder, builder_args, builder_argdict
|
||||||
|
|
||||||
from artiq.gateware import rtio
|
from artiq.gateware import rtio
|
||||||
|
from artiq.gateware import jesd204_tools
|
||||||
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series
|
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series
|
||||||
from artiq.gateware.drtio.transceiver import gtp_7series
|
from artiq.gateware.drtio.transceiver import gtp_7series
|
||||||
from artiq.gateware.drtio.siphaser import SiPhaser7Series
|
from artiq.gateware.drtio.siphaser import SiPhaser7Series
|
||||||
|
@ -257,6 +258,15 @@ class Satellite(_SatelliteBase):
|
||||||
platform.request("hmc7043_out_en"))
|
platform.request("hmc7043_out_en"))
|
||||||
self.csr_devices.append("hmc7043_out_en")
|
self.csr_devices.append("hmc7043_out_en")
|
||||||
|
|
||||||
|
# DDMTD
|
||||||
|
sysref_pads = platform.request("rtm_fpga_sysref", 0)
|
||||||
|
self.submodules.sysref_ddmtd = jesd204_tools.DDMTD(sysref_pads, self.rtio_clk_freq)
|
||||||
|
self.csr_devices.append("sysref_ddmtd")
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.sysref_ddmtd.cd_helper.clk, self.drtio_transceiver.gtps[0].txoutclk)
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.sysref_ddmtd.cd_helper.clk, self.crg.cd_sys.clk)
|
||||||
|
|
||||||
|
|
||||||
class SatmanSoCBuilder(Builder):
|
class SatmanSoCBuilder(Builder):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
Loading…
Reference in New Issue