Reshape — Control Systems/Base Blocks
Control_Systems/Base_Blocks/Reshape · 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.
Reshape
Control Systems / Base Blocks
Lays the input's elements into a different shape: y = reshape(u),
taken and written column by column, exactly as MATLAB's
reshape does. The number of elements never changes and neither does
their order – only the shape they occupy.
Ports
- u – the signal to reshape, of any size [m,n]. Its element count m·n is what every output shape below must match.
- ref – present only for Derive from reference input port: a signal whose DIMENSIONS the output copies. Only its shape is used – the values on this port are never read, in the simulator or in any generated core. Add or remove this port to match the chosen dimensionality; a mismatch is reported rather than guessed at.
- Output – y, carrying u's elements in the chosen shape. Its size is set by Output Dimensionality, and it is the one thing this block exists to change.
Parameters
- Output Dimensionality – which shape to produce. This selects the
code path rather than retuning one, so each option is a separate branch in all ten
export targets.
- 1-D array – a flat run of m·n elements. The default, as in Simulink. An ICore signal is always two-dimensional, so this produces the same [m·n, 1] column that the next option does; the distinction is preserved for the Simulink bridge, which writes back the option you chose.
- Column vector (2-D) – [m·n, 1].
- Row vector (2-D) – [1, m·n].
- Customize – the shape given by Output Dimensions.
- Derive from reference input port – the shape of the signal on the ref port. Adds that port.
- Output Dimensions – used by Customize only. Either a
single number
n, meaning an [n,1] column, or a pair[r,c]. Its product must equal the input's element count – a reshape neither creates nor drops elements – and a mismatch is reported with both counts. Defaults to[1,1], as in Simulink. - 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. Nothing is exposed as a tunable parameter: the shape is structural, fixed into the generated code at export time along with the element-by-element mapping it implies. Every target emits the same column-major permutation written out entry by entry rather than a call to a library reshape, so the ten agree by construction instead of by each language's own flattening convention.
The three HDL targets are fully synthesizable: a reshape is a rewiring, so the generated cores carry plain assignments with no arithmetic at all.
Simulink bridge
Import and export, mapped to simulink/Math Operations/Reshape.
"Output Dimensionality" goes to OutputDimensionality, one option for
one option, so that round trip is lossless; "Output Dimensions" goes to
OutputDimensions as a pass-through value.
The port count is not a parameter on either side: Simulink grows its own
reference port when OutputDimensionality is set, so export writes
nothing extra, and import reads that value to widen the ICore port list to
match.
The rate does NOT cross: Simulink's Reshape block defines only
OutputDimensionality and OutputDimensions, with no
SampleTime, so the entry sets
hasSampleTimeParam = false and "Sampling Time (s)" stays on the ICore
side.
Notes
- Algebraic, with no state: the output depends only on the current input.
- No state space, deliberately. A reshape IS linear on the vectorized signal, but it is not a left multiplication y = D·u of the signal matrix – turning a column into a row is a transpose, which no D·u can express – so model reduction reports the block as unmergeable rather than merging a matrix that does not represent it.
- To remove singleton dimensions rather than choose a shape, use Squeeze – though on ICore's two-dimensional signals that block is a pass-through.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Base_Blocks/Reshape |
| family | Control_Systems/Base_Blocks |
| solver environment class | ICoreBlock_0_Control_Systems_1_Base_Blocks_2_Reshape |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Base_Blocks/Reshape/ICoreBlock_0_Control_Systems_1_Base_Blocks_2_Reshape.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Base_Blocks/Reshape/ICoreBlock_0_Control_Systems_1_Base_Blocks_2_Reshape.h |
| default size on canvas | 80 × 70 px |
| ports at insert | 1 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 | in | ICoreDouble | u |
| 2 | 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 |
|---|---|---|
Output Dimensionality | 1-D array%~%Column vector (2-D)%~%Row vector (2-D)%~%Cust… | OutputDimensionality |
Output Dimensions | [1,1] | OutputDimensions |
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::Both |
| Simulink path | simulink/Math Operations/Reshape |
| port-count rule | PortsParam::ReshapeOutputDimensionality |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
Output Dimensionality | OutputDimensionality | 1-D array → 1-D array, Column vector (2-D) → Column vector (2-D), Row vector (2-D) → Row vector (2-D), Customize → Customize, Derive from reference input port → Derive from reference input port |
Output Dimensions | OutputDimensions | passes through |
Caveat (shown to the user): the rate does not cross: Simulink's Reshape block defines only OutputDimensionality and OutputDimensions, with no SampleTime, so "Sampling Time (s)" stays on the ICore side
Catalog contract: src/ICoreSDK/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The checker has a blind spot here — it could not resolve something (a grouped port bullet, a computed config name), which is reported and never counted as a pass. A reader has to settle it:
B0Ports lists 3 entries for 2 ports (1 in, 1 out) — grouped, or one undocumented? a reader must say
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).
Reshape block -- the same elements in a different shape MATLAB's reshape(), COLUMN-MAJOR, in Simulink's five flavours. The element COUNT never changes and neither does the element ORDER; only the shape they are laid into does.
COLUMN-MAJOR IS THE WHOLE BLOCK, and it was verified against the real Simulink block rather than assumed, because a row-major slip transposes every non-vector result and still looks plausible: a 4-wide [1 2 -1 0.5] reshaped to Customize [2,2] comes back as [1 -1; 2 0.5], which is the column-major fill. Row-major would have given [1 2; -1 0.5].
ICORE HAS NO 1-D SIGNALS. An ICoreMatrix is always two-dimensional, so "1-D array" produces the same [m*n, 1] column that "Column vector (2-D)" does. The distinction is kept anyway because it is a real distinction ON THE SIMULINK SIDE - the bridge writes back the OutputDimensionality the user chose - and collapsing the two options would silently rewrite an imported model's parameter. The block's description says this outright.
ONE OPTION CHANGES THE BLOCK'S SHAPE. "Derive from reference input port" takes a SECOND input whose dimensions the output copies, exactly as in Simulink, so the port count is user-editable and verifyInitializedPortSignals insists on the count the chosen value implies. The reference carries only a SHAPE: its values are never read, here or in any generated core. On the bridge side that port move is what PortsParam::ReshapeOutputDimensionality exists for - Simulink grows its own port when OutputDimensionality is set, and an import that did not grow ICore's would land the second add_line on a port that was never created.
Sample results#
| t | in ICoreDouble-Out-0 | out ICoreDouble-Out-0 |
|---|---|---|
| 0 | -2 | -2 |
| 0.4 | 0.5 | 0.5 |
| 0.8 | -2 | -2 |
| 1.2 | 0.5 | 0.5 |
| 1.6 | -2 | -2 |
| 2 | 0.5 | 0.5 |
| 2.4 | -2 | -2 |
| 2.8 | 0.5 | 0.5 |
| 3.2 | -2 | -2 |
| 3.6 | 0.5 | 0.5 |
| 4 | -2 | -2 |
| 4.4 | 0.5 | 0.5 |
| 4.8 | -2 | -2 |
| 5.2 | 0.5 | 0.5 |
Every 4th of 60 samples, from the table stimulus.
The same rig also ran:
| Stimulus | What it is | Output range |
|---|---|---|
impulse | Impulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair) | 0 … 1 |
ramp | Ramp: slope 1 from t = 0 | 0 … 5.8 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | -1 … 0.9996 |
step | Step: 0 -> 1 at t = 1 s | 0 … 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__Reshape.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).