forked from M-Labs/artiq
sayma: 2.4GHz DAC clocking (4X interpolation)
* gets another clock divider out of the way * gets one cycle within range of the HMC7043 analog delay alone * SYSREF/RTIO alignment removed, to be replaced with DDMTD-based scheme
This commit is contained in:
parent
cc9420d2c8
commit
4941fb3300
|
@ -184,7 +184,7 @@ fn dac_setup(dacno: u8, linerate: u64) -> Result<(), &'static str> {
|
||||||
|
|
||||||
write(ad9154_reg::SPI_PAGEINDX, 0x3); // A and B dual
|
write(ad9154_reg::SPI_PAGEINDX, 0x3); // A and B dual
|
||||||
|
|
||||||
write(ad9154_reg::INTERP_MODE, 0x01); // 2x
|
write(ad9154_reg::INTERP_MODE, 0x03); // 4x
|
||||||
write(ad9154_reg::MIX_MODE, 0);
|
write(ad9154_reg::MIX_MODE, 0);
|
||||||
write(ad9154_reg::DATA_FORMAT, 0*ad9154_reg::BINARY_FORMAT); // s16
|
write(ad9154_reg::DATA_FORMAT, 0*ad9154_reg::BINARY_FORMAT); // s16
|
||||||
write(ad9154_reg::DATAPATH_CTRL,
|
write(ad9154_reg::DATAPATH_CTRL,
|
||||||
|
|
|
@ -117,6 +117,9 @@ mod hmc830 {
|
||||||
// Max reference frequency: 350MHz, however f_ref >= 200MHz requires
|
// Max reference frequency: 350MHz, however f_ref >= 200MHz requires
|
||||||
// setting 0x08[21]=1
|
// setting 0x08[21]=1
|
||||||
//
|
//
|
||||||
|
// Warning: Output divider is not synchronized! Set to 1 for deterministic
|
||||||
|
// phase at the output.
|
||||||
|
//
|
||||||
// :param r_div: reference divider [1, 16383]
|
// :param r_div: reference divider [1, 16383]
|
||||||
// :param n_div: VCO divider, integer part. Integer-N mode: [16, 2**19-1]
|
// :param n_div: VCO divider, integer part. Integer-N mode: [16, 2**19-1]
|
||||||
// fractional mode: [20, 2**19-4]
|
// fractional mode: [20, 2**19-4]
|
||||||
|
@ -155,10 +158,11 @@ mod hmc830 {
|
||||||
pub mod hmc7043 {
|
pub mod hmc7043 {
|
||||||
use board_misoc::{csr, clock};
|
use board_misoc::{csr, clock};
|
||||||
|
|
||||||
// All frequencies assume 1.2GHz HMC830 output
|
// Warning: dividers are not synchronized with HMC830 clock input!
|
||||||
pub const DAC_CLK_DIV: u16 = 1; // 1200MHz
|
// Set DAC_CLK_DIV to 1 for deterministic phase.
|
||||||
pub const FPGA_CLK_DIV: u16 = 8; // 150MHz
|
pub const DAC_CLK_DIV: u16 = 1; // 2400MHz
|
||||||
pub const SYSREF_DIV: u16 = 128; // 9.375MHz
|
pub const FPGA_CLK_DIV: u16 = 16; // 150MHz
|
||||||
|
pub const SYSREF_DIV: u16 = 256; // 9.375MHz
|
||||||
const HMC_SYSREF_DIV: u16 = SYSREF_DIV*8; // 1.171875MHz (must be <= 4MHz)
|
const HMC_SYSREF_DIV: u16 = SYSREF_DIV*8; // 1.171875MHz (must be <= 4MHz)
|
||||||
|
|
||||||
// enabled, divider, output config
|
// enabled, divider, output config
|
||||||
|
@ -385,35 +389,18 @@ pub mod hmc7043 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sysref_offset_dac(dacno: u8, phase_offset: u16) {
|
pub fn sysref_offset_dac(dacno: u8, phase_offset: u8) {
|
||||||
/* Analog delay resolution: 25ps
|
|
||||||
* Digital delay resolution: 1/2 input clock cycle = 416ps for 1.2GHz
|
|
||||||
* 16*25ps = 400ps: limit analog delay to 16 steps instead of 32.
|
|
||||||
*/
|
|
||||||
let analog_delay = (phase_offset % 17) as u8;
|
|
||||||
let digital_delay = (phase_offset / 17) as u8;
|
|
||||||
spi_setup();
|
spi_setup();
|
||||||
if dacno == 0 {
|
if dacno == 0 {
|
||||||
write(0x00d5, analog_delay);
|
write(0x00d5, phase_offset);
|
||||||
write(0x00d6, digital_delay);
|
|
||||||
} else if dacno == 1 {
|
} else if dacno == 1 {
|
||||||
write(0x00e9, analog_delay);
|
write(0x00e9, phase_offset);
|
||||||
write(0x00ea, digital_delay);
|
|
||||||
} else {
|
} else {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
clock::spin_us(100);
|
clock::spin_us(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sysref_offset_fpga(phase_offset: u16) {
|
|
||||||
let analog_delay = (phase_offset % 17) as u8;
|
|
||||||
let digital_delay = (phase_offset / 17) as u8;
|
|
||||||
spi_setup();
|
|
||||||
write(0x0111, analog_delay);
|
|
||||||
write(0x0112, digital_delay);
|
|
||||||
clock::spin_us(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sysref_slip() {
|
pub fn sysref_slip() {
|
||||||
spi_setup();
|
spi_setup();
|
||||||
write(0x0002, 0x02);
|
write(0x0002, 0x02);
|
||||||
|
@ -429,11 +416,11 @@ pub fn init() -> Result<(), &'static str> {
|
||||||
hmc830::detect()?;
|
hmc830::detect()?;
|
||||||
hmc830::init();
|
hmc830::init();
|
||||||
|
|
||||||
// 1.2GHz out
|
// 2.4GHz out
|
||||||
#[cfg(hmc830_ref = "100")]
|
#[cfg(hmc830_ref = "100")]
|
||||||
hmc830::set_dividers(1, 24, 0, 2);
|
hmc830::set_dividers(1, 24, 0, 1);
|
||||||
#[cfg(hmc830_ref = "150")]
|
#[cfg(hmc830_ref = "150")]
|
||||||
hmc830::set_dividers(2, 32, 0, 2);
|
hmc830::set_dividers(2, 32, 0, 1);
|
||||||
|
|
||||||
hmc830::check_locked()?;
|
hmc830::check_locked()?;
|
||||||
|
|
||||||
|
|
|
@ -3,167 +3,7 @@ use board_misoc::{csr, config};
|
||||||
use hmc830_7043::hmc7043;
|
use hmc830_7043::hmc7043;
|
||||||
use ad9154;
|
use ad9154;
|
||||||
|
|
||||||
fn sysref_sample() -> bool {
|
fn sysref_cal_dac(dacno: u8) -> Result<u8, &'static str> {
|
||||||
unsafe { csr::sysref_sampler::sample_result_read() == 1 }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
enum SysrefSample {
|
|
||||||
Low,
|
|
||||||
High,
|
|
||||||
Unstable
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sysref_sample_stable(phase_offset: u16) -> SysrefSample {
|
|
||||||
hmc7043::sysref_offset_fpga(phase_offset);
|
|
||||||
let s1 = sysref_sample();
|
|
||||||
hmc7043::sysref_offset_fpga(phase_offset-5);
|
|
||||||
let s2 = sysref_sample();
|
|
||||||
if s1 == s2 {
|
|
||||||
if s1 {
|
|
||||||
return SysrefSample::High;
|
|
||||||
} else {
|
|
||||||
return SysrefSample::Low;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return SysrefSample::Unstable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sysref_cal_fpga() -> Result<u16, &'static str> {
|
|
||||||
info!("calibrating SYSREF phase offset at FPGA...");
|
|
||||||
|
|
||||||
let initial_phase_offset = 136;
|
|
||||||
|
|
||||||
let mut slips0 = 0;
|
|
||||||
let mut slips1 = 0;
|
|
||||||
// make sure we start in the 0 zone
|
|
||||||
while sysref_sample_stable(initial_phase_offset) != SysrefSample::Low {
|
|
||||||
hmc7043::sysref_slip();
|
|
||||||
slips0 += 1;
|
|
||||||
if slips0 > 1024 {
|
|
||||||
return Err("failed to reach 1->0 transition (cal)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get near the edge of the 0->1 transition
|
|
||||||
while sysref_sample_stable(initial_phase_offset) != SysrefSample::High {
|
|
||||||
hmc7043::sysref_slip();
|
|
||||||
slips1 += 1;
|
|
||||||
if slips1 > 1024 {
|
|
||||||
return Err("failed to reach 0->1 transition (cal)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for d in 0..initial_phase_offset {
|
|
||||||
let phase_offset = initial_phase_offset - d;
|
|
||||||
hmc7043::sysref_offset_fpga(phase_offset);
|
|
||||||
if !sysref_sample() {
|
|
||||||
let result = phase_offset + 17;
|
|
||||||
info!(" ...done, phase offset: {}", result);
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Err("failed to reach 1->0 transition with fine delay");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sysref_rtio_slip_to(target: bool) -> Result<u16, &'static str> {
|
|
||||||
let mut slips = 0;
|
|
||||||
while sysref_sample() != target {
|
|
||||||
hmc7043::sysref_slip();
|
|
||||||
slips += 1;
|
|
||||||
if slips > 1024 {
|
|
||||||
return Err("failed to reach SYSREF transition");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(slips)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sysref_rtio_check_period(phase_offset: u16) -> Result<(), &'static str> {
|
|
||||||
const N: usize = 32;
|
|
||||||
let mut nslips = [0; N];
|
|
||||||
let mut error = false;
|
|
||||||
|
|
||||||
// meet setup/hold (assuming FPGA timing margins are OK)
|
|
||||||
hmc7043::sysref_offset_fpga(phase_offset);
|
|
||||||
// if we are already in the 1 zone, get out of it
|
|
||||||
sysref_rtio_slip_to(false)?;
|
|
||||||
for i in 0..N {
|
|
||||||
nslips[i] = sysref_rtio_slip_to(i % 2 == 0)?;
|
|
||||||
if nslips[i] != hmc7043::SYSREF_DIV/2 {
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if error {
|
|
||||||
info!(" SYSREF slip half-periods: {:?}", nslips);
|
|
||||||
return Err("unexpected SYSREF slip half-periods seen");
|
|
||||||
} else {
|
|
||||||
info!(" SYSREF slip half-periods at FPGA have expected length ({})", hmc7043::SYSREF_DIV/2);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sysref_rtio_align(phase_offset: u16) -> Result<(), &'static str> {
|
|
||||||
// This needs to take place before DAC SYSREF scan, as
|
|
||||||
// the HMC7043 input clock (which defines slip resolution)
|
|
||||||
// is 2x the DAC clock, so there are two possible phases from
|
|
||||||
// the divider states. This deterministically selects one.
|
|
||||||
|
|
||||||
info!("aligning SYSREF with RTIO...");
|
|
||||||
|
|
||||||
sysref_rtio_check_period(phase_offset)?;
|
|
||||||
|
|
||||||
// meet setup/hold (assuming FPGA timing margins are OK)
|
|
||||||
hmc7043::sysref_offset_fpga(phase_offset);
|
|
||||||
// if we are already in the 1 zone, get out of it
|
|
||||||
let slips0 = sysref_rtio_slip_to(false)?;
|
|
||||||
// get to the edge of the 0->1 transition (our final setpoint)
|
|
||||||
let slips1 = sysref_rtio_slip_to(true)?;
|
|
||||||
info!(" ...done ({}/{} slips)", slips0, slips1);
|
|
||||||
|
|
||||||
let mut margin_minus = None;
|
|
||||||
for d in 0..phase_offset {
|
|
||||||
hmc7043::sysref_offset_fpga(phase_offset - d);
|
|
||||||
if !sysref_sample() {
|
|
||||||
margin_minus = Some(d);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// meet setup/hold
|
|
||||||
hmc7043::sysref_offset_fpga(phase_offset);
|
|
||||||
|
|
||||||
if margin_minus.is_some() {
|
|
||||||
let margin_minus = margin_minus.unwrap();
|
|
||||||
// one phase slip (period of the 1.2GHz input clock)
|
|
||||||
let period = 2*17; // approximate: 2 digital coarse delay steps
|
|
||||||
let margin_plus = if period > margin_minus { period - margin_minus } else { 0 };
|
|
||||||
info!(" margins at FPGA: -{} +{}", margin_minus, margin_plus);
|
|
||||||
if margin_minus < 10 || margin_plus < 10 {
|
|
||||||
return Err("SYSREF margin at FPGA is too small, board needs recalibration");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Err("unable to determine SYSREF margin at FPGA");
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sysref_auto_rtio_align() -> Result<(), &'static str> {
|
|
||||||
let entry = config::read_str("sysref_phase_fpga", |r| r.map(|s| s.parse()));
|
|
||||||
let phase_offset = match entry {
|
|
||||||
Ok(Ok(phase)) => phase,
|
|
||||||
_ => {
|
|
||||||
let phase = sysref_cal_fpga()?;
|
|
||||||
if let Err(e) = config::write_int("sysref_phase_fpga", phase as u32) {
|
|
||||||
error!("failed to update FPGA SYSREF phase in config: {}", e);
|
|
||||||
}
|
|
||||||
phase
|
|
||||||
}
|
|
||||||
};
|
|
||||||
sysref_rtio_align(phase_offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sysref_cal_dac(dacno: u8) -> Result<u16, &'static str> {
|
|
||||||
info!("calibrating SYSREF phase at DAC-{}...", dacno);
|
info!("calibrating SYSREF phase at DAC-{}...", dacno);
|
||||||
|
|
||||||
let mut d = 0;
|
let mut d = 0;
|
||||||
|
@ -182,12 +22,12 @@ fn sysref_cal_dac(dacno: u8) -> Result<u16, &'static str> {
|
||||||
}
|
}
|
||||||
|
|
||||||
d += 1;
|
d += 1;
|
||||||
if d > 128 {
|
if d > 23 {
|
||||||
return Err("no sync errors found when scanning delay");
|
return Err("no sync errors found when scanning delay");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d += 17; // get away from jitter
|
d += 5; // get away from jitter
|
||||||
hmc7043::sysref_offset_dac(dacno, d);
|
hmc7043::sysref_offset_dac(dacno, d);
|
||||||
ad9154::dac_sync(dacno)?;
|
ad9154::dac_sync(dacno)?;
|
||||||
|
|
||||||
|
@ -200,7 +40,7 @@ fn sysref_cal_dac(dacno: u8) -> Result<u16, &'static str> {
|
||||||
}
|
}
|
||||||
|
|
||||||
d += 1;
|
d += 1;
|
||||||
if d > 128 {
|
if d > 23 {
|
||||||
return Err("no sync errors found when scanning delay");
|
return Err("no sync errors found when scanning delay");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,7 +50,7 @@ fn sysref_cal_dac(dacno: u8) -> Result<u16, &'static str> {
|
||||||
Ok(phase)
|
Ok(phase)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sysref_dac_align(dacno: u8, phase: u16) -> Result<(), &'static str> {
|
fn sysref_dac_align(dacno: u8, phase: u8) -> Result<(), &'static str> {
|
||||||
let mut margin_minus = None;
|
let mut margin_minus = None;
|
||||||
let mut margin_plus = None;
|
let mut margin_plus = None;
|
||||||
|
|
||||||
|
@ -218,7 +58,7 @@ fn sysref_dac_align(dacno: u8, phase: u16) -> Result<(), &'static str> {
|
||||||
|
|
||||||
hmc7043::sysref_offset_dac(dacno, phase);
|
hmc7043::sysref_offset_dac(dacno, phase);
|
||||||
ad9154::dac_sync(dacno)?;
|
ad9154::dac_sync(dacno)?;
|
||||||
for d in 0..128 {
|
for d in 0..24 {
|
||||||
hmc7043::sysref_offset_dac(dacno, phase - d);
|
hmc7043::sysref_offset_dac(dacno, phase - d);
|
||||||
let realign_occured = ad9154::dac_sync(dacno)?;
|
let realign_occured = ad9154::dac_sync(dacno)?;
|
||||||
if realign_occured {
|
if realign_occured {
|
||||||
|
@ -229,7 +69,7 @@ fn sysref_dac_align(dacno: u8, phase: u16) -> Result<(), &'static str> {
|
||||||
|
|
||||||
hmc7043::sysref_offset_dac(dacno, phase);
|
hmc7043::sysref_offset_dac(dacno, phase);
|
||||||
ad9154::dac_sync(dacno)?;
|
ad9154::dac_sync(dacno)?;
|
||||||
for d in 0..128 {
|
for d in 0..24 {
|
||||||
hmc7043::sysref_offset_dac(dacno, phase + d);
|
hmc7043::sysref_offset_dac(dacno, phase + d);
|
||||||
let realign_occured = ad9154::dac_sync(dacno)?;
|
let realign_occured = ad9154::dac_sync(dacno)?;
|
||||||
if realign_occured {
|
if realign_occured {
|
||||||
|
@ -242,7 +82,7 @@ fn sysref_dac_align(dacno: u8, phase: u16) -> Result<(), &'static str> {
|
||||||
let margin_minus = margin_minus.unwrap();
|
let margin_minus = margin_minus.unwrap();
|
||||||
let margin_plus = margin_plus.unwrap();
|
let margin_plus = margin_plus.unwrap();
|
||||||
info!(" margins: -{} +{}", margin_minus, margin_plus);
|
info!(" margins: -{} +{}", margin_minus, margin_plus);
|
||||||
if margin_minus < 10 || margin_plus < 10 {
|
if margin_minus < 5 || margin_plus < 5 {
|
||||||
return Err("SYSREF margins at DAC are too small, board needs recalibration");
|
return Err("SYSREF margins at DAC are too small, board needs recalibration");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -115,9 +115,12 @@ fn startup() {
|
||||||
{
|
{
|
||||||
board_artiq::ad9154::jesd_reset(false);
|
board_artiq::ad9154::jesd_reset(false);
|
||||||
board_artiq::ad9154::init();
|
board_artiq::ad9154::init();
|
||||||
|
/*
|
||||||
|
TODO:
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if let Err(e) = board_artiq::jesd204sync::sysref_auto_dac_align() {
|
if let Err(e) = board_artiq::jesd204sync::sysref_auto_dac_align() {
|
||||||
error!("failed to align SYSREF at DAC: {}", e);
|
error!("failed to align SYSREF at DAC: {}", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -489,9 +489,12 @@ pub extern fn main() -> i32 {
|
||||||
info!("TSC loaded from uplink");
|
info!("TSC loaded from uplink");
|
||||||
#[cfg(has_ad9154)]
|
#[cfg(has_ad9154)]
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
TODO:
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if let Err(e) = board_artiq::jesd204sync::sysref_auto_dac_align() {
|
if let Err(e) = board_artiq::jesd204sync::sysref_auto_dac_align() {
|
||||||
error!("failed to align SYSREF at DAC: {}", e);
|
error!("failed to align SYSREF at DAC: {}", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,22 +91,3 @@ class UltrascaleTX(Module, AutoCSR):
|
||||||
self.submodules.control = JESD204BCoreTXControl(self.core)
|
self.submodules.control = JESD204BCoreTXControl(self.core)
|
||||||
self.core.register_jsync(platform.request("dac_sync", dac))
|
self.core.register_jsync(platform.request("dac_sync", dac))
|
||||||
self.core.register_jref(jesd_crg.jref)
|
self.core.register_jref(jesd_crg.jref)
|
||||||
|
|
||||||
|
|
||||||
# This assumes:
|
|
||||||
# * coarse RTIO frequency = 16*SYSREF frequency
|
|
||||||
# * JESD and coarse RTIO clocks are the same
|
|
||||||
# (only reset may differ).
|
|
||||||
# * SYSREF meets setup/hold at the FPGA when sampled
|
|
||||||
# in the JESD/RTIO domain.
|
|
||||||
#
|
|
||||||
# Look at the 4 LSBs of the coarse RTIO timestamp counter
|
|
||||||
# to determine SYSREF phase.
|
|
||||||
|
|
||||||
class SysrefSampler(Module, AutoCSR):
|
|
||||||
def __init__(self, coarse_ts, jref):
|
|
||||||
self.sample_result = CSRStatus()
|
|
||||||
|
|
||||||
sample = Signal()
|
|
||||||
self.sync.jesd += If(coarse_ts[:4] == 0, sample.eq(jref))
|
|
||||||
self.specials += MultiReg(sample, self.sample_result.status)
|
|
||||||
|
|
|
@ -223,10 +223,6 @@ class Standalone(MiniSoC, AMPSoC, RTMCommon):
|
||||||
self.get_native_sdram_if())
|
self.get_native_sdram_if())
|
||||||
self.csr_devices.append("rtio_analyzer")
|
self.csr_devices.append("rtio_analyzer")
|
||||||
|
|
||||||
self.submodules.sysref_sampler = jesd204_tools.SysrefSampler(
|
|
||||||
self.rtio_tsc.coarse_ts, self.ad9154_crg.jref)
|
|
||||||
self.csr_devices.append("sysref_sampler")
|
|
||||||
|
|
||||||
|
|
||||||
class MasterDAC(MiniSoC, AMPSoC, RTMCommon):
|
class MasterDAC(MiniSoC, AMPSoC, RTMCommon):
|
||||||
"""
|
"""
|
||||||
|
@ -395,10 +391,6 @@ class MasterDAC(MiniSoC, AMPSoC, RTMCommon):
|
||||||
self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con)
|
self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con)
|
||||||
self.csr_devices.append("routing_table")
|
self.csr_devices.append("routing_table")
|
||||||
|
|
||||||
self.submodules.sysref_sampler = jesd204_tools.SysrefSampler(
|
|
||||||
self.rtio_tsc.coarse_ts, self.ad9154_crg.jref)
|
|
||||||
self.csr_devices.append("sysref_sampler")
|
|
||||||
|
|
||||||
|
|
||||||
def workaround_us_lvds_tristate(platform):
|
def workaround_us_lvds_tristate(platform):
|
||||||
# Those shoddy Kintex Ultrascale FPGAs take almost a microsecond to change the direction of a
|
# Those shoddy Kintex Ultrascale FPGAs take almost a microsecond to change the direction of a
|
||||||
|
@ -684,10 +676,6 @@ class Satellite(BaseSoC, RTMCommon):
|
||||||
self.config["I2C_BUS_COUNT"] = 1
|
self.config["I2C_BUS_COUNT"] = 1
|
||||||
self.config["HAS_SI5324"] = None
|
self.config["HAS_SI5324"] = None
|
||||||
|
|
||||||
self.submodules.sysref_sampler = jesd204_tools.SysrefSampler(
|
|
||||||
self.rtio_tsc.coarse_ts, self.ad9154_crg.jref)
|
|
||||||
self.csr_devices.append("sysref_sampler")
|
|
||||||
|
|
||||||
rtio_clk_period = 1e9/rtio_clk_freq
|
rtio_clk_period = 1e9/rtio_clk_freq
|
||||||
gth = self.drtio_transceiver.gths[0]
|
gth = self.drtio_transceiver.gths[0]
|
||||||
platform.add_period_constraint(gth.txoutclk, rtio_clk_period/2)
|
platform.add_period_constraint(gth.txoutclk, rtio_clk_period/2)
|
||||||
|
|
Loading…
Reference in New Issue