Generated reference › Weighted Sample Time Math — Control Systems/Base Blocks
kind: generated#block#control-systems-base-blocks

Weighted Sample Time Math — Control Systems/Base Blocks

Ts

Control_Systems/Base_Blocks/Weighted_Sample_Time_Math · 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.

Weighted Sample Time Math

Control Systems / Base Blocks

Does arithmetic between the input and the block's own sample time, scaled by a weight: y = u <op> (Ts·w), applied entry by entry. It is how a rate-dependent constant – a per-step increment, a discrete integrator's step, a frequency in samples – is written once and follows the model's rate instead of being retyped whenever that rate changes.

Ports

  • Input – the signal u, of any size [m,n]. The two only operations ignore it, but the port stays: it is what fixes the output size and the rate.
  • Outputy, of the SAME size [m,n]. The block never reshapes a signal.

Parameters

  • Operation – which arithmetic runs. This selects the code path rather than retuning one, so each option is a separate branch in all ten export targets.
    • u + Ts*w – adds the weighted sample time. The default, as in Simulink.
    • u - Ts*w – subtracts it.
    • u * (Ts*w) – scales the input by it.
    • u / (Ts*w) – divides the input by it. Requires a nonzero weight.
    • Ts*w only – the output is the weighted sample time itself, the same value in every entry. The input is ignored, though its size still sets the output's.
    • 1/(Ts*w) only – the output is the RECIPROCAL of the weighted sample time, in every entry. Note this is 1/(Ts·w) and not w/Ts. Requires a nonzero weight.
  • Weight – the factor w the sample time is multiplied by. Scalar; defaults to 1, which makes the block plain sample-time arithmetic. Must be nonzero for the two dividing operations, which are reported and stop the run otherwise rather than exporting a core that divides by zero.
  • Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period. On this block it is not just scheduling: the rate the block ends up running at IS the Ts in the arithmetic above, so changing it changes the output.

Code export

All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text.

The product Ts·w – not the weight on its own – is exposed as the generated core's single tunable parameter. That is deliberate: a deployed core runs at one fixed rate, so Ts is structural there and retuning w alone would be meaningless without it. Retuning the product is exactly retuning w at the exported rate. The operation is fixed into the arithmetic at export time, since it selects which code is emitted.

Add, subtract and multiply are native Q16.16 on the three HDL targets and fully synthesizable. The two dividing operations are simulation-only there: division has no Q16.16 primitive, so those cores convert at the port boundary and divide in real arithmetic – the same choice the Divide block makes. They also carry no infinity, so a zero divisor answers 0 rather than ±Inf.

Simulink bridge

Import and export, mapped to simulink/Math Operations/Weighted Sample Time Math. "Operation" goes to TsampMathOp, one option for one option (+, -, *, /, Ts Only, 1/Ts Only), so that round trip is lossless; "Weight" goes to weightValue as a pass-through value. TsampMathImp is written as a fixed Online Calculations: its alternative is a fixed-point scaling adjustment with no meaning for the doubles ICore carries, and an imported block set to it is reported rather than silently accepted.

The rate does NOT cross, and on this block that is worth stating twice: Simulink's Weighted Sample Time Math defines no SampleTime parameter at all – it takes its rate from the signal driving it – so the entry sets hasSampleTimeParam = false and "Sampling Time (s)" stays on the ICore side. Since the rate is part of this block's ARITHMETIC, an ICore block carrying an explicit rate exports to a Simulink block that will inherit a different one and compute something else. Drive both sides at the same rate.

Notes

  • Algebraic, with no state: the output depends only on the current input and on the block's rate.
  • State space: carried only for u * (Ts*w) and u / (Ts*w), which are the two linear operations, and only when the block has an explicit positive "Sampling Time (s)". An inherited rate is not resolved until the model is built, and model reduction reads the state space without building one – so rather than merge a D derived from a guess, the block reports why it has none. The other four operations are affine or constant, which A/B/C/D cannot carry, exactly as for Bias.

Code facts#

