Generated reference › Convolution — Control Systems/Correlation And Convolution
kind: generated#block#control-systems-correlation-and-convolution

Convolution — Control Systems/Correlation And Convolution

Control_Systems/Correlation_And_Convolution/Convolution · 2 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.

Convolution

Control Systems / Correlation And Convolution

Convolves the last NA samples of one stream with the last NB samples of another, every sample: y[n] = Σk a[k]·b[n−k], a vector of NA + NB − 1 entries. It is the streaming counterpart of MATLAB's conv applied to the two windows.

Both operands are signals. Nothing in the arithmetic is a constant, so none of the NA×NB products can be folded away at export – which is what separates this block from Discrete FIR Filter, whose second operand comes from configuration.

Ports

  • a – the first stream. Scalar; the block keeps its own window of the last NA samples – see Notes.
  • b – the second stream. Scalar, with its own window of the last NB samples.
  • y – the convolution of the two windows, a column of NA + NB − 1 entries. Its size follows from the two window lengths alone and does not depend on the inputs' values.

Parameters

  • Window Length A – NA, how many samples of a take part. A whole number from 1 to 32. The bound is a code-size bound: both windows are unrolled in every target and the emitted work is their product.
  • Window Length B – NB, the same for b. The two need not be equal, and the output grows with their sum.
  • Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.

Code export

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

The two window lengths are structural: they decide how many multiplies the exported core contains and how wide its output is, which no runtime parameter can change, so they are baked in at export time rather than offered as tunable parameters. Re-export after changing either.

The three HDL targets are genuine synthesizable Q16.16: two shift registers and a fixed multiply-accumulate tree, with every product accumulated at full width and shifted back once per output entry rather than per term.

Simulink bridge

No equivalent (Support::None). The Signal Processing Toolbox ships no Simulink library at all. DSP System Toolbox does have a Convolution block, and it is a different shape: it convolves two vector-valued inputs and takes both lengths from those inputs' dimensions, having no length parameter of its own, so this block's two window lengths have nothing to map onto. The bridge reports this block rather than dropping it silently, and it therefore has no parity testbench. Code export verification still covers it across all ten languages.

Notes

  • Stateful, and discrete by nature (setDiscreteOnlyBlock(true)): both windows advance once per sample.
  • Oldest-first is the published order. a[0] is the oldest sample still in the window and a[NA−1] the newest, so the windows read as segments of the signal in time order and the result is what conv returns for those segments.
  • The windows are zero-prefilled, and the zeros count. Before the windows have filled, their initial zeros take part in the sum, so the first max(NA, NB)−1 outputs of a run are a startup transient rather than a convolution of real data. MATLAB's conv is a batch function with both vectors in hand and has no transient; a streaming block cannot avoid one.
  • Verified against MATLAB. On a = [0.7 −1.3 0.45 2.1 −0.6] against b = [−0.9 0.25 1.7 −0.35 0.8], this block's arithmetic and R2026a's conv agree to the last unit in the last place on all nine entries.
  • Scalar inputs. Each input is one channel with its own window; a vector input is refused rather than convolving the first element and dropping the rest.
  • No state space. The block is bilinear rather than linear – it multiplies two signals together – so it carries no A/B/C/D pair and model reduction correctly declines to merge it.

Code facts#

FactValue
registered typeControl_Systems/Correlation_And_Convolution/Convolution
familyControl_Systems/Correlation_And_Convolution
solver environment classICoreBlock_0_Control_Systems_1_Correlation_And_Convolution_2_Convolution
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Correlation_And_Convolution/Convolution/ICoreBlock_0_Control_Systems_1_Correlation_And_Convolution_2_Convolution.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Correlation_And_Convolution/Convolution/ICoreBlock_0_Control_Systems_1_Correlation_And_Convolution_2_Convolution.h
default size on canvas132 × 80 px
ports at insert2 in, 1 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDoublea
2inICoreDoubleb
3outICoreDoubley

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
Window Length A8—
Window Length B8—

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::None
Simulink path—
port-count rulePortsParam::None
SampleTime parameteryes

Caveat (shown to the user): no Simulink equivalent: conv() is a MATLAB function and the Signal Processing Toolbox ships no Simulink library at all. DSP System Toolbox's Convolution block is a different shape -- it convolves two VECTOR inputs and takes both lengths from their dimensions, having no length parameter of its own, so this block's two window lengths have nothing to map onto. Reported rather than dropped, and it carries no parity testbench

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

Convolution -- the linear convolution of two windowed streams, y = conv(a, b) TWO SIGNALS, NOT A SIGNAL AND A COEFFICIENT SET. Both operands are live: the block keeps the last NA samples of one input and the last NB samples of the other, and every sample it recomputes all NA + NB - 1 entries of their convolution. Nothing can be folded away at export time, because there is no constant in the arithmetic -- which is exactly what separates this block from Discrete FIR Filter, whose second operand comes from configuration.

MEASURED AGAINST MATLAB R2026a rather than asserted. On a = [0.7 -1.3 0.45 2.1 -0.6] and b = [-0.9 0.25 1.7 -0.35 0.8], conv(a, b) in R2026a and this block's arithmetic agree to the last unit in the last place on all nine entries. The probe is recorded in the notes of the toolbox-blocks plan, Family B.

⚠ THE WINDOWS ARE ZERO-PREFILLED AND THE ZEROS COUNT -- the convention Detrend and Moving Median carry, the latter measured against Simulink. The first max(NA, NB) - 1 outputs of a run are a startup transient. MATLAB's conv() has both whole vectors in hand and has no transient at all; a streaming block cannot avoid one, so the choice is which one to document.

⚠ OLDEST-FIRST IS THE PUBLISHED ORDER; NEWEST-FIRST IS THE STORAGE ORDER. a[0] is the oldest sample still in the window, so the two windows read as segments of the signal in time order and the answer is MATLAB's. The shift register beneath holds the newest sample at index 0, because that is the cheapest shift in all ten targets. The two orders meet in exactly one expression per backend and nowhere else.

Sample results#

Convolution — Step: 0 -> 1 at t = 1 sConvolution — Step: 0 -> 1 at t = 1 s00.51012345t (s)in ICoreDouble-Out-0in ICoreDouble-Out-0out ICoreDouble-Out-0 [15x1] entry 0

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 … 27.04
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias0 … 0.9991
tableRepeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample0 … 9

Plotted: step — Step: 0 -> 1 at t = 1 s

Category dynamic · sample time 0.1 · 60 steps · commit 3c100aff6f27235305db4ad4d572f32e342718ad · produced by docsSample --out <folder> --blocks Convolution Circular_Convolution Convolution_Matrix Deconvolution Cross_Correlation Cross_Covariance --steps 60 · data docs/generated/samples/Control_Systems__Correlation_And_Convolution__Convolution.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).