Generated reference › Rate Transition — Control Systems/Signal Attributes
kind: generated#block#control-systems-signal-attributes

Rate Transition — Control Systems/Signal Attributes

Control_Systems/Signal_Attributes/Rate_Transition · 1 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.

Rate Transition

Control Systems / Signal Attributes

Re-samples a signal onto a slower period and holds it in between. With N = round(Output Sample Time / the block's own period):

y[k] = u[N·floor(k/N)]

So at N = 3 the block takes the input on samples 0, 3, 6, … and repeats each taken value twice. The first sample is taken, not held over, so nothing is delayed at the start, and the value published between takes is the one taken at the top of the interval. N = 1 – which is what a non-positive Output Sample Time means – is a plain wire.

Ports

  • Input – the signal u at the fast rate, of any size [m,n]. It is read on every sample and used on one in N.
  • Output – y, the same size as the input, updated on one sample in N and holding its value in between. The block never reshapes a signal.

Parameters

  • Output Sample Time (s) – the period to re-sample onto, a scalar in seconds. Zero or less means no re-sampling and the block is a wire; that is the default, and matches the −1 the Simulink counterpart ships with. A value that is not a whole multiple of the block's own period is rounded to the nearest multiple and reported once, rather than refused – the ratio, not the period, is what the block can act on.
  • Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period. This is the fast side: the output period above is counted in multiples of it.

Code export

All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. N is resolved at export time and inlined as a constant rather than exposed as a tunable parameter, because the count is fixed once the model's rates are: retuning it on a deployed core would mean re-deriving it from a period the core no longer carries. At N = 1 the block emits a plain copy with no state at all, so a model that leaves the parameter alone pays nothing for the block being present.

The three HDL targets are synthesizable. The state is one counter register and one held value per element, with no arithmetic to quantize – values are copied, not computed, so the exported core is bit-exact against the simulation rather than merely close.

Simulink bridge

Import and export, mapped to simulink/Signal Attributes/Rate Transition. "Output Sample Time (s)" to OutPortSampleTime, as a plain pass-through; Simulink's OutPortSampleTimeOpt ships as Specify, which is the setting that pair needs, so nothing has to be written to it.

The rate does NOT cross. That block defines no SampleTime parameter – set_param against R2026a answers "RateTransition block does not have a parameter named 'SampleTime'" – so "Sampling Time (s)" stays on the ICore side. Writing it anyway would be a hard error that aborts the whole generated script.

Three Simulink parameters have no counterpart here and are left at their defaults. Integrity and Deterministic were measured to make no difference at all to the fast-to-slow behaviour this block implements – an output period of 0.02 answered [1 1 3 3 5 5 …] with each of them on and off. InitialCondition belongs to the slow-to-fast direction, which is not implemented (see Notes), and never appears in the direction that is.

Notes

  • Stateful: a phase counter, plus the value currently being held.
  • Discrete only. N counts SAMPLES, which only means what it says if the block is evaluated once per sample; under a continuous solver the sub-steps of a single step would each advance the counter. The block therefore takes its period from its own Sampling Time (s), falling back to the model's global rate.
  • Fast to slow only. Simulink's block also converts slow to fast, delaying by a whole input period and filling that period with an initial condition. That direction needs the rate of the signal ARRIVING, and a block here is told its own period and never its input's, so it is not offered rather than approximated.
  • Deliberately carries no state space. The block is linear but not time-invariant – which of the N phases a sample falls in decides whether the output follows the input or ignores it – so no single A/B/C/D describes it, and a reduction that absorbed it would silently put the fast rate back.

Code facts#

FactValue
registered typeControl_Systems/Signal_Attributes/Rate_Transition
familyControl_Systems/Signal_Attributes
solver environment classICoreBlock_0_Control_Systems_1_Signal_Attributes_2_Rate_Transition
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Attributes/Rate_Transition/ICoreBlock_0_Control_Systems_1_Signal_Attributes_2_Rate_Transition.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Signal_Attributes/Rate_Transition/ICoreBlock_0_Control_Systems_1_Signal_Attributes_2_Rate_Transition.h
default size on canvas80 × 70 px
ports at insert1 in, 1 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDouble—
2outICoreDouble—

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
Output Sample Time (s)-1OutPortSampleTime

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 Attributes/Rate Transition
port-count rulePortsParam::None
SampleTime parameterno — the counterpart defines none; the rate stays on the ICore side
ICore configSimulink parameterValue translation
Output Sample Time (s)OutPortSampleTimepasses through

Caveat (shown to the user): Integrity and Deterministic do not cross and are left at their defaults: both were measured to make no difference to the fast-to-slow conversion this block implements. InitialCondition does not cross either -- it belongs to the slow-to-fast direction, which is not implemented here because it needs the rate of the arriving signal and a block is told only its own. The rate itself stays on the ICore side: the Simulink block defines no SampleTime parameter

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

Rate Transition -- re-samples a signal onto a slower period and holds it in between y[k] = u[N*floor(k/N)], N = round(Output Sample Time / the block's own period). See the header for the R2026a measurements the rule was written from, for why the first sample is taken rather than held over, and for the slow-to-fast direction that is deliberately not implemented.

ONE PLACE COUNTS THE PHASES. stepsPerOutput() derives N once from the config and the block's resolved period, and the live solver and all ten generators go through it -- so an export cannot disagree with the simulation about how long a sample is held.

⚠ THE PERIOD IS NOT KNOWN UNTIL AFTER THE PORT-SIZE PASS. ICoreModelBuild assigns block sampling times AFTER it has sized the ports and verified them, so getSamplingTime() reads zero inside initializePortSignalSize() and verifyInitializedPortSignals(). N is therefore derived lazily, at the first step and at generation time, and the warning about a period that is not a whole multiple is armed once rather than emitted from the sizing pass.

Sample results#

Rate Transition — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sampleRate Transition — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample-202-2-10123inputoutput
tin ICoreDouble-Out-0out ICoreDouble-Out-0
0-2-2
0.40.50.5
0.8-2-2
1.20.50.5
1.6-2-2
20.50.5
2.4-2-2
2.80.50.5
3.2-2-2
3.60.50.5
4-2-2
4.40.50.5
4.8-2-2
5.20.50.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)0 … 1
rampRamp: slope 1 from t = 00 … 5.8
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias-1 … 0.9996
stepStep: 0 -> 1 at t = 1 s0 … 1

Plotted: table — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample

Category static · sample time 0.1 · 60 steps · commit 7c7bede29383f473643ac43dbea18cc57b585aa1 · produced by docsSample --out <folder> --blocks Unit_Conversion Rate_Transition --steps 60 · data docs/generated/samples/Control_Systems__Signal_Attributes__Rate_Transition.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).