Variant Sink — Control Systems/Signal Routing
Control_Systems/Signal_Routing/Variant_Sink · 1 input / 2 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.
Variant Sink
Control Systems / Signal Routing
Sends its input to one of its outputs, the one whose variant
control is true: yk = u. Each output has a control, a
condition over the project's variables such as V==1, and the choice is
made before the run from the variables' values then. The outputs that are
not chosen are absent: every block they alone feed leaves the run, as
Simulink removes it.
Ports
- Input – u, any size [m,n].
- y1 … yN – the choices, one per variant control, each of the input's size. Add or remove outputs from the block's port settings, and keep one control per output. The chosen one carries u; a block that reads an output not chosen and also something else keeps running and reads 0 from it, as in Simulink.
Parameters
- Variant Controls – one control per output, in port order, written
as Simulink writes them,
{'V==1';'V==2'}, or as a plain list,V==1; V==2. A control is a condition that is true or false:V==1,V~=1,V>=1 && V<=2,V==1 || W==2,mod(V,2)==1, ortrueandfalse.(default)marks the output taken when no other control is true. A bare name such asVis not a condition and is refused, as Simulink refuses it. The default is{'true';'false'}: the first output. - Variant Control Mode – expression evaluates the controls as
conditions; label treats each control as a name and takes the output whose
name is Label Mode Active Choice; sim codegen switching takes the
output whose control is
(sim), and each control must be(sim)or(codegen). - Label Mode Active Choice – in label mode, the name of the chosen output. Unused in the other modes.
- Allow Zero Variant Controls – Off: a run with no control true is refused. On: with no control true every output is absent, and the block leaves the run with everything after it.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period. It does not cross to Simulink, whose block has no rate parameter.
When a run is refused
In Simulink's words: no control true (must have at least one active
port), more than one true (must have only one active port), two
(default) controls, a bare name, a variable the project does not
define, a value that is not true or false, and a number of controls that is not
the number of outputs.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. The choice is made before the export, so the generated body copies the input to the chosen output and holds no condition; what the other outputs alone fed is not exported, and an output not chosen that still reaches the exported core's interface carries zeros. Re-export after changing a variable a control reads. The HDL targets are fully synthesizable.
Simulink bridge
Import and export, mapped to simulink/Signal Routing/Variant Sink.
Variant Controls crosses as the cell VariantControls, which is
what sets Simulink's output count; Variant Control Mode,
Label Mode Active Choice and Allow Zero Variant Controls as
VariantControlMode, LabelModeActiveChoice and
AllowZeroVariantControls. The activation time is written as
update diagram, the only one ICore makes; a model with another is
reported on import. The rate does not cross.
Notes
- Algebraic, with no state.
- Controls name variables of the project's variables space; Simulink's
Simulink.Variantobjects and model workspace are not carried. - To choose by a setting rather than a condition, use Signal Routing / Manual Variant Sink.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Signal_Routing/Variant_Sink |
| family | Control_Systems/Signal_Routing |
| solver environment class | ICoreBlock_0_Control_Systems_1_Signal_Routing_2_Variant_Sink |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Routing/Variant_Sink/ICoreBlock_0_Control_Systems_1_Signal_Routing_2_Variant_Sink.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Routing/Variant_Sink/ICoreBlock_0_Control_Systems_1_Signal_Routing_2_Variant_Sink.h |
| default size on canvas | 80 × 90 px |
| ports at insert | 1 in, 2 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 | — |
| 2 | out | ICoreDouble | y1 |
| 3 | out | ICoreDouble | y2 |
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 |
|---|---|---|
Variant Controls | {'true';'false'} | VariantControls |
Variant Control Mode | expression%~%label%~%sim codegen switching~~expression | VariantControlMode |
Label Mode Active Choice | — | LabelModeActiveChoice |
Allow Zero Variant Controls | Off%~%On~~Off | AllowZeroVariantControls |
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/Variant Sink |
| port-count rule | PortsParam::VariantControlsOut |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| always set | VariantActivationTime = update diagram |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
Variant Controls | VariantControls | passes through |
Variant Control Mode | VariantControlMode | expression → expression, label → label, sim codegen switching → sim codegen switching |
Label Mode Active Choice | LabelModeActiveChoice | passes through |
Allow Zero Variant Controls | AllowZeroVariantControls | Off → off, On → on |
Caveat (shown to the user): the controls cross as the cell
VariantControls, which sets Simulink's output count; the activation time isupdate diagram, the only one ICore makes; the block has NO SampleTime parameter, so a rate set here does not cross
Catalog contract: src/ICoreBlocks/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The checker has a blind spot here — it could not resolve something (a grouped port bullet, a computed config name), which is reported and never counted as a pass. A reader has to settle it:
B0Ports lists 2 entries for 3 ports (1 in, 2 out), and the 2 they cover does not reconcile — grouped, or one undocumented? a reader must sayB0no sample under docs/generated/samples/ — nothing to cross-check (P8.1)
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).
Variant Sink -- one input to one of N outputs, the one whose variant control is true y<k> = u, where control k is the true one; every other output is ABSENT. Measured on R2026a (FEATURES_TO_ADD.md §F.BF3):
VariantControlsis a cell, one condition per output, default {'true';'false'}, and the output count FOLLOWS it; the dialog is the Variant Source's withoutOutputFunctionCall; no SampleTime. Driven by a Constant with a To Workspace on each output, the inactive output's variable is absent from the run, and a Sum reading it and a Constant 5 stays and reads 0 from it -- which is what the build's pruning does (BF3.3). The choice, the pruning, the refusals and the ten generators are ICoreVariantBlockBase's.
Sample results#
No sample run is committed for this block. Samples come from the headless harness (DOCS_PLAN.md P8.1) into docs/generated/samples/; until one exists this block's behaviour is witnessed by the parity and export-verification suites, not by a plot here.