How to create 64 bit integer data type in Simulink

28 views (last 30 days)
I need to write a custom C mex S function to take signed long long as its input and output datatype. But Simulink seems not to support int64 and uint64 in its built-in data type. How should I do when define the input/output datatype in hand-written C mex S function?

Answers (3)

Erik Petrini
Erik Petrini on 24 Oct 2018
Apparently this can be done by using fixdt, but I can't find recommended settings to implement int64/uint64 such that it matches the current other Simulink types. Guidance on interfacing with long long in the best way would be appreciated. Especially since it's a fickle data type in the C standard.

Mikhail
Mikhail on 23 Apr 2020
This can be done in the following way:
  • Register you custom 64 bit unsigned data type and assign to the first output port:
DTypeId dataTypeIdReg;
dataTypeIdReg = ssRegisterDataTypeFxpBinaryPoint(S, 0, 64, 0, 1);
if (dataTypeIdReg == INVALID_DTYPE_ID) return;
ssSetOutputPortDataType(S, 0, dataTypeIdReg);
  • Don't forget to include fixedpoint.h and fixedpoint.c as explained in documentation: https://www.mathworks.com/help/releases/R2020a/fixedpoint/ug/structure-of-the-s-function.html
  • Build your C-MEX S-Function with -lfixedpoint flag.
  • This shouln't require Fixed-Point Designer license because uint64 is a built-in Simulink datatype.
  • It makes me so frustrated that MathWorks claims 64-bit full support for Simulink R2020a (read release notes), yet they don't support SS_UINT64 (similar to SS_UINT32 etc) in S-functions.

Andy Bartlett
Andy Bartlett on 19 May 2020
Edited: Andy Bartlett on 19 May 2020
Hi
Mikhail's instructions on registering a 64 bit integer type are spot-on. Nice job!
Starting in R2017a, 64 bit integers in Simulink do NOT require a Fixed-Point Designer license or install.
In R2020a, there are a few new APIs in fixedpoint.h for integers.
ssRegisterDataTypeInteger /* A wee tiny bit simpler than what Mikhail showed.*/
ssGetDataTypeIsInteger
ssGetDataTypeIsSpecifiedInteger
The header listings are given below.
Note, this header is installed with Simulink even if Fixed-Point Designer is not installed.
Using these APIs with types equivalent to built-in types does not require a Fixed-Point Designer license (since R2017a).
The latter API can be used to dispatch code based on integer type.
For example,
if (ssGetDataTypeIsSpecifiedInteger(S,dataTypeID,0,8)) {
/* handle 8 bit unsigned integers */
...
}
else if (ssGetDataTypeIsSpecifiedInteger(S,dataTypeID,0,64)) {
/* handle 64 bit unsigned integers */
...
}
else if (ssGetDataTypeIsSpecifiedInteger(S,dataTypeID,0,64)) {
/* handle 64 bit Signed integers */
}
Regarding Simulink's set of statically define type SS_ enums like SS_UINT8.
For a variety of reasons, MathWorks is not currently planning to extend this set of statically defined enums to 64 bit integers, to half-precision floating-point, or to other future types. Please give the API above a try and let us know your feedback.
If using the new API's is not a satisfactory, we'd be happy to better understand your needs and the level of priority.
Regards
Andy Bartlett
-----------------------------------------------------------
Excerpts from fixedpoint.h header
-----------------------------------------------------------
/* Function: ssRegisterDataTypeInteger ===============================
*
* This function fully registers any integer data type with Simulink and
* returns a Data Type Id. Supported types are
* Unsigned with wordlength 1 up to 128
* Signed with wordlength 2 up to 128
*
* This function is available for any Simulink install, even if
* Fixed-Point Designer is not installed.
* If the registered wordlength of the integer is 8, 16, 32, or 64,
* then a Simulink license is sufficient.
* For any of the other 124 possible wordlengths,
* a Fixed-Point Designer license is required.
*
*
* Unlike the standard Simulink function, ssRegisterDataType, additional
* registration steps do not need to be taken
* and should not be taken. The returned Data Type Id can be used to specify
* the data types of input ports, output ports, RunTimeParameters, and DWork
* states. The Data Type Id can also be used with all the standard
* data type access methods in simstruc.h such as ssGetDataTypeSize.
*
* The input arguments are
* isSigned TRUE if signed, FALSE if unsigned
* wordLength total number of bits including any sign bit
* obeyDataTypeOverride if FALSE ignore system's setting for Data Type Override
* if TRUE obey Data Type Override setting, depending
* on Data Type Override, resulting data type could be
* True Double, True Single, Scaled Double, or the
* requested fixed point type.
*
* Cautions:
*
* 1) If the registered data type is not one of the builtin data types, then
* a Fixed-Point License will be checked out. To prevent, a Fixed-Point
* License from being checked out when a user simply opens or views a model,
* calls to registration should be protected with
* if ( ssGetSimMode(S) != SS_SIMMODE_SIZES_CALL_ONLY )
* ssRegisterDataType ...
*
* 2) In general, there is no fixed relationship between the Data Type Id value
* and the input arguments. Simulink hands out data type Ids on a first come,
* first served basis, so small changes to a model can cause a different data
* type id value to be returned. Always use functions to get data type
* attributes from the data type id; never directly rely on the data type
* id value.
*/
FIXPOINT_EXPORT_EXTERN_C DTypeId ssRegisterDataTypeInteger(
SimStruct *S,
int isSigned,
int wordLength,
int obeyDataTypeOverride
);
/* Function: ssGetDataTypeIsInteger
*
* Giving a registered Data Type Id, determine the if the data
* type is one of 255 integer types supported by Simulink.
* Unsigned with wordlength 1 up to 128
* Signed with wordlength 2 up to 128
*/
FIXPOINT_EXPORT_EXTERN_C int ssGetDataTypeIsInteger(
SimStruct *S,
DTypeId dataTypeId
);
/* Function: ssGetDataTypeIsSpecifiedInteger
*
* Giving a registered Data Type Id, determine
* if the data type is an integer with the specified
* signedness and wordlength.
*/
FIXPOINT_EXPORT_EXTERN_C int ssGetDataTypeIsSpecifiedInteger(
SimStruct *S,
DTypeId dataTypeId,
int isSigned,
int wordLength
);
  1 Comment
Mikhail
Mikhail on 20 May 2020
Hi Andy,
Great to see MathWorks stuff checking into some of the obscure questions on FEX!
My main complaint is that uint64 is currently the second class citizen Simulink, no matter what MathWorks says in release notes. This can be easily seen in so many ways:
1) There is no documentation for ssRegisterDataTypeInteger and companion functions. For example, what is the difference between ssRegisterDataTypeFxpBinaryPoint and ssRegisterDataTypeInteger?
2) There is no visibility of uint64 capabilities in documentation. SS_UINT64 is not in the list of built-in data types, and this misleads to conclusion that S-Functions don't support 64 bit data types. In fact, I had to dig through the LCT generated code to figure out how it managed to support 64 bit data types.
3) When using this API you suggested, there is a dependency on libfixedpoint. For host-based builds, this requires changing a toolchain and supplying -lfixedpoint (in addition to supplying -lfixedpoint to mex). This is not a feature parity with SS_* datatypes.
4) And the worst. The S-Function using 64 bits data types must be inlined (this is from my experience, please tell me I'm wrong) for target-based builds. I'm not against throwing in some TLC, but I would really prefer not to inline S-Function in some cases. This also makes this API less capable than true built-in data types, where I don't have to worry about it.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!