How do I convert a floating point C code to fixed point?
Asked Answered
C

5

15

I have a C code which uses doubles. I want to be able to run the code on a DSP (TMS320). But the DSP doesn't support doubles, only fixed-point numbers. What is the best way to convert the code into fixed-point? Is there a good C library for fixed-point numbers (implemented as integers)?

Caspar answered 6/12, 2010 at 16:10 Comment(3)
This is a pretty big topic. There's a great discussion in this SO question: #80177. Just about all the answers had some useful nuggets.Guru
Out of curiosity, how does the DSP's compiler represent fixed points? As two integers? For example, how would you add two fixed-point numbers together?Andie
They are represented as 32-bit values (long), with a shift implicit in the type. For example, if you have 16 bits after the point (_iq16), you represent the fixed-point number 1.0 by the integer 65536 in the underlying type. For adding and subtracting fixed point numbers of the same type you can use the standard integer operations. Multiplication needs an extra shift to correct the scaling.Durr
P
8

TI provides a fixed-point library called "IQmath":

http://focus.ti.com/lit/sw/sprc990/sprc990.pdf

Converting involves analyzing your current code - for each variable you need to know what range it can hold, and what precision it needs. Then you can decide which type to store it in. IQMath provides types from q30 with a range of +/-2 and a precision of 0.0000000001 to q1 with a range of ~+/- 1 million and a precision of 0.5.

For operations which can possibly overflow the range of the variables, you need to add checks for overflow, and decide how to handle it - pin it at max, store with a different scale, raise an error, etc.

There is really no way to convert to fixed point without really gaining a deep understanding of the dataflow of your process.

Publishing answered 6/12, 2010 at 20:3 Comment(0)
C
15

The following code defines a type Fixed, using integers as its internal representation. Additions and subtractions are performed simply with the + and - operators. Multiplication is performed using the defined MULT macro.

#include <stdio.h>
typedef int Fixed;

#define FRACT_BITS 16
#define FRACT_BITS_D2 8
#define FIXED_ONE (1 << FRACT_BITS)
#define INT2FIXED(x) ((x) << FRACT_BITS)
#define FLOAT2FIXED(x) ((int)((x) * (1 << FRACT_BITS))) 
#define FIXED2INT(x) ((x) >> FRACT_BITS)
#define FIXED2DOUBLE(x) (((double)(x)) / (1 << FRACT_BITS))
#define MULT(x, y) ( ((x) >> FRACT_BITS_D2) * ((y)>> FRACT_BITS_D2) )

I was using the above code to represent fractions in my image processing algorithm. It was faster than the version which was using doubles and the results were almost exactly the same.

Caspar answered 21/3, 2011 at 11:54 Comment(1)
check this library too: http://www.sf.net/projects/fixedptcLusitania
P
8

TI provides a fixed-point library called "IQmath":

http://focus.ti.com/lit/sw/sprc990/sprc990.pdf

Converting involves analyzing your current code - for each variable you need to know what range it can hold, and what precision it needs. Then you can decide which type to store it in. IQMath provides types from q30 with a range of +/-2 and a precision of 0.0000000001 to q1 with a range of ~+/- 1 million and a precision of 0.5.

For operations which can possibly overflow the range of the variables, you need to add checks for overflow, and decide how to handle it - pin it at max, store with a different scale, raise an error, etc.

There is really no way to convert to fixed point without really gaining a deep understanding of the dataflow of your process.

Publishing answered 6/12, 2010 at 20:3 Comment(0)
G
5

Most DSP toolchains include libraries for floating-point emulation in software. This will be slow, but you should initially build your code with floating-point support, then profile to see if there are just a few places that you need to convert to fixed-point to get sufficient performance. You will also need to have the floating-point stuff running to provide a comparison as you port to fixed-point, to make sure you haven't lost anything in the process.

Guru answered 6/12, 2010 at 16:24 Comment(0)
C
2

If the C code uses doubles very seldom/sparsely, then you might be able to use a floating point emulation library without causing your C code to run 10X to 100X slower. If don't want that performance hit and there are a lot of floating point operations, and you know the scale and precision required at every arithmetic and store operation for every realistic input, then you might be able convert each arithmetic operation, manually, to used scaled integer data types and operations. But analyzing precision requirements is, in general, non-trivial for DSP type code. There are many DSP and Numerical Methods textbook chapters on the subject.

Coronal answered 6/12, 2010 at 17:11 Comment(1)
... do elaborate on the last sentence, for this to qualify as helpful.Adachi
C
0

There are a few libraries out there that may do this for you. More likely, though, the PSP for your device should include some sort of math library. It should be documented. You will likely have to re-write some your code, because the control constructs you use when doing primitive-based floating-point arithmetic may not make sense when you use the API provided by your PSP.

For example - you might convert this

double arraysum = 0.0;
for (int i = 0; i < arraylen; i++) 
{
    arraysum += array[i];
}

to this

psp_decimal_t arraysum;
if (0 != psp_sum_elements(&array, arraylen, &arraysum))
{
    printf("error!");
}
Concussion answered 6/12, 2010 at 16:25 Comment(1)
Sadly, I have been unable to find that content anywhere else, nor the individual that posted it.Concussion

© 2022 - 2024 — McMap. All rights reserved.