DSP - HISTOGRAM ANALYZER
Builds a histogram of an integer input stream, one sample per clock, and INDEPENDENTLY scans it to extract statistics: total, lowest and highest occupied bin, range, mode and mode count, median, four configurable quantiles, IQR, mean, variance, standard deviation, skewness, kurtosis, four configurable threshold occupancies, FWHM, FWTM and a sub-bin peak position by parabolic interpolation - plus the integrity outputs without which every one of those numbers can be silently wrong: BIN_SATURATED, SAT_BINS, UNDERFLOW, OVERFLOW, NONEMPTY_BINS and LOST. Input conditioning is fully runtime: subtract a BASE, rebin by a SHIFT, clamp to MAX_BIN. Three operating modes - FREEZE (stop while analysing), LIVE (never stop, single buffer) and DOUBLE (ping-pong) - trade dead time, memory and snapshot consistency against each other. Every statistic can be switched off, which removes its pin AND its logic before synthesis.
Introduction
The Histogram Analyzer is two engines sharing one memory.
The binner takes one sample per clock, conditions it, and increments one bin. The scanner walks that histogram at the end of every accumulation frame and extracts statistics from it. They are independent: the scanner never sees a sample and the binner never sees a statistic. That separation is the whole design - it is what lets a block accumulate at the full clock rate and still produce a full statistical description of the distribution without a second pass over the data.
Input conditioning: subtract, shift, clamp - in that order
$$ d = x - \mathrm{BASE}, \qquad b = \left\lfloor \frac{d}{2^{\mathrm{SHIFT}}} \right\rfloor, \qquad \mathrm{bin} = \mathrm{clamp}(b,; 0,; \mathrm{MAX_BIN}) $$
The order matters and it is fixed. BASE is subtracted first, so you can aim the histogram at a window of the input range (subtract 1000 and only the region above 1000 is binned). SHIFT then divides by a power of two, which is how you rebin: SHIFT = 3 puts eight input codes into every bin. Only then is the result clamped into $[0, \mathrm{MAX_BIN}]$.
All three are runtime input pins, and so is PERIOD, the number of samples in a frame. They are latched on the first accepted sample of a frame, so changing any of them mid-frame takes effect on the NEXT frame - a histogram is never binned two different ways.
Out-of-range samples are CLAMPED, not discarded
A sample below the base lands in bin 0 and increments UNDERFLOW. A sample
above MAX_BIN lands in MAX_BIN and increments OVERFLOW. They are counted,
not thrown away, so TOTAL always equals the number of samples the frame
accumulated and the quantiles stay well defined. The two counters are what
tell you the distribution was clipped: a large UNDERFLOW or OVERFLOW means
the mean, the variance and the tail quantiles are all being pulled towards
the edge bins and should not be trusted. Fix the BASE and the SHIFT, not the
statistics.
The three operating modes
These are genuinely different hardware, not a mode bit.
| RAM | dead time | snapshot | needs IN_DV gaps | |
|---|---|---|---|---|
| FREEZE | 1x | yes, the whole scan | consistent | no |
| LIVE | 1x | none | NOT consistent | yes |
| DOUBLE | 2x | none | consistent | no |
FREEZE accumulates for one frame, stops the binner, scans, and
resumes. The statistics are a perfectly consistent snapshot of exactly the
samples of that frame. The price is dead time: every sample that arrives
during the scan is ignored, and LOST counts them. For a slow control loop
reading a detector spectrum every few milliseconds this is usually the right
answer, because the scan is a few thousand clocks and the frame is millions.
DOUBLE uses two RAMs, ping-pong: the binner fills one while the scanner walks the other, and they swap at every frame end. Consistent snapshot, no dead time, no stall. It costs twice the block RAM and nothing else. If you have the memory, use this one.
LIVE uses one RAM and never stops the binner: the scanner steals the memory on clocks the binner is not using. It costs you two things, both real, and you should not choose it without understanding them.
What LIVE mode actually costs you
1. The statistics are not a consistent snapshot. The scanner reads bin 0 at the start of the scan and the last bin thousands of clocks later, while the binner keeps writing. The “histogram” the statistics describe was therefore never simultaneously in the memory. Every result is a smear over the scan window:
TOTALis not the count of any one frame - it is the sum of bin contents read at different times.- A peak that moves during the scan can be counted twice (once at its old position, once at its new one) or missed entirely.
- The mean, variance, skewness and kurtosis are the moments of that smear, not of the signal.
- With Clear on Scan enabled, each bin holds the counts accumulated since that bin was last cleared - one frame ago, but at a different phase for every bin. That is a defensible measurement (it is how a sweeping analyser works) but it is not a snapshot.
Being precise about it, because “the numbers are approximate” is not useful: the scan reads every bin twice, once per pass, and in LIVE mode the two readings differ. The total, the mode and the occupied-bin range come from the first pass; the cumulative count, the occupancies and the central moments come from the second. The moments are divided by the population the second pass saw, so each moment is at least self-consistent. The quantiles cannot be: a quantile needs the total before the pass that resolves it, so it is tested against the first pass’s total while counting the second pass’s bins. In FREEZE and DOUBLE mode the memory is frozen and all of this collapses to one number; in LIVE mode it does not, and that last item is the one irreducible inconsistency of the mode.
If the distribution is stationary over the scan window none of this matters and LIVE mode is free. If it is not - a drifting baseline, a peak moving, a burst - the numbers are wrong in ways no flag can tell you about. Use FREEZE or DOUBLE.
2. The scan needs idle clocks, and can stall for ever. The histogram memory has one read port and one write port. A one-sample-per-clock increment is read the old count on one clock, write the new one on the next, so the binner occupies the read port on every clock a sample is accepted and the write port on the following clock. The scanner therefore advances
one bin per clock on which NO sample was accepted this clock or the previous one.
With IN_DV tied permanently high, the scanner never advances and no
result is ever produced: SCANNING stays high and SCAN_POS stops moving,
which is exactly how you see it on a scope. LIVE mode is for streams with
gaps - roughly, an IN_DV duty cycle below about two thirds.
The two costs compound with the SERIAL moment engine: a bin then needs several such free clocks rather than one, so the duty cycle has to leave proportionally more room. The compiler log warns when both are selected.
That same arbitration rule is what makes the mode safe: because the scanner only moves when the binner is touching neither port, a clear-on-scan can never land between the read and the write of an increment, so no count is ever lost.
Dropped frames
In LIVE and DOUBLE mode a frame that completes while the scanner is still
busy has its result dropped: no OUT_DV, no buffer swap. Accumulation is
unaffected and the next frame is analysed normally. Keep PERIOD comfortably
above the scan length (the compiler log prints it) and this never happens.
FREEZE mode cannot drop a frame, because its binner is stopped for the whole
scan.
Everything is in BIN units
MIN_BIN, MAX_BIN_OCC, MODE_BIN, MEDIAN, the quantiles, IQR,
RANGE, FWHM, FWTM and PEAK_POS are bin indices. MEAN,
VARIANCE and STDDEV are in bins and bins squared. SKEWNESS and
KURTOSIS are dimensionless.
To convert a bin index back to the input scale:
$$ x ;=; \mathrm{BASE} ;+; \left(\mathrm{bin} + \tfrac{1}{2}\right)\cdot 2^{\mathrm{SHIFT}} $$
The block deliberately does not do this for you: BASE and SHIFT are runtime pins, the conversion is one shift and one add in your own logic or in software, and doing it here would mean a second Q format on every one of a dozen outputs.
How the scan works, and why it is two passes
$$ \textbf{pass 1:}\quad M_0=\sum_k H_k,\qquad M_1=\sum_k k,H_k $$
plus the mode (argmax, first occurrence), the lowest and highest occupied bin, how many bins are non-empty and how many are saturated.
Between the passes one division produces the mean $m = M_1/M_0$, and with it $k_0=\lfloor m\rfloor$, the origin the central moments are taken about.
$$ \textbf{pass 2:}\quad C_n=\sum_k (k-k_0)^n H_k \quad (n=2,3,4) $$
plus the running cumulative count (median, quantiles, IQR), the threshold occupancies, the half- and tenth-maximum crossings either side of the mode, the three bins around the mode for the parabolic interpolation - and the clear, if it is enabled.
Why the quantiles force two passes: a quantile is the first bin whose cumulative count reaches $q$ of the total, and the total is only known once the whole histogram has been added up. The alternative - predicting the total from the sample counter - breaks the moment a bin saturates or the histogram is cumulative, so the block does the honest thing and reads the bins twice.
Why the moments are taken about $k_0$ and not about zero: the exact integer numerators for the third and fourth moments about zero carry factors of $M_0^3$ and $M_0^4$ and reach $8\cdot\text{ADDR_BITS}+4\cdot\text{BIN_BITS}$ bits, which is not buildable. About $k_0$ every central sum is bounded by $M_0\cdot\text{range}^n$ instead, and the leftover fractional offset $e = m - k_0 < 1$ is folded back in afterwards with the exact identities
$$ \mu_2 = a_2 - e^2,\qquad \mu_3 = a_3 - 3ea_2 + 2e^3,\qquad \mu_4 = a_4 - 4ea_3 + 6e^2a_2 - 3e^4 $$
with $a_n = C_n/M_0$. That is what the two-pass structure buys.
No divider in the per-bin path
The quantile test is
$$ \text{cum} \times 100 ;\ge; \text{PCT} \times M_0 $$
with PCT a compile-time constant, so both sides are constant multiplies (shift-adds) and there is no divider anywhere in the loop that runs once per bin. The powers of the bin offset are built incrementally ($d_2=d\cdot d$, $d_3=d_2\cdot d$, $d_4=d_2\cdot d_2$) - there is no general power either. Every division in the block lives in the tail, happens once per frame, and shares one serial restoring stage; the square root shares one digit-recurrence stage the same way. Skewness and kurtosis are computed as chained divisions,
$$ \text{skew} = \frac{\mu_3/\mu_2}{\sigma},\qquad \text{kurt} = \frac{\mu_4/\mu_2}{\mu_2} $$
rather than one division by $\mu_2^{3/2}$ or $\mu_2^2$: two narrow divisions instead of one very wide one, which costs clocks we have and saves bits we do not.
The per-bin multipliers: SERIAL or PIPELINED
There is no divider in the per-bin path, but with SKEWNESS or KURTOSIS enabled there are six multiplies on every bin of pass 2:
$$ d_2 = d\cdot d,\quad C_2 \mathrel{+}= d_2 H,\quad d_3 = d_2 d,\quad C_3 \mathrel{+}= d_3 H,\quad d_4 = d_2 d_2,\quad C_4 \mathrel{+}= d_4 H $$
and they are wide: $d_4$ alone is $4\log_2 N_{\rm bins}+4$ bits, so at 1024 bins $d_4\cdot H$ is a 44 x BitsPerBin product. Running one bin per clock means all six exist at the same time, which is of order 10 to 15 DSP48 slices on a part that may only have 80 - and it grows with the bin count.
Moment Implementation chooses which way to pay:
- SERIAL (default) - spend several clocks per bin and drive one shared multiplier through the six products. Typically three to four times fewer DSP48s. Pass 2 becomes 4 clocks per bin with one of the two shape moments enabled, 6 with both.
- PIPELINED - six parallel multipliers, one bin per clock, shortest scan.
The two produce bit-identical results. The serial engine changes only when each exact integer product is formed, never how; the regression suite runs matched SERIAL/PIPELINED pairs and requires every output of every frame to agree to the bit. Only the latency differs, and the formula below carries it.
The scan happens once per frame and PERIOD is normally far larger than the scan, so SERIAL is almost always the right trade: at 1024 bins it moves the scan from roughly 2500 to roughly 8000 clocks, which matters only if PERIOD is close to the scan length in the first place. Choose PIPELINED when you are deliberately running short frames back to back and have DSPs to spare.
The setting does nothing unless SKEWNESS or KURTOSIS is enabled: with MEAN / VARIANCE / STDDEV alone the per-bin path is $d_2 = d\cdot d$ and $C_2 \mathrel{+}= d_2 H$, two multiplies, and there is nothing worth folding. SERIAL then costs exactly nothing - same schedule, same latency, same logic.
Latency
With $n_b = \mathrm{MAX_BIN}+1$ bins actually scanned, the clocks from the
last accepted sample of a frame to its OUT_DV pulse are
$$ L(n_b) = n_b + 5 + ,\text{mean}, + ,\text{pass 2},,P + N_{\rm div}(D+1) + ,\sigma, $$
where $D$ is the serial divider width, $R$ the square-root width, $N_{\rm div}$ the number of tail divisions, and $P$ the clocks pass 2 spends on one bin - $P=1$ except with the SERIAL moment engine active (see above), where it is 4 with one shape moment enabled and 6 with both. The compiler log prints the actual number for your configuration. In LIVE mode this is a lower bound: the two pass terms stretch by one clock for every clock the scanner is denied the memory, so a SERIAL scan there needs $P$ free clocks per bin rather than one.
The practical consequence: MAX_BIN is the knob that controls latency. The RAM is sized by Max Bins (exponent), but only bins $0\ldots$MAX_BIN are scanned, so a 4096-bin RAM run with MAX_BIN = 255 scans in a quarter of the time. Size the RAM for the worst case and use MAX_BIN for everything else.
Bin saturation - read this one
A bin counts up to $2^{\text{BitsPerBin}}-1$ and then stops. From that
moment the histogram understates the peak, and therefore so do the mode
count, the mean, the variance, every quantile and every moment - silently.
BIN_SATURATED goes high for the frame in which an increment was actually
dropped, and SAT_BINS says how many bins are sitting at the maximum. They
are on by default and they should stay on. If they fire, either shorten the
frame (lower PERIOD), widen the bins (raise SHIFT), or raise Bits per Bin.
Typical uses
- Multichannel analyser / pulse-height spectrum. Feed pulse heights, disable Clear on Scan, and the histogram is the spectrum. MODE_BIN and PEAK_POS locate the photopeak, FWHM and FWTM measure the energy resolution and the tailing, and OCC0..3 with runtime THR pins are region-of-interest counters.
- Baseline and noise monitoring. MEDIAN is a baseline estimate that a few outliers cannot move; IQR is a robust noise width that needs no square root at all.
- ADC health. NONEMPTY_BINS on a raw ADC stream finds stuck bits and missing codes instantly; UNDERFLOW and OVERFLOW find clipping.
- Distribution shape. SKEWNESS and KURTOSIS discriminate a Gaussian noise floor from pile-up or from a bimodal distribution.
- Threshold scanning. Sweep THR0 from software and read OCC0 for an S-curve, without re-running the acquisition.
Pin Description
IN_DV is high and the block is accepting (see the mode notes:
FREEZE ignores samples during its scan).
'1', so the block free-runs out of the
box. In LIVE mode this must have gaps or the scan never completes.
UNDERFLOW.
OVERFLOW.
OUT_DV.
OCC0 counts everything at or above
it. Present only when Enable OCC0 = YES. Latched when the scan starts,
so it is a scan parameter and not a per-sample one. Unconnected defaults
to the THR0 default bin property, which is what makes a swept
software-controlled threshold work without re-synthesis.
RD_DATA one clock later, flagged
by RD_DV - which is low whenever the memory was busy, so poll it.
RD_ADDR, one clock after it was presented. Present
only when Enable Read Bus = YES. Valid only on the clocks RD_DV is
high; it holds otherwise.
RD_DATA carries the answer for the address presented
on the previous clock. Low whenever the scanner (or, outside DOUBLE mode,
the binner) had the memory.
THR0: the numerator of the
threshold occupancy. The denominator is TOTAL, which is a pin of its
own - the block deliberately exposes both instead of paying for a divider
so that software can form the ratio for free.
OUT_DV pulse, so the two fall together.
OUT_DV, so latch it with the
results.
Properties
Number of INTEGER bits of the input sample (the sign, when present, uses one of them).
Integer bits of the input (the sign, when present, uses one of them). 1..64.Default: 16
Range: 1 – 64
Number of FRACTIONAL bits of the input sample, i.e. the bits to the right of the binary point. Total width = integer + fractional bits, and must not exceed 64.
Fractional bits of the input. 0..64. Total input width must be 2..64 bits.Default: 0
Range: 0 – 64
Select whether the input sample is signed (two’s complement) or unsigned.
SIGNED (two’’s complement) or UNSIGNED input. The subtraction of BASE is done at one bit more than the input width either way, so a signed input minus a positive base cannot wrap.Default: SIGNED
Options: UNSIGNED SIGNED
The histogram RAM has 2^MaxBinsExponent bins: 10 means 1024 bins. This sizes the MEMORY, so it costs block RAM whether or not you use every bin – the MAX_BIN input then chooses how many of them are actually binned into and scanned AT RUN TIME. Keep it at the largest histogram you will ever ask for and use MAX_BIN for everything else, because a shorter scan is also a shorter latency.
The histogram RAM has $2^{\text{MaxBinsExponent}}$ bins: 10 means 1024. 2..16, default 10. This sizes the memory, so it costs block RAM whether or not you use every bin - theMAX_BIN input then chooses how
many are actually binned into and scanned at run time. Size this for the
largest histogram you will ever ask for and use MAX_BIN for everything
else, because a shorter scan is also a shorter latency.
Default: 10
Range: 2 – 16
Counts per bin: 8 (max 255), 16 (max 65535) or 32 (max 4294967295). THE RAM IS SIZED FROM THIS EXACTLY – nothing is padded to a machine word, so 8 bits per bin costs a quarter of what 32 does. When a bin reaches its maximum it STOPS COUNTING and BIN_SATURATED is raised: past that point every statistic understates the peak, so either size this for the longest frame you will run or watch that flag.
Counts per bin: 8 (max 255), 16 (max 65535) or 32 (max 4294967295). The RAM is sized from this exactly - nothing is padded to a machine word, so 8 bits per bin costs a quarter of what 32 does. When a bin reaches its maximum it stops counting andBIN_SATURATED is raised; past
that point every statistic understates the peak. Total RAM =
$2^{\text{MaxBinsExponent}}\times$ BitsPerBin bits, doubled in DOUBLE
mode.
Default: 16
Options: 8 16 32
FREEZE: accumulate for one frame, STOP, analyse, resume. Perfectly consistent statistics, one RAM, but the block is deaf for the whole scan and LOST counts what it missed. LIVE: never stop accumulating and analyse the same single RAM as the scanner can get at it. No dead time and no second RAM, but (a) the statistics are NOT a consistent snapshot – bin 0 is read at the start of the scan and the last bin thousands of clocks later, so the result describes a histogram that was never simultaneously in the memory – and (b) the scan only advances on clocks where no sample was accepted this clock or the previous one, so with IN_DV tied high it NEVER FINISHES. Use it only for a stationary distribution on a gappy stream. DOUBLE: two RAMs, ping-pong. Consistent snapshot, no dead time, no stall; twice the block RAM. This is the one to pick unless memory is tight.
FREEZE (default): accumulate one frame, stop the binner, analyse,
resume. Consistent statistics, one RAM, dead time for the whole scan
(counted in LOST).
LIVE: never stop accumulating and analyse the same single RAM. No dead time and no second RAM, but (a) the statistics are not a consistent snapshot - the scan smears over its own duration - and (b) the scan only advances on clocks where no sample was accepted this clock or the previous one, so with IN_DV tied high it never finishes. Only for a stationary distribution on a gappy stream.
DOUBLE: two RAMs, ping-pong. Consistent snapshot, no dead time, no stall; twice the block RAM. Pick this unless memory is tight.
Default: FREEZE
Options: FREEZE LIVE DOUBLE
YES: the scanner zeroes each bin as it reads it on its last pass, so every frame starts from an empty histogram and the statistics describe THAT frame. NO: the histogram is CUMULATIVE and grows for ever, which is what a multichannel analyser wants – and is exactly why BIN_SATURATED exists. In DOUBLE mode this is also what makes a buffer reusable after the swap.
YES (default): the scanner zeroes each bin as it reads it on its last pass, so every frame starts from an empty histogram and the statistics describe that frame. NO: the histogram is cumulative and grows for ever, which is what a multichannel analyser wants - and is exactly whyBIN_SATURATED exists. In DOUBLE mode this is also what makes a
buffer reusable after the swap.
Default: YES
Options: NO YES
YES: the TOTAL (how many counts the scanned histogram holds) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theTOTAL pin exists. It is the denominator of every occupancy and the flag that says whether anything was measured. Default YES.
Default: YES
Options: NO YES
YES: the MIN_BIN (lowest occupied bin) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theMIN_BIN pin exists. Default YES.
Default: YES
Options: NO YES
YES: the MAX_BIN_OCC (highest occupied bin) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theMAX_BIN_OCC pin exists. Default YES.
Default: YES
Options: NO YES
YES: the RANGE (MAX_BIN_OCC - MIN_BIN, one subtract) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theRANGE pin exists (MAX_BIN_OCC - MIN_BIN, one subtract). It pulls the occupied-bin registers in. Default NO.
Default: NO
Options: NO YES
YES: the MODE_BIN (argmax; the FIRST bin if the maximum is tied) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theMODE_BIN pin exists. Default YES.
Default: YES
Options: NO YES
YES: the MODE_COUNT (the count in MODE_BIN) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theMODE_COUNT pin exists. Default YES.
Default: YES
Options: NO YES
YES: the MEDIAN (the first bin whose cumulative count reaches half the total) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theMEDIAN pin exists. It needs the running cumulative count and
therefore the second pass, which roughly doubles the scan length.
Default YES.
Default: YES
Options: NO YES
YES: the QUANT0 pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theQUANT0 pin exists. Needs the second pass. Default NO.
Default: NO
Options: NO YES
Which quantile this slot reports, in PERCENT (1..99): the first bin whose cumulative count reaches this fraction of the total. 50 is the median, 25 and 75 the quartiles. It is a COMPILE TIME constant on purpose – the test is cumulative100 >= percenttotal, and with the percentage fixed both sides are constant multiplies, so no divider is needed anywhere in the per-bin path.
Which quantile QUANT0 reports, in percent (1..99): the first bin whose cumulative count reaches this fraction of the total. Compile time on purpose - the test is cumulative x 100 >= percent x total, and with the percentage fixed both sides are constant multiplies, so no divider is needed in the per-bin path. Default 10.Default: 10
Range: 1 – 99
YES: the QUANT1 pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theQUANT1 pin exists. Default NO.
Default: NO
Options: NO YES
Which quantile this slot reports, in PERCENT (1..99): the first bin whose cumulative count reaches this fraction of the total. 50 is the median, 25 and 75 the quartiles. It is a COMPILE TIME constant on purpose – the test is cumulative100 >= percenttotal, and with the percentage fixed both sides are constant multiplies, so no divider is needed anywhere in the per-bin path.
Percentile for QUANT1, 1..99. Default 25.Default: 25
Range: 1 – 99
YES: the QUANT2 pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theQUANT2 pin exists. Default NO.
Default: NO
Options: NO YES
Which quantile this slot reports, in PERCENT (1..99): the first bin whose cumulative count reaches this fraction of the total. 50 is the median, 25 and 75 the quartiles. It is a COMPILE TIME constant on purpose – the test is cumulative100 >= percenttotal, and with the percentage fixed both sides are constant multiplies, so no divider is needed anywhere in the per-bin path.
Percentile for QUANT2, 1..99. Default 75.Default: 75
Range: 1 – 99
YES: the QUANT3 pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theQUANT3 pin exists. Default NO.
Default: NO
Options: NO YES
Which quantile this slot reports, in PERCENT (1..99): the first bin whose cumulative count reaches this fraction of the total. 50 is the median, 25 and 75 the quartiles. It is a COMPILE TIME constant on purpose – the test is cumulative100 >= percenttotal, and with the percentage fixed both sides are constant multiplies, so no divider is needed anywhere in the per-bin path.
Percentile for QUANT3, 1..99. Default 90.Default: 90
Range: 1 – 99
YES: the IQR (the interquartile range, P75 - P25). It builds its OWN 25 % and 75 % trackers, so it does not care what the four QUANT slots are set to pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theIQR pin exists. It builds its own 25 % and 75 % trackers,
so it is independent of the four QUANT slots and you do not have to spend
two of them to get it. Default NO.
Default: NO
Options: NO YES
YES: the MEAN (the centroid, in BIN units) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theMEAN pin exists. The mean division is built anyway whenever
the variance, the standard deviation, the skewness or the kurtosis is
enabled, because they all need $k_0=\lfloor\text{mean}\rfloor$.
Default YES.
Default: YES
Options: NO YES
Number of INTEGER bits of the MEAN output, in BIN units (the sign, when present, uses one of them).
Integer bits of the MEAN output. It is a BIN INDEX, so it needs at least MaxBinsExponent bits to reach the top of the histogram.Default: 16
Range: 1 – 64
Number of FRACTIONAL bits of the MEAN output, in BIN units, i.e. the bits to the right of the binary point. Total width = integer + fractional bits, and must not exceed 64.
Fractional bits of the MEAN output. This is a centroid: the fraction is the useful part, so do not skimp. Total width 2..64.Default: 8
Range: 0 – 64
Select whether the MEAN output, in BIN units is signed (two’s complement) or unsigned.
SIGNED or UNSIGNED. A bin index is never negative, so UNSIGNED buys one bit.Default: UNSIGNED
Options: UNSIGNED SIGNED
YES: the VARIANCE (in BIN^2) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theVARIANCE pin exists. It needs the second central sum and therefore the second pass and one tail division. Default YES.
Default: YES
Options: NO YES
Number of INTEGER bits of the VARIANCE output, in BIN^2 (the sign, when present, uses one of them).
Integer bits of the VARIANCE output. It is in BIN SQUARED: allow about twice MaxBinsExponent.Default: 24
Range: 1 – 64
Number of FRACTIONAL bits of the VARIANCE output, in BIN^2, i.e. the bits to the right of the binary point. Total width = integer + fractional bits, and must not exceed 64.
Fractional bits of the VARIANCE output. Total width 2..64.Default: 8
Range: 0 – 64
Select whether the VARIANCE output, in BIN^2 is signed (two’s complement) or unsigned.
SIGNED or UNSIGNED. The variance is clamped at zero, so UNSIGNED is safe and buys one bit.Default: UNSIGNED
Options: UNSIGNED SIGNED
YES: the STDDEV (the square root of the variance, in BIN units). It reuses the same serial digit-recurrence root the skewness needs, so the two together cost only one engine pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theSTDDEV pin exists and one square-root run is scheduled in the
tail. It pulls in the variance datapath even when the VARIANCE pin is
off, and it shares its root with the skewness. Default YES.
Default: YES
Options: NO YES
Number of INTEGER bits of the STDDEV output, in BIN units (the sign, when present, uses one of them).
Integer bits of the STDDEV output, in BIN units.Default: 16
Range: 1 – 64
Number of FRACTIONAL bits of the STDDEV output, in BIN units, i.e. the bits to the right of the binary point. Total width = integer + fractional bits, and must not exceed 64.
Fractional bits of the STDDEV output. Total width 2..64.Default: 8
Range: 0 – 64
Select whether the STDDEV output, in BIN units is signed (two’s complement) or unsigned.
SIGNED or UNSIGNED. A standard deviation is never negative, so UNSIGNED buys one bit.Default: UNSIGNED
Options: UNSIGNED SIGNED
YES: the SKEWNESS (mu3 / sigma^3, dimensionless; negative = a left tail). It pulls in the third central sum and TWO more serial divisions pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theSKEWNESS pin exists. It pulls in the third central sum and
two more serial divisions plus the square root, so it lengthens the
tail noticeably. It is also one of the two settings that make Moment
Implementation mean anything: the third central sum is what puts wide
multipliers in the per-bin path. Default NO.
Default: NO
Options: NO YES
Number of INTEGER bits of the SKEWNESS output (the sign, when present, uses one of them).
Integer bits of the SKEWNESS output. Real skewness is small - a few units - so 6 bits is generous.Default: 6
Range: 1 – 64
Number of FRACTIONAL bits of the SKEWNESS output, i.e. the bits to the right of the binary point. Total width = integer + fractional bits, and must not exceed 64.
Fractional bits of the SKEWNESS output. This is where the resolution goes.Default: 10
Range: 0 – 64
Select whether the SKEWNESS output is signed (two’s complement) or unsigned.
Use SIGNED: the sign is the whole point (left tail vs right tail).Default: SIGNED
Options: UNSIGNED SIGNED
YES: the KURTOSIS (mu4 / sigma^4). It pulls in the FOURTH central sum, which is the widest accumulator in the block, and two more serial divisions pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theKURTOSIS pin exists. It pulls in the fourth central sum -
the widest accumulator in the block - and two more serial divisions. It
also pulls in the third central sum, which the offset correction
$\mu_4 = a_4 - 4ea_3 + 6e^2a_2 - 3e^4$ needs, whether or not SKEWNESS is
enabled. Together with SKEWNESS it is what makes Moment Implementation
matter. Default NO.
Default: NO
Options: NO YES
EXCESS: kurtosis - 3, so a Gaussian reads 0 and the sign tells you directly whether the distribution is heavier or lighter tailed than normal. RAW: the plain fourth standardised moment (a Gaussian reads 3).
EXCESS (default): kurtosis - 3, so a Gaussian reads 0 and the sign tells you directly whether the distribution is heavier or lighter tailed than normal. RAW: the plain fourth standardised moment (a Gaussian reads 3).Default: EXCESS
Options: RAW EXCESS
Number of INTEGER bits of the KURTOSIS output (the sign, when present, uses one of them).
Integer bits of the KURTOSIS output. With EXCESS a Gaussian is 0 and a very peaked distribution a few tens.Default: 8
Range: 1 – 64
Number of FRACTIONAL bits of the KURTOSIS output, i.e. the bits to the right of the binary point. Total width = integer + fractional bits, and must not exceed 64.
Fractional bits of the KURTOSIS output.Default: 8
Range: 0 – 64
Select whether the KURTOSIS output is signed (two’s complement) or unsigned.
Use SIGNED with the EXCESS definition, which is negative for a flat distribution.Default: SIGNED
Options: UNSIGNED SIGNED
YES: the OCC0 (how many counts sit at or above threshold bin THR0) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theTHR0 input and the OCC0 output exist - a region-of-interest
counter with a runtime threshold. Needs the second pass. Default NO.
Default: NO
Options: NO YES
Value the THR0 input takes when it is left unconnected.
Bin the THR0 input takes when left unconnected. Must be within the histogram, i.e. below $2^{\text{MaxBinsExponent}}$.Default: 0
Range: 0 – 65535
YES: the OCC1 (how many counts sit at or above threshold bin THR1) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theTHR1 input and the OCC1 output exist. Default NO.
Default: NO
Options: NO YES
Value the THR1 input takes when it is left unconnected.
Bin the THR1 input takes when left unconnected.Default: 0
Range: 0 – 65535
YES: the OCC2 (how many counts sit at or above threshold bin THR2) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theTHR2 input and the OCC2 output exist. Default NO.
Default: NO
Options: NO YES
Value the THR2 input takes when it is left unconnected.
Bin the THR2 input takes when left unconnected.Default: 0
Range: 0 – 65535
YES: the OCC3 (how many counts sit at or above threshold bin THR3) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theTHR3 input and the OCC3 output exist. Default NO.
Default: NO
Options: NO YES
Value the THR3 input takes when it is left unconnected.
Bin the THR3 input takes when left unconnected.Default: 0
Range: 0 – 65535
YES: the BIN_SATURATED (a bin hit its maximum count during this frame and STOPPED counting). WITHOUT THIS EVERY OTHER STATISTIC IS SILENTLY WRONG once a bin saturates – leave it on pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theBIN_SATURATED pin exists. Without it every other statistic
is silently wrong once a bin saturates. It costs one flip-flop. Leave
it on. Default YES.
Default: YES
Options: NO YES
YES: the SAT_BINS (how many bins are AT the maximum count) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theSAT_BINS pin exists - how many bins are at the maximum count, i.e. how badly the histogram is clipped from above. Default NO.
Default: NO
Options: NO YES
YES: the UNDERFLOW (samples that fell below the BASE and were clamped into bin 0) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theUNDERFLOW pin exists - samples clamped into bin 0. Together with OVERFLOW this is what distinguishes a clipped distribution from a real one. Default YES.
Default: YES
Options: NO YES
YES: the OVERFLOW (samples that fell above MAX_BIN and were clamped into it). With UNDERFLOW this is what distinguishes a clipped distribution from a real one pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theOVERFLOW pin exists - samples clamped into MAX_BIN. Default YES.
Default: YES
Options: NO YES
YES: the NONEMPTY_BINS (the support size: how many bins are not zero). One comparator, and it tells you instantly whether the binning is sensible pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theNONEMPTY_BINS pin exists - the support size, one comparator. Default NO.
Default: NO
Options: NO YES
YES: the LOST (samples the block refused: the FREEZE dead time, and the cold clear after reset). Free in LIVE and DOUBLE mode, where it can only count the cold clear pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theLOST pin exists - samples the block refused (the FREEZE dead
time, and the cold clear after reset). In LIVE and DOUBLE mode it can
only count the cold clear. Default NO.
Default: NO
Options: NO YES
YES: the FWHM (full width at half maximum, in BINS: the distance between the first bin below MODE_COUNT/2 on each side of the mode). Two threshold crossings, no interpolation pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theFWHM pin exists. Two comparators and two registers; it pulls
in the mode registers and the second pass. The comparison is
$2H_k < \text{MODE_COUNT}$, so there is no division. Default NO.
Default: NO
Options: NO YES
YES: the FWTM (full width at TENTH maximum, in BINS). Same two comparators with a different constant; FWTM/FWHM is the standard peak-tailing figure pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theFWTM pin exists - the same machinery with $10H_k$ instead of
$2H_k$. FWTM/FWHM is the standard peak-tailing figure. Default NO.
Default: NO
Options: NO YES
YES: the PEAK_POS (the sub-bin peak position by parabolic interpolation on MODE_BIN-1, MODE_BIN, MODE_BIN+1). One division, and it removes the bin quantisation from the peak position pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: thePEAK_POS pin exists - the sub-bin mode position by parabolic
interpolation. One tail division, and it removes the bin quantisation
from the peak position, which is usually the dominant error on a narrow
peak. Default NO.
Default: NO
Options: NO YES
Number of INTEGER bits of the PEAK_POS output, in BIN units (the sign, when present, uses one of them).
Integer bits of the PEAK_POS output. It is an absolute bin index plus a fraction, so this must hold the largest bin index: at least MaxBinsExponent usable integer bits. The property validator refuses a configuration where it cannot.Default: 16
Range: 1 – 64
Number of FRACTIONAL bits of the PEAK_POS output, in BIN units, i.e. the bits to the right of the binary point. Total width = integer + fractional bits, and must not exceed 64.
Fractional bits of PEAK_POS. This is the sub-bin resolution you are paying the division for.Default: 8
Range: 0 – 64
Select whether the PEAK_POS output, in BIN units is signed (two’s complement) or unsigned.
SIGNED or UNSIGNED. The position is never negative, so UNSIGNED buys one bit.Default: UNSIGNED
Options: UNSIGNED SIGNED
YES: the the RD_ADDR / RD_DATA / RD_DV bus, which reads individual bins from outside. RD_DATA answers one clock after RD_ADDR and RD_DV says so; the bus stands back whenever the scanner or (except in DOUBLE mode) the binner is using the memory, so poll RD_DV rather than assuming a fixed latency pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theRD_ADDR / RD_DATA / RD_DV bus exists, which reads
individual bins from outside - this is how you get the whole spectrum
out, not just its statistics. The bus shares the histogram read port and
stands back when the memory is busy, so poll RD_DV. Default NO.
Default: NO
Options: NO YES
YES: the BUSY (accumulating, or scanning, or clearing after reset; its last high clock is the OUT_DV pulse) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theBUSY pin exists. Default NO.
Default: NO
Options: NO YES
YES: the ACCUMULATING (a frame is open and taking samples) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theACCUMULATING pin exists. Default NO.
Default: NO
Options: NO YES
YES: the SCANNING (the analyser is walking the histogram or finishing its arithmetic). In LIVE mode this is how you SEE a stalled scan pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theSCANNING pin exists. In LIVE mode this is how you see a stalled scan. Default NO.
Default: NO
Options: NO YES
YES: the SCAN_POS (which bin the scanner is on – scan progress) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theSCAN_POS pin exists - which bin the scanner is on. Default NO.
Default: NO
Options: NO YES
YES: the SAMPLE_COUNT (samples accumulated so far in the current frame; it HOLDS the final count through the scan and past OUT_DV) pin is present. NO: the pin AND all of its logic are removed BEFORE synthesis, so nothing is paid for it. Note the internal dependencies the core resolves for you: the variance, the standard deviation, the skewness and the kurtosis all need the mean; the skewness needs the standard deviation; FWHM, FWTM and PEAK_POS all need the mode; and any of the quantiles, the occupancies or the moments turns the scan into TWO passes.
YES: theSAMPLE_COUNT pin exists - a fixed 32 bit count that holds the frame length through the scan and past OUT_DV. Default NO.
Default: NO
Options: NO YES
ROUND: round to nearest when a result has to be requantised into a coarser output format. TRUNCATE: drop the bits (cheaper, adds a negative bias).
ROUND: round to nearest when a result has to be requantised into a coarser output format. TRUNCATE: drop the bits (cheaper, adds a negative bias). Only the derived outputs are affected - counts and bin indices are exact either way.Default: ROUND
Options: TRUNCATE ROUND
YES: clip to the largest representable value of each output format (symmetric for signed formats). NO: wrap around.
YES: clip to the largest representable value of each output format (symmetric bounds for signed formats). NO: wrap around. Only matters when an output format is too narrow for the value.Default: YES
Options: NO YES
How the per-bin moment products of SKEWNESS and KURTOSIS are built. SERIAL: one shared multiplier driven through the six products over several clocks per bin – typically three to four times fewer DSP48s, at the cost of a longer scan (the scan happens once per frame, so this is almost always the right trade). PIPELINED: six parallel multipliers, one bin per clock, shortest scan. BOTH PRODUCE BIT-IDENTICAL RESULTS – only the latency differs. This setting does NOTHING unless SKEWNESS or KURTOSIS is enabled: with MEAN / VARIANCE / STDDEV alone the per-bin path is two multiplies and there is nothing to fold.
How the per-bin moment products of SKEWNESS and KURTOSIS are built.
SERIAL (default): one shared multiplier is driven through the six products over several clocks per bin - typically three to four times fewer DSP48 slices, at the cost of a longer scan (4 clocks per bin with one shape moment enabled, 6 with both). The scan runs once per frame, so this is almost always the right trade.
PIPELINED: six parallel multipliers, one bin per clock, shortest scan and the most DSPs.
The two are BIT IDENTICAL - only the latency differs, and the compiler log prints the scan length for both. This setting does nothing unless SKEWNESS or KURTOSIS is enabled: with MEAN / VARIANCE / STDDEV alone the per-bin path is only two multiplies and there is nothing to fold.
Default: SERIAL
Options: SERIAL PIPELINED
Reading the results
Every enabled output is written together in the same clock and flagged by a
one-clock OUT_DV pulse. Between pulses they hold, so a downstream
register can latch them on OUT_DV or a CPU can read them at leisure.
An output that is not enabled has no pin and no logic: it is removed by the preprocessor before synthesis, so the symbol and the generated entity agree by construction. Some outputs pull others in internally, which costs logic but never a pin:
| enabling | also builds |
|---|---|
| VARIANCE, STDDEV, SKEWNESS, KURTOSIS | the mean division |
| SKEWNESS | the standard deviation (the square root) |
| FWHM, FWTM, PEAK_POS | the mode registers |
| any quantile, occupancy or moment | the second pass (roughly doubles the scan) |
The read bus
With Enable Read Bus on, RD_ADDR presents a bin index and RD_DATA
answers one clock later with RD_DV high. The bus shares the histogram’s
read port, so it stands back whenever the scanner - or, except in DOUBLE
mode, the binner - is using the memory. Poll RD_DV; do not assume a fixed
latency. In DOUBLE mode the bus reads the buffer that is not being
filled, i.e. the one the scanner walks, so it only ever has to wait for the
scanner.
This is how you get the whole spectrum out, not just its statistics: sweep RD_ADDR from 0 to MAX_BIN and collect RD_DATA whenever RD_DV is high.
Status outputs and their exact edges
Every output of this core is a register, so each is seen one clock after the event that sets it.
ACCUMULATINGis high while a frame is open - from the clock after its first sample is accepted to the clock after its last.SCANNINGis high from the clock after a frame is handed over until the scan and its arithmetic are finished. In LIVE mode this is how you see a stalled scan: SCANNING stays high while SCAN_POS does not move.BUSY= accumulating, or scanning, or clearing after reset. Its last high clock is theOUT_DVpulse - the two fall together.SCAN_POSis the bin the scanner is working on: scan progress.SAMPLE_COUNTis the number of samples accumulated so far in the current frame. It is not cleared at the frame end: it holds the final count through the whole scan and pastOUT_DV, so on theOUT_DVclock it reads the length of the frame whose result is being presented.
Reset and the cold clear
A block RAM comes up undefined, so after reset the block sweeps every bin
writing zero before it accepts anything. That takes $2^{\text{Max Bins
(exponent)}}$ clocks - 1024 bins is 1024 clocks - and BUSY is high
throughout. Samples arriving during the cold clear are counted in LOST.
This is not optional housekeeping: without it the first histogram would be
whatever was left in the RAM.
Degenerate cases, all forced explicitly
- A single occupied bin. The variance, the standard deviation, the IQR, the skewness and the kurtosis are all 0 (there is no spread, and a distribution with no spread has no shape). MEDIAN, MODE_BIN, MIN_BIN and MAX_BIN_OCC are that bin, RANGE is 0.
- A peak with no crossing. If no bin either side of the mode falls below half (or a tenth of) the maximum, FWHM/FWTM use the histogram edges - the honest answer for a peak that fills the whole range.
- No parabolic vertex. PEAK_POS falls back to the plain MODE_BIN when the mode sits on an edge bin, or when the three-point curvature $2H_m - H_{m-1} - H_{m+1}$ is not strictly positive (a flat top - there is no vertex to find). The offset is clamped to $\pm\tfrac12$ bin, because a parabolic vertex is by construction inside the central bin; a peak leaning left gives a negative offset, one leaning right a positive one.
- Total zero. Every statistic reads 0, so
TOTAL == 0is the flag that says “nothing was measured”. Note that the frame mechanism cannot actually produce this - a frame ends after PERIOD accepted samples, so it always holds at least PERIOD counts - it is a defensive guard.
Accuracy
Everything that is a count or a bin index is exact: total, min/max bin, range, mode, mode count, median, quantiles, IQR, occupancies, non-empty and saturated bin counts, underflow, overflow, lost, FWHM and FWTM involve nothing but an add and a compare.
The derived quantities - mean, variance, stddev, skewness, kurtosis, peak position - are carried internally with a fractional width derived from the widest output format you asked for, plus four guard bits, and every division and square root floors. In the regression they land within one to a few LSB of the exactly-rounded value, with the bound propagated from that internal precision rather than measured. Give an output a couple of extra fractional bits if you care about its last one.