Compiler generated code for TI C2000 device errors with "floating constant is out of range"
5 views (last 30 days)
Simulink generally uses doubles by default for data types, and consequently, the generated code also uses doubles by default. This issue is due to the TI compiler used by Simulink to build the generated code. The TI compiler treats both singles and doubles as 32-bit single-precision floating point numbers (which is atypical for compilers). This is done because using singles on a TI C2000 device is much more efficient than using doubles (since singles are handled in hardware and doubles are handled in software). So because Simulink and the C language expect these numbers to be treated as 64-bit double-precision floats, they are allowed to become much smaller and more precise than what could be stored in a 32-bit single-precision float. When the TI compiler goes to compile the generated code, it tries to fit these very small/precise numbers into 32 bits and fails because it really needs 64 bits.
I recommend that you modify your Simulink model to switch the relevant variables from doubles to singles. This should constrict the values of these variables to within the range of a 32-bit floating point number.
More Answers (1)
Andy Bartlett on 10 Dec 2020
Edited: Andy Bartlett on 10 Dec 2020
Having a model that simulates with 64-bit floating-point doubles, but behaves as 32-bit floating-point on the target misses some of the key benefits of model based design. For example, it is often easier, faster, cheaper, and sometimes safer to discover your numeric edge cases in Simulink simulations than on the embedded device.
To get the full benefits of tight numeric agreement between the model and the embedded device behavior, the model can be converted from use of 64-bit floating-point doubles to 32-bit floating-point singles. There is a Single Precision Converter tool that ships with Fixed-Point Designer that will automatically convert a subsystem or model to use single precision types. Demonstrated in this video.
The compiler error message "floating constant is out of range" suggest you have a constant term such as a parameter that is too big for singles
abs( param ) > realmax('single') % 3.4028e+38
or too small to be represented with full 24 bits of precision.
abs( param ) < realmin('single') % 1.1755e-38
For the latter case, if the TI C2000 handles denormalized floating-point values with flush to zero, then all these small values will quantized to zero. Thus they will have 100% relative precision loss. That precision loss may or may not effect whether your design still meets behavioral requirements.
One way to avoid these issues is to re-scale your design.
For example, if the values are too big, then re-scale the physical units to a different SI prefix. For example, change the units of a signal from something fine like micro-X to something coarser like kilo-X. Where 'X' is meters, amps, watts, etc. This re-scaling would make all the values 10^9 times small and thus more likely to avoid crossing single's range limit of realmax('single').
Likewise, if the values are to small for single precision, then switch from a coarser unit like mega-X to something finer like micro-X. This re-scaling would make all the values 10^12 bigger and thus more liikely to stay above realmin('single').
The scaling changes don't have to correspond to an SI prefix change. You could use any scaling amount that works for your design. Using a scaling change that is an exact power of two (2^n) would have the advantage of avoiding rounding errors in any online re-scaling multiplications.