Sine Wave on FPGA - Page 1
Forum section: electronics / general

author: knight
author_rank: Regular Contributor
timestamp: March 18, 2022, 10:47:41 am
content: I want to make a sine wave using the approximation shown in this video,I have an 8-bit phase accumulator which goes from 0 to 255 and then overflows. I want to use this 0-255 output and create the sine wave. Can anyone give an idea how to do it using the equations in the video?Thanks

author: woofy
author_rank: Frequent Contributor
timestamp: March 18, 2022, 11:42:31 am
content: Quote from: knight on March 18, 2022, 10:47:41 amIf you have a RAM block available, use the output as an address to the RAM which will be loaded with a pre-calculated sine table.

author: knight
author_rank: Regular Contributor
timestamp: March 18, 2022, 11:57:45 am
content: Quote from: woofy on March 18, 2022, 11:42:31 amI want to avoid using RAM as i plan to increase bit width of phase accumulator to 16 bits.

author: emece67
author_rank: Frequent Contributor
timestamp: March 18, 2022, 12:12:25 pm
content: .

author: knight
author_rank: Regular Contributor
timestamp: March 18, 2022, 12:43:12 pm
content: Quote from: emece67 on March 18, 2022, 12:12:25 pmFor 128<x<256, it would be just the negative/complement of the original formula, right?

author: emece67
author_rank: Frequent Contributor
timestamp: March 18, 2022, 01:22:55 pm
content: .

author: Berni
author_rank: Super Contributor
timestamp: March 18, 2022, 01:37:13 pm
content: The most efficient method for generating high resolution sine waves in hardware is CORDIC:https://zipcpu.com/dsp/2017/08/30/cordic.htmlThis is commonly used as a way of generating sine wave signals in the digital world. But it is not quite all that simple to do.Easier method that should still work well is a lookup table with interpolation between samples. If you stick to power of 2 numbers for your table size, then you can simplify the interpolation math down into just bitshit and addition operations. So it should be pretty compact and fast.

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 18, 2022, 06:09:44 pm
content: Using a table storing one period is definitely one easy approach and doesn't necessarily require a huge amount of samples. You just need to implement some interpolation on top of that, and the degree of interpolation + size of the table will determine your accuracy. A reasonably-sized table with even just linear interpolation is often more than good enough (but we know nothing about the OP's requirements.)You don't need a lot of memory. Even a small FPGA with a few KBytes of EBR will absolutely do the trick. One thousand samples is plenty for most cases. But you need interpolation!The benefit of the table-based approach with interpolation is that it can be reused for any kind of periodic signal, whereas implementations specific to sine functions will just generate sine waves. So unless you're VERY short on memory (like an ultra-small CPLD), I'll favor that.The other approach is CORDIC as said above. Actually, the base idea is a rotation matrix, something that I also use in software for generating continuous sine waves (much faster, and usually more accurate than implementing an approximation of sin(x) for any x, when you only need successive values with a fixed step in x.)

author: pcprogrammer
author_rank: Super Contributor
timestamp: March 18, 2022, 06:55:41 pm
content: When it is only a sine that is needed one can suffice with just a quarter sine in a lookup table.See:https://www.fpga4fun.com/DDS.html

author: ejeffrey
author_rank: Super Contributor
timestamp: March 18, 2022, 07:27:50 pm
content: Quote from: knight on March 18, 2022, 11:57:45 amYou don't need the lookup table width to match your accumulator. In fact it rarely does. The accumulator width sets your frequency resolution while the lookup table width is normally close to your DAC resolution and contributes to spurs. So a common approach is to have a 32-48 bit accumulator for very fine frequency resolution but only a 10-12 bit lookup table.As mentioned your lookup table only needs to hold 1/4 cycle, the rest can be calculated from that. Interpolation helps, a lot and dithering can spread out the spurs to make them less objectionable.

author: BrianHG
author_rank: Super Contributor
timestamp: March 18, 2022, 07:32:10 pm
content: Unless you store your table in logic gates, careful that you do not needlessly over-minimize.For example, Altera's M9K blockram has the smallest possible size of 1k X 8, or 256word x 32, or 512word x16.Each of these will utilize 1 block ram chunk.Even if you think you are smart and say I will squeeze my quarter sine table into 64words by 8 bits, this will still consume the same 1 blockram chunk as making a table of 1024words by 8 bits, or 256words by 32 bits. Only the extra bits are thrown in the garbage and cannot be used by any other HDL code.

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 18, 2022, 07:47:18 pm
content: Quote from: BrianHG on March 18, 2022, 07:32:10 pmIndeed.

author: NorthGuy
author_rank: Super Contributor
timestamp: March 18, 2022, 07:52:42 pm
content: This is FPGA, so you don't need to use tricks to do things fast. With few pipelined DSPs you can calculate sine values with Taylor series at very high frequency. 400-500 MHz may be feasible. In reality, you don't really need it that fast.You can use various tricks to optimize your caluclations, but this won't really make it faster, but rather save the area. That is your efforts will lead to using less DSPs, or less logic, but they will not lead to increased speed.Thus, unless you're really concerned with using few extra DSPs, I would use Taylor series. Since you don't need high precision, you'll need only 2-3 members.

author: emece67
author_rank: Frequent Contributor
timestamp: March 18, 2022, 09:01:29 pm
content: .

author: free_electron
author_rank: Super Contributor
timestamp: March 18, 2022, 09:14:30 pm
content: Quote from: SiliconWizard on March 18, 2022, 06:09:44 pmyou only need a quarter period. count up, count down, change sign, count up count down , change sign repeat ...

author: BrianHG
author_rank: Super Contributor
timestamp: March 18, 2022, 09:42:33 pm
content: Quote from: free_electron on March 18, 2022, 09:14:30 pmMore like use the top 2 most significant bits of your position counter to decide the direction of addressing the table & if the output should be set to a negative value while all the least significant bits address your FPGA blockram. At least with this, you can randomly jump to any angle within your sine table.Then look at the minimum FPGA blockram size and strategically choose you final resolution of your sine table.

author: hamster_nz
author_rank: Super Contributor
timestamp: March 19, 2022, 06:11:20 am
content: I've added an new thread on how CORDIC works,, including a VHDL implementation.Hopefully those interested find it of value.CORDIC is really pretty neat, and can also be used to calculate atan2(y,x) and k*sqrt(x^2+y^2) too.