Programmable Modulus Implementation on AD9915

I have a system using that AD9915 that requires adjustment and precise control of the phase, amplitude and frequency.  Currently, we clock the DDS at 2.5GHz which sets the system clock at (1/16) 156.25MHz.  We set the function pins to 0010 to set the FTW using the 32 parallel pins, then 0100 for POW-AMP.  We then set the IO UPDATE.  This is as follows:

Cycle 0: FTW (0010)

Cycle 1: POW+AMP (0100)

Cycle 2: IO UPDATE

It takes use 3 cycles to update phase/frequency/amplitude which would allow us to update every 3/156.25MHz = 19.2ns.

I would like to try to improve the output frequency stepping resolution by using the programmable modulus mode but have some questions regarding its implementation.  My understanding is that, in addition to sending the FTW, we also need to set the 32 bit A and the B registers.  My question is: what is the fastest way to set frequency, phase and amplitude?  Do we need to set the A and B values using 16 bit parallel programming mode? Could we, for example, do something like this:

Cycle 0: POW+AMP (0100)

Cycle 1: FTW (0010)

Cycle 2: A[31:16] (0000)

Cycle 3: A[15:0] (0000)

Cycle 4: B[31:16] (0000)

Cycle 5: B[15:0] (0000)

Cycle 6: IO UPDATE

In this configuration it takes use 7 cycles to update phase/frequency/amplitude which would allow us to update every 7/156.25MHz = 44.8ns.

Is there a better/faster way?

  • 0
    •  Analog Employees 
    on Nov 15, 2019 2:19 AM over 1 year ago

    Hi Flames12,

    Cycle 0: POW+AMP (0100)

    Cycle 1: FTW (0010)

    Cycle 2: A[31:16] (0000)

    Cycle 3: A[15:0] (0000)

    Cycle 4: B[31:16] (0000)

    Cycle 5: B[15:0] (0000)

    Cycle 6: IO UPDATE

    I do see one recommendations that might improve this sequence:

    • If the values of your A and B only vary in the lower 16-bit then you may omit re-updating the higher 16-bits. So this would let you save 1 - 2 cycles. However this doesn't guarantee a deterministic update since the modulation implementation can either update from 5 - 7 cycles.

    I hope this is helpful, so far you are already using the fastest for updating the register. But still, I'll update you when I find other means for this.

    Best Regards

    Louijie

  • Hello Louijie,

    Thank you very much for your reply!  Great suggestion about the updating of only the lower A and B.

    Could you confirm that it is indeed possible to do the following things when using programmable modulus mode:

    - Update the POW+AMP using direct (0100)

    - Update the FTW using direct (0010)

    I suppose another implementation that could increase the speed but foregoes resolution could be:

    - initialize A to 1

    - initialize the upper B bits to 0

    - Only use a smaller number of bits in B (less than 16), say 10.

    This would increase the resolution to fs*(FTW + 1/B[0:15])/(2^32) but obviously the steps would not be regularly spaced...  This would have the advantage that you'd only need to set the lower A register saving 3 cycles.

    Can you comment on whether it is possible to use direct programming while in programmable modulus mode to set POW, AMP & FTW?

    Any comments on the proposed lower B register implementation would also be appreciated.

    Thanks again!

  • 0
    •  Analog Employees 
    on Nov 25, 2019 2:06 AM over 1 year ago in reply to Flames12

    Hi Flames12,

    My colleague verified the portion where POW+AMP updates, followed by an FTW update. It is possible to do so.

    Regarding on your plan to do the following:

    I suppose another implementation that could increase the speed but foregoes resolution could be:

    - initialize A to 1

    - initialize the upper B bits to 0

    - Only use a smaller number of bits in B (less than 16), say 10.

    It can really help in compressing the number of cycles or state transitions needed to perform modulation, however I hope that your application doesn't constrain this method. Allow me to reiterate the content of the datasheet, the formula to derive the frequency is:

    The equation is straightforward but the recommended routine to supply the variables of this equation can be tricky. The steps of this routine are:

    1. The user must first define f0/fS as a ratio of relatively prime integers, M/N.
    2. That is, having converted f0 and fS to integers, M and N, reduce the fraction, M/N, to the lowest terms.
    3. Then, divide M × 2^32 by N. The integer part of this division operation is the value of FTW (Register 0x04[31:0]).
    4. The remainder, Y, of this division operation is Y = (2^32 × M) – (FTW × N) The value of Y facilitates the determination of A and B by taking the fraction, Y/N, and reducing it to the lowest terms.
    5. Then, the numerator of the reduced fraction is A (Register 0x06[31:0]) and the denominator is the B (Register 0x05[31:0]).

    A and B are derived values and truncating their values may not be the ideal approach. Thus, as long as you have an algorithm that can abide to the constrains of having A and B not exceeding 16 bits, then the method would work flawlessly.

    Best Regards

    Louijie