Enumerated Constant — Control Systems/Sources
Control_Systems/Sources/Enumerated_Constant · 0 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.
Enumerated Constant
Control Systems / Sources
A source that emits one member of a MATLAB enumeration for the whole run:
y = the underlying value of the named enumeration member
ICore has one signal type, the double, and holds no enumeration definitions, so the enumeration's name and member are carried for the Simulink bridge while the number this block actually emits is stated separately.
Ports
- Output – the underlying value. It has no inputs, and its size is the
size of the Underlying Value parameter: a scalar gives a scalar signal, an
[m,n] value an [m,n] signal. Use the vector form to carry Simulink's vector
Value,
[SlDemoSign.Negative; SlDemoSign.Zero].
Parameters
- Output Data Type – the enumeration class, in Simulink's own spelling:
Enum: SlDemoSign. It is carried verbatim across the bridge and is not read by anything on the ICore side. - Value – the member, in Simulink's own spelling:
SlDemoSign.Negative, or a bracketed list of members for a vector output. Also carried verbatim, and its only ICore-side use is the count check below. - Underlying Value – the number ICore emits: the integer MATLAB stores
behind that member (
SlDemoSignis Positive 1, Zero 0, Negative −1). One entry per member named in Value, in the same order, and every entry must be a whole number. This parameter does not cross to Simulink – there is nothing to map it to, because Simulink reads the class definition instead. - Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period. The value emitted never changes, so the rate only decides how often the port is refreshed.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. The underlying value is exposed as a tunable parameter on the generated core rather than being inlined, so a deployed core can be re-pointed at a different member without regenerating it. No target carries the enumeration TYPE: what is generated is the number, in the target's own numeric type. Like Constant and unlike the time-driven sources, the block reads no clock, so the three HDL targets are genuinely synthesizable; note that their Q16.16 datapath carries whole numbers only up to about ±32767, so an enumeration whose underlying values are larger than that cannot be represented in hardware.
Simulink bridge
Import and export, mapped to simulink/Sources/Enumerated Constant.
"Output Data Type" to OutDataTypeStr, "Value" to Value,
"Sampling Time (s)" to SampleTime, as on every block. Both text
parameters pass through unchanged, so the mapping is lossless in both directions.
"Underlying Value" does not cross, in either direction, and cannot: Simulink
derives it from the enumeration's classdef, which is not visible to ICore. So an
imported block comes back with whatever underlying value was already set here, and it
is the one parameter a user must check by hand after an import. Note also that
Simulink's SampleTime defaults to inf (a constant sample
time, evaluated once) while ICore's default of 0 inherits the surrounding rate, so a
model round-tripped through Simulink returns with an explicit rate rather than
inf.
Notes
- Algebraic, stateless and time-independent, exactly like Constant – the output is the same at every instant.
- The stated underlying value is not verified against the real enumeration, because the classdef lives on the MATLAB path and not in this process. What is verified is that Value and Underlying Value carry the same number of entries and that each entry is a whole number; a mismatch stops the run and names the block.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Sources/Enumerated_Constant |
| family | Control_Systems/Sources |
| solver environment class | ICoreBlock_0_Control_Systems_1_Sources_2_Enumerated_Constant |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Sources/Enumerated_Constant/ICoreBlock_0_Control_Systems_1_Sources_2_Enumerated_Constant.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Sources/Enumerated_Constant/ICoreBlock_0_Control_Systems_1_Sources_2_Enumerated_Constant.h |
| default size on canvas | 90 × 70 px |
| ports at insert | 0 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | out | ICoreDouble | — |
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 variable | Default | Simulink parameter |
|---|---|---|
Output Data Type | Enum: SlDemoSign | OutDataTypeStr |
Value | SlDemoSign.Positive | Value |
Underlying Value | 1 | not crossed |
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.
Simulink bridge#
| support | Support::Both |
| Simulink path | simulink/Sources/Enumerated Constant |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
| deliberately not crossed | Underlying Value |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
Output Data Type | OutDataTypeStr | passes through |
Value | Value | passes through |
Caveat (shown to the user): 'Underlying Value' has no Simulink counterpart and cannot have one: Simulink reads the number behind an enumeration member from the class definition on its own path, which ICore cannot see. It is therefore ICore-side only, and the ONE parameter to check by hand after an import -- an imported block keeps whatever value was already set here, so a wrong one runs the ICore simulation on a different number from the Simulink model with nothing to say so. The two text parameters pass through unchanged and are lossless both ways. As on Constant, Simulink's SampleTime defaults to 'inf' where ICore's default of 0 inherits the surrounding rate, so a round trip returns an explicit rate rather than 'inf'.
Catalog contract: src/ICoreSDK/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).
Enumerated Constant block — y = the underlying value of a fixed enumeration member Simulink's Enumerated Constant emits one member of a MATLAB enumeration class, as a signal of that enumerated type. ICore has exactly one signal type -- the double -- and holds no enumeration definitions anywhere, so the two halves of that idea are carried separately:
- "Output Data Type" and "Value" hold Simulink's own text ("Enum: SlDemoSign",
"SlDemoSign.Negative") and cross the bridge verbatim. Simulink resolves them against the classdef on its path; this process never has to know what the class contains.
- "Underlying Value" holds the NUMBER ICore emits, which is the integer MATLAB stores
behind that member.
The hazard that split creates is worth being blunt about: nothing in this process can check the stated underlying value against the real enumeration, because the definition lives on the MATLAB path. Get it wrong and the ICore simulation runs on a different number from the Simulink model it exports to, with nothing to say so. What CAN be checked is checked -- the two configs must agree in how many entries they carry, and an underlying value must be a whole number, since a fractional one is not an enumeration's underlying value at all -- and both live in verifyInitializedPortSignals below.
Everything else is Constant: the parameter's SHAPE is the output's shape, so a vector Value ("[SlDemoSign.Negative; SlDemoSign.Zero]") gives a two-entry port, and the block is algebraic, stateless and time-independent.
Code export: all ten targets, and the three HDL ones are synthesizable rather than simulation-only -- there is no clock to read, only a Q16.16 literal driven onto the signal.
Sample results#
Plotted: free — No input: the block run alone
Category source · sample time 0.1 · 60 steps · commit ccf005c8 · produced by docsSample --out <folder> --steps 60 · data docs/generated/samples/Control_Systems__Sources__Enumerated_Constant.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).