Hi there,
I'm working on writing a design tree for the Quad MxFE that bypasses the data paths and channelizers on the transmit and receive paths, writing data directly to the DACs and reading data directly to the ADCs, with no interpolation or decimation, upmixing or downmixing.
This is possible according to the AD9081/AD9082 System Development User Guide (UG-1578), but as far as I know, there isn't an example design provided by Analog for the AD9081 in which this bypass mode of operation is implemented.
As such, I want to check that my approach is correct - the relevant sections of the device tree I have made are below:
// relevant ad9081 device tree definitions #define ADRF4360_RFAUX8_FREQUENCY_HZ 1500000000 #define HMC7043_FPGA_XCVR_CLKDIV 2 #define HMC7043_FPGA_LINK_CLKDIV_TX 2 #define HMC7043_FPGA_LINK_CLKDIV_RX 2 #define HMC7043_SYSREF_CLKDIV 1024 // Later try setting this to 128 to see if it still works #define HMC7043_SYSREF_TIMER (HMC7043_SYSREF_CLKDIV * 4) #define AD9081_DAC_FREQUENCY ADRF4360_RFAUX8_FREQUENCY_HZ #define AD9081_ADC_FREQUENCY 1500000000 /* TX path */ #define AD9081_TX_LANERATE_KHZ 24750000 #define AD9081_TX_LINK_CLK 375000000 #define AD9081_TX_MAIN_INTERPOLATION 1 #define AD9081_TX_CHAN_INTERPOLATION 1 #ifndef AD9081_TX_MAIN_NCO_SHIFT #define AD9081_TX_MAIN_NCO_SHIFT 0 #endif #ifndef AD9081_TX_CHAN_NCO_SHIFT #define AD9081_TX_CHAN_NCO_SHIFT 0 #endif #define AD9081_GAIN 1024 #define AD9081_TX_JESD_MODE 11 #define AD9081_TX_JESD_SUBCLASS 1 #define AD9081_TX_JESD_VERSION 2 #define AD9081_TX_JESD_M 4 #define AD9081_TX_JESD_F 2 #define AD9081_TX_JESD_K 128 #define AD9081_TX_JESD_N 16 #define AD9081_TX_JESD_NP 16 #define AD9081_TX_JESD_CS 0 #define AD9081_TX_JESD_L 4 #define AD9081_TX_JESD_S 1 #define AD9081_TX_JESD_HD 0 #define AD9081_JRX_TPL_PHASE_ADJUST 15 /* RX path */ #define AD9081_RX_LANERATE_KHZ 24750000 #define AD9081_RX_LINK_CLK 375000000 #define AD9081_RX_MAIN_DECIMATION 1 #define AD9081_RX_CHAN_DECIMATION 1 #ifndef AD9081_RX_MAIN_NCO_SHIFT #define AD9081_RX_MAIN_NCO_SHIFT 0 #endif #ifndef AD9081_RX_CHAN_NCO_SHIFT #define AD9081_RX_CHAN_NCO_SHIFT 0 #endif #ifndef AD9081_ADC_NYQUIST_ZONE #define AD9081_ADC_NYQUIST_ZONE AD9081_ADC_NYQUIST_ZONE_EVEN #endif #define AD9081_RX_JESD_MODE 11 #define AD9081_RX_JESD_SUBCLASS 1 #define AD9081_RX_JESD_VERSION 2 #define AD9081_RX_JESD_M 4 #define AD9081_RX_JESD_F 2 #define AD9081_RX_JESD_K 128 #define AD9081_RX_JESD_N 16 #define AD9081_RX_JESD_NP 16 #define AD9081_RX_JESD_CS 0 #define AD9081_RX_JESD_L 4 #define AD9081_RX_JESD_S 1 #define AD9081_RX_JESD_HD 0 // ad9081 device tree instantiation snippet &trx0_ad9081 { adi,tx-dacs { #size-cells = <0>; #address-cells = <1>; adi,dac-frequency-hz = /bits/ 64 <AD9081_DAC_FREQUENCY>; adi,main-data-paths { #address-cells = <1>; #size-cells = <0>; adi,interpolation = <AD9081_TX_MAIN_INTERPOLATION>; trx0_ad9081_dac0: dac@0 { reg = <0>; adi,crossbar-select = <&trx0_ad9081_tx_fddc_chan0>; adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_TX_MAIN_NCO_SHIFT>; }; trx0_ad9081_dac1: dac@1 { reg = <1>; adi,crossbar-select = <&trx0_ad9081_tx_fddc_chan1>; adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_TX_MAIN_NCO_SHIFT>; }; trx0_ad9081_dac2: dac@2 { reg = <2>; adi,crossbar-select = <&trx0_ad9081_tx_fddc_chan2>; adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_TX_MAIN_NCO_SHIFT>; }; trx0_ad9081_dac3: dac@3 { reg = <3>; adi,crossbar-select = <&trx0_ad9081_tx_fddc_chan3>; adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_TX_MAIN_NCO_SHIFT>; }; }; adi,channelizer-paths { #address-cells = <1>; #size-cells = <0>; adi,interpolation = <AD9081_TX_CHAN_INTERPOLATION>; trx0_ad9081_tx_fddc_chan0: channel@0 { reg = <0>; adi,gain = <AD9081_GAIN>; /* value * 10^(gain_dB/20) */ adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_TX_CHAN_NCO_SHIFT>; }; trx0_ad9081_tx_fddc_chan1: channel@1 { reg = <1>; adi,gain = <AD9081_GAIN>; /* value * 10^(gain_dB/20) */ adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_TX_CHAN_NCO_SHIFT>; }; trx0_ad9081_tx_fddc_chan2: channel@2 { reg = <2>; adi,gain = <AD9081_GAIN>; /* value * 10^(gain_dB/20) */ adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_TX_CHAN_NCO_SHIFT>; }; trx0_ad9081_tx_fddc_chan3: channel@3 { reg = <3>; adi,gain = <AD9081_GAIN>; /* value * 10^(gain_dB/20) */ adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_TX_CHAN_NCO_SHIFT>; }; }; adi,jesd-links { #size-cells = <0>; #address-cells = <1>; trx0_ad9081_tx_jesd_l0: link@0 { #address-cells = <1>; #size-cells = <0>; reg = <0>; adi,tpl-phase-adjust = <AD9081_JRX_TPL_PHASE_ADJUST>; adi,logical-lane-mapping = /bits/ 8 <0 1 2 3 4 5 6 7>; adi,link-mode = <AD9081_TX_JESD_MODE>; /* JESD Quick Configuration Mode */ adi,subclass = <AD9081_TX_JESD_SUBCLASS>; /* JESD SUBCLASS 0,1,2 */ adi,version = <AD9081_TX_JESD_VERSION>; /* JESD VERSION 0=204A,1=204B,2=204C */ adi,dual-link = <0>; /* JESD Dual Link Mode */ adi,converters-per-device = <AD9081_TX_JESD_M>; /* JESD M */ adi,octets-per-frame = <AD9081_TX_JESD_F>; /* JESD F */ adi,frames-per-multiframe = <AD9081_TX_JESD_K>; /* JESD K */ adi,converter-resolution = <AD9081_TX_JESD_N>; /* JESD N */ adi,bits-per-sample = <AD9081_TX_JESD_N>; /* JESD NP' */ adi,control-bits-per-sample = <AD9081_TX_JESD_CS>; /* JESD CS */ adi,lanes-per-device = <AD9081_TX_JESD_L>; /* JESD L */ adi,samples-per-converter-per-frame = <AD9081_TX_JESD_S>; /* JESD S */ adi,high-density = <AD9081_TX_JESD_HD>; /* JESD HD */ }; }; }; adi,rx-adcs { #size-cells = <0>; #address-cells = <1>; adi,adc-frequency-hz = /bits/ 64 <AD9081_ADC_FREQUENCY>; adi,nyquist-zone = <AD9081_ADC_NYQUIST_ZONE>; adi,main-data-paths { #address-cells = <1>; #size-cells = <0>; trx0_ad9081_adc0: adc@0 { reg = <0>; adi,decimation = <AD9081_RX_MAIN_DECIMATION>; adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_RX_MAIN_NCO_SHIFT>; adi,nco-mixer-mode = <AD9081_ADC_NCO_ZIF>; /* NCO off, no mixing */ //adi,crossbar-select = <&trx0_ad9081_rx_fddc_chan0>; /* Statically assigned */ }; trx0_ad9081_adc1: adc@1 { reg = <1>; adi,decimation = <AD9081_RX_MAIN_DECIMATION>; adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_RX_MAIN_NCO_SHIFT>; adi,nco-mixer-mode = <AD9081_ADC_NCO_ZIF>; /* NCO off, no mixing */ //adi,crossbar-select = <&trx0_ad9081_rx_fddc_chan1>; /* Statically assigned */ }; trx0_ad9081_adc2: adc@2 { reg = <2>; adi,decimation = <AD9081_RX_MAIN_DECIMATION>; adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_RX_MAIN_NCO_SHIFT>; adi,nco-mixer-mode = <AD9081_ADC_NCO_ZIF>; /* NCO off, no mixing */ //adi,crossbar-select = <&trx0_ad9081_rx_fddc_chan4>; /* Statically assigned */ }; trx0_ad9081_adc3: adc@3 { reg = <3>; adi,decimation = <AD9081_RX_MAIN_DECIMATION>; adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_RX_MAIN_NCO_SHIFT>; adi,nco-mixer-mode = <AD9081_ADC_NCO_ZIF>; /* NCO off, no mixing */ //adi,crossbar-select = <&trx0_ad9081_rx_fddc_chan5>; /* Statically assigned */ }; }; adi,channelizer-paths { #address-cells = <1>; #size-cells = <0>; trx0_ad9081_rx_fddc_chan0: channel@0 { reg = <0>; adi,decimation = <AD9081_RX_CHAN_DECIMATION>; adi,digital-gain-6db-enable = <0>; adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_RX_CHAN_NCO_SHIFT>; }; trx0_ad9081_rx_fddc_chan1: channel@1 { reg = <1>; adi,decimation = <AD9081_RX_CHAN_DECIMATION>; adi,digital-gain-6db-enable = <0>; adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_RX_CHAN_NCO_SHIFT>; }; trx0_ad9081_rx_fddc_chan4: channel@4 { reg = <4>; adi,decimation = <AD9081_RX_CHAN_DECIMATION>; adi,digital-gain-6db-enable = <0>; adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_RX_CHAN_NCO_SHIFT>; }; trx0_ad9081_rx_fddc_chan5: channel@5 { reg = <5>; adi,decimation = <AD9081_RX_CHAN_DECIMATION>; adi,digital-gain-6db-enable = <0>; adi,nco-frequency-shift-hz = /bits/ 64 <AD9081_RX_CHAN_NCO_SHIFT>; }; }; adi,jesd-links { #size-cells = <0>; #address-cells = <1>; trx0_ad9081_rx_jesd_l0: link@0 { reg = <0>; adi,converter-select = <&trx0_ad9081_rx_fddc_chan0 FDDC_I>, <&trx0_ad9081_rx_fddc_chan1 FDDC_I>, <&trx0_ad9081_rx_fddc_chan4 FDDC_I>, <&trx0_ad9081_rx_fddc_chan5 FDDC_I>; adi,logical-lane-mapping = /bits/ 8 <0 1 2 3 4 5 6 7>; adi,link-mode = <AD9081_RX_JESD_MODE>; /* JESD Quick Configuration Mode */ adi,subclass = <AD9081_RX_JESD_SUBCLASS>; /* JESD SUBCLASS 0,1,2 */ adi,version = <AD9081_RX_JESD_VERSION>; /* JESD VERSION 0=204A,1=204B,2=204C */ adi,dual-link = <0>; /* JESD Dual Link Mode */ adi,device-id = <3>; adi,converters-per-device = <AD9081_RX_JESD_M>; /* JESD M */ adi,octets-per-frame = <AD9081_RX_JESD_F>; /* JESD F */ adi,frames-per-multiframe = <AD9081_RX_JESD_K>; /* JESD K */ adi,converter-resolution = <AD9081_RX_JESD_N>; /* JESD N */ adi,bits-per-sample = <AD9081_RX_JESD_NP>; /* JESD NP' */ adi,control-bits-per-sample = <AD9081_RX_JESD_CS>; /* JESD CS */ adi,lanes-per-device = <AD9081_RX_JESD_L>; /* JESD L */ adi,samples-per-converter-per-frame = <AD9081_RX_JESD_S>; /* JESD S */ adi,high-density = <AD9081_RX_JESD_HD>; /* JESD HD */ }; }; }; };
The main differences from the Analog example designs are as follows:
I have set AD9081_TX_MAIN_INTERPOLATION and AD9081_TX_CHAN_INTERPOLATION to 1. According to the AD9081/AD9082 software development guide, this should result in the virtual converters being mapped 1-to-1 directly to the DACs.
In main-data-paths, under tx-dacs, I have instantiated four data paths (normally this would be two for a design with upmixing and my JESD parameters).
In channelizer-paths, under tx-dacs, I have instantiated four channelizer paths (normally this would be two for a design with upmixing and my JESD parameters).
jesd-links, under tx-dacs, is as it normally would be.
I have set AD9081_RX_MAIN_DECIMATION and AD9081_RX_CHAN_DECIMATION to 1. According to the AD9081 software development guide, this doesn't result in bypass operation unlike for the DACs, but it does stop decimation from occurring.
In main-data-paths, under rx-adcs, I have instantiated four data paths (as normal for M=4), but I have set nco-mixer-mode to AD9081_ADC_NCO_ZIF to turn off downmixing.
In channelizer-paths, under rx-adcs, I have instantiated four channelizer paths (as normal for M=4, with ADC 2 mapping to Channel 4 and ADC 3 mapping to Channel 5 as done in other example designs).
jesd-links, under rx-adcs, is configured to select only the FDDC_I parts of the channelizers, rather than FDDC_I and FDDC_Q as would be used in a design with downmixing.
Was this the right approach?
Many thanks,
Kari
(Note 1, the nco-mode variable that appears in Analog device trees defining this doesn't appear in the C file that reads the device tree - I believe this may be an mistake and an update of the variable name from nco-mode to nco-mixer-mode in the device tree example files may have been forgotten.
Note 2, I have also changed the clocking to use the RFAUX8 output of the ADRF4360 and the selected output of the ADRF5020 as the DAC clock input frequency is <8 GHz, but I haven't discussed these changes above because I have high confidence that they will work)
Added additional notes
[edited by: Salisen at 1:13 PM (GMT -5) on 24 Jan 2022]