Storage Containers
Introduction
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.
Storage Containers in Simulation
In simulation, signals are stored in one of several types of containers of a specific size.
Storage Container Categories
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 |
Storage Containers in Simulation Example
An sfix24_En10
data type has a word length of 24, but is
actually stored in 32 bits during simulation. For this signal,
ssGetDataTypeStorageContainCat
returnsFXP_STORAGE_INT32
.ssGetDataTypeStorageContainerSize
orsizeof( )
returns4
, which is the storage container size in bytes.ssGetDataTypeFxpContainWordLen
returns32
, which is the storage container word length in bits.ssGetDataTypeFxpWordLength
returns24
, which is the data type word length in bits.
Storage Containers in Code Generation
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
.
Emulation
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.
Storage Container TLC Functions
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.