Fixed-Point Data in Stateflow Charts
Fixed-point numbers use integers and integer arithmetic to approximate real numbers. They are an efficient means for performing computations involving real numbers without requiring floating-point support in underlying system hardware.
Fixed-point numbers represent real numbers by using the encoding scheme:
V ≈ Vapprox = SQ + B.
V is a precise real-world value that you want to approximate with a fixed-point number.
Vapprox is the approximate real-world value that results from the fixed-point representation.
Q is an integer that encodes the fixed-point number. This value is called the quantized integer.
S is a coefficient that determines the precision of the fixed-point representation. This value is called the slope.
B is an additive correction called the bias.
The quantized integer Q is the only part of the fixed-point representation that varies in value. In the generated code, the quantities S and B are constant and appear only as literal numbers or expressions. If a fixed-point number changes, its quantized integer Q changes but S and B remain unchanged.
To determine the quantized integer Q corresponding to a real-world value V, round the quantity (V – B)/S to an integer. For example, to represent the number V = 15.345 in a fixed-point type with slope S = 0.5 and bias B = 0.1, you use the quantized integer
Q = round((V – B)/S) = round((15.345 – 0.1)/0.5) = round(30.49) = 30.
Because you round Q to an integer, you lose some precision in representing the number 15.345. The number that Q actually represents is
Vapprox = SQ + B = 0.5 ⨉ 30 + 0.1 = 15.1.
Using fixed-point numbers to represent real numbers with integers involves the loss of some precision. However, with a suitable choice of S and B, you can minimize this loss to acceptable levels. For instance, by changing the coding scheme to use S = 0.25 and B = 0.1, you can represent the number V = 15.345 with greater precision as:
Q = round((V – B)/S) = round((15.345 – 0.1)/0.25) = round(60.98) = 61
Vapprox = SQ + B = 0.25 ⨉ 61 + 0.1 = 15.35.
The difference between Vapprox and V is always less than the slope S.
Specify Fixed-Point Data
In the Model Explorer, you can specify the fixed-point encoding for a data object by
using the Data Type Assistant, as described in Fixed-Point Data Properties. Set the Mode field to
Fixed point and specify these properties:
Word length: Specify the bit size of the word that holds the quantized integer Q.
Slope and bias.
If you select
Binary point, the Data Type Assistant displays the Fraction length field, which specifies the binary point location. Choosing a Fraction length of n defines a fixed-point encoding with a slope of S = 2-n and a bias of B = 0 .
If you select
Slope and bias, the Data Type Assistant displays fields for entering the Slope S and Bias B for the fixed-point encoding scheme.
Alternatively, you can specify the encoding for a fixed-point data object directly by
fixdt (Simulink) function. In the Property
Inspector or the Model Explorer, in the Type field, enter
an expression in one of these
fixdt(Signed, WordLength, FractionLength)
fixdt(Signed, WordLength, Slope, Bias)
Some encoding schemes are computationally expensive, particularly in multiplication and division operations. Selecting a slope that is an integer power of two and a zero bias avoids these computationally expensive instructions. Using binary point scaling is recommended.
Stateflow® charts convert real numbers into fixed-point numbers during data initialization and as part of casting operations in the application. These conversions compute a quantized integer Q from a real number input. The type of conversion depends on the action language for the chart.
Conversion in Charts That Use MATLAB as the Action Language
In a chart that uses MATLAB® as the action language, you define the method for all conversions through the fixed-point properties for the chart. See Fixed-Point Properties.
For example, if you set the MATLAB Chart
fimath property to
MATLAB, then the chart rounds the resulting quantized integer to its
nearest integer value.
Conversions in Charts That Use C as the Action Language
Charts that use C as the action language employ two methods for converting fixed-point data:
Offline conversions initialize data during code generation. Offline conversions are designed to maximize accuracy. These conversions round the resulting quantized integer to its nearest integer value. Offline conversions are performed for initialization of data (variables and constants) in the Stateflow hierarchy and from the MATLAB workspace.
Online conversions perform casting operations during run time. Online conversions are designed to maximize computational efficiency. They are faster and more efficient, but less precise than offline conversions. Instead of rounding Q to its nearest integer, online conversions round to the floor (except for division, which can round to 0, depending on the C compiler).
For example, this table illustrates the difference between offline and online conversions of real numbers to fixed-point numbers defined with a slope of S = 2-4 and a bias of B = 0. For each real-world value V, the chart computes a quantized integer Q by rounding (V-B)/S to the nearest integer (in offline conversion) or to the floor (in online conversion). For each conversion, Vapprox = QS + B is the approximate real-world value resulting from Q.
Fixed-Point Context-Sensitive Constants
In charts that use C as the action language, you can avoid explicit type casts by using
fixed-point context-sensitive constants. These constants infer their type from the context
in which they occur. They are written like ordinary numbers with the suffix
c. For example,
123.4c are valid fixed-point context-sensitive constants that you can
use in action statements.
Although fixed-point context-sensitive constants can appear in expressions with any data types (including integers and floating-point data), their main use is with fixed-point numbers. The algorithm that interprets the context-sensitive constant computes a type that provides maximum accuracy without overflow. The algorithm depends on:
The operations in the expression
The other data types in the context
The value of the constant
Fixed-point context-sensitive constants infer their type according to these rules:
In a casting operation, the constant has the type to which it is being cast.
In a simple assignment operation of the form
a = b:
bis a context-sensitive constant, it has the same type as
bis an addition or subtraction operation, then the constant has the same type as the other operand.
bis a multiplication or division operation with a fixed-point operand, then the constant has the type that provides the best possible precision for a fixed-point result, as determined by the
bis a multiplication or division operation with a floating-point operand of type
single, then the constant has the same type as the floating-point operand.
In a special assignment operation of the form
a := b:
bis a context-sensitive constant, it has the same type as
bis an arithmetic operation with a floating-point operand of type
single, or if
ais a floating-point data object, then the constant has the same type as the floating-point number.
bis an addition or subtraction operation with a fixed-point operand and
ais a fixed-point data object, then the constant has the same type as
bis a multiplication or division operation with a fixed-point operand and
ais a fixed-point data object, then the constant has the type that provides the best possible precision for a fixed-point result.
As an argument in a function call, the constant has the same type as the formal argument.
You cannot use context-sensitive constants as both operands of a binary operation or as the leftmost operand of an assignment operation.
Tips for Using Fixed-Point Data
Develop and test your application by using double- or single-precision floating-point numbers. Using double- or single-precision floating-point numbers does not limit the range or precision of your computations. Once your application works as designed, you can start substituting fixed-point data for double-precision data.
Open the Configuration Parameters dialog box and, in the Hardware Implementation pane, set the integer word size for the simulation environment to the integer size of the intended target environment. Code generated by Stateflow uses this integer size to select result types for your fixed-point operations. See Hardware Implementation Pane (Simulink).
When you simulate your model, use overflow detection to warn you when the result of a fixed-point operation exceeds the numeric capacity of its fixed-point type. Open the Configuration Parameters dialog box and, in the Diagnostics > Data Validity pane, set the Wrap on overflow and Saturate on overflow parameters to
warning. If you encounter overflow errors in fixed-point data, increase the range of your data by:
Increasing the Word length value for the overflowing fixed-point data. For example, change the number of bits used to encode the fixed-point data from 16 to 32. This action changes the base integer type for Q from
Decreasing the Fraction length value (if using
Binary pointscaling) or increasing the Slope value (if using
Slope and biasscaling). For example, decrease the Fraction length value from 4 to 1 (or, equivalently, increase the Slope value from S = 2-4 = 0.0625 to S = 2-1 = 0.5). This action increases the range of your fixed-point data but decreases the available precision.
For more information, see Detect Data Range Violations.
If you encounter issues with model behavior stemming from inadequate precision in your fixed-point data, increase the precision of your data by increasing the Fraction length value (if using
Binary pointscaling) or decreasing the Slope value (if using
Slope and biasscaling). For example, increase the Fraction length value from 2 to 3 (or, equivalently, decrease the Slope value from S = 2-2 = 0.25 to S = 2-3 = 0.125). This action increases the precision of your fixed-point data but decreases the available range.
In charts that use C as the action language, you can use a special assignment operation
:=and context-sensitive constants to maintain as much precision as possible. See Override Fixed-Point Promotion in C Charts and Fixed-Point Context-Sensitive Constants.
If you do not use context-sensitive constants with fixed-point types, noninteger numeric constants (constants that have a decimal point) can force fixed-point operations to produce floating-point results.
Automatic Scaling of Fixed-Point Data
Automatic scaling tools can change the settings of Stateflow fixed-point data. You can prevent automatic scaling by selecting the Lock data type setting against changes by the fixed-point tools option for the fixed-point data object. See Lock data type against Fixed-Point tools. For methods on autoscaling fixed-point data, see Choosing a Range Collection Method (Fixed-Point Designer).
Share Fixed-Point Data with Simulink Models
To share fixed-point data with Simulink® models:
Use the same property values to specify the data in the Stateflow chart and in the Simulink model. For an example of this method of sharing input data from a Simulink model, see Model Bang-Bang Temperature Control System.
For some Simulink blocks, you can specify the type of input or output data directly. For example, you can specify the fixed-point data type for a Constant block directly in the Output data type field by using the
Define the data as Input or Output in the Stateflow chart and instruct the sending or receiving block in the Simulink model to inherit its type from the chart data. In many blocks, you can set data types through inheritance from the driving block, or through back propagation from the next block. You can set the data type of a Simulink block to match the data type of the Stateflow port to which it connects.
For example, you can set the Constant block to inherit its type from the Stateflow Input to Simulink port that it supplies. Set the Output data type block parameter to
Inherit via back propagation.
Implementation of Fixed-Point Data in Stateflow
Stateflow charts define fixed-point data types from the values that you specify for S, B, and the base integer type for Q.
For each fixed-point data, the chart defines an integer variable for Q in the generated code. This integer is the only part of a fixed-point number that changes in value. The available base types for Q are the unsigned integer types
uint32, and the signed integer types
int32. If a fixed-point number has a slope S = 1 and a bias B = 0, it is equivalent to its quantized integer Q and behaves exactly as its base integer type.
The slope S is factored into a coefficient F with 1 ≤ F < 2 and an integer power of two with exponent E:
S = F ⨉ 2E.
If the fractional slope F is greater than 1, it is converted into a fixed-point number. Encoding schemes with F > 1 can be computationally expensive, particularly in multiplication and division operations. Setting F = 1 avoids these computationally expensive instructions. In this setting, scaling by a power of 2 is implemented as bit shifts, which are more efficient than multiply instructions. Therefore, using binary-point-only scaling, in which F = 1 and B = 0, is recommended.
Operations for fixed-point types are implemented with solutions for the quantized integer as described in Arithmetic Operations for Fixed-Point Data. To generate efficient code, the fixed-point promotion rules choose values for slope and bias that cancel difficult terms in the solutions. See Promotion Rules for Fixed-Point Operations.