The code generated by Stateflow Coder 7.2 (R2009a) for comparison operations involving different fixed-point datatypes is the result of analysis and scaling.
First, the expression:
is broken down into:
Temp1 = In2 + In3
In1 >= Temp1
where Temp1 is an automatic conceptual temporary variable.
Now, consider:
Here, Stateflow Coder needs to automatically select a data type and scaling for Temp1. Since the scaling of both inputs matches and the biases are zero:
In2 & In3: uint16, slope=0.01
And the operation is addition, Stateflow will select same slope
For the container type, since Stateflow is modeled after C (where any operation on a type smaller than signed int results in the operand(s) to be promoted to a signed int), In2 and In3 are promoted to int32. Hence:
Going back to the comparison operation:
In1 >= Temp1
Temp1: uint32, slope 0.01
In1: uint32, slope=0.001
Since, their scaling is not the same, we need to find a common data type. The Stateflow rule in such cases is that the data type with the greatest positive range is used:
Max for Temp1 is 0.01 * (2^32-1) = 42949672.95
Max for In1 is 0.001 * (2^32-1) = 4294967.295
Temp1's max is 10 times larger, so Temp1's type is used for comparison.
This further breaks down the expression to:
Temp2 = Real World Cast of In1 to type of Temp1
Temp2 >= Temp1
To perform the cast of In1 to the type of Temp1, we must started with Real World values:
Recall the fixed-point scaling equations that relate Real World Value to Stored Integer Value:
V_Temp2 = 0.01 * Temp2
V_In1 = 0.001 * In
Substituting these last two equations into the cast equation gives:
0.01 * Temp2 = 0.001 * In1
Solving for Temp2:
Temp2 = (0.001/0.01) * In1
Simplifies to:
For a fixed point implementation, we need to approximate 0.1. Since In1 is uint32, a 32 bit approximation will be used:
0.1 is approximately 3435973837 * 2^-35 = 0.100000000005821
The operation becomes:
Temp2 = (3435973837 * 2^-35) * In1
Or equivalently:
Temp2 = (3435973837 * In1) >> 35
This operation is what the generated code
mul_u32_u32_u32_sr35(In1, 3435973837U)
is doing.
Finally, since Temp1 is signed, there is a cast
(int32_T)mul_u32_u32_u32_sr35(In1, 3435973837U)
The resultant expression is:
((int32_T)mul_u32_u32_u32_sr35(In1, 3435973837U) >= In2 + In3)
as found in the generated code.
Best Answer