RF FM Demod (discriminator)
FM discriminator. Recovers the message as the instantaneous frequency of a complex I/Q baseband signal: it forms d[n] = z[n]*conj(z[n-1]) and takes arg(d) with a CORDIC atan2. The argument of the product is already the wrapped phase increment, so no phase unwrap is needed. Real output, scaled so that a per-sample phase step of pi maps to full scale.
Introduction
The FM Demod (discriminator) block recovers the message from a complex
I/Q baseband FM signal z[n] = I[n] + jQ[n]. The instantaneous frequency is
the phase difference between consecutive samples, obtained from the argument
of the product with the conjugate of the previous sample:
d[n] = z[n] * conj(z[n-1])
= (I*Ip + Q*Qp) + j(Q*Ip - I*Qp)
msg[n] = arg(d[n]) = atan2(Im d, Re d)
Because arg(d) is the phase increment per sample, it is already wrapped
into (-pi, pi] and no explicit phase unwrap is required. The atan2 is
computed with a fixed-point CORDIC (vectoring mode). The output is the
instantaneous frequency (proportional to the message), scaled so that
arg = pi maps to full scale 2^(OutputSize-1) (i.e. +-pi <-> +-Fs/2 of
deviation).
Feed this block complex baseband: for a real passband FM input, put a DDC (mixer + decimator) or the Hilbert block in front. This block uses the standard property grid (no custom designer).
Pin Description
InputSize bits.
InputSize bits.
OutputSize bits; full scale 2^(OutputSize-1) corresponds to a
per-sample phase step of pi (Fs/2 deviation).
Properties
I/Q input bit width.
I/Q input bit width. Range 4 to 32, default 16.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
Frequency output width (full scale = +-pi = +-Fs/2 deviation).
Frequency output width; full scale (2^(OutputSize-1)) = +-pi = +-Fs/2
deviation. One of 12, 14, 16, 18, 20, 24, default 18.
Default: 18
Options: 12 14 16 18 20 24
atan2 precision (more = finer, more logic).
Number of CORDIC iterations for the atan2. More iterations give finer angle precision at the cost of logic. One of 10, 12, 14, 16, 18, default 14.Default: 14
Options: 10 12 14 16 18
Usage
CORDIC atan2
atan2(y, x) is computed by CORDIC vectoring over CordicN iterations. The
input is first folded into the right half-plane (adding +-pi when x < 0),
then rotated toward the real axis, accumulating the per-stage angles:
for i in 0..CordicN-1:
if yi > 0: xi += yi>>i; yi -= xi>>i; ang += ATAN_LUT[i]
else: xi -= yi>>i; yi += xi>>i; ang -= ATAN_LUT[i]
The angle table holds ATAN_LUT[i] = round(atan(2^-i) / pi * 2^(OutputSize-1))
(fm_demod_atan.inc), so the result comes out directly in the output’s
angle units where pi == 2^(OutputSize-1).
Output scaling
OUT = atan2(Im d, Re d), with pi -> 2^(OutputSize-1) (full scale)
A per-sample phase step of pi radians (the fastest representable, = Fs/2 of frequency deviation) produces full-scale output; smaller deviations scale linearly.
Bit widths
IN_I,IN_Q: signedInputSizebits.- Conjugate-product terms:
2*InputSize + 2bits. OUT: signedOutputSizebits.
Latency and throughput
#pragma HLS PIPELINE II=1: one output sample per clock.VALID_OUTis asserted high on every valid output sample.- All ports use the
ap_noneinterface (no ready/valid handshake).
Reset
RESET is the HLS synchronous reset (ap_rst). It clears the stored
previous sample (pi_, pq_); the first output after reset uses a zero
previous sample.
Typical applications
- FM / FSK demodulation of a complex-baseband signal after a DDC.
- Instantaneous-frequency estimation of any analytic signal (e.g. from the Hilbert block).
Resources & Timing
-
Latency: 1 clock cycle (pipelined CORDIC, II=1)
-
Throughput: 1 sample per clock (II=1)
Implemented with Vitis HLS. Four multipliers for the conjugate product,
then an unrolled CordicN-stage CORDIC (shift-add only, no multipliers) for
the atan2. The angle constants (fm_demod_atan.inc) are compile-time
constants. The HLS unique name depends on InputSize, OutputSize and
CordicN.