Generated reference › Data Type Conversion — Control Systems/Signal Attributes
kind: generated#block#control-systems-signal-attributes

Data Type Conversion — Control Systems/Signal Attributes

1.7 1

Control_Systems/Signal_Attributes/Data_Type_Conversion · 1 input / 1 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Description#

The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.

Data Type Conversion

Control Systems / Signal Attributes

Changes a signal's data type and nothing else: y = u, entry by entry, with the output carrying the type you choose. This is the only block that changes a type – everywhere else a link joins two ports of the same type or is refused, so a conversion is always something you put in the wire on purpose and can see on the canvas.

Ports

  • Input – the signal u, of any size [m,n]. It accepts any numeric type: floating point, integer, fixed point or boolean, and an enumerated type. Text and buses are refused, because converting them is a different operation with different answers.
  • Output – the same values y, of the SAME size [m,n], carrying the type set below. The block never reshapes a signal.

Parameters

  • Output data type – the type the output port carries. The list is every numeric type the application knows, so it grows when the application does, then fixdt(1,16,8), an example of a fixed-point type – any fixdt(signed, word length, fraction length) is chosen by writing it so, as Simulink spells it – then Enum: Name for each enumerated type the project defines, and then Inherit: Inherit via back propagation. Defaults to a 64-bit float, which converts nothing.
  • Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.

How the conversion happens

The block passes the number through unchanged; the output port applies the type when the value is stored. An integer type truncates toward zero and then wraps to its width, so 3.7 becomes 3 and 200 into an 8-bit signed integer becomes −56. A fixed-point type fixdt(s, w, f) is a w-bit integer, signed when s is 1, times 2−f: the value is truncated toward zero onto that grid and wraps to w bits, so 0.3 into fixdt(1,8,4) becomes 0.25, −0.3 becomes −0.25 and 8.5 becomes −7.5, and fixdt(s, w, 0) is the w-bit integer. The word may be 1 to 53 bits (a double holds every such value exactly) and the fraction −64 to 64; fixdt(s, w), whose scaling Simulink leaves to best precision, and a slope and bias are refused when the model is built. A boolean stores 1 for any non-zero value and 0 otherwise. A 32-bit float keeps only what a 32-bit float can hold. A value that is not finite becomes 0 in an integer or boolean output, because neither has a representation for it, and that is reported once per port per run.

The rule is applied in exactly one place, which is what makes a simulation and the code generated from it agree on the answer rather than agree approximately.

Enumerated types

A project defines an enumerated type with defineEnum: named members, each with a whole-number underlying value. Converting from an enumerated signal gives each member's underlying value in the chosen type, so a member whose value is 7 becomes 7, and 1 in a boolean output. Converting to an enumerated type (Enum: Name) takes an integer input or another enumerated signal, and keeps each value as the member with that underlying value. A floating-point or boolean input is refused when the model is built, and so is a type the project does not define. A value that no member has stops the simulation at the step where it appears, naming the block, the value and the type; it is never rounded or replaced by the default. Simulink behaves the same way in each case.

Inherit via back propagation

With this choice the output takes its type from where it is consumed, as Simulink's does: when the model is built, it becomes the one numeric type every block it feeds accepts – a boolean into a Logical Operator, a 64-bit float into a Gain or when nothing narrows the choice. Through a subsystem boundary the blocks inside count. If the blocks it feeds accept no type in common, or several but not a 64-bit float, the build stops and names the output; choose its type then. Simulink refuses both cases too. A Bitwise Operator takes the one integer type its own setting chooses, so that is the type here, where Simulink refuses a floating default it cannot narrow.

Code export

Python, MATLAB, Java, Rust, C, C++ and PLC Structured Text carry every type this block offers. The generated core stores signals in its own floating-point type and applies the chosen type where the simulation applies it, so the two hold the same number.

An enumerated input or output is carried as its whole-number underlying value, as a 32-bit integer is: Python, MATLAB, Java, Rust, C, C++ and PLC Structured Text carry it, and VHDL, Verilog and SystemVerilog refuse it by name, as they refuse a 32-bit integer.

VHDL, Verilog and SystemVerilog hold every signal in a 16.16 fixed-point word, and carry what that word holds exactly: a 64-bit float, a boolean, the integers of 16 bits and below except the unsigned 16-bit one, and a fixed-point type with at most 16 fraction bits and 15 integer bits, each with the type applied where the simulation applies it. Any other setting is refused by name at export time with the reason – never exported as a number that would differ from the simulation.

