Arctan calculation on FPGA - Page 1
Forum section: electronics / general

author: NiHaoMike
author_rank: Super Contributor
timestamp: April 27, 2021, 02:07:19 pm
content: I have an ADC capturing I/Q samples at 768kHz (from a Tayloe mixer frontend) and sending those samples to a Spartan 6 LX100 FPGA. The object is to decode a FM signal contained in those samples, and research found that good FM decode algorithms use an arctan function.Exactly what would be the best way to calculate arctan on a FPGA? I found many references to the CORDIC algorithm, but also a note that such an algorithm is best for devices without hardware multipliers. The Spartan 6 does have hardware multipliers, so is some other algorithm better for calculating arctan? Note that because communications is such an important part of the design, the design should prioritize performance and robustness over minimizing resource use. (I can consider using as much as half the chip just for communications related tasks on 2x diversity receive channels although I don't think it will need that much.)

author: dtodorov
author_rank: Contributor
timestamp: April 27, 2021, 02:21:49 pm
content: Surely not an expert in FPGA DSPs here, but I'd consider using LUT-based approach, especially if high precision (e.g. > 10bits) is not needed. Probably even initialized BRAM could do the job.

author: filssavi
author_rank: Frequent Contributor
timestamp: April 27, 2021, 02:32:12 pm
content: I am not too familiar with the Spartan 6 architecture, but I bet it would be pretty easy to get up to 16 bit precision with a clever LUT based approach (Implemented in BRAM of course)...Use all trigonometric functions in your favour (symmetries and what not) to reduce your memory footprint, this should at least double your resolution for free, you can also Do linear interpolation between adjacent samples to get even higher resolution.If you use dual port RAM you can also double the throughputCORDIC is very good for high precision stuff (think >24 bits)

author: rstofer
author_rank: Super Contributor
timestamp: April 27, 2021, 03:08:56 pm
content: Maybe this paper will add some ideas:https://www.researchgate.net/publication/259385247_Fast_computation_of_arctangent_functions_for_embedded_applications_A_comparative_analysis

author: ledtester
author_rank: Super Contributor
timestamp: April 27, 2021, 03:43:20 pm
content: Here's an approximation that comes from "Understanding Digital Signal Processing" (2nd Edition) by Richard G. Lyons:That excerpt of the book is also available at:https://www.embedded.com/performing-efficient-arctangent-approximation/

author: Bassman59
author_rank: Super Contributor
timestamp: April 27, 2021, 04:09:41 pm
content: Quote from: ledtester on April 27, 2021, 03:43:20 pmThe Lyons book is the most readable/understandable signal-processing textbook I have come across. Absolutely worth the money.Read it first, and then for more in-depth stuff go to Oppenheim and Schafer.

author: JohnnyMalaria
author_rank: Super Contributor
timestamp: April 27, 2021, 05:21:07 pm
content: Quote from: NiHaoMike on April 27, 2021, 02:07:19 pmI'm doing something similar on a Zynq. I use the Xilinx CORDIC IP for doing IQ to amplitude/phase and the reverse. Though I'm using a version that does not support Spartan 6, an earlier version does:https://www.xilinx.com/support/documentation/ip_documentation/cordic_ds249.pdfTo test it, I create realistic (for my needs) amplitude and phase data, calculate the corresponding IQ data and see how the CORDIC performs. The attached shows it does a very good - and very fast - job. The left-side show the generated amplitude and phase. The right-side show the output from the FPGA implementation when fed with the IQ data. Note, the output data are decimated by a factor of 32 in my application, hence why they appear a little less noisy. Note, the phase wrapping is a different but that's due to an intentional offset change needed for my application.

author: hamster_nz
author_rank: Super Contributor
timestamp: April 28, 2021, 02:27:15 am
content: QuoteThat data rate is so low that you can use a single lookup table to look up successive CORDIC constants and add/subtract to whatever precision you need. It should need very little resources.Mike

author: BrianHG
author_rank: Super Contributor
timestamp: April 28, 2021, 02:37:18 am
content: If you don't mind a SystemVerilog core, then go here:https://opencores.org/projects/cordic_atan_iqIf the idea is to write your own, do not go to the link.

author: Scrts
author_rank: Frequent Contributor
timestamp: April 28, 2021, 01:27:45 pm
content: Quote from: JohnnyMalaria on April 27, 2021, 05:21:07 pmThis is the right approach. Use whatever is available out of the box to validate your concept and if it's bloated and you need to optimize, then you do it after your 1st sample works well. Don't waste time on something that is already available on the shelf.