FactValue
registered typeControl_Systems/Base_Blocks/Weighted_Sample_Time_Math
familyControl_Systems/Base_Blocks
solver environment classICoreBlock_0_Control_Systems_1_Base_Blocks_2_Weighted_Sample_Time_Math
sourcesrc/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Base_Blocks/Weighted_Sample_Time_Math/ICoreBlock_0_Control_Systems_1_Base_Blocks_2_Weighted_Sample_Time_Math.cpp
headersrc/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Base_Blocks/Weighted_Sample_Time_Math/ICoreBlock_0_Control_Systems_1_Base_Blocks_2_Weighted_Sample_Time_Math.h
default size on canvas90 × 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
Operationu + Ts*w%~%u - Ts*w%~%u * (Ts*w)%~%u / (Ts*w)%~%Ts*w only…TsampMathOp
Weight1weightValue

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/Math Operations/Weighted Sample Time Math
port-count rulePortsParam::None
SampleTime parameterno — the counterpart defines none; the rate stays on the ICore side
always setTsampMathImp = Online Calculations
ICore configSimulink parameterValue translation
OperationTsampMathOpu + Ts*w+, u - Ts*w-, u * (Ts*w)*, u / (Ts*w)/, Ts*w onlyTs Only, 1/(Ts*w) only1/Ts Only
WeightweightValuepasses through

Caveat (shown to the user): the rate does not cross: Simulink's Weighted Sample Time Math defines no SampleTime parameter -- it takes its rate from the driving signal -- and on this block the rate is part of the ARITHMETIC, so drive both sides at the same rate or they compute different things

Catalog contract: src/ICoreSDK/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).

Weighted Sample Time Math block -- arithmetic against the block's own sample time y = u <op> (Ts*w), entry by entry, where Ts is the rate this block runs at and w is a configured weight. The six operations were MEASURED against the real Simulink block rather than read off the documentation, because two of them are easy to get subtly wrong:

"+" y = u + Ts*w "-" y = u - Ts*w "*" y = u * (Ts*w) "/" y = u / (Ts*w) "Ts Only" y = Ts*w -- the input is ignored entirely "1/Ts Only" y = 1 / (Ts*w) -- NOT w/Ts, which is the tempting reading

(Measured at Ts = 0.01, w = -2.5: "1/Ts Only" answers -40 = 1/(0.01*-2.5), not -250 = w/Ts.)

WHERE Ts COMES FROM, AND WHY THE STATE SPACE IS CONDITIONAL. Ts is getSamplingTime(), which ICoreModelBuild resolves in assignBlockSamplingTimes() -- and that runs AFTER initializePortsSignalMatrixSize(), i.e. after loadBlockConfig(). So Ts is authoritative in compute_h and in every generator (both run after a completed build) but NOT inside loadBlockConfig, which is where a state space would have to be derived. The model reduction commands read the state space off the solver environment WITHOUT building the model, so a D built from an unresolved rate would be silently wrong rather than merely absent -- a wrong matrix merged into a plant is worse than a refused merge. The block therefore carries a state space only when its own "Sampling Time (s)" config is positive, which is the one case where Ts is knowable without a build, AND the operation is one of the two linear ones.

HDL. Add, subtract and multiply are native Q16.16 and fully synthesizable. The two DIVIDING operations are simulation-only real arithmetic with a zero guard, which is the same choice -- and the same code shape -- the Divide block makes for its own division.

Sample results#

Weighted Sample Time Math — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sampleWeighted Sample Time Math — 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-1.9
0.40.50.6
0.8-2-1.9
1.20.50.6
1.6-2-1.9
20.50.6
2.4-2-1.9
2.80.50.6
3.2-2-1.9
3.60.50.6
4-2-1.9
4.40.50.6
4.8-2-1.9
5.20.50.6

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 … 1.1
rampRamp: slope 1 from t = 00.1 … 5.9
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias-0.9 … 1.1
stepStep: 0 -> 1 at t = 1 s0.1 … 1.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 ccf005c8 · produced by docsSample --out <folder> --steps 60 · data docs/generated/samples/Control_Systems__Base_Blocks__Weighted_Sample_Time_Math.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).