The preceding example in What Is Fixed-Point Data? does not answer the question of how the values for the slope, S, the quantized integer, Q, and the bias, B, are implemented as integers. These values are implemented as follows:
Stateflow^{®} software defines a fixed-point data type from values that you specify.
You specify values for S, B,
and the base integer type for Q. The available
base types for Q are the unsigned integer types uint8
, uint16
,
and uint32
, and the signed integer types int8
, int16
,
and int32
. For specific instructions on how to
enter fixed-point data, see Specify Fixed-Point Data.
Notice that 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.
Stateflow software implements an integer variable for the Q value of each fixed-point data in generated code.
This is the only part of a fixed-point number that varies in value. The quantities S and B are constant and appear only as literal numbers or expressions in generated code.
The slope, S, is factored into an integer power of two, E, and a coefficient, F, such that S = F × 2^{E} and 1 ≤ F < 2.
The powers of 2 are implemented as bit shifts, which are more efficient than multiply instructions. Setting F = 1 avoids the computationally expensive multiply instructions for values of F > 1. This binary-point-only scaling is implemented with bit shifts only and is recommended.
Operations for fixed-point types are implemented with solutions for the quantized integer as described in Fixed-Point Operations.
To generate efficient code, the fixed-point promotion rules choose values for S_{c} and B_{c} that conveniently cancel out difficult terms in the solutions. See Addition (+) and Subtraction (-) and Multiplication (*) and Division (/).
You can use a special assignment operator (:=
)
and context-sensitive constants to maintain as much precision as possible
in your fixed-point operations. See Assignment (=, :=) Operations and Fixed-Point Context-Sensitive Constants.
Any remaining numbers, such as the fractional slope, F, that cannot be expressed as a pure integer or a power of 2, are converted into fixed-point numbers.
These remaining numbers can be computationally expensive in multiplication and division operations. Therefore, using binary-point-only scaling in which F = 1 and B = 0 is recommended.
Simulation can detect when the result of a fixed-point operation overflows the capacity of its fixed-point type. See Detect Overflow for Fixed-Point Types.
You can specify fixed-point data in a chart as follows:
Add data to your chart, as described in Add Data from the Stateflow Editor.
Doing so adds a default definition of the new data object to the Stateflow hierarchy, and the Data properties dialog box appears.
Click the Show data type assistant button to display the Data Type Assistant.
In the Mode field of the Data
Type Assistant, select Fixed point
.
Specify the fixed-point data properties as described in Fixed-Point Data Properties.
Specify the name, size, and other properties for the new data object as described in Set Data Properties.
Note: You can also specify a fixed-point constant indirectly in action statements by using a fixed-point context-sensitive constant. See Fixed-Point Context-Sensitive Constants. |
For chart-level data of the following scopes, word length can be any integer between 0 and 128.
Input
Output
Parameter
Data Store Memory
For other Stateflow data, word length can be any integer between 0 and 32.
You can explicitly pass chart-level data with word lengths up to 128 bits as inputs and outputs of the following functions:
MATLAB^{®} functions
Simulink^{®} functions
Truth table functions that use MATLAB action language
For an example of using fixed-point data
with word lengths greater than 32 bits, see the description for
the sf_multiword_fixpt
model.
You can use fixed-point constants without using the Data properties
dialog box or Model Explorer, by using context-sensitive constants.
These constants infer their types from the context in which they occur.
They are written like ordinary constants, but have the suffix C
or c
.
For example, the numbers 4.3C
and 123.4c
are
valid fixed-point context-sensitive constants you can use in action
statements.
These rules apply to context-sensitive constants:
If any type in the context is a double, then the context-sensitive constant is cast to type double.
In an addition or subtraction operation, the type of the context-sensitive constant is the type of the other operand.
In a multiplication or division operation with a fixed-point number, they obtain the best possible precision for a fixed-point result.
The Fixed-Point Designer™ function fixptbestexp
provides
this functionality.
In a cast, the context is the type to which the constant is being cast.
As an argument in a function call, the context is the type of the formal argument. In an assignment, the context is the type of the left-hand operand.
You cannot use context-sensitive constants on the left-hand side of an assignment.
You cannot use context-sensitive constants as both operands of a binary operation.
While you can use fixed-point context-sensitive constants in
context with any types (for example, int32
or double
),
their main use is with fixed-point numbers. The algorithm that computes
the type to assign to a fixed-point context-sensitive constant depends
on these factors:
The operator
The data types in the context
The value of the constant
The algorithm computes a type that provides maximum accuracy without overflow.
When you use fixed-point numbers, follow these guidelines:
Develop and test your application 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. You need this while you are building your application.
Once your application works well, start substituting fixed-point data for double-precision data during the simulation phase, as follows:
Set the integer word size for the simulation environment to the integer size of the intended target environment.
Stateflow generated code uses this integer size to select result types for your fixed-point operations. See Set the Integer Word Size for a Target.
Add the suffix C to literal numeric constants.
This suffix casts a literal numeric constant in the type of
its context. For example, if x
is fixed-point data,
the expression y = x/3.2C
first converts the numerical
constant 3.2 to the fixed-point type of x
and then
performs the division with a fixed-point result. See Fixed-Point Context-Sensitive Constants for more information.
Note: If you do not use context-sensitive constants with fixed-point types, noninteger numeric constants (for example, constants that have a decimal point) can force fixed-point operations to produce floating-point results. |
When you simulate, use overflow detection.
See Detect Overflow for Fixed-Point Types for instructions on how to set overflow detection in simulation.
If you encounter overflow errors in fixed-point data, you can do one of the following to add range to your data.
Increase the number of bits in the overflowing fixed-point data.
For example, change the base type for Q from int16
to int32
.
Increase the range of your fixed-point data by increasing the power of 2 value, E.
For example, you can increase E from –2 to –1. This action decreases the available precision in your fixed-point data.
If you encounter problems with model behavior stemming from inadequate precision in your fixed-point data, you can do one of the following to add precision to your data:
Increase the precision of your fixed-point data by decreasing the value of the power of 2 binary point E.
For example, you can decrease E from –2 to –3. This action decreases the available range in your fixed-point data.
If you decrease the value of E, you can prevent overflow by increasing the number of bits in the base data type for Q.
For example, you can change the base type for Q from int16
to int32
.
If you cannot avoid overflow for lack
of precision, try using the :=
assignment operator
in place of the = operator for assigning the results of multiplication
and division operations.
You can use the :=
operator to increase the
range and precision of the result of fixed-point multiplication and
division operations at the expense of computational efficiency. See Assignment Operator :=.
Overflow occurs when the magnitude of a result assigned to a
data exceeds the numeric capacity of that data. To detect overflow
during simulation, set Wrap on overflow in the Diagnostics:
Data Validity pane of the Model Configuration Parameters
dialog box to error
or warning
.
To share fixed-point data with Simulink models, use one of these methods:
Define identically in both Stateflow charts and Simulink models the data that you input from or output to Simulink blocks.
The values that you enter for the Stored Integer and Scaling fields in the shared data's properties dialog box in a Stateflow chart (see Specify Fixed-Point Data) must match similar fields that you enter for fixed-point data in a Simulink model. See Use Fixed-Point Chart Inputs for an example of this method of sharing input data from a Simulink model using a Gateway In block.
For some Simulink blocks, you can specify the type of input or output data directly. For example, you can set fixed-point output data directly in the block dialog box of the Constant block by using the Output data type parameter.
Define the data as Input or Output in the Data properties dialog box in the Stateflow chart and instruct the sending or receiving block in the Simulink model to inherit its type from the chart data.
Many blocks allow you to set their data types and scaling 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. To do so, select Inherit via back propagation
for
the Output data type parameter in the block dialog
box.