Generated reference › Repeating Sequence Interpolated — Control Systems/Sources
kind: generated#block#control-systems-sources

Repeating Sequence Interpolated — Control Systems/Sources

Control_Systems/Sources/Repeating_Sequence_Interpolated · 0 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.

Repeating Sequence Interpolated

Control Systems / Sources

A source that walks a (time, output) table one sample at a time and starts again at the end:

y[k] = lookup((k mod P)·Ts), where P = last time / Ts + 1 samples

Unlike Repeating Sequence, which reads the simulation clock, this block counts its own samples – so its position is exact however long the run is, and the rate is part of what sets the period.

Ports

  • Output – the looked-up value, always a scalar. It has no inputs; the position in the table comes from the block's own index, advancing once per sample.

Parameters

  • Output Values – what the waveform is at each table point, as a row or column vector; both spell the same list.
  • Time Values – when each of those points occurs, as a vector of the same length, holding at least two strictly increasing values, none of them negative. The LAST of them must be a whole number of samples at the block's rate, since it is what the cycle is measured against.
  • Lookup Method – what to do at a phase that falls between two table points.
    • Interpolation-Use End Values – a straight line between the two neighbouring points. The "end values" part only comes into it for a table that does not start at zero: below the first point the first value is held rather than extrapolated backwards. Above the last point cannot arise – the phase stops exactly there.
    • Use Input Nearest – the value at whichever of the two points is nearer in time.
    • Use Input Below – the value at the largest table time at or below the phase, which makes the output a staircase that steps at each table point.
    • Use Input Above – the value at the smallest table time at or above the phase, the same staircase shifted one point earlier.
  • 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 only how often the block runs: it is a term in the period, so changing it changes the length of the cycle as well as how finely the table is walked.

The period is the last time value plus one sample

A table whose last time is one second, at a hundredth-second rate, repeats every 101 samples rather than a hundred: the cycle covers the range from zero to that last time inclusively, giving every sample instant in it a turn, and wrapping on the sample after. This is Simulink's behaviour (verified against the R2026a block) rather than a choice made here, and it is the difference that catches people comparing the two.

Note that the phase is measured from zero, not from the table's first time. A table beginning at 0.2 s therefore spends its first twenty samples below its own first point – holding the first value – and still repeats on (last time)/Ts + 1 samples counted from zero.

Code export

All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. The table and the lookup method are baked into the arithmetic at export time rather than exposed as tunable parameters, and they have to be: the number of points decides how many branches the generated code has, so the table and the structure of the code cannot be separated. Each branch is emitted as its own comparison, which is the one shape all ten targets spell the same way. Because the phase comes from a counter and not from a clock, the three HDL targets are not simulation-only here: they are an ordinary counting register feeding that chain.

The HDL caveat is range rather than timing. A signal is carried in Q16.16 there, which reaches 32767, so a table entry outside that cannot be represented.

Simulink bridge

Import and export, mapped to simulink/Sources/Repeating Sequence Interpolated. "Output Values" to OutValues, "Time Values" to TimeValues, and "Lookup Method" to LookUpMeth – the four values are Simulink's own strings, so that mapping is 1:1 and lossless both ways. The rate crosses too, but under Simulink's own name for it: this block is a masked subsystem there and calls its rate parameter tsamp rather than SampleTime (verified against the R2026a block dialog), so "Sampling Time (s)" maps to tsamp. That the rate is also a term in the period is true on both sides, so the two agree.

Notes

  • Stateful: the whole state is the position in the cycle, which starts at 0 at the beginning of every run, so a re-run reproduces the waveform exactly.
  • Discrete by nature, so it always takes its period from its own "Sampling Time (s)".
  • A table time that falls exactly on a sample instant sits on a branch boundary for the three staircase methods, where the answer is decided by the last bit of a double. It is well defined – at or below counts as below – but a table whose times avoid the sample grid is the more robust thing to configure when the staircase methods are used.
  • See Repeating Sequence Stair for the same idea with no time axis at all, and Repeating Sequence for a clock-driven, always-interpolated one.

Code facts#

FactValue
registered typeControl_Systems/Sources/Repeating_Sequence_Interpolated
familyControl_Systems/Sources
solver environment classICoreBlock_0_Control_Systems_1_Sources_2_Repeating_Sequence_Interpolated
sourcesrc/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Sources/Repeating_Sequence_Interpolated/ICoreBlock_0_Control_Systems_1_Sources_2_Repeating_Sequence_Interpolated.cpp
headersrc/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Sources/Repeating_Sequence_Interpolated/ICoreBlock_0_Control_Systems_1_Sources_2_Repeating_Sequence_Interpolated.h
default size on canvas85 × 70 px
ports at insert0 in, 1 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1outICoreDouble

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 Values[3 1 4 2 1]OutValues
Time Values[0 0.1 0.5 0.6 1]TimeValues
Lookup MethodInterpolation-Use End Values%~%Use Input Nearest%~%Use In…LookUpMeth

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/Sources/Repeating Sequence Interpolated
port-count rulePortsParam::None
SampleTime parameteryes
rate parameter nametsamp
ICore configSimulink parameterValue translation
Output ValuesOutValuespasses through
Time ValuesTimeValuespasses through
Lookup MethodLookUpMethInterpolation-Use End ValuesInterpolation-Use End Values, Use Input NearestUse Input Nearest, Use Input BelowUse Input Below, Use Input AboveUse Input Above

Caveat (shown to the user): the rate crosses as 'tsamp' - Simulink's Repeating Sequence Interpolated is a masked subsystem and does not use the standard 'SampleTime' parameter name. Note that on this block the rate is also a term in the PERIOD, which repeats every (last time value / rate) + 1 samples on both sides

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

Repeating Sequence Interpolated block — a sample-driven table lookup, repeated forever y[k] = lookup( (k mod P) * Ts ) P = last time / Ts + 1

A (time, output) table walked one SAMPLE at a time, with a choice of four rules for what to do between the table's points. The cycle is a whole number of samples, and the phase is simply that many sample periods -- computed from an integer index rather than from an accumulated clock, so it is exact and cannot drift over a long run.

THE PERIOD IS THE LAST TIME VALUE PLUS ONE SAMPLE, which is the one thing about this block that surprises everybody, and it is Simulink's behaviour rather than a choice made here. Verified against simulink/Sources/Repeating Sequence Interpolated with the default table (times [0 0.1 0.5 0.6 1], values [3 1 4 2 1]) at tsamp = 0.01: sample 100 (t = 1.00) emits the LAST value, 1, and sample 101 emits the FIRST, 3 -- a cycle of 101 samples, not 100. The reason is that the cycle covers [0, last time] INCLUSIVELY: every sample instant from zero to the last time gets its turn, and the wrap happens on the sample after the last.

NOTE WHAT THAT MEANS FOR A TABLE THAT DOES NOT START AT ZERO. The phase is measured from ZERO, not from the table's first time, so a table beginning at 0.2 s spends its first 20 samples BELOW its own first point -- and the period is still (last time)/Ts + 1, counted from zero. Verified with times [0.2 0.27 0.4 0.5]: the block holds 0.7 for samples 0..20, walks the table from sample 21, reaches the last value at sample 50 and wraps at 51. Below the first point every lookup method returns the FIRST value - held, not extrapolated backwards along the first segment, which is what "Use End Values" means here and the one place the end values are reached at all. Above the last point cannot happen: the phase stops exactly there.

Discrete by nature (setDiscreteOnlyBlock): the position advances once per SAMPLE, so the block must take its period from its own "Sampling Time (s)" rather than be pushed through a continuous solver's intermediate stages, which would advance it several times per step. Note what follows from that: the rate is not just how often the block runs, it is a TERM IN THE PERIOD -- change the sampling time and the waveform's cycle changes with it.

Code export: all ten targets, none of them simulation-only -- the phase comes from the block's own index and not from a clock, so the HDL cores are an ordinary counting register feeding a chain of comparisons. The one HDL caveat is RANGE, not timing: a signal is Q16.16 there, so table entries outside +/-32767 do not fit.

Sample results#

Repeating Sequence Interpolated — No input: the block run aloneRepeating Sequence Interpolated — No input: the block run alone1234012345t (s)

Plotted: free — No input: the block run alone

Category source · sample time 0.1 · 60 steps · commit ccf005c8 · produced by docsSample --out <folder> --steps 60 · data docs/generated/samples/Control_Systems__Sources__Repeating_Sequence_Interpolated.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).