Cosine — Control Systems/Lookup Tables
Control_Systems/Lookup_Tables/Cosine · 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.
Cosine
Control Systems / Lookup Tables
Computes y = cos(2πu) from a quarter-wave lookup table in 16-bit
fixed point – the same approximation Simulink's Cosine block makes, not a call to
cos().
This block is an approximation by design. Its output is quantized to multiples of 2−14 and lands roughly 6×10−5 from the true cosine. That is the point of it: a table and a few adds are far cheaper on a fixed-point target than a series expansion. If you want true cosine, use Trigonometric Function instead.
Note the argument is in cycles, not radians: u = 1 is one full period.
Ports
- Input – the phase u in cycles, of any size [m,n]. Any value is accepted; the phase wraps, so u and u+1 give the same output.
- Output – the approximated cosine y, of the SAME size [m,n], always in [−1, 1] and always a multiple of 2−14.
Parameters
- Number Of Data Points – how many points the quarter-wave table holds, and therefore the accuracy. Defaults to 33, as in Simulink. More points mean a finer table and a smaller error between the points; it does not change the 2−14 output step, which is set by the 16-bit word and is the floor on accuracy however large the table gets. At least two.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
How the value is produced
A quarter period is added to the phase – which is all that separates cosine from sine – then it is cast to a multiple of 2−16 and wrapped into one period; the quarter with the same magnitude is found by symmetry; the table is read and linearly interpolated there; and the result is truncated to the 2−14 grid before the sign is put back. Each of those steps is Simulink's, and reproducing them is what makes this block match it rather than merely resemble it – verified against the R2026a block to zero mismatches over 644 samples at three different table sizes.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. The table is baked in at export time: its size decides how many branches the generated code has, so it cannot be a tunable parameter.
The three HDL targets are not simulation-only, and they are the case this block was shaped for: the arithmetic is adds, one multiply per branch, and shifts, with no divider and no transcendental function anywhere. The Q16.16 datapath even matches the block's own 2−16 input cast exactly, so the HDL cores agree with the software ones rather than approximating them.
Simulink bridge
Import and export, mapped to simulink/Lookup Tables/Cosine.
"Number Of Data Points" to NumDataPoints as a plain pass-through value.
The block always writes Formula = cos(2*pi*u) and
OutputWordLength = 16, which is what this block is.
This Simulink block has no SampleTime parameter (verified against
the R2026a dialog), so the rate stays on the ICore side and a block configured with an
explicit positive rate reports that it did not cross. Simulink's other two formulas
– exp(j*2*pi*u) and the combined sine-and-cosine – are complex
or two-output and have no counterpart here; see Sine for the other real one.
Notes
- Algebraic, with no state.
- Elementwise: the output carries the input's size.
- Not linear, and so deliberately carries no state space.
- See Sine for the same table, which this block reaches by shifting the phase a quarter period. The two share one implementation.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Lookup_Tables/Cosine |
| family | Control_Systems/Lookup_Tables |
| solver environment class | ICoreBlock_0_Control_Systems_1_Lookup_Tables_2_Cosine |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Lookup_Tables/Cosine/ICoreBlock_0_Control_Systems_1_Lookup_Tables_2_Cosine.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Lookup_Tables/Cosine/ICoreBlock_0_Control_Systems_1_Lookup_Tables_2_Cosine.h |
| default size on canvas | 75 × 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 | — |
| 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 |
|---|---|---|
Number Of Data Points | std::to_string(QWT::DEFAULT_POINTS) | NumDataPoints |
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/Lookup Tables/Cosine |
| port-count rule | PortsParam::None |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| deliberately not crossed | InternalRulePriority |
| always set | Formula = cos(2*pi*u), OutputWordLength = 16 |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
Number Of Data Points | NumDataPoints | passes through |
Caveat (shown to the user): an APPROXIMATION on both sides, not true cosine: the output is quantized to 2^-14 and lands ~6e-5 from cos(). This block reproduces Simulink's fixed-point pipeline exactly rather than computing cos(), which is what makes the two comparable at a tight tolerance. Simulink's other formulas - exp(j*2*pi*u) and the combined sine-and-cosine - are complex or two-output and have no counterpart here. The Simulink block has NO SampleTime parameter, so the rate stays on the ICore side
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).
Cosine block — y = cos(2*pi*u) as SIMULINK computes it: a 16-bit quarter-wave lookup Every step of the pipeline, and why it is an approximation rather than a call to cos(), is in ICoreQuarterWaveTable.h. This file is the block around it: ports, config, the Simulink entry, and the ten spellings of one shared body.
Algebraic, stateless, elementwise. No state space (see header).
Sample results#
| t | in ICoreDouble-Out-0 | out ICoreDouble-Out-0 |
|---|---|---|
| 0 | -2 | 1 |
| 0.4 | 0.5 | -1 |
| 0.8 | -2 | 1 |
| 1.2 | 0.5 | -1 |
| 1.6 | -2 | 1 |
| 2 | 0.5 | -1 |
| 2.4 | -2 | 1 |
| 2.8 | 0.5 | -1 |
| 3.2 | -2 | 1 |
| 3.6 | 0.5 | -1 |
| 4 | -2 | 1 |
| 4.4 | 0.5 | -1 |
| 4.8 | -2 | 1 |
| 5.2 | 0.5 | -1 |
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) | 1 … 1 |
ramp | Ramp: slope 1 from t = 0 | -1 … 1 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | -0.999 … 1 |
step | Step: 0 -> 1 at t = 1 s | 1 … 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__Lookup_Tables__Cosine.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).