1
\$\begingroup\$

I am supposed to generate a sine wave in cyclone 2 altera? I get that I have to store the values in LUT or some memory. I think cyclone 2 uses a 4 input LUT. I am not sure how I should go on with the next step. How do I give or feed the values and Is there a way to store more values than a single LUT can hold? DAC interface?

For example, SIN is often implemented as a table lookup. If 10 bit angles are good enough resolution, then the whole function can be implemented as a lookup table with 1024 entries. (Actually in the case of SIN, only 1/4 cycle is stored then negated or indexed backwards depending on the actual quadrant, but that is a aside specific to SIN).

I got this from one of the older answers. But what is the 10 bit angle resolution? I guess they are using 1024 samples for 1/4 cycle. Is that right?

\$\endgroup\$
  • \$\begingroup\$ What is your EE question? \$\endgroup\$ – Andy aka May 8 '15 at 13:38
  • \$\begingroup\$ I think it's a short answer: YES :). It's a 10 bit address for the ROM, which gives an amplitude. Implementing such big ROMs/RAMs is better suited for BlockRAMs or AltSyncRAMs, then for LUT based memory. \$\endgroup\$ – Paebbels May 8 '15 at 15:01
  • \$\begingroup\$ What frequency and sample rate? What interface do you need? You probably want to use either a single block RAM or sine sort of compressed lookup table depending on the resolution you need. \$\endgroup\$ – alex.forencich May 8 '15 at 17:02
  • \$\begingroup\$ Frequency and sample rates should be like inputs.As I change them the output would change too. Interface.. I meant connecting the digital values to analog output. How to store the values in ROM? \$\endgroup\$ – Muthu Subramanian May 9 '15 at 15:50
4
\$\begingroup\$

There are three ways todo this (forth listed for completeness) and it comes downto space-time tradeoffs:

Do you do the calculations ahead of time (storage space) or do you do the calculations on the fly (time tradeoff)

1) Look up table. Do the calculations ahead of time & store the information in a ROM/table. By realising you only have to store 1/4 of the waveform can decrease the amount you need to store. However... depending on the accuracy & the number of steps can lead to a very large table

2) Interpolated LUT. A tradeoff between a lookup table and full calculations. Take advance of the change between entries might be well within accepted errors. Sometimes only 3 points are required (NOTE: 3point example is for atan only)

3) CORDIC. (COordinate Rotation DIgital Computer). Basically a hunting algorithm which can be reduced to simple add's and shifts. The accuracy is pretty much governed by the number of computational steps

4) Full taylor expansion. If accuracy is paramount, speed is imporant but local storage isn't an option

My advice. Look into a CORDIC. There are plenty of example cordics in VHDL and an FPGA is perfect for a CORDIC. A project I am working on at the moment heavily uses cordic's (12bit, 14 cycles to settle)

Example cordic in python

#http://code.activestate.com/recipes/576792-polar-to-rectangular-conversions-using-cordic/
def to_polar(x, y):
    'Rectangular to polar conversion using ints scaled by 100000. Angle in degrees.'
    theta = 0
    for i, adj in enumerate((4500000, 2656505, 1403624, 712502, 357633, 178991, 89517, 44761)):
        sign = 1 if y < 0 else -1
        x, y, theta = x - sign*(y >> i) , y + sign*(x >> i), theta - sign*adj
    return theta, x * 60726 // 100000

def to_rect(r, theta):
    'Polar to rectangular conversion using ints scaled by 100000. Angle in degrees.'
    x, y = 60726 * r // 100000, 0
    for i, adj in enumerate((4500000, 2656505, 1403624, 712502, 357633, 178991, 89517, 44761)):
        sign = 1 if theta > 0 else -1
        x, y, theta = x - sign*(y >> i) , y + sign*(x >> i), theta - sign*adj
    return x, y

#if __name__ == '__main__':
#    print(to_rect(471700, 5799460))     # r=4.71700  theta=57.99460
#    print(to_polar(250000, 400000))     # x=2.50000  y=4.00000

Notes on CORDICS and FPGA's http://www.uio.no/studier/emner/matnat/ifi/INF5430/v12/undervisningsmateriale/dirk/Lecture_cordic.pdf

\$\endgroup\$
1
\$\begingroup\$

Generally the way you do this is with a lookup table stored in a block RAM. For example, you could use a 1024 entry table with 8-bit entries. The entries would be calculated with sin or cos and stored in the RAM in an initial block. Then you would use a phase accumulator to read the samples out of the RAM at the correct times and send them to the DAC. If you need a very high resolution, then you need a table with a lot of entries and it can very quickly become too large to fit in FPGA block RAM. In that case, it's possible to use a compressed lookup table. A compressed table stores information that can be used to recreate samples from a much larger lookup table. Here is an example of a quadrature sine/cosine lookup table that has 18 bit phase resolution and 16 bit amplitude resolution, but requires less than 2k lookup table entries across 3 lookup tables: https://github.com/alexforencich/verilog-dsp/blob/master/rtl/sine_dds_lut.v

\$\endgroup\$
0
\$\begingroup\$

I think you are confused about what a LUT (Look Up Table) is.

A LUT is just a memory initialized with fixed values that do not change during normal behaviour.

In a FPGA architecture you have basically LUTs combined with registers. These LUTs are initialized with the values of a truth table to define a combinational output logic of some inputs.

In the case of a Sine Wave you can initialize for example a 1024 depth block memory (due to the high quantity of data) to store the discretized result of a angle input of 10 bit width. That is, for the 360 degrees you calculate the sine result for 1024 divisions angle pieces and use this value to initialize her position. These values must be rounded to the bit width output, so more precision you need more depth and output width and more block memories of the FPGA you have to consume.

That's the initial approach to the problem. In addition you can take advantage of the nature of the sine wave, calculating only values for the first quadrant (0 to 90 degrees) and using some combinational logic to transform any angle to her equivalent value in the first quadrant. You will have the same result but saving 3/4 of block memory.

To do this you can use a Core Wizard from your FPGA vendor or search a HDL template to define a initialized block memory that could be correctly interpreted by the synthesizer.

And as a final step you can use a DAC to pass a digital value from the LUT to a voltage. Bigger the memory, bigger the resolution of this "analogical" sine wave.

That's all. Good Luck

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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