RF Complex Peak Detector (|A|^2 hold)
Tracks the maximum instantaneous power |A|^2 = I^2 + Q^2 of a complex stream and holds it, refreshing to the current sample after a programmable hold time. Typical use: RSSI / envelope peak capture and simple threshold detection.
Introduction
The Complex Peak Detector computes the instantaneous power of every incoming sample and reports the largest value seen recently:
mag[n] = IN_I[n]^2 + IN_Q[n]^2 (|A|^2, squared magnitude)
PEAK = max held value
It is a peak-with-hold detector, not a full sliding-window maximum.
Whenever a new sample exceeds the current peak, the peak jumps up to it
immediately and the hold timer restarts. If no new maximum arrives within
HoldLen samples, the timer expires and the peak is refreshed (dropped)
to the current sample. This is the behaviour normally wanted for RSSI /
envelope tracking: fast attack, timed release.
Pin Description
max(|A|^2). Signed (non-negative),
2*InputSize + 1 bits.
Properties
Bit width of each I/Q sample.
Bit width of each signed I / Q input sample. Range 4 to 32, default 16. Output width =2*InputSize + 1.
Default: 16
Options: 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
Number of samples the peak is held before being reset to the current |A|^2.
Hold time in samples before the peak is released (refreshed to the current|A|^2). Selectable from 16, 32, 64, 128, 256, 512, 1024,
2048, 4096, 8192, 16384, default 256. A larger value holds a peak
longer (slower release).
Default: 256
Options: 16 32 64 128 256 512 1024 2048 4096 8192 16384
Usage
Stateful / feedback behaviour
This is a stateful block. The C++ core keeps two static registers:
static out_t peak; // held maximum |A|^2
static cnt_t cnt; // samples since the peak was last refreshed
Each clock:
mag = IN_I^2 + IN_Q^2
if (mag > peak): peak = mag; cnt = 0 // fast attack
else if (cnt >= HoldLen-1): peak = mag; cnt = 0 // timed release
else: cnt = cnt + 1
Note the release resets the peak to the current sample mag, not to
zero, so the output continuously reflects a recent envelope estimate.
Squared magnitude (no square root)
The block outputs power |A|^2, not amplitude |A|. Avoiding the square
root keeps it to two multipliers and an adder. If you need linear amplitude
or dB, take the root / log downstream (or use the Complex Magnitude blocks).
Bit widths
Data is signed; the squared magnitude is non-negative.
IN_I,IN_Q: signedInputSizebits.- internal product
I^2,Q^2:2*InputSizebits each. PEAK_MAGSQ: signed2*InputSize + 1bits (the+1holds the sum of the two squares without overflow).
Reset behaviour
RESET is the HLS synchronous reset (ap_rst). On assertion the held peak
and the hold counter are cleared to zero. The peak then rebuilds from the
incoming samples.
Latency and throughput
#pragma HLS PIPELINE II=1: one sample pair per clock.- 1-clock latency.
- All ports use
ap_none. #pragma HLS INTERFACE ap_ctrl_none port=return: no block-level control.
Typical applications
- RSSI / envelope peak capture after a mixer or magnitude stage.
- Threshold / trigger generation (compare
PEAK_MAGSQto a constant). - AGC assist feeding a slow level controller.
Resources & Timing
-
Latency: 1 clock cycle
-
Throughput: 1 sample per clock (II=1)
Two multipliers (I^2, Q^2), one adder, one comparator and a hold counter. No BRAM, no square root. Stateful (static peak + counter registers). Peak-with-hold, not a true sliding-window max, so it is O(1) per sample regardless of HoldLen.