Simulink bridge

Import and export, mapped to simulink/Signal Attributes/Data Type Conversion. "Output data type" crosses as OutDataTypeStr (back propagation as Inherit: Inherit via back propagation), and "Sampling Time (s)" as SampleTime, as on every block. An enumerated output type crosses as Enum: Name, and the type itself as a Simulink.defineIntEnumType line at the top of the exported script; an import reads that line back, or a classdef file of the type's name beside the script. A fixed-point output type crosses as its fixdt(s,w,f). An integer or fixed-point output type is written with RndMeth Zero, Simulink's name for this block's rounding toward zero (Simulink's own default is Floor, which would turn −0.5 into −1); an imported block with any other rounding still truncates, and the import says so. Simulink's "Input and output to have equal" choice does not cross: this block always converts the value, which is Simulink's "Real World Value" setting, and the stored-integer reading has no counterpart here.

Notes

  • Algebraic, with no state: the output depends only on the current input.
  • Carries no state space, although y = u would be one. A model reduction that absorbed this block into a neighbouring plant would absorb the TYPE with it and silently drop the conversion, which is the one thing the block is for.
  • Choosing a 64-bit float output converts nothing and is the default, so dropping the block into a diagram changes no value until you set the type.
  • A 64-bit integer output is exact only to about 9 007 199 254 740 992 (253): values are carried as doubles during a run, and a double cannot hold every 64-bit integer.

Code facts#

FactValue
registered typeControl_Systems/Signal_Attributes/Data_Type_Conversion
familyControl_Systems/Signal_Attributes
solver environment classICoreBlock_0_Control_Systems_1_Signal_Attributes_2_Data_Type_Conversion
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Attributes/Data_Type_Conversion/ICoreBlock_0_Control_Systems_1_Signal_Attributes_2_Data_Type_Conversion.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Attributes/Data_Type_Conversion/ICoreBlock_0_Control_Systems_1_Signal_Attributes_2_Data_Type_Conversion.h
default size on canvas90 × 70 px
ports at insert1 in, 1 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDouble—
2outICoreDouble—

Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.

Configuration variables#

Config variableDefaultSimulink parameter
Output data typeoutputTypeComboSpec()—

Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.

supportSupport::Both
Simulink pathsimulink/Signal Attributes/Data Type Conversion
port-count rulePortsParam::
SampleTime parameteryes

Caveat (shown to the user): "the output type crosses as OutDataTypeStr

Catalog contract: src/ICoreBlocks/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h

Description vs code#

The lists agree. check_block_descriptions.py finds no disagreement between the description's Ports, Parameters, Code export and Simulink bridge lists and the code's.

The verdict above is tools/docs/check_block_descriptions.py (P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.

File banner (developer view)#

The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).

Data Type Conversion -- the one way to change a signal's type y = u. The block does not convert anything; its OUTPUT PORT does, because a port applies its kind to every value written into it and does it exactly once. So "converting" here is declaring the output port to be of the chosen type and passing the number through, and the generated body in all ten languages is a copy.

That is also why this block has no per-language arithmetic to reconcile -- there is none. What it does have is the first CONFIG-SELECTED OUTPUT TYPE in the library: the combo is built from the signal-type registry rather than from a literal list, so a type added to the registry is offered here on the same commit, with no edit in this file.

Sample results#

Data Type Conversion — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sampleData Type Conversion — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample-202-2-10123inputoutput
tin ICoreDouble-Out-0out ICoreDouble-Out-0
0-2-2
0.040.50.5
0.08-2-2
0.120.50.5
0.16-2-2
0.20.50.5
0.24-2-2
0.280.50.5
0.32-2-2
0.360.50.5
0.4-2-2
0.440.50.5
0.48-2-2
0.520.50.5

Every 4th of 60 samples, from the table stimulus.

The same rig also ran:

StimulusWhat it isOutput range
impulseImpulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair)0 … 1
rampRamp: slope 1 from t = 00 … 0.59
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias0 … 0.9246
stepStep: 0 -> 1 at t = 1 s0 … 0

Plotted: table — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample

Category static · sample time 0.01 · 60 steps · commit 1bdd228c3 · produced by docsSample --out <folder> --blocks Data_Type_Conversion --steps 60 · data docs/generated/samples/Control_Systems__Signal_Attributes__Data_Type_Conversion.json · the SVG is generated from those numbers by tools/docs/plot_svg.py, so it is a run and not a drawing (R-D10).