Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] library: common: ad_dds: Incorrect Calculation of Phase Increment #1408

Open
ekigwana opened this issue Aug 2, 2024 · 2 comments
Open
Labels

Comments

@ekigwana
Copy link
Contributor

ekigwana commented Aug 2, 2024

Describe the bug
The formula to calculate the phase increment for the DDS is incorrect.

To Reproduce
The formula https://github.com/analogdevicesinc/hdl/blob/main/docs/library/common/ad_dds/index.rst?plain=1#L191 should be:

INCR = \frac{f_{out} * (2^{phaseDW} - 1)}{f_{if} * clkratio}

For a frequency output of 1 Hz it is clear that 1 * ^{phaseDW} will overflow!
With clock ratio multiplied in the numerator in the case of a clock ratio of two
The output frequency of the DDS quadruples. So instead of getting 12.5 kHz out, the output is 50 kHz. With clock ratio multiplied by the interface frequency in the denominator the frequency is always what is expected in the simulation. The only difference in that there are clock ratio consecutive samples on every clock.

I wondered what the Linux kernel driver is doing and checked here https://github.com/analogdevicesinc/linux/blob/main/drivers/iio/frequency/cf_axi_dds.c#L886 and it appears to follow the spirit of what I mentioned above. However, using iio-oscope connected to an adrv9009-zu11eg SDR I set the frequency of TX1 to 39.999985 MHz and a DDS Mode of One CW Tone

Steps to reproduce the behavior:

  1. Using iio-oscope connect to an adrv9009-zu11eg SDR or any SDR using multiple JESD lanes for TX
  2. Set the frequency of TX1 to 39.999985 MHz on the ADRV9009 tab
  3. Go to the debug tab by clicking on it
  4. Select the 'axi-adrv9009-tx-hpc' device under Device Selection combo box
  5. Set the Source to 'AXI_CORE' under Register Map Settings
  6. Set the read address byte to 0x0404 according to https://wiki.analog.com/resources/fpga/docs/axi_dac_ip
  7. Click read and observe results
  8. DDS_INC_1[15:0] indicates 21333

Expected behavior
I expect to see:
DDS_INC_1[15:0] = (39.999985 MHz * (2^16-1)/(122.88 MHz * 2) = int(10 666.4999)

The value read back is is consistent with ignoring the clock ratio altogether
DDS_INC_1[15:0] = (39.999985 MHz * (2^16-1)/(122.88 MHz) = int(21 332.9998)
The kernel folks need to account for the clock ratio here otherwise the frequency is incorrect

The value that the documentation says it should be is:
DDS_INC_1[15:0] = (39.999985 MHz * 2^16) * 2)/(122.88 MHz) = int(42 666.6507)

Desktop (please complete the following information):

  • Project name and used carrier board: adrv9009-zu11eg fmc
  • Used Software: Linux, IIO-Oscilloscpe (master)
  • Tool version Vivado 2023.2
  • HDL Release version: [adrv9009zu11eg] git branch <hdl_2021_r2> git clean [2023-03-31 20:39:12] UTC
@ekigwana ekigwana added the bug label Aug 2, 2024
@AndreiGrozav
Copy link
Contributor

Hi.

Sorry for the delayed reply.
The formula is correct, I guess you misinterpreted it because is not rendered. The frequency ration is a multiplying factor of the equation, it is not part of the divisor.
Have a look at https://wiki.analog.com/resources/fpga/docs/dds#frequency_-_dds_incr

Andrei

@ekigwana
Copy link
Contributor Author

Hi.

Sorry for the delayed reply. The formula is correct, I guess you misinterpreted it because is not rendered. The frequency ration is a multiplying factor of the equation, it is not part of the divisor. Have a look at https://wiki.analog.com/resources/fpga/docs/dds#frequency_-_dds_incr

Andrei

If that formula is correct, how come the register value does not match on the development board and yet the output frequency is correct?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants