diff --git a/artiq/firmware/libboard_artiq/ad9154.rs b/artiq/firmware/libboard_artiq/ad9154.rs index d10ae53b3..717a06eb5 100644 --- a/artiq/firmware/libboard_artiq/ad9154.rs +++ b/artiq/firmware/libboard_artiq/ad9154.rs @@ -34,9 +34,9 @@ fn read(addr: u16) -> u8 { } // ad9154 mode 1 -// linerate 5Gbps or 6Gbps -// deviceclock_fpga 125MHz or 150MHz -// deviceclock_dac 500MHz or 600MHz +// linerate 10Gbps +// deviceclock_fpga 125MHz +// deviceclock_dac 1000MHz struct JESDSettings { did: u8, @@ -87,7 +87,7 @@ const JESD_SETTINGS: JESDSettings = JESDSettings { np: 16, f: 2, s: 2, - k: 16, + k: 32, cs: 0, subclassv: 1, @@ -144,7 +144,7 @@ pub fn setup(dacno: u8, linerate: u64) -> Result<(), &'static str> { write(ad9154_reg::DEVICE_CONFIG_REG_1, 0x01); // magic write(ad9154_reg::DEVICE_CONFIG_REG_2, 0x01); // magic - write(ad9154_reg::INTERP_MODE, 0x03); // 4x + write(ad9154_reg::INTERP_MODE, 0x01); // 2x write(ad9154_reg::MIX_MODE, 0); write(ad9154_reg::DATA_FORMAT, 0*ad9154_reg::BINARY_FORMAT); // s16 write(ad9154_reg::DATAPATH_CTRL, @@ -351,6 +351,28 @@ pub fn setup(dacno: u8, linerate: u64) -> Result<(), &'static str> { write(ad9154_reg::GENERAL_JRX_CTRL_0, 0x1*ad9154_reg::LINK_EN | 0*ad9154_reg::LINK_PAGE | 0*ad9154_reg::LINK_MODE | 0*ad9154_reg::CHECKSUM_MODE); + + // JESD Checks + let jesd_checks = read(ad9154_reg::JESD_CHECKS); + if jesd_checks & ad9154_reg::ERR_DLYOVER == ad9154_reg::ERR_DLYOVER { + error!("LMFC_Delay > JESD_K Parameter") + } + if jesd_checks & ad9154_reg::ERR_WINLIMIT == ad9154_reg::ERR_WINLIMIT { + error!("Unsupported Window Limit") + } + if jesd_checks & ad9154_reg::ERR_JESDBAD == ad9154_reg::ERR_JESDBAD { + error!("Unsupported M/L/S/F Selection") + } + if jesd_checks & ad9154_reg::ERR_KUNSUPP == ad9154_reg::ERR_KUNSUPP { + error!("Unsupported K Values") + } + if jesd_checks & ad9154_reg::ERR_SUBCLASS == ad9154_reg::ERR_SUBCLASS { + error!("Unsupported SUBCLASSV Value") + } + if jesd_checks & ad9154_reg::ERR_INTSUPP == ad9154_reg::ERR_INTSUPP { + error!("Unsupported Interpolation Factor") + } + info!(" ...done"); Ok(()) } diff --git a/artiq/firmware/libboard_artiq/hmc830_7043.rs b/artiq/firmware/libboard_artiq/hmc830_7043.rs index adf753141..d4768aa36 100644 --- a/artiq/firmware/libboard_artiq/hmc830_7043.rs +++ b/artiq/firmware/libboard_artiq/hmc830_7043.rs @@ -149,20 +149,20 @@ pub mod hmc7043 { // enabled, divider, output config, is sysref const OUTPUT_CONFIG: [(bool, u16, u8, bool); 14] = [ - (true, DAC_CLK_DIV, 0x08, false), // 0: DAC1_CLK - (true, SYSREF_DIV, 0x01, true), // 1: DAC1_SYSREF - (true, DAC_CLK_DIV, 0x08, false), // 2: DAC0_CLK - (true, SYSREF_DIV, 0x01, true), // 3: DAC0_SYSREF - (true, SYSREF_DIV, 0x10, true), // 4: AMC_FPGA_SYSREF0 - (false, FPGA_CLK_DIV, 0x10, true), // 5: AMC_FPGA_SYSREF1 - (false, 0, 0x10, false), // 6: unused - (true, FPGA_CLK_DIV, 0x10, true), // 7: RTM_FPGA_SYSREF0 - (true, FPGA_CLK_DIV, 0x08, false), // 8: GTP_CLK0_IN - (false, 0, 0x10, false), // 9: unused - (false, 0, 0x10, false), // 10: unused - (false, 0, 0x08, false), // 11: unused / uFL - (false, 0, 0x10, false), // 12: unused - (false, FPGA_CLK_DIV, 0x10, true), // 13: RTM_FPGA_SYSREF1 + (true, DAC_CLK_DIV, 0x08, false), // 0: DAC1_CLK + (true, SYSREF_DIV, 0x01, true), // 1: DAC1_SYSREF + (true, DAC_CLK_DIV, 0x08, false), // 2: DAC0_CLK + (true, SYSREF_DIV, 0x01, true), // 3: DAC0_SYSREF + (true, SYSREF_DIV, 0x10, true), // 4: AMC_FPGA_SYSREF0 + (false, FPGA_CLK_DIV, 0x10, true), // 5: AMC_FPGA_SYSREF1 + (false, 0, 0x10, false), // 6: unused + (true, FPGA_CLK_DIV, 0x10, true), // 7: RTM_FPGA_SYSREF0 + (true, FPGA_CLK_DIV/2, 0x08, false), // 8: GTP_CLK0_IN + (false, 0, 0x10, false), // 9: unused + (false, 0, 0x10, false), // 10: unused + (false, 0, 0x08, false), // 11: unused / uFL + (false, 0, 0x10, false), // 12: unused + (false, FPGA_CLK_DIV, 0x10, true), // 13: RTM_FPGA_SYSREF1 ]; fn spi_setup() { @@ -393,8 +393,6 @@ pub mod hmc7043 { pub fn init() -> Result<(), &'static str> { #[cfg(all(hmc830_ref = "125", rtio_frequency = "125.0"))] const DIV: (u32, u32, u32, u32) = (2, 32, 0, 1); // 125MHz -> 2.0GHz - #[cfg(all(hmc830_ref = "150", rtio_frequency = "150.0"))] - const DIV: (u32, u32, u32, u32) = (2, 32, 0, 1); // 150MHz -> 2.4GHz /* do not use other SPI devices before HMC830 SPI mode selection */ hmc830::select_spi_mode(); @@ -406,7 +404,7 @@ pub fn init() -> Result<(), &'static str> { hmc830::check_locked()?; if hmc7043::get_id() == hmc7043::CHIP_ID { - error!("HMC7043 detected while in reset (board rework missing?)"); + error!("HMC7043 detected while in reset"); } hmc7043::enable(); hmc7043::detect()?; diff --git a/artiq/firmware/runtime/rtio_clocking.rs b/artiq/firmware/runtime/rtio_clocking.rs index 3b230bacc..45876e935 100644 --- a/artiq/firmware/runtime/rtio_clocking.rs +++ b/artiq/firmware/runtime/rtio_clocking.rs @@ -119,19 +119,6 @@ fn setup_si5324_as_synthesizer() { 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 diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index 0f448a1bd..206caf237 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -300,9 +300,7 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], #[cfg(has_ad9154)] let (succeeded, retval) = { #[cfg(rtio_frequency = "125.0")] - const LINERATE: u64 = 5_000_000_000; - #[cfg(rtio_frequency = "150.0")] - const LINERATE: u64 = 6_000_000_000; + const LINERATE: u64 = 10_000_000_000; match _reqno { jdac_common::INIT => (board_artiq::ad9154::setup(_dacno, LINERATE).is_ok(), 0), jdac_common::PRINT_STATUS => { board_artiq::ad9154::status(_dacno); (true, 0) }, @@ -417,19 +415,6 @@ fn hardware_tick(ts: &mut u64) { } } -#[cfg(all(has_si5324, rtio_frequency = "150.0"))] -const SI5324_SETTINGS: si5324::FrequencySettings - = si5324::FrequencySettings { - n1_hs : 6, - nc1_ls : 6, - n2_hs : 10, - n2_ls : 270, - n31 : 75, - n32 : 75, - bwsel : 4, - crystal_ref: true -}; - #[cfg(all(has_si5324, rtio_frequency = "125.0"))] const SI5324_SETTINGS: si5324::FrequencySettings = si5324::FrequencySettings { diff --git a/artiq/gateware/jesd204_tools.py b/artiq/gateware/jesd204_tools.py index d05d6432f..6baa07f15 100644 --- a/artiq/gateware/jesd204_tools.py +++ b/artiq/gateware/jesd204_tools.py @@ -19,31 +19,27 @@ from jesd204b.core import JESD204BCoreTXControl class UltrascaleCRG(Module, AutoCSR): - linerate = int(6e9) # linerate = 20*data_rate*4/8 = data_rate*10 + linerate = int(10e9) # linerate = 20*data_rate*4/8 = data_rate*10 # data_rate = dac_rate/interp_factor - refclk_freq = int(150e6) + refclk_freq = int(250e6) fabric_freq = int(125e6) - def __init__(self, platform, use_rtio_clock=False): + def __init__(self, platform): self.jreset = CSRStorage(reset=1) self.refclk = Signal() self.clock_domains.cd_jesd = ClockDomain() - refclk2 = Signal() refclk_pads = platform.request("dac_refclk", 0) platform.add_period_constraint(refclk_pads.p, 1e9/self.refclk_freq) self.specials += [ - Instance("IBUFDS_GTE3", i_CEB=0, p_REFCLK_HROW_CK_SEL=0b00, + Instance("IBUFDS_GTE3", i_CEB=0, p_REFCLK_HROW_CK_SEL=0b01, i_I=refclk_pads.p, i_IB=refclk_pads.n, - o_O=self.refclk, o_ODIV2=refclk2), - AsyncResetSynchronizer(self.cd_jesd, self.jreset.storage), + o_O=self.refclk), ] - if use_rtio_clock: - self.cd_jesd.clk.attr.add("keep") - self.comb += self.cd_jesd.clk.eq(ClockSignal("rtio")) - else: - self.specials += Instance("BUFG_GT", i_I=refclk2, o_O=self.cd_jesd.clk) + self.cd_jesd.clk.attr.add("keep") + self.comb += self.cd_jesd.clk.eq(ClockSignal("rtio")) + self.specials += AsyncResetSynchronizer(self.cd_jesd, self.jreset.storage) PhyPads = namedtuple("PhyPads", "txp txn") @@ -61,7 +57,7 @@ class UltrascaleTX(Module, AutoCSR): "qpll": JESD204BGTHQuadPLL }[pll_type] ps = JESD204BPhysicalSettings(l=8, m=4, n=16, np=16) - ts = JESD204BTransportSettings(f=2, s=2, k=16, cs=0) + ts = JESD204BTransportSettings(f=2, s=2, k=32, cs=0) settings = JESD204BSettings(ps, ts, did=0x5a, bid=0x5) jesd_pads = platform.request("dac_jesd", dac) @@ -142,7 +138,7 @@ class UltrascaleTX(Module, AutoCSR): pll, phy.transmitter, **phy_channel_cfg) self.submodules.core = JESD204BCoreTX( - phys, settings, converter_data_width=64) + phys, settings, converter_data_width=128, tx_half=tx_half) self.submodules.control = JESD204BCoreTXControl(self.core) self.core.register_jsync(platform.request("dac_sync", dac)) @@ -166,7 +162,7 @@ class DDMTDEdgeDetector(Module): # 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): + def __init__(self, input_pads, rtio_clk_freq=125e6): N = 64 self.reset = CSRStorage(reset=1) self.locked = CSRStatus() @@ -189,7 +185,7 @@ class DDMTD(Module, AutoCSR): i_RST=self.reset.storage, o_LOCKED=helper_locked, - # VCO at 1200MHz with 150MHz RTIO frequency + # VCO at 1000MHz/1200MHz with 125MHz/150MHz RTIO frequency p_CLKFBOUT_MULT_F=8.0, p_DIVCLK_DIVIDE=1, diff --git a/artiq/gateware/targets/metlino.py b/artiq/gateware/targets/metlino.py index 4f609e1c7..552a3ed7d 100755 --- a/artiq/gateware/targets/metlino.py +++ b/artiq/gateware/targets/metlino.py @@ -54,7 +54,7 @@ class Master(MiniSoC, AMPSoC): add_identifier(self, gateware_identifier_str=gateware_identifier_str) platform = self.platform - rtio_clk_freq = 150e6 + rtio_clk_freq = 125e6 self.comb += platform.request("input_clk_sel").eq(1) self.comb += platform.request("filtered_clk_sel").eq(1) diff --git a/artiq/gateware/targets/sayma_amc.py b/artiq/gateware/targets/sayma_amc.py index 9e611a618..7e324c948 100755 --- a/artiq/gateware/targets/sayma_amc.py +++ b/artiq/gateware/targets/sayma_amc.py @@ -173,11 +173,11 @@ class SatelliteBase(MiniSoC): class JDCGSAWG(Module, AutoCSR): def __init__(self, platform, sys_crg, jesd_crg, dac): # Kintex Ultrascale GTH, speed grade -1C: - # CPLL linerate (D=1): 4.0 - 8.5 Gb/s + # QPLL0 linerate (D=1): 9.8 - 12.5 Gb/s self.submodules.jesd = jesd204_tools.UltrascaleTX( - platform, sys_crg, jesd_crg, dac) + platform, sys_crg, jesd_crg, dac, pll_type="qpll", tx_half=True) - self.submodules.sawgs = [sawg.Channel(width=16, parallelism=4) for i in range(4)] + self.submodules.sawgs = [sawg.Channel(width=16, parallelism=8) for i in range(4)] for conv, ch in zip(self.jesd.core.sink.flatten(), self.sawgs): assert len(Cat(ch.o)) == len(conv) @@ -187,34 +187,42 @@ class JDCGSAWG(Module, AutoCSR): class JDCGPattern(Module, AutoCSR): def __init__(self, platform, sys_crg, jesd_crg, dac): self.submodules.jesd = jesd204_tools.UltrascaleTX( - platform, sys_crg, jesd_crg, dac) + platform, sys_crg, jesd_crg, dac, pll_type="qpll", tx_half=True) self.sawgs = [] ramp = Signal(4) self.sync.rtio += ramp.eq(ramp + 1) - samples = [[Signal(16) for i in range(4)] for j in range(4)] + samples = [[Signal(16) for i in range(8)] for j in range(4)] self.comb += [ a.eq(Cat(b)) for a, b in zip( self.jesd.core.sink.flatten(), samples) ] # ch0: 16-step ramp with big carry toggles - for i in range(4): + for i in range(8): self.comb += [ samples[0][i][-4:].eq(ramp), samples[0][i][:-4].eq(0x7ff if i % 2 else 0x800) ] # ch1: 50 MHz + # - Formulae: + # target cosine wave frequency: f = 50e6 + # DAC sampling frequency: fs = 1000e6 + # number of samples per coarse RTIO period: P = 8 + # number of samples needed per wave period: M = (1/f) / (1/fs)) = 20 + # number of repeating samples needed: N = LCM(P, M) = 40 + # number of RTIO periods needed for repeating: k = N/P = 5 + # discretized value of the wave: y[i] = cos(i/M * 2pi) from math import pi, cos - data = [int(round(cos(i/12*2*pi)*((1 << 15) - 1))) - for i in range(12)] - k = Signal(2) - self.sync.rtio += If(k == 2, k.eq(0)).Else(k.eq(k + 1)) + data = [int(round(cos(i/20*2*pi)*((1 << 15) - 1))) + for i in range(40)] + k = Signal(max=5) + self.sync.rtio += If(k == 4, k.eq(0)).Else(k.eq(k + 1)) self.comb += [ Case(k, { - i: [samples[1][j].eq(data[i*4 + j]) for j in range(4)] - for i in range(3) + i: [samples[1][j].eq(data[i*8 + j]) for j in range(8)] + for i in range(5) }) ] # ch2: ch0, ch3: ch1 @@ -227,13 +235,13 @@ class JDCGPattern(Module, AutoCSR): class JDCGSyncDDS(Module, AutoCSR): def __init__(self, platform, sys_crg, jesd_crg, dac): self.submodules.jesd = jesd204_tools.UltrascaleTX( - platform, sys_crg, jesd_crg, dac) + platform, sys_crg, jesd_crg, dac, pll_type="qpll", tx_half=True) self.coarse_ts = Signal(32) self.sawgs = [] ftw = round(2**len(self.coarse_ts)*9e6/600e6) - parallelism = 4 + parallelism = 8 mul_1 = Signal.like(self.coarse_ts) mul_2 = Signal.like(self.coarse_ts) @@ -271,9 +279,7 @@ class Satellite(SatelliteBase): DRTIO satellite with local DAC/SAWG channels, as well as TTL channels via FMC and VHDCI carrier. """ def __init__(self, jdcg_type, **kwargs): - SatelliteBase.__init__(self, 150e6, - identifier_suffix="." + jdcg_type, - **kwargs) + SatelliteBase.__init__(self, identifier_suffix="." + jdcg_type, **kwargs) platform = self.platform @@ -307,8 +313,7 @@ class Satellite(SatelliteBase): self.submodules += phy rtio_channels.append(rtio.Channel.from_phy(phy)) - self.submodules.jesd_crg = jesd204_tools.UltrascaleCRG( - platform, use_rtio_clock=True) + self.submodules.jesd_crg = jesd204_tools.UltrascaleCRG(platform) cls = { "sawg": JDCGSAWG, "pattern": JDCGPattern, diff --git a/artiq/gateware/targets/sayma_rtm.py b/artiq/gateware/targets/sayma_rtm.py index 9e8571636..0dd112d3c 100755 --- a/artiq/gateware/targets/sayma_rtm.py +++ b/artiq/gateware/targets/sayma_rtm.py @@ -278,7 +278,7 @@ def main(): builder_args(parser) soc_sayma_rtm_args(parser) parser.add_argument("--rtio-clk-freq", - default=150, type=int, help="RTIO clock frequency in MHz") + default=125, type=int, help="RTIO clock frequency in MHz") parser.add_argument("--gateware-identifier-str", default=None, help="Override ROM identifier") parser.set_defaults(output_dir=os.path.join("artiq_sayma", "rtm"))