Xilinx
HLS
Block Preview

Introduction

The Complex CORDIC (mag + phase) block converts a complex input A = IN_I + j*IN_Q from rectangular to polar form:

      MAG   = |A| * K_cordic
    PHASE = atan2(IN_Q, IN_I)
  

It uses the CORDIC algorithm in vectoring mode: the vector (x, y) is rotated in successively smaller angle steps atan(2^-k) to drive y towards zero. Each step is a shift and an add/sub, so there are no multipliers and no lookup of trig values (only a small constant table of the step angles).

  • Every rotation that zeroes y is accumulated into the phase register z, so at the end z = atan2(Q, I).
  • The residual x at the end equals |A| multiplied by the fixed CORDIC processing gain K_cordic ~= 1.647 (the product of sqrt(1+2^-2k) over all iterations).

For the reverse conversion (polar -> rect) see Component_ComplexPolarToRect, which shares the same phase scaling.

Pin Description

IN_I Input InputSize bit BIT VECTOR
In-phase (I) input sample. Signed, Input Bit Width bits.
Default: Must be connected
IN_Q Input InputSize bit BIT VECTOR
Quadrature (Q) input sample. Signed, Input Bit Width bits.
Default: Must be connected
CLK Input 1 bit BIT
System clock input. Default: Acquisition clock.
Default: Default Board Clock
RESET Input 1 bit BIT
HLS synchronous reset (ap_rst). Default: Global reset.
Default: Default Board Reset
MAG Output InputSize + 2 bit BIT VECTOR
Magnitude |A| scaled by the CORDIC gain (~1.647x). Unsigned, InputSize + 2 bits.
PHASE Output 16 bit BIT VECTOR
Phase atan2(IN_Q, IN_I), signed 16 bits with +/-Pi = +/-32768.

Properties

Property window

Input Bit Width InputSize

Bit width of each I/Q input (signed). MAG = InputSize+2, PHASE = 16 (Pi = 32768).

Bit width of each signed I / Q input sample. Range 4 to 32, default 16. Sets MAG = InputSize + 2; PHASE is fixed at 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

CORDIC Iterations NIter

Number of CORDIC iterations. 16 gives ~15-bit phase precision. Latency = NIter clocks.

Number of CORDIC iterations. Selectable 8, 12, 16, 20; default 16 (~15-bit phase precision). Latency equals NIter clocks. Values above 16 give no extra phase resolution because the 16-bit angle LUT is exhausted past iteration 15.

Default: 16

Options: 8 12 16 20

Usage

Phase scaling

PHASE is a signed 16-bit value in which +/-Pi maps to +/-2^15:

      PHASE = round(atan2(Q, I) * 32768 / Pi)      (range -32768 .. +32767)
    +Pi/2 = +16384,   -Pi/2 = -16384,   0 = 0
  

This is the same wrapped, full-scale phase convention used by the NCO and the polar->rect block, so a phase from this block can be fed straight into a phase accumulator or the polar->rect converter.

Quadrant folding

Plain CORDIC vectoring only converges for the right half-plane (x >= 0). The block first folds the input into that half-plane and pre-loads z with the removed rotation:

      x >= 0            : z = 0,        (x, y) unchanged
    x < 0, y >= 0     : z = +Pi/2,    (x, y) -> ( y, -x)   (2nd quadrant)
    x < 0, y <  0     : z = -Pi/2,    (x, y) -> (-y,  x)   (3rd quadrant)
  

The remaining CORDIC iterations then resolve the angle within +/-Pi/2, and the pre-load restores the full +/-Pi range.

Iterations and precision

Each iteration k = 0 .. N_ITER-1 adds/subtracts ATAN_LUT[k], the value round(atan(2^-k) * 32768 / Pi):

      k :  0     1     2     3    4    5    6   7   8   9  10 11 12 13 ...
    LUT: 8192  4836  2555  1297 651  326  163 81  41  20 10 5  3  1  ...
  

The angle step halves each iteration, so precision improves by roughly one bit per iteration until it hits the 16-bit phase quantum. Selectable N_ITER values:

      N_ITER   phase precision    latency
    8        ~8 bits            8 clocks
    12       ~12 bits           12 clocks
    16       ~15 bits (default) 16 clocks
    20       ~15 bits (LUT exhausted past k=15)
  

Beyond k = 15 the scaled step angle rounds to 0, so N_ITER = 16 already reaches the resolution floor of the 16-bit phase word; 20 adds latency without extra phase accuracy but can still tighten the magnitude estimate.

Bit widths and the CORDIC gain

  • IN_I, IN_Q : signed InputSize bits.
  • MAG : unsigned InputSize + 2 bits. The two extra bits hold the ~1.647x CORDIC processing gain (MAG ~= 1.647 * |A|). For RSSI / AGC the constant scale is harmless; divide by 1.647 (multiply by 0.607) downstream if a calibrated magnitude is needed.
  • PHASE : signed 16 bits (fixed, Pi = 32768).

Latency and throughput

  • #pragma HLS PIPELINE II=1 : one sample per clock.
  • The N_ITER iterations are fully unrolled and pipelined, so latency is N_ITER clocks (default 16) while throughput stays at one sample per clock. (The schematic symbol reports a nominal latency of 16.)
  • All ports use the ap_none interface (no ready/valid handshake).

Reset

RESET is the HLS synchronous reset (ap_rst) and clears the pipeline registers.

Typical applications

  • FM / phase discriminator : differentiate PHASE across samples to recover instantaneous frequency (see also Component_FMDemod).
  • Magnitude / envelope detector when the fixed 1.647x gain is acceptable.
  • Phase measurement for a digital PLL, carrier recovery, or a coherent-detection loop.
  • Polar formatting of a complex stream ahead of log/dB or quantiser stages.

Resources & Timing

  • Latency: NIter clock cycles (default 16)

  • Throughput: 1 sample per clock (II=1)

Multiplier-free: the NIter iterations are fully unrolled into a pipeline of shift-and-add stages plus a small constant angle LUT. Magnitude carries a fixed ~1.647x CORDIC processing gain. Phase precision is bounded by the 16-bit phase word (Pi = 32768).