Search code examples
vhdltrigonometryfpga

How to add a LUT in VHDL to generate a sine


I've made an I2S transmitter to generate a "sound" out of my FPGA. The next step I would like to do, is create a sine. I've made 16 samples in a LUT. My question is how to implement something like this in VHDL. And also how you load the samples in sequence. Who has tried this already, and could share his knowledge?

I've made a Lookup table with 16 samples:

0               0π
0,382683432     1/16π
0,707106781     1/8π
0,923879533     3/16π
1               1/4π
0,923879533     5/16π
0,707106781     3/8π
0,382683432     7/16π
3,23114E-15     1π
-0,382683432    1 1/16π
-0,707106781    1 1/8π
-0,923879533    1 3/16π
-1              1 1/4π
-0,923879533    1 5/16π
-0,707106781    1 3/8π
-0,382683432    1 7/16π
-6,46228E-15    2π

Solution

  • The simplest solution is to make a ROM which is just a big case statement.

    FPGA synthesis tools will map this on ore more LUT's.

    Note that for bigger tables only 1/4 of the wave is stored, the other values are derived.


    I would like to send out a 24 bit samples, do you also know how to do that with this data (binary!)?

    24 bits (signed) mean you have to convert your floating point values to integer values in the range -8388608..8388607. (For symmetry reason you would use -8388608..8388607)

    Thus multiply the sine values (which you know are in the range -1..1) with 8388607.

    The frequency of the sine depends on how fast (many samples per second) you send.