forked from M-Labs/artiq
phaser: 300 MHz sample rate clock/dac
This commit is contained in:
parent
b3e4a1df03
commit
ad264ac070
|
@ -7,16 +7,16 @@ Ultimately it will be the basis for the ARTIQ Sayma Smart Arbitrary Waveform Gen
|
||||||
|
|
||||||
*Features*:
|
*Features*:
|
||||||
|
|
||||||
* 4 channels
|
* up to 4 channels
|
||||||
* 500 MHz data rate per channel (KC705 limitation)
|
* up to 500 MHz data rate per channel (KC705 limitation)
|
||||||
* 4x interpolation to 2 GHz DAC sample rate
|
* 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
|
* 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
|
* Full configurability of the AD9154 and AD9516 through SPI with ARTIQ kernel support
|
||||||
* All SPI registers and register bits exposed as human readable names
|
* All SPI registers and register bits exposed as human readable names
|
||||||
* Parametrized JESD204B core (also capable of operation with eight lanes)
|
* 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 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.
|
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.
|
* 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.
|
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.
|
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/``. ::
|
* 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.
|
* 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.
|
for an example that exercises several different use cases of synchronized phase, amplitude, and frequency updates.
|
||||||
* Implement your own experiments using the SAWG channels.
|
* 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.
|
* Changes to the AD9154 configuration can also be performed at runtime in experiments.
|
||||||
See the example ``dac_setup.py``.
|
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).
|
This can e.g. be used to enable and evaluate mix mode without having to change any other code (bitstream/bios/runtime/startup_kernel).
|
||||||
|
|
|
@ -19,10 +19,10 @@ ts = JESD204BTransportSettings(
|
||||||
)
|
)
|
||||||
jesd_settings = JESD204BSettings(ps, ts, did=0x5a, bid=0x5)
|
jesd_settings = JESD204BSettings(ps, ts, did=0x5a, bid=0x5)
|
||||||
jesd_checksum = jesd_settings.get_configuration_checksum()
|
jesd_checksum = jesd_settings.get_configuration_checksum()
|
||||||
# external clk=2000MHz
|
# external clk=300MHz
|
||||||
# pclock=250MHz
|
# pclock=150MHz
|
||||||
# deviceclock_fpga=250MHz
|
# deviceclock_fpga=150MHz
|
||||||
# deviceclock_dac=2000MHz
|
# deviceclock_dac=300MHz
|
||||||
|
|
||||||
|
|
||||||
class DACSetup(EnvExperiment):
|
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_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_MIX_MODE, 0)
|
||||||
self.ad9154.dac_write(AD9154_DATA_FORMAT, AD9154_BINARY_FORMAT_SET(0)) # s16
|
self.ad9154.dac_write(AD9154_DATA_FORMAT, AD9154_BINARY_FORMAT_SET(0)) # s16
|
||||||
self.ad9154.dac_write(AD9154_DATAPATH_CTRL,
|
self.ad9154.dac_write(AD9154_DATAPATH_CTRL,
|
||||||
|
|
|
@ -28,10 +28,10 @@ class StartupKernel(EnvExperiment):
|
||||||
if self.ad9154.clock_read(AD9516_PART_ID) != 0x41:
|
if self.ad9154.clock_read(AD9516_PART_ID) != 0x41:
|
||||||
raise ValueError("AD9516 not found")
|
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 |
|
self.ad9154.clock_write(AD9516_PFD_AND_CHARGE_PUMP, 1*AD9516_PLL_POWER_DOWN |
|
||||||
0*AD9516_CHARGE_PUMP_MODE)
|
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 |
|
self.ad9154.clock_write(AD9516_INPUT_CLKS, 0*AD9516_SELECT_VCO_OR_CLK |
|
||||||
0*AD9516_BYPASS_VCO_DIVIDER)
|
0*AD9516_BYPASS_VCO_DIVIDER)
|
||||||
|
|
||||||
|
@ -47,25 +47,21 @@ class StartupKernel(EnvExperiment):
|
||||||
self.ad9154.clock_write(AD9516_OUT1, 0*AD9516_OUT1_POWER_DOWN |
|
self.ad9154.clock_write(AD9516_OUT1, 0*AD9516_OUT1_POWER_DOWN |
|
||||||
2*AD9516_OUT1_LVPECLDIFFERENTIAL_VOLTAGE)
|
2*AD9516_OUT1_LVPECLDIFFERENTIAL_VOLTAGE)
|
||||||
|
|
||||||
# FPGA deviceclk, dclk/2
|
# FPGA deviceclk, dclk/1
|
||||||
self.ad9154.clock_write(AD9516_DIVIDER_4_3, AD9516_DIVIDER_4_BYPASS_2)
|
self.ad9154.clock_write(AD9516_DIVIDER_4_3, 0*AD9516_DIVIDER_4_NOSYNC |
|
||||||
self.ad9154.clock_write(AD9516_DIVIDER_4_0,
|
1*AD9516_DIVIDER_4_BYPASS_1 | 1*AD9516_DIVIDER_4_BYPASS_2)
|
||||||
(2//2-1)*AD9516_DIVIDER_0_HIGH_CYCLES |
|
|
||||||
(2//2-1)*AD9516_DIVIDER_0_LOW_CYCLES)
|
|
||||||
self.ad9154.clock_write(AD9516_DIVIDER_4_4, 0*AD9516_DIVIDER_4_DCCOFF)
|
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 |
|
self.ad9154.clock_write(AD9516_OUT9, 1*AD9516_OUT9_LVDS_OUTPUT_CURRENT |
|
||||||
2*AD9516_OUT9_LVDS_CMOS_OUTPUT_POLARITY |
|
2*AD9516_OUT9_LVDS_CMOS_OUTPUT_POLARITY |
|
||||||
0*AD9516_OUT9_SELECT_LVDS_CMOS)
|
0*AD9516_OUT9_SELECT_LVDS_CMOS)
|
||||||
|
|
||||||
# sysref f_data*S/(K*F), dclk/32
|
# sysref f_data*S/(K*F), dclk/16
|
||||||
self.ad9154.clock_write(AD9516_DIVIDER_3_0, (32//2-1)*AD9516_DIVIDER_3_HIGH_CYCLES_1 |
|
self.ad9154.clock_write(AD9516_DIVIDER_3_0, (16//2-1)*AD9516_DIVIDER_3_HIGH_CYCLES_1 |
|
||||||
(32//2-1)*AD9516_DIVIDER_3_LOW_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 |
|
self.ad9154.clock_write(AD9516_DIVIDER_3_1, 0*AD9516_DIVIDER_3_PHASE_OFFSET_1 |
|
||||||
0*AD9516_DIVIDER_3_PHASE_OFFSET_2)
|
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 |
|
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_DIVIDER_3_4, 0*AD9516_DIVIDER_3_DCCOFF)
|
||||||
self.ad9154.clock_write(AD9516_OUT6, 1*AD9516_OUT6_LVDS_OUTPUT_CURRENT |
|
self.ad9154.clock_write(AD9516_OUT6, 1*AD9516_OUT6_LVDS_OUTPUT_CURRENT |
|
||||||
2*AD9516_OUT6_LVDS_CMOS_OUTPUT_POLARITY |
|
2*AD9516_OUT6_LVDS_CMOS_OUTPUT_POLARITY |
|
||||||
|
|
Loading…
Reference in New Issue