Equivalent Noise Bandwidth — Control Systems/Spectral Measurements
Control_Systems/Spectral_Measurements/Equivalent_Noise_Bandwidth · 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.
Equivalent Noise Bandwidth
Control Systems / Spectral Measurements
Reports how much white noise the window on its input lets through,
measured against the rectangular window of the same length:
B = N·Σw² / (Σw)² in bins, or
B = fₛ·Σw² / (Σw)² in hertz. This
is MATLAB's enbw, and it is the number that turns a windowed
periodogram into a power density.
It is a property of the window alone – no signal enters it. A rectangular window answers exactly 1 bin; every taper answers more, because tapering trades resolution for leakage.
Ports
- w – the window, a vector: an [N,1] column or a [1,N] row, with N from 1 to 64. These are the window's coefficients, not a signal.
- B – the equivalent noise bandwidth, a scalar, in bins or in hertz depending on Sample Rate (Hz).
Parameters
- Sample Rate (Hz) – zero or less reports the bandwidth in
bins, which is
enbw(w); a positive value reports it in hertz, which isenbw(w, fs)and is the same quantity times fₛ/N. - Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period. It is unrelated to Sample Rate (Hz), which describes the data the window will be applied to.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. Every one emits the same single expression – two sums, one square, one division, one scale – with the window length and the scale inlined.
The three HDL targets are simulation-only real
arithmetic. A division is not a Q16.16 operation, and what is divided by is a
squared sum, which leaves that format at any useful window length. The
generated cores convert at the port boundary and evaluate in
real: correct in simulation, and not offered as
synthesizable.
Simulink bridge
No equivalent (Support::None). enbw is a
Signal Processing Toolbox MATLAB function, and the DSP System Toolbox's
libraries were searched on the installed R2026a rather than assumed: they carry
a Window Function block, which applies a window, and no block that
measures one. The bridge reports this block rather than dropping it, and it
carries no parity testbench; code export verification still covers it
across all ten languages.
Notes
- Algebraic, with no state. The whole window arrives on the port, so the same input twice gives the same answer twice.
- Measured against R2026a. At length 8: 1 for
rectwin, 1.497060323767081 forhamming, 1.714285714285714 forhann, 1.973436993845157 forblackman, and 18.713254047088512 forhammingat fₛ = 100 – all reproduced to the last bit. - The denominator is floored at 10−12, not tested. One expression is shared by ten backends and VHDL has no inline conditional, so the floor takes the place of a branch. It sits seven orders below what a Q16.16 port can carry, so it cannot move an answer this block can be handed – but a window whose entries sum to zero has no equivalent noise bandwidth, and what it gets back is a very large number rather than a NaN.
- A rectangular window is exactly 1, in every backend: N·N·a² over (N·a)² cancels.
- No state space. The map is not linear in the input – it divides by a function of it – so the block carries none.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Spectral_Measurements/Equivalent_Noise_Bandwidth |
| family | Control_Systems/Spectral_Measurements |
| solver environment class | ICoreBlock_0_Control_Systems_1_Spectral_Measurements_2_Equivalent_Noise_Bandwidth |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Spectral_Measurements/Equivalent_Noise_Bandwidth/ICoreBlock_0_Control_Systems_1_Spectral_Measurements_2_Equivalent_Noise_Bandwidth.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Spectral_Measurements/Equivalent_Noise_Bandwidth/ICoreBlock_0_Control_Systems_1_Spectral_Measurements_2_Equivalent_Noise_Bandwidth.h |
| default size on canvas | 150 × 72 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 | w |
| 2 | out | ICoreDouble | B |
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 |
|---|---|---|
Sample Rate (Hz) | 0 | — |
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): no Simulink equivalent. enbw is a Signal Processing Toolbox MATLAB function, not a block, and the DSP System Toolbox libraries were searched on the installed R2026a rather than assumed: dspsigops carries a Window Function block, which APPLIES a window, and nothing that measures one
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).
Equivalent Noise Bandwidth -- how much white noise a window lets through (MATLAB enbw) B = N * SUM(w^2) / (SUM w)^2 in bins B = fs * SUM(w^2) / (SUM w)^2 in hertz -- the same quantity times fs/N
It answers a question about the WINDOW and no signal enters it: how wide a rectangular filter would have to be to pass the same white-noise power. A rectangular window is exactly 1 bin by construction; every taper is more, because tapering costs resolution.
⚠ MEASURED AGAINST R2026a, not asserted. At length 8, enbw answers 1 for rectwin, 1.497060323767081 for hamming, 1.714285714285714 for hann and 1.973436993845157 for blackman; at fs = 100 it answers 18.713254047088512 for hamming. The closed form above reproduces all five to the last bit -- checked by evaluating N*sum(w.^2)/sum(w)^2 beside enbw() in the same session rather than by reading its documentation.
ONE EXPRESSION, TEN BACKENDS. Two sums over the window, one square, one division and one scale -- written once and spelled ten ways, because the moment the ten diverge they diverge differently. The only per-target vocabulary is the literal format and the MAX function.
⚠ THE DENOMINATOR IS FLOORED, NOT TESTED, and that is Peak To RMS's rule reached again for its reason: VHDL has no inline conditional, so one shared expression cannot branch. (SUM w)^2 is floored at 1e-12 -- seven orders below what a Q16.16 port can even carry -- so no window this block can be handed reads as floored, and a window that sums to zero (which has no equivalent noise bandwidth) answers a large number rather than a NaN in ten cores at once.
HDL IS SIMULATION-ONLY
real. A division is not a Q16.16 operation, and the quantity being divided by is a SQUARED sum, which at any useful window length leaves the format entirely. The generated cores convert at the port boundary and evaluate inreal: correct in simulation, and not offered as synthesizable. Reference for the same choice: Rolling Statistics' Peak To RMS, Recursive IIR.ALGEBRAIC: the whole window arrives on the port, so one step is one measurement.
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) | 0 … 1 |
ramp | Ramp: slope 1 from t = 0 | 0 … 1 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | 0 … 1 |
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 3c100aff6f27235305db4ad4d572f32e342718ad · produced by docsSample --out <folder> --blocks Equivalent_Noise_Bandwidth --steps 60 · data docs/generated/samples/Control_Systems__Spectral_Measurements__Equivalent_Noise_Bandwidth.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).