Probe — Control Systems/Signal Attributes
Control_Systems/Signal_Attributes/Probe · 1 input / 3 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.
Probe
Control Systems / Signal Attributes
Reports three properties of the signal that reaches it, one per output port: w = m×n, the element count of an [m,n] input; Ts = [period 0], the rate the block runs at; and c = 0, its complexity. None of the three depends on the samples – sizes and rates are resolved when the model is built, so all three are constant for a whole run.
Ports
- Input u – the signal being asked about, of any size [m,n]. Its VALUES are never read; only its size, and the rate this block runs at.
- Output w – the element count m×n, always 1×1. A [2,3] input answers 6, a three-element vector answers 3, a scalar answers 1. It is a count and not a dimension.
- Output Ts – the rate, always 1×2, carrying [period offset]. The offset is always 0: ICore has no sample-time offset to report.
- Output c – the complexity, always 1×1 and always 0. Every ICore signal is a real matrix, so there is no complex case for this port to report.
Parameters
- None beyond the rate below. What this block reports is a property of the model, not something to set.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period. On this block alone the value is also an output: it is what the Ts port carries.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. All three answers are inlined as literals rather than exposed as tunable parameters, and that is not an optimization: on a generated core the signal sizes and the rate are already fixed, so there is nothing left to measure at run time. The three HDL targets are fully synthesizable – the body is three constant assignments with no arithmetic to quantize.
Simulink bridge
Import and export, mapped to simulink/Signal Attributes/Probe. Three of that block's
four outputs are always implied and written on export –
ProbeWidth, ProbeSampleTime and ProbeComplexSignal all
on – so the exported block shows the same three ports in the same order.
The DIMENSIONS output is pinned off and REPORTED.
ProbeSignalDimensions is always written off, and a Simulink model
that had it on is reported on import rather than mapped. Simulink emits the dimensions
vector there, which is [width] for a one-dimensional signal and [rows columns] for a
two-dimensional one – measured in R2026a, where a three-element signal answered a scalar
3. Every ICore signal is an [m,n] matrix with no one-dimensional case, so there is no
value this port could carry that is right in both tools.
The rate does NOT cross. That block defines no SampleTime parameter
– verified by set_param against R2026a, which answers "Probe block does not
have a parameter named 'SampleTime'" – so "Sampling Time (s)" stays on the ICore side.
Simulink's four output-data-type settings (ProbeWidthDataType and its three
siblings) have no counterpart here, every ICore signal being a matrix of doubles, and are left
at their defaults.
Notes
- Algebraic, with no state, and constant for a whole run: both numbers it reports are resolved by the model build before the first step.
- The rate reported is this block's own. Simulink's Probe reports the rate of the SIGNAL that arrives – measured: driven from a 0.02 s source inside a model stepping at 0.01 s it answered [0.02 0]. ICore carries no rate on a wire; a block has one. Left inheriting, the two are the same number; given an explicit period, this block reports that period.
- Under a variable-step solver a block's period is the initial step rather than a rate it keeps, so the Ts port reports that initial step. Use a fixed-step solver when the value is meant to be read.
- Deliberately carries no state space, for the reason Width gives: the outputs do not depend on the input at all, so there is no A/B/C/D that represents the relation – it would need a constant term and a state space has nowhere to hold one. Model reduction reports the block as unmergeable rather than absorbing it.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Signal_Attributes/Probe |
| family | Control_Systems/Signal_Attributes |
| solver environment class | ICoreBlock_0_Control_Systems_1_Signal_Attributes_2_Probe |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Attributes/Probe/ICoreBlock_0_Control_Systems_1_Signal_Attributes_2_Probe.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Attributes/Probe/ICoreBlock_0_Control_Systems_1_Signal_Attributes_2_Probe.h |
| default size on canvas | 80 × 90 px |
| ports at insert | 1 in, 3 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 | u |
| 2 | out | ICoreDouble | w |
| 3 | out | ICoreDouble | Ts |
| 4 | out | ICoreDouble | c |
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#
No config variable beyond the Sampling Time (s) every block carries.
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 Attributes/Probe |
| port-count rule | PortsParam::None |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| always set | ProbeWidth = on, ProbeSampleTime = on, ProbeComplexSignal = on, ProbeSignalDimensions = off |
Caveat (shown to the user): three of Simulink's four outputs cross, in its own order: width, sample time and complexity. The DIMENSIONS output is pinned off and a model that had it on is reported -- Simulink emits the dimensions VECTOR there, [width] for a 1-D signal and [rows columns] for a 2-D one, and an ICore signal is always an [m,n] matrix with no 1-D case to distinguish. The rate does not cross either: the Simulink block defines no SampleTime parameter, so "Sampling Time (s)" stays on the ICore side -- and on this block it is also what the Ts output reports
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:
B0no 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).
Probe -- three properties of the signal that arrives w = m*n (1x1), Ts = [period 0] (1x2), c = 0 (1x1). See the header for why the rate is the BLOCK's rather than the wire's, and for why Simulink's fourth output is refused rather than answered.
ONE PLACE PER NUMBER, TEN BACKENDS INLINE IT. widthOf() and periodOf() are the only two readers of the model's resolved state in this file, and compute_h and all ten generators go through them, so the live run and every export cannot disagree about what the block reports. They are free functions here rather than members, because a header in this tree holds public declarations and a two-line private residue and nothing else.
BOTH NUMBERS ARE FIXED BEFORE THE FIRST STEP, which is what makes inlining them honest rather than an optimization. Port sizes are resolved by the model build's convergence loop, and a block's rate is assigned by the build too; neither is touched again while the model runs. That also keeps this block clear of the trap ADDING_NEW_BLOCKS.md section 7 describes, where a generator reads a member the block MUTATES while running and every backend bakes in the same wrong constant: there is no such member here.
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.