MATLAB: Are conditions involving comparison operations on fixed-point datatypes in the Stateflow chart not reproduced faithfully in code generated using Stateflow Coder 7.2 (R2009a)

Stateflow Coder

I have a Simulink model containing Stateflow which I am generating code from, using Stateflow Coder 7.2 (R2009a).
I have the following logic in my Stateflow chart that accounts for a state transition from STATE1 to STATE2:
if (In1 >= In2 + In3)
{
/*State goes into STATE2*/
}
else
{
/*Remains in the STATE1*/
}
where:
In1 is of type U32 (unsigned int – 32 bit), with resolution 0.001
In2 is of type U32, with resolution 0.01
In3 is of type U32, with resolution 0.01
However, the generated code for this transition condition is as follows:
if ((int32_T)mul_u32_u32_u32_sr35(In1, 3435973837U) >= In2 + In3)
{
/*State goes into STATE2*/
}
else
{
/*Remains in the STATE1*/
}
The Real-Time Workshop>Hardware Implementation pane has the following settings:
ProdHWDeviceType = "32-bit Generic"
Bits per int = 32
I would like to know what the significance of the number 3435973837U here is, and why there is a typecast to int32_T.

Best Answer

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:
(In1 >= In2 + In3)
is broken down into:
Temp1 = In2 + In3
In1 >= Temp1
where Temp1 is an automatic conceptual temporary variable.
Now, consider:
Temp1 = In2 + In3
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
Temp1: slope = 0.01
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:
Temp1: int32, slope 0.01
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:
V_Temp2 = V_In1
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:
Temp2 = 0.1 * In1
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.