0
\$\begingroup\$

VLSI/FPGA beginner here.

I interfaced my Digilent Arty A7-35 with a DAC, using basic DDS (implementing timing diagram of the DAC on FPGA) and interfacing LUT(s) to form sine waves of multiple frequencies.

Trouble is, as LUT values increase, the output frequency of the sine wave decreases, exponentially.

Below is the graph plotted in Excel:

[![enter image description here][1]][1]

I have observed that the output sine waveform becomes smoother with an increase in LUT values, which is obvious due to an increase in precision, and a decrease in the number of jumps between values. However, a professor informed me that there is no certainty that frequency will definitely decrease with an increase in the number of LUT values, but rather that there will be a change.

There are two problems that I am facing:

  1. My observations after increasing LUT values to 2^16, contradict the professor (not completely, but as of now, it is definitely decreasing).
  2. I need to produce a sine wave of less frequency with a lower number of LUT values, because of memory constraints.

My questions:

  1. What is the relation between LUT values and output frequency?
  2. Is it possible to produce a sine wave of lower frequency with lesser LUT values?

I could think of one solution: Induce a delay between sending data to the DAC, by which I can space out the data, thereby causing frequency to decrease, but implementing this would be a hassle.

Additionally, reducing the number of LUT values could help reduce timing issues.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

The number of LUT values corresponds simply to the temporal resolution of your output waveform. So if you have an 8-bit LUT, your output waveform cannot be more accurate than 256 steps if reading directly from the LUT, and will have less resolution when outputting at higher frequencies.

The frequency of the DDS output waveform is controlled by how fast you increment your phase accumulator. If you set the phase accumulator to increment at one LUT value per cycle, then the frequency of the output waveform will be simply the sample rate divided by the number of LUT entries. If you increased to incrementing by two LUT addresses per cycle, you double the output waveform frequency.

The beauty of DDS is that it allows you to also increment by fractional values to control the waveform frequency - however doing so also introduces jitter and spurious frequencies into the output waveform. This is because the fraction position within the LUT gets rounded to the nearest sample. This is where having more entries in the LUT helps somewhat - the maximum frequency drops, but the temporal resolution increases - you get less rounding of the phase accumulator value.

To output at lower frequencies, you need to add additional resolution to the phase accumulator value. This could mean increasing the length of the LUT, but that becomes impractical at lower frequencies as you have found out. Instead, you keep the LUT size the same, but still increase the phase accumulator bit size. To select the output value, you simply truncate the lower bits of the phase value when feeding into the LUT. This has the effect of reading the same sample repeatedly, giving you a stepped waveform.

Of course for very accurate waveforms, or much lower frequencies, a stepped waveform is undesirable. As such you can start doing some linear approximations to increase the output resolution. A simple linear interpolator can be made by taking your phase accumulator value, and reading two samples from the LUT, one either side of the value, then interpolate between the two.

Lets say your LUT is 10bit, and your accumulator is 16bit:

  1. Set x1 = accum[15:6] and x2 = x1 + 1.

  2. Read from addresses x1 and x2 from your LUT. This gives you the bounding points for the sample value y1 = LUT[x1] and y2 = LUT[x2].

  3. Your output value is then linearly interpolated between the two values:

    y = (y1 * (64 - accum[5:0])) + y2 * accum[5:0])

\$\endgroup\$
3
  • \$\begingroup\$ Of course, I have used a counter for this purpose, are you referring to that? \$\endgroup\$
    – DaveFenner
    Commented Feb 8 at 11:40
  • \$\begingroup\$ Your counter is essentially the phase accumulator, with an increment of 1. If you make that counter larger width and truncate the LSBs as mentioned above, that will give you a lower frequency output \$\endgroup\$ Commented Feb 8 at 12:11
  • \$\begingroup\$ @MaheshNamboodiri See the final paragraph/numbered list. It shows the calculations required for a rudementary linear interpolation. \$\endgroup\$ Commented Feb 8 at 16:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.