Generated reference › Dot Product — Control Systems/Base Blocks
kind: generated#block#control-systems-base-blocks

Dot Product — Control Systems/Base Blocks

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

Dot Product

Control Systems / Base Blocks

Multiplies its two inputs entry by entry and adds every product together: y = Σ u₁(i,j) · u₂(i,j). For two vectors that is the ordinary inner product; for two matrices it is the sum over all entries. The result is always a single number.

Ports

  • u₁ – the first factor, of any size [m,n].
  • u₂ – the second factor, which must be the SAME size [m,n]. This block does not expand a scalar over a vector.
  • Output – the inner product, always a scalar [1,1], whatever the input size. This is the one block in the family that reduces two signals at once.

Parameters

  • 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. There is nothing to tune, so nothing is exposed as a parameter on the generated core.

Every target accumulates the products in the same order – row by row, left to right. Floating-point addition is not associative, so a reduction that regrouped the sum would land a rounding step away from the reference; spelling the loop out is what keeps the seven floating-point targets bit-identical. The three HDL ones quantize to Q16.16 before they add anything, so they agree to their format rather than to the last bit.

The three HDL targets carry the whole accumulation in Q16.16 fixed point and are fully synthesizable: a sum of products needs no divider and no function call. Verilog and SystemVerilog accumulate in a double-width register (2*ICORE_WIDTH) and shift back once, so intermediate sums cannot wrap. VHDL accumulates in the shared Fx variable, which is Q16.16 (sfixed(15 downto -16)): every product is rounded as it is added, and on a long vector a partial sum that exceeds the 16 integer bits will wrap there when it would not in Verilog.

Simulink bridge

Import and export, mapped to simulink/Math Operations/Dot Product. The block has no parameters of its own, so the only pair is the global one: "Sampling Time (s)" to SampleTime, as on every block. Simulink conjugates its first input, which for the real signals this library carries is the identity, so the two compute the same thing.

Notes

  • Algebraic, with no state.
  • Not linear: the block multiplies two signals, so it is not linear in either one and deliberately carries no state space. Sum of Elements is the reduction that IS linear – its coefficients are constants – and that one can be absorbed by model reduction.
  • The output does not follow the input size, so a downstream block sees a scalar however wide the inputs are.

Code facts#

FactValue
registered typeControl_Systems/Base_Blocks/Dot_Product
familyControl_Systems/Base_Blocks
solver environment classICoreBlock_0_Control_Systems_1_Base_Blocks_2_Dot_Product
sourcesrc/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Base_Blocks/Dot_Product/ICoreBlock_0_Control_Systems_1_Base_Blocks_2_Dot_Product.cpp
headersrc/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Base_Blocks/Dot_Product/ICoreBlock_0_Control_Systems_1_Base_Blocks_2_Dot_Product.h
default size on canvas60 × 60 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
1inICoreDoubleu1
2inICoreDoubleu2
3outICoreDouble

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#

No config variable beyond the Sampling Time (s) every block carries.

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/Dot Product
port-count rulePortsParam::None
SampleTime parameteryes

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

Dot Product block -- inner product of two signals y = sum over every element of (u1 .* u2). Two equally sized inputs in, one SCALAR out, whatever the input shape. Algebraic and stateless, no state space (see header).

The output is 1x1 regardless of the inputs, so the size is forced in initializePortSignalSize() rather than left to the base class's "outputs take the input's size" default. Nothing is reported from there: it runs on every port-size-resolution pass, and verifyInitializedPortSignals() is the gate that judges the settled sizes.

Every target accumulates in the SAME order -- row-major over the elements -- because floating-point addition is not associative and a different order is a different sum. That is why the software targets spell the loop out instead of calling a language's own dot/sum, whose reduction order is not guaranteed.

Sample results#

Dot Product — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sampleDot Product — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample05012345t (s)in ICoreDouble-Out-0in ICoreDouble-Out-0out ICoreDouble-Out-0
tin ICoreDouble-Out-0in ICoreDouble-Out-0out ICoreDouble-Out-0
0-2-24
0.40.50.50.25
0.8-2-24
1.20.50.50.25
1.6-2-24
20.50.50.25
2.4-2-24
2.80.50.50.25
3.2-2-24
3.60.50.50.25
4-2-24
4.40.50.50.25
4.8-2-24
5.20.50.50.25

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 … 33.64
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias0 … 1
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 ccf005c8 · produced by docsSample --out <folder> --steps 60 · data docs/generated/samples/Control_Systems__Base_Blocks__Dot_Product.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).