Generated reference › Bus Creator — Control Systems/Signal Routing
kind: generated#block#control-systems-signal-routing

Bus Creator — Control Systems/Signal Routing

Control_Systems/Signal_Routing/Bus_Creator · 2 input / 1 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++

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.

Bus Creator

Control Systems / Signal Routing

Packs several signals into one bus: a single wire carrying named elements, so a group of related signals can be routed together and taken apart again by a Bus Selector at the far end.

Ports

  • Inputs – two by default, and the count is user-editable. Each one becomes one element of the bus, in port order. An input accepts any signal type except another bus, and the element takes whatever that input carries – its type and its size are copied, not chosen here.
  • Output (bus) – the bus. Its "size" is the list of elements rather than a number of rows and columns, which is why the block face shows the element count.

Parameters

  • Element names – a comma-separated list, one name per input, in port order. These are what a Bus Selector picks by, so they must be unique and none may be blank. Adding an input without adding a name is an error the build reports.
  • Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.

Notes

  • Routing only – no value is scaled, converted or reordered. What arrives on input n is what element n carries.
  • A bus cannot contain another bus. Connecting one to an input is refused with the element's name, rather than silently flattened.
  • Algebraic, with no state, and no state space: there is no A/B/C/D that describes packing differently typed signals into one.
  • The element types are decided by what you connect, so changing an upstream block's output type changes the bus. Both ends are checked when the model is built: two bus wires fit together only if their elements match in order, name, type and size.

Code export

Exported to Python (a dict) and MATLAB (a struct), keyed by the element names above – so the generated code selects an element by the same name the Bus Selector does.

Exported to C, C++, Java and Rust as a declared record: a struct (a static class in Java) named Bus0, Bus1, and so on, one per distinct bus in the model, with one field per element under the element's own name. Two buses with the same elements, in the same order, of the same types and sizes, share one record. Each field is stored the way a signal of that type and size is stored in that language: a matrix of doubles for a numeric element, text for a String. Because each element name becomes a field, it must be a plain identifier (a letter or underscore, then letters, digits or underscores) and not a reserved word of C, C++, Java or Rust; export to those four refuses any other name and says which one. Simulink sets the same rule for bus element names.

Not exported to VHDL, Verilog, SystemVerilog or PLC Structured Text. Each refuses by name at export, with its own reason: the HDL trio needs a fixed bit width, and the Structured Text exporter emits no type declarations at all. Select the elements you need with a Bus Selector and route them separately if the model has to generate code for one of those.

Simulink bridge

Import and export, mapped to simulink/Signal Routing/Bus Creator. The port count crosses as Inputs. "Sampling Time (s)" does not cross. Simulink's Bus Creator is a virtual block with no SampleTime parameter at all, so an explicit rate here is reported as staying on the ICore side, in the export report and as a warning in the generated script.

The element names cross as the names of the input lines. Simulink has no element-name setting: it names each element after the line into its port, and signal1, signal2, and so on for an unnamed line. So an export names each input line after its element, and a Bus Selector in Simulink then finds the element by the same name. On import, a Simulink Bus Creator that a Bus Selector reads becomes this block, its elements named after its input lines, or signalK where a line has no name. A Bus Creator that only feeds blocks reading it as a vector becomes a Mux, because that is what Simulink computes there. One source line can carry only one name, so a signal feeding two bus elements of different names keeps the first, and the export says so.

Code facts#

FactValue
registered typeControl_Systems/Signal_Routing/Bus_Creator
familyControl_Systems/Signal_Routing
solver environment classICoreBlock_0_Control_Systems_1_Signal_Routing_2_Bus_Creator
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Routing/Bus_Creator/ICoreBlock_0_Control_Systems_1_Signal_Routing_2_Bus_Creator.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Routing/Bus_Creator/ICoreBlock_0_Control_Systems_1_Signal_Routing_2_Bus_Creator.h
default size on canvas40 × 110 px
ports at insert2 in, 1 out
code generators implementedPython, MATLAB, Java, Rust, C, C++

Ports#

#DirectionSignal typeDescription label
1inICoreDouble—
2inICoreDouble—
3outICoreBus—

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
Element namesa, bnot 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.

supportSupport::Both
Simulink pathsimulink/Signal Routing/Bus Creator
port-count rulePortsParam::MuxCount
SampleTime parameterno — the counterpart defines none; the rate stays on the ICore side
deliberately not crossedElement names

Caveat (shown to the user): Simulink names a bus's elements after its input LINES (signal1..N when a line is unnamed, measured on R2026a), so the names cross as line names: the export names each input line, the import reads them

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).

Bus Creator -- packs its inputs into one bus signal The block that OWNS a bus spec. Names come from config; element types and sizes are inferred from whatever is connected, which is why the spec is built in the sizing loop and not in loadBlockConfig() -- an upstream type is not resolved until the loop has run.

Code export: Python and MATLAB build a record from an EXPRESSION, so a bus reaches them with nothing declared anywhere. C, C++, Java and Rust declare one record type per distinct spec (FEATURES_TO_ADD.md BF1.3), and the bodies here are plain copies into it. HDL and PLC refuse a bus by name.

Per step the shape is fixed (BF1.4): each element is written IN PLACE, and an input whose value is not its element's rows x cols stops the run by name instead of reshaping the element under its spec.

Sample results#

Bus Creator — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sampleBus Creator — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample-20200.10.20.30.40.5t (s)in ICoreDouble-Out-0in ICoreDouble-Out-0

This block carries a ICoreBus signal, whose value is text rather than a number and is not something a plot has an axis for. The samples are in the table below, exactly as the run recorded them.

tin ICoreDouble-Out-0in ICoreDouble-Out-0out ICoreBus-Out-0
0-2-2{'a': -2, 'b': -2}
0.040.50.5{'a': 0.5, 'b': 0.5}
0.08-2-2{'a': -2, 'b': -2}
0.120.50.5{'a': 0.5, 'b': 0.5}
0.16-2-2{'a': -2, 'b': -2}
0.20.50.5{'a': 0.5, 'b': 0.5}
0.24-2-2{'a': -2, 'b': -2}
0.280.50.5{'a': 0.5, 'b': 0.5}
0.32-2-2{'a': -2, 'b': -2}
0.360.50.5{'a': 0.5, 'b': 0.5}
0.4-2-2{'a': -2, 'b': -2}
0.440.50.5{'a': 0.5, 'b': 0.5}
0.48-2-2{'a': -2, 'b': -2}
0.520.50.5{'a': 0.5, 'b': 0.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)—
rampRamp: slope 1 from t = 0—
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias—
stepStep: 0 -> 1 at t = 1 s—

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__Bus_Creator.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).