Search code examples
floating-pointvhdltrigonometryfpgaxilinx

Trigonometric functions for single-precision floating point numbers in VHDL


How to calculate trigonometric functions: arctangent, arcsine or, at least, sine and cosine in VHDL? I have a value in IEEE 754 single-precision floating-point format (t.e. a sign, a mantissa, an exponent) (picture below). As I know, it could be implemented as a look-up table or via CORDIC algorithm. Both implementations are suitable for me. Precision up to Pi/1000 would be enought. The implementation should be synthesizable. Device - Artix-7 FPGA.

Similar code in C:

yaw   = atan2(2.0f * (q[1] * q[2] + q[0] * q[3]), q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3]);   
pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2]));
roll  = atan2(2.0f * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3]);

Solution

  • You said "I have a value in IEEE 754 single-precision floating-point format ". I would definitely try to avoid using IEEE format numbers. It make things unnecessary complex. I don't know where that number came from or how you got that into the FPGA but the first thing to do is to try to convert that to a fixed point format.

    Xilinx have off-the-shelf Cordic code for you for Arc Tan. That would make your life a lot easier. As expected it does not accept IEEE numbers but does work with "signed fractions" and precision sizes between 8 and 48 bits. You should get their Cordic IP manual and read up on what it can do. I have not seen Cordic code for asin yet.

    You might need to put in some effort to control the I/O as the IP only works with streaming AXI4 interfaces.

    What does surprise me is that you provide you example in C code but are talking about using VHDL. I would expect anybody familiar with C to use (System) Verilog as the langues are very, very close. Also at the risk of upsetting some people: if at all possible use System Verilog. Verilog has had several more iterations then VHDL and is much closer to how modern languages are used these days.