Documentation regarding implemenation of DDS (Transport layer) in FPGA Reference design.

Hello, 

I was wondering if there was any kind of documentation (or any reference) that I could follow to understand the implementation of the DDS core in the FPGA reference design? Unfortunately, Im a newbie and there are a lot of files related to the DDS in the design and its becoming incredibly confusing to follow for me, so apologies for that! 

Im running the 2019_R1 version on the a10soc + DAQ2. 

Any kind of information (even if vague) on the structure/architecture of the DDS implemented would be really really appreciated! 

Thank you so much for your time and hope you have a great day! 

Top Replies

  • +1
    •  Analog Employees 
    on Jan 15, 2021 1:50 PM 1 month ago

    Hi,

    Unfortunately, we only have documentation regarding the DDS at the level of a black box.
    You can control the frequency and the amplitude of the sine outputted by the DDS.
    What is your end goal for understanding the DDS? Maybe I can give you a few hints.
    There is a lot of documentation online regarding the principle of how a DDS works and you can find comments through out the code that can help you understand what is what...
    wiki.analog.com/.../axi_dac_ip
    Click on expand regmap for the DAC Channel

    Andrei 

  • Hello Andrei, 

    Really sorry about the late reply, unfortunately my health has not been keeping up with me. 

    Thank you so much for your reply, my main question was to see if there was any documentation about how the DDS is interfaced with the transport layer module. The reason I'm asking this question is because I'm trying to implement a frequency sweep (chirp) module in fabric, which interfaces with the transport layer https://ez.analog.com/fpga/f/q-a/538765/generating-a-chirp-sweep-signal-using-a10soc-and-fmc-daq2-boards

    Since the frequency sweep module I'm looking to make uses a multicore-DDS I wanted to see how the DDS is being implemented in the reference design, so that I could use that framework (mostly just the interface itself) and be able to place my module infront of the transport layer. Basically since I'm very new to the FPGA world, and this project is huge i just wanted a point of reference that I could look at in terms of connecting the module correctly to the transport layer. 

    With that in mind, I was wondering if there was anything you could point me to which could help me with this? How could I place my own module infront of the transport layer and disconnect the DMA, DDS etc. Most importantly, what are the ports I need to connect to (for example dac_ddata input) and what data format are the expecting. 

    Thank you so much for your time and effort! I really appreciate the support. 

    Warm Regards, 

    Udai

  • 0
    •  Analog Employees 
    on Jan 27, 2021 8:35 AM 1 month ago in reply to URathore946

    Hi Udai,

    Hope you get better.

    You can start from here. As you probably know a generic DDS consists of a phase accumulator and a phase to amplitude converter. You only have to deal with the phase accumulator(the easy part).

    That phase to amplitude convertor is controlled by a frequency word  that determines a timely overflow(the actual period of the sinewave). Change that phase to accumulator according to your needs for the chirp sweep.

    You can add the ad_dds.v directly in the block design as an RTL module.

    If you want to keep both the external DDS and DMA data you have to include a multiplexer in the block design. For this you can use https://github.com/analogdevicesinc/hdl/blob/master/library/common/ad_mux.v

    Andrei

  • Hello Andrei, 

    Firstly thank you so much for your incredibly quick and helpful reply, that clears up a lot of confusion for me straight of the bat. And Thank you so much for explaining it in such a basic way, it really helped me a lot!! 

    I just had a few more questions building on that: 

    1. A really basic question, but just to clarify, ad_dds_sine_cordic (or cordic DDS) is the dds being used right? I can tell there are two possible DDS's cordic and polynomial (ad_dds_sine) which can be used and as far as I can tell (from the quartus project) that the cordic is being utilised. 

    2. This question is a bit more specific: I wanted to know what CLK_RATIO is and how its being used? The reason I ask this is because, as far as I can tell, CLK_RATIO is primarily being used for generating the subcores, and getting an understanding of this register would really help me understand the relation between the subcores, sample rate and system clock. 

        I traced CLK_RATIO back to the regmap and it is being defined as :  localparam DATA_PATH_WIDTH = OCTETS_PER_BEAT * 8 * NUM_LANES / NUM_CHANNELS / BITS_PER_SAMPLE;

    Even just a clarification of this equation ^ would be incredibly appreciated as I'm not sure in what order the arithmetic is being performed. 

    3. Lastly, apologies for this question but how exactly can I do this: 

    You can add the ad_dds.v directly in the block design as an RTL module.

    I'm sorry about this question, while I'm familiar with HDL and the concepts of RTL etc. I'm incredibly new to Quartus/Xilinx and dont really know how to get around these projects as well *yet*. 

    Thank you so so much for your time and effort towards answering all of my questions, words cannot describe how much I appreciate the support. 

    Hope you have a great day! 

    Regards,

    Udai 

  • 0
    •  Analog Employees 
    on Jan 28, 2021 10:41 AM 1 month ago in reply to URathore946

    Hi Udai,

    1. A really basic question, but just to clarify, ad_dds_sine_cordic (or cordic DDS) is the dds being used right? I can tell there are two possible DDS's cordic and polynomial (ad_dds_sine) which can be used and as far as I can tell (from the quartus project) that the cordic is being utilised. 

    Yes, our designs use the CORDIC version, which is a bit more precise than the polynomial version. The polynomial uses more DSP's and the CORDIC more FF and LUT.

    2. This question is a bit more specific: I wanted to know what CLK_RATIO is and how its being used? The reason I ask this is because, as far as I can tell, CLK_RATIO is primarily being used for generating the subcores, and getting an understanding of this register would really help me understand the relation between the subcores, sample rate and system clock. 

    The clock ratio instantiates more DDS cores, but it does not affect the register map, other than letting the software know what is the clock ratio, that is used to calculate the frequency word.
    In the case of daq2 the clock ratio is 4. This ratio is chosen for the maximum sampling frequency 1GSPS, resulting in a internal clock of 250M, which is closer to the upper limit of what some FPGAs can handle and going lower helps with the design timing. So, in one clock cycle(250M) we need to generate 4 consecutive samples in order to "keep the DAC happy". This is done by 4 DDS modules(phase to amplitude converters). the phase accumulator part is all in one place.
    When the frequency is changed by software the 4 phases are align to the new frequency word. The counter increment will be multiplied with clock ration to get a continuity of the 4 consecutive samples generated at t to t+1 samples.

        I traced CLK_RATIO back to the regmap and it is being defined as :  localparam DATA_PATH_WIDTH = OCTETS_PER_BEAT * 8 * NUM_LANES / NUM_CHANNELS / BITS_PER_SAMPLE;

     This parameters are related to the sampling frequency that is translated into the JESD lane rate.
    If you are at the beginning, I would keep thing simple for now and go with the maximum sample rate, and change it if you need in the future. You can learn more about the JESD framework starting from here.

    3. Lastly, apologies for this question but how exactly can I do this: 

    You can add the ad_dds.v directly in the block design as an RTL module.

    I'm sorry about this question, while I'm familiar with HDL and the concepts of RTL etc. I'm incredibly new to Quartus/Xilinx and dont really know how to get around these projects as well *yet*. 

    I see now that you are using an Intel carrier, I thought of our Xilinx flow. For intel which uses qsys, you can't directly integrate RTL code in the qsys design, as far as I know. You need to packetize the Verilog code into an IP using TCL. There are examples of this on our github/library, look for files named *_hw.tcl.
    e.g.: https://github.com/analogdevicesinc/hdl/blob/master/library/axi_ad9144/axi_ad9144_hw.tcl
    For
    more info see Intel/Altera documentation.

    Andrei