Switch — Control Systems/Signal Routing
Control_Systems/Signal_Routing/Switch · 3 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.
Switch
Control Systems / Signal Routing
Passes the first input or the third, entry by entry, decided by the second. Which test the middle input is put to is a parameter, so this one block covers "when the control is high", "when it is above a level" and "when it is not zero".
Ports
- u1 – the value passed when the test PASSES.
- u2 – the control. It is what the test is applied to; its value is never passed on.
- u3 – the value passed when the test FAILS.
- Output – the chosen value, of the inputs' shared size [m,n].
All three inputs accept any numeric type – floating point, integer or boolean – so a boolean control signal connects directly and so does an analog one. They must all be the same size, or be scalars, which are used against every entry of the others. Text and buses are refused.
Parameters
- Criteria – the test applied to the control.
- Control at or above threshold
- Control above threshold – the default, as in Simulink.
- Control is not zero – the threshold is not used. This is the natural choice for a boolean control.
- Threshold – the level the first two criteria compare against. Ignored by the third.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
What comes out is a 64-bit float
The output always carries the 64-bit floating-point type, whatever is switched through it. Routing an integer signal through this block therefore produces a floating-point one: put a Data Type Conversion block after it if the integer type has to continue. This is deliberate – a link carries its source port's type and nothing in the application converts a type without being asked to – but it is a difference from Simulink, whose Switch gives back the type it was given.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. The criterion and the threshold are fixed into the generated code at export time, and the three hardware targets are fully synthesizable: a switch is a comparison and a multiplexer, which the fixed-point datapath does natively.
One case is not applicable rather than unsupported: a diagram that drives this block's control from a genuinely boolean signal cannot be exported to the three hardware targets, because they carry every signal in one fixed-point format and do not yet apply a signal's type to it. That is refused by name for that diagram, with the reason, and recorded as "not applicable" - the block itself is unaffected and every other diagram still exports to all ten.
Simulink bridge
Import and export, mapped to simulink/Signal Routing/Switch.
"Criteria" to Criteria, one option for one option, and "Threshold"
to Threshold as a number; "Sampling Time (s)" to
SampleTime, as on every block.
AllowDiffInputSizes is always written as off and
InputSameDT as off, matching this block: the inputs
share one size (or are scalars) and are free to carry different types.
ZeroCross, RndMeth and
SaturateOnIntegerOverflow are solver and fixed-point settings with
no counterpart here and do not cross.
Notes
- Algebraic, with no state: the output depends only on the current inputs.
- Not linear – it is piecewise, and which piece is taken depends on a signal – so the block deliberately carries no state space and model reduction reports it as unmergeable.
- The control's own value is never passed through, only tested.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Signal_Routing/Switch |
| family | Control_Systems/Signal_Routing |
| solver environment class | ICoreBlock_0_Control_Systems_1_Signal_Routing_2_Switch |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Routing/Switch/ICoreBlock_0_Control_Systems_1_Signal_Routing_2_Switch.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Routing/Switch/ICoreBlock_0_Control_Systems_1_Signal_Routing_2_Switch.h |
| default size on canvas | 80 × 80 px |
| ports at insert | 3 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 | in | ICoreDouble | u1 |
| 2 | in | ICoreDouble | u2 |
| 3 | in | ICoreDouble | u3 |
| 4 | 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 |
|---|---|---|
Criteria | Control at or above threshold%~%Control above threshold%~… | Criteria |
Threshold | 0 | Threshold |
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/Signal Routing/Switch |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
| always set | AllowDiffInputSizes = off, InputSameDT = off |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
Criteria | Criteria | Control at or above threshold → u2 >= Threshold, Control above threshold → u2 > Threshold, Control is not zero → u2 ~= 0 |
Threshold | Threshold | passes through |
Caveat (shown to the user): the three criteria map 1:1 onto Simulink's; the output type does NOT cross, because this block's output is always a 64-bit float where Simulink's Switch gives back the type it was given -- put a Data Type Conversion after it if an integer type has to continue
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).
Switch -- pass the first input or the third, decided by the second ALL FOUR PORTS ARE DECLARED AS 64-BIT FLOATS, AND EACH OF THE THREE INPUTS ACCEPTS ANY NUMERIC TYPE -- so a boolean, integer or floating-point link may land on any of them, including the control. Declaring the control port boolean instead would have made every diagram using this block non-exportable to the three hardware-description targets, because those carry every signal in one fixed-point format and do not yet apply a signal's type to it; the refusal is a property of the whole diagram, not of one cell. A switch is a comparison and a multiplexer, which is the one thing a fixed-point datapath does natively, so surrendering that permanently to spell a default differently would be a poor trade. The header carries the argument in full.
ONE CRITERION, THREE SPELLINGS, TEN LANGUAGES. The three criteria are a comparison against a threshold or a test for non-zero; each generator asks one shared helper in this file for the condition in its own spelling and drops it into its own select, so the rule is written once.
THE BLOCK NEVER ROUNDS ITS OWN OUTPUT: it chooses a value and stores it, and the output port applies its type once, as on every block.
Sample results#
| t | in ICoreDouble-Out-0 | in ICoreDouble-Out-0 | in ICoreDouble-Out-0 | out ICoreDouble-Out-0 |
|---|---|---|---|---|
| 0 | -2 | -2 | -2 | -2 |
| 0.04 | 0.5 | 0.5 | 0.5 | 0.5 |
| 0.08 | -2 | -2 | -2 | -2 |
| 0.12 | 0.5 | 0.5 | 0.5 | 0.5 |
| 0.16 | -2 | -2 | -2 | -2 |
| 0.2 | 0.5 | 0.5 | 0.5 | 0.5 |
| 0.24 | -2 | -2 | -2 | -2 |
| 0.28 | 0.5 | 0.5 | 0.5 | 0.5 |
| 0.32 | -2 | -2 | -2 | -2 |
| 0.36 | 0.5 | 0.5 | 0.5 | 0.5 |
| 0.4 | -2 | -2 | -2 | -2 |
| 0.44 | 0.5 | 0.5 | 0.5 | 0.5 |
| 0.48 | -2 | -2 | -2 | -2 |
| 0.52 | 0.5 | 0.5 | 0.5 | 0.5 |
Every 4th of 60 samples, from the table stimulus.
The same rig also ran:
| Stimulus | What it is | Output range |
|---|---|---|
impulse | Impulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair) | 0 … 1 |
ramp | Ramp: slope 1 from t = 0 | 0 … 0.59 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | 0 … 0.9246 |
step | Step: 0 -> 1 at t = 1 s | 0 … 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 31d36c2c3 · produced by docsSample --out <folder> --blocks Bus_Creator,Bus_Selector,Logical_Operator,Relational_Operator,Bitwise_Operator,Switch --steps 60 · data docs/generated/samples/Control_Systems__Signal_Routing__Switch.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).