From ad264ac07093e0098574e72adbc1cef79e99ac75 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Mon, 21 Nov 2016 16:58:07 +0100 Subject: [PATCH] phaser: 300 MHz sample rate clock/dac --- README_PHASER.rst | 12 +++++----- artiq/examples/phaser/repository/dac_setup.py | 10 ++++----- artiq/examples/phaser/startup_kernel.py | 22 ++++++++----------- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/README_PHASER.rst b/README_PHASER.rst index 617519ea8..723d22601 100644 --- a/README_PHASER.rst +++ b/README_PHASER.rst @@ -7,16 +7,16 @@ Ultimately it will be the basis for the ARTIQ Sayma Smart Arbitrary Waveform Gen *Features*: -* 4 channels -* 500 MHz data rate per channel (KC705 limitation) -* 4x interpolation to 2 GHz DAC sample rate +* up to 4 channels +* up to 500 MHz data rate per channel (KC705 limitation) +* up to 8x interpolation to 2.4 GHz DAC sample rate * Real-time control over amplitude, frequency, phase of each channel through ARTIQ RTIO commands * Full configurability of the AD9154 and AD9516 through SPI with ARTIQ kernel support * All SPI registers and register bits exposed as human readable names * Parametrized JESD204B core (also capable of operation with eight lanes) * The code can be reconfigured. Possible example configurations are: support 2 channels at 1 GHz datarate, support 4 channels at 300 MHz data rate, no interpolation, and using mix mode to stress the second and third Nyquist zones (150-300 MHz and 300-450 MHz). -The hardware required to use the ARTIQ phaser branch is a KC705 with an AD9154-FMC-EBZ plugged into the HPC connector and a low-noise 2 GHz reference clock. +The hardware required to use the ARTIQ phaser branch is a KC705 with an AD9154-FMC-EBZ plugged into the HPC connector and a low-noise sample rate reference clock. This work was supported by the Army Research Lab. @@ -90,7 +90,7 @@ Setup * Refer to the ARTIQ documentation to configure an IP address and other settings for the transmitter device. If the board was running stock ARTIQ before, the settings will be kept. -* A 2 GHz of roughly 10 dBm (0.2 to 3.4 V peak-to-peak into 50 Ohm) must be connected to the AD9154-FMC-EBZ J1. +* A 300 MHz clock of roughly 10 dBm (0.2 to 3.4 V peak-to-peak into 50 Ohm) must be connected to the AD9154-FMC-EBZ J1. The external RTIO clock, DAC deviceclock, FPGA deviceclock, and SYSREF are derived from this signal. * An example device database, several status and test scripts are provided in ``artiq/examples/phaser/``. :: @@ -113,7 +113,7 @@ Usage * Run ``artiq_run repository/demo.py`` for an example that exercises several different use cases of synchronized phase, amplitude, and frequency updates. for an example that exercises several different use cases of synchronized phase, amplitude, and frequency updates. * Implement your own experiments using the SAWG channels. -* Verify clock stability between the 2 GHz reference clock and the DAC outputs. +* Verify clock stability between the sample rate reference clock and the DAC outputs. * Changes to the AD9154 configuration can also be performed at runtime in experiments. See the example ``dac_setup.py``. This can e.g. be used to enable and evaluate mix mode without having to change any other code (bitstream/bios/runtime/startup_kernel). diff --git a/artiq/examples/phaser/repository/dac_setup.py b/artiq/examples/phaser/repository/dac_setup.py index ed9a2da76..13b575045 100644 --- a/artiq/examples/phaser/repository/dac_setup.py +++ b/artiq/examples/phaser/repository/dac_setup.py @@ -19,10 +19,10 @@ ts = JESD204BTransportSettings( ) jesd_settings = JESD204BSettings(ps, ts, did=0x5a, bid=0x5) jesd_checksum = jesd_settings.get_configuration_checksum() -# external clk=2000MHz -# pclock=250MHz -# deviceclock_fpga=250MHz -# deviceclock_dac=2000MHz +# external clk=300MHz +# pclock=150MHz +# deviceclock_fpga=150MHz +# deviceclock_dac=300MHz class DACSetup(EnvExperiment): @@ -123,7 +123,7 @@ class DACSetup(EnvExperiment): self.ad9154.dac_write(AD9154_SPI_PAGEINDX, 0x3) # A and B dual - self.ad9154.dac_write(AD9154_INTERP_MODE, 3) # 4x + self.ad9154.dac_write(AD9154_INTERP_MODE, 0) # 1x self.ad9154.dac_write(AD9154_MIX_MODE, 0) self.ad9154.dac_write(AD9154_DATA_FORMAT, AD9154_BINARY_FORMAT_SET(0)) # s16 self.ad9154.dac_write(AD9154_DATAPATH_CTRL, diff --git a/artiq/examples/phaser/startup_kernel.py b/artiq/examples/phaser/startup_kernel.py index b611eef1a..3fb678ab4 100644 --- a/artiq/examples/phaser/startup_kernel.py +++ b/artiq/examples/phaser/startup_kernel.py @@ -28,10 +28,10 @@ class StartupKernel(EnvExperiment): if self.ad9154.clock_read(AD9516_PART_ID) != 0x41: raise ValueError("AD9516 not found") - # use clk input, dclk=clk/4 + # use clk input, dclk=clk/2 self.ad9154.clock_write(AD9516_PFD_AND_CHARGE_PUMP, 1*AD9516_PLL_POWER_DOWN | 0*AD9516_CHARGE_PUMP_MODE) - self.ad9154.clock_write(AD9516_VCO_DIVIDER, 2) + self.ad9154.clock_write(AD9516_VCO_DIVIDER, 0) self.ad9154.clock_write(AD9516_INPUT_CLKS, 0*AD9516_SELECT_VCO_OR_CLK | 0*AD9516_BYPASS_VCO_DIVIDER) @@ -47,25 +47,21 @@ class StartupKernel(EnvExperiment): self.ad9154.clock_write(AD9516_OUT1, 0*AD9516_OUT1_POWER_DOWN | 2*AD9516_OUT1_LVPECLDIFFERENTIAL_VOLTAGE) - # FPGA deviceclk, dclk/2 - self.ad9154.clock_write(AD9516_DIVIDER_4_3, AD9516_DIVIDER_4_BYPASS_2) - self.ad9154.clock_write(AD9516_DIVIDER_4_0, - (2//2-1)*AD9516_DIVIDER_0_HIGH_CYCLES | - (2//2-1)*AD9516_DIVIDER_0_LOW_CYCLES) + # FPGA deviceclk, dclk/1 + self.ad9154.clock_write(AD9516_DIVIDER_4_3, 0*AD9516_DIVIDER_4_NOSYNC | + 1*AD9516_DIVIDER_4_BYPASS_1 | 1*AD9516_DIVIDER_4_BYPASS_2) self.ad9154.clock_write(AD9516_DIVIDER_4_4, 0*AD9516_DIVIDER_4_DCCOFF) self.ad9154.clock_write(AD9516_OUT9, 1*AD9516_OUT9_LVDS_OUTPUT_CURRENT | 2*AD9516_OUT9_LVDS_CMOS_OUTPUT_POLARITY | 0*AD9516_OUT9_SELECT_LVDS_CMOS) - # sysref f_data*S/(K*F), dclk/32 - self.ad9154.clock_write(AD9516_DIVIDER_3_0, (32//2-1)*AD9516_DIVIDER_3_HIGH_CYCLES_1 | - (32//2-1)*AD9516_DIVIDER_3_LOW_CYCLES_1) + # sysref f_data*S/(K*F), dclk/16 + self.ad9154.clock_write(AD9516_DIVIDER_3_0, (16//2-1)*AD9516_DIVIDER_3_HIGH_CYCLES_1 | + (16//2-1)*AD9516_DIVIDER_3_LOW_CYCLES_1) self.ad9154.clock_write(AD9516_DIVIDER_3_1, 0*AD9516_DIVIDER_3_PHASE_OFFSET_1 | 0*AD9516_DIVIDER_3_PHASE_OFFSET_2) - self.ad9154.clock_write(AD9516_DIVIDER_3_2, (2//2-1)*AD9516_DIVIDER_3_HIGH_CYCLES_2 | - (2//2-1)*AD9516_DIVIDER_3_LOW_CYCLES_2) self.ad9154.clock_write(AD9516_DIVIDER_3_3, 0*AD9516_DIVIDER_3_NOSYNC | - 0*AD9516_DIVIDER_3_BYPASS_1 | 0*AD9516_DIVIDER_3_BYPASS_2) + 0*AD9516_DIVIDER_3_BYPASS_1 | 1*AD9516_DIVIDER_3_BYPASS_2) self.ad9154.clock_write(AD9516_DIVIDER_3_4, 0*AD9516_DIVIDER_3_DCCOFF) self.ad9154.clock_write(AD9516_OUT6, 1*AD9516_OUT6_LVDS_OUTPUT_CURRENT | 2*AD9516_OUT6_LVDS_CMOS_OUTPUT_POLARITY |