While coding with the API for user-written fixed-point S-functions, it is important to keep in mind the difference between storage container size, storage container word length, and signal word length. The sections that follow discuss the containers used by the API to store signals in simulation and code generation.
In simulation, signals are stored in one of several types of containers of a specific size.
During simulation, fixed-point signals are held in one of the types of storage containers, as shown in the following table. In many cases, signals are represented in containers with more bits than their specified word length.
Fixed-Point Storage Containers
Container Category | Signal | Container Word Length | Container Size |
---|---|---|---|
| 1 to 8 bits | 8 bits | 1 byte |
| 9 to 16 bits | 16 bits | 2 bytes |
| 17 to 32 bits | 32 bits | 4 bytes |
| 33 to word length of | Length of | Length of |
| Greater than the word length of | Multiples of length of | Multiples of length of |
When the number of bits in the signal word length is less than the size of the container, the word length bits are always stored in the least significant bits of the container. The remaining container bits must be sign extended:
If the data type is unsigned, the sign extension bits must be cleared to zero.
If the data type is signed, the sign extension bits must be set to one for strictly negative numbers, and cleared to zero otherwise.
For example, a signal of data type sfix6_En4
is
held in a FXP_STORAGE_INT8
container. The signal
is held in the six least significant bits. The remaining two bits
are set to zero when the signal is positive or zero, and to one when
it is negative.
A signal of data type ufix6_En4
is held in
a FXP_STORAGE_UINT8
container. The signal is held
in the six least significant bits. The remaining two bits are always
cleared to zero.
The signal and storage container word lengths are returned by
the ssGetDataTypeFxpWordLength
and ssGetDataTypeFxpContainWordLen
functions,
respectively. The storage container size is returned by the ssGetDataTypeStorageContainerSize
function.
The container category is returned by the ssGetDataTypeStorageContainCat
function,
which in addition to those in the table above, can also return the
following values.
Other Storage Containers
Container Category | Description |
---|---|
| Returned if the storage container category is unknown |
| The container type for a Simulink® |
| The container type for a Simulink |
| The container type for a data type that has been overridden
with |
An sfix24_En10
data type has a word length
of 24, but is actually stored in 32 bits during simulation. For this
signal,
ssGetDataTypeStorageContainCat
returns FXP_STORAGE_INT32
.
ssGetDataTypeStorageContainerSize
or sizeof(
)
returns 4
, which is the storage container
size in bytes.
ssGetDataTypeFxpContainWordLen
returns 32
,
which is the storage container word length in bits.
ssGetDataTypeFxpWordLength
returns 24
,
which is the data type word length in bits.
The storage containers used by this API for code generation
are not always the same as those used for simulation. During code
generation, a native C data type is always used. Floating-point data
types are held in C double
or float
.
Fixed-point data types are held in C signed and unsigned char
, short
, int
,
or long
.
Because it is valuable for rapid prototyping and hardware-in-the-loop testing, the emulation of smaller signals inside larger containers is supported in code generation. For example, a 29-bit signal is supported in code generation if there is a C data type available that has at least 32 bits. The rules for placing a smaller signal into a larger container, and for dealing with the extra container bits, are the same in code generation as for simulation.
If a smaller signal is emulated inside a larger storage container
in simulation, it is not necessarily emulated in code generation.
For example, a 24-bit signal is emulated in a 32-bit storage container
in simulation. However, some DSP chips have native support for 24-bit
quantities. On such a target, the C compiler can define an int
or
a long
to be exactly 24 bits. In this case, the
24-bit signal is held in a 32-bit container in simulation, and in
a 24-bit container in code generation.
Conversely, a signal that was not emulated in simulation might
need to be emulated in code generation. For example, some DSP chips
have minimal support for integers. On such chips, char
, short
, int
,
and long
might all be defined to 32 bits. In that
case, it is necessary to emulate 8- and 16-bit fixed-point data types
in code generation.
Since the mapping of storage containers in simulation to storage containers in code generation is not one-to-one, the Target Language Compiler (TLC) functions for storage containers are different from those in simulation:
FixPt_DataTypeNativeType
FixPt_DataTypeStorageDouble
FixPt_DataTypeStorageSingle
FixPt_DataTypeStorageScaledDouble
FixPt_DataTypeStorageSInt
FixPt_DataTypeStorageUInt
FixPt_DataTypeStorageSLong
FixPt_DataTypeStorageULong
FixPt_DataTypeStorageSShort
FixPt_DataTypeStorageUShort
FixPt_DataTypeStorageMultiword
The first of these TLC functions, FixPt_DataTypeNativeType
,
is the closest analogue to ssGetDataTypeStorageContainCat
in
simulation. FixPt_DataTypeNativeType
returns a
TLC string that specifies the type of the storage container, and the Simulink
Coder™ product
automatically inserts a typedef
that maps the string
to a native C data type in the generated code.
For example, consider a fixed-data type that is held in FXP_STORAGE_INT8
in
simulation. FixPt_DataTypeNativeType
will return int8_T
.
The int8_T
will be typdef
'd
to a char
, short
, int
,
or long
in the generated code, depending upon what
is appropriate for the target compiler.
The remaining TLC functions listed above return TRUE
or FALSE
depending
on whether a particular standard C data type is used to hold a given
API-registered data type. Note that these functions do not necessarily
give mutually exclusive answers for a given registered data type,
due to the fact that C data types can potentially overlap in size.
In C,
sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long).
One or more of these C data types can be, and very often are, the same size.