sayma: DDMTD SYSREF measurement demonstration

This commit is contained in:
Sebastien Bourdeauducq 2019-01-25 16:00:31 +08:00
parent 4941fb3300
commit 3356717316
6 changed files with 86 additions and 8 deletions

View File

@ -178,7 +178,7 @@ pub mod hmc7043 {
(true, FPGA_CLK_DIV, 0x08), // 8: GTP_CLK1
(false, 0, 0x10), // 9: AMC_MASTER_AUX_CLK
(false, 0, 0x10), // 10: RTM_MASTER_AUX_CLK
(false, 0, 0x10), // 11: FPGA_ADC_SYSREF, LVDS
(true, FPGA_CLK_DIV, 0x10), // 11: FPGA_ADC_SYSREF, LVDS, used for DDMTD RTIO/SYSREF alignment
(false, 0, 0x08), // 12: ADC1_CLK
(false, 0, 0x08), // 13: ADC1_SYSREF
];

View File

@ -3,6 +3,15 @@ use board_misoc::{csr, config};
use hmc830_7043::hmc7043;
use ad9154;
pub fn sysref_auto_rtio_align() -> Result<(), &'static str> {
for _ in 0..256 {
hmc7043::sysref_slip();
let dt = unsafe { csr::sysref_ddmtd::dt_read() };
info!("dt={}", dt);
}
Ok(())
}
fn sysref_cal_dac(dacno: u8) -> Result<u8, &'static str> {
info!("calibrating SYSREF phase at DAC-{}...", dacno);

View File

@ -115,12 +115,9 @@ fn startup() {
{
board_artiq::ad9154::jesd_reset(false);
board_artiq::ad9154::init();
/*
TODO:
if let Err(e) = board_artiq::jesd204sync::sysref_auto_rtio_align() {
error!("failed to align SYSREF at FPGA: {}", e);
}
*/
if let Err(e) = board_artiq::jesd204sync::sysref_auto_dac_align() {
error!("failed to align SYSREF at DAC: {}", e);
}

View File

@ -489,12 +489,9 @@ pub extern fn main() -> i32 {
info!("TSC loaded from uplink");
#[cfg(has_ad9154)]
{
/*
TODO:
if let Err(e) = board_artiq::jesd204sync::sysref_auto_rtio_align() {
error!("failed to align SYSREF at FPGA: {}", e);
}
*/
if let Err(e) = board_artiq::jesd204sync::sysref_auto_dac_align() {
error!("failed to align SYSREF at DAC: {}", e);
}

View File

@ -1,7 +1,7 @@
from collections import namedtuple
from migen import *
from migen.genlib.cdc import MultiReg
from migen.genlib.cdc import MultiReg, BusSynchronizer
from migen.genlib.resetsync import AsyncResetSynchronizer
from misoc.interconnect.csr import *
@ -91,3 +91,69 @@ class UltrascaleTX(Module, AutoCSR):
self.submodules.control = JESD204BCoreTXControl(self.core)
self.core.register_jsync(platform.request("dac_sync", dac))
self.core.register_jref(jesd_crg.jref)
# See "Digital femtosecond time difference circuit for CERN's timing system"
# by P. Moreira and I. Darwazeh
class DDMTD(Module, AutoCSR):
def __init__(self, input_pads, rtio_clk_freq=150e6):
N = 64
self.dt = CSRStatus(N.bit_length())
# # #
self.clock_domains.cd_helper = ClockDomain(reset_less=True)
helper_fb = Signal()
helper_output = Signal()
input_se = Signal()
beat1 = Signal()
beat2 = Signal()
self.specials += [
Instance("MMCME2_BASE",
p_CLKIN1_PERIOD=1e9/rtio_clk_freq,
i_CLKIN1=ClockSignal("rtio"),
i_RST=ResetSignal("rtio"),
# VCO at 1200MHz with 150MHz RTIO frequency
p_CLKFBOUT_MULT_F=8.0,
p_DIVCLK_DIVIDE=1,
o_CLKFBOUT=helper_fb, i_CLKFBIN=helper_fb,
# helper PLL ratio: 64/65 (N=64)
p_CLKOUT0_DIVIDE_F=8.125,
o_CLKOUT0=helper_output,
),
Instance("BUFG", i_I=helper_output, o_O=self.cd_helper.clk),
Instance("IBUFDS", i_I=input_pads.p, i_IB=input_pads.n, o_O=input_se),
Instance("FD", i_C=self.cd_helper.clk, i_D=input_se, o_Q=beat1),
Instance("FD", i_C=self.cd_helper.clk, i_D=ClockSignal("rtio"), o_Q=beat2),
]
counting = Signal()
counter = Signal(N.bit_length())
beat1_r = Signal()
beat2_r = Signal()
result = Signal.like(counter)
self.sync.helper += [
If(counting,
counter.eq(counter + 1)
).Else(
result.eq(counter)
),
beat1_r.eq(beat1),
If(beat1 & ~beat1_r, counting.eq(1), counter.eq(0)),
beat2_r.eq(beat2),
If(beat2 & ~beat2_r, counting.eq(0))
]
bsync = BusSynchronizer(len(result), "helper", "sys")
self.submodules += bsync
self.comb += [
bsync.i.eq(result),
self.dt.status.eq(bsync.o)
]

View File

@ -223,6 +223,9 @@ class Standalone(MiniSoC, AMPSoC, RTMCommon):
self.get_native_sdram_if())
self.csr_devices.append("rtio_analyzer")
self.submodules.sysref_ddmtd = jesd204_tools.DDMTD(platform.request("adc_sysref"))
self.csr_devices.append("sysref_ddmtd")
class MasterDAC(MiniSoC, AMPSoC, RTMCommon):
"""
@ -391,6 +394,9 @@ class MasterDAC(MiniSoC, AMPSoC, RTMCommon):
self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con)
self.csr_devices.append("routing_table")
self.submodules.sysref_ddmtd = jesd204_tools.DDMTD(platform.request("adc_sysref"))
self.csr_devices.append("sysref_ddmtd")
def workaround_us_lvds_tristate(platform):
# Those shoddy Kintex Ultrascale FPGAs take almost a microsecond to change the direction of a
@ -676,6 +682,9 @@ class Satellite(BaseSoC, RTMCommon):
self.config["I2C_BUS_COUNT"] = 1
self.config["HAS_SI5324"] = None
self.submodules.sysref_ddmtd = jesd204_tools.DDMTD(platform.request("adc_sysref"))
self.csr_devices.append("sysref_ddmtd")
rtio_clk_period = 1e9/rtio_clk_freq
gth = self.drtio_transceiver.gths[0]
platform.add_period_constraint(gth.txoutclk, rtio_clk_period/2)