Playback — Control Systems/Sources
Control_Systems/Sources/Playback · 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.
Playback
Control Systems / Sources
A source that replays a recorded signal, interpolating linearly between the recorded points:
y(t) = the recording read at t, or the configured extrapolation when t falls outside it
It plays the recording once and does not repeat – which is what makes the two ends a question worth answering, and why each of them has a rule of its own below. It is the counterpart to Signal Recorder: that block writes a run's signal out, this one plays one back in.
Ports
- Output – the replayed value, always a scalar. It has no inputs; the position in the recording comes from the simulation clock.
Parameters
- Recorded Data – the recording itself, as a matrix of two
columns: a time in the first and the value at that time in the second, one row
per recorded point. At least two rows, and the times must be strictly
increasing. Written as
[0 0.4; 0.15 -1.1; 0.4 0.8; 0.7 0.25], which is four points spanning seven tenths of a second. - Extrapolation Before First Point – what to emit before the
recording starts.
- Linear extrapolation – carry the first recorded segment backwards, so the signal arrives at the recording along the slope it leaves with.
- Hold first value – sit at the first recorded value until the recording begins.
- Ground value – zero.
- Extrapolation After Last Point – what to emit after it ends, with the same three choices reading from the other end (Hold last value holds the final recorded value).
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period. On this block it only decides how finely the recording is resampled, not what it computes.
Where the ends are
The recorded range is closed at both ends: at exactly the first recorded time, and at exactly the last, the block emits the recorded value. The extrapolation rules apply strictly before the first and strictly after the last. This matters for Ground value in particular, which would otherwise answer zero at the very instant the recording still has a value for.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. Each uses a per-block local sample clock rather than a global one. The recording is baked into the arithmetic at export time rather than exposed as a tunable parameter, and it has to be: the number of recorded points decides how many branches the generated code has, so the recording and the structure of the code cannot be separated. Each segment is emitted as its own comparison and straight-line expression, which is the one shape all ten targets spell the same way – so a long recording makes a long function, and a recording of thousands of points is better resampled before it is played. The three HDL targets carry the block in simulation-only form: the comparisons and the interpolation are done in real arithmetic and quantized on the way out to the fixed-point signal ports.
Simulink bridge
Neither direction. Simulink has a counterpart –
simulink/Sources/Playback, and its two extrapolation choices are exactly the
ones above – but its data does not arrive as numbers. It is named by a
Signals parameter holding a reference to an MLDATX or MAT file, a
workspace variable or a spreadsheet, and there is no parameter on that block a table
of values could be written into. An exchanged model would therefore carry the
extrapolation settings and no recording at all, which is worse than not crossing.
Rather than assert a mapping that cannot be honoured, the bridge reports this block
and skips it. To cross a model containing one, place the Simulink block by hand and
point it at the recording yourself.
Notes
- Time-driven and stateless: the output depends only on the current time, so a re-run replays the recording exactly and there is no initial state to seed.
- Plays once. See Repeating Sequence for the same kind of table played over and over, and Signal Recorder for the block at the other end of the workflow.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Sources/Playback |
| family | Control_Systems/Sources |
| solver environment class | ICoreBlock_0_Control_Systems_1_Sources_2_Playback |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Sources/Playback/ICoreBlock_0_Control_Systems_1_Sources_2_Playback.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Sources/Playback/ICoreBlock_0_Control_Systems_1_Sources_2_Playback.h |
| default size on canvas | 80 × 70 px |
| ports at insert | 0 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | out | ICoreDouble | — |
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 variable | Default | Simulink parameter |
|---|---|---|
Recorded Data | [0 0.4; 0.15 -1.1; 0.4 0.8; 0.7 0.25] | — |
Extrapolation Before First Point | Linear extrapolation%~%Hold first value%~%Ground value~~L… | — |
Extrapolation After Last Point | Linear extrapolation%~%Hold last value%~%Ground value~~Li… | — |
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::None |
| Simulink path | — |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
Caveat (shown to the user): Simulink's Playback takes its DATA by reference - a 'Signals' parameter naming an MLDATX or MAT file, a workspace variable or a spreadsheet - and offers no parameter a table of values could be written into. The two extrapolation choices map exactly, but an exchanged model would carry those and no recording at all, so the mapping is reported here rather than asserted. Place the Simulink block by hand and point it at the recording yourself if you need it
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).
Playback block — replay a recorded signal once, with a choice of what to do at each end y(t) = the recorded (time, value) pairs interpolated linearly, for t inside the recording; the configured extrapolation outside it
The counterpart to Signal Recorder: where that block writes a run's signal out, this one plays a recording back in. It does NOT repeat -- that is what makes it a playback rather than a repeating source, and it is why the two ends need a rule of their own.
WHY THE RECORDING IS A CONFIG MATRIX AND NOT A FILE. Simulink's Playback names its data source with a
Signalsparameter carrying a reference to an MLDATX or MAT file, a workspace variable or a spreadsheet. Nothing about that reference can cross to generated code: a core exported to ten languages cannot be handed a MATLAB file to open, and an exported model cannot carry a file path that means anything on the far side. So the recording lives in the block, as an N-by-2 matrix of (time, value) rows, which every backend can bake in. That is also what makes the block exportable at all.WHY THERE IS NO SIMULINK BRIDGE, and it is the same fact from the other side. There is no parameter on Simulink's Playback that a table of numbers could be written into -- its data arrives by file reference, and its two extrapolation choices are all the numeric configuration it has. Registering the block as exportable would assert a mapping that could not be honoured, so it registers Support::None with that reason and the bridge reports it rather than emitting something that quietly plays nothing. See the description.
THE BOUNDARIES ARE HALF-OPEN AT THE START AND CLOSED AT THE END: the recorded range is [first time, last time], so the after-rule applies strictly AFTER the last recorded time. That matters for the Ground choice in particular, which would otherwise answer zero at the very instant the recording still has a value for.
Time-driven and stateless: the output depends only on the current time, so there is no state to seed and a re-run replays the recording exactly.
Code export: all ten targets. The three HDL ones are SIMULATION-ONLY -- they read the testbench's sim_time in real arithmetic and quantize only at the port, exactly as Sine Wave does, because a Q-format datapath has no clock to derive t from.
Sample results#
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__Playback.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).