Xilinx
HLS
Block Preview

Introduction

The Complex Conj-Multiplier multiplies operand A by the conjugate of operand B, sample by sample:

      OUT_I[n] = A_I*B_I + A_Q*B_Q
    OUT_Q[n] = A_Q*B_I - A_I*B_Q
  

Equivalently, with A = A_I + j*A_Q and B = B_I + j*B_Q,

      OUT = A * conj(B)
  

Because arg(A*conj(B)) = arg(A) - arg(B), the argument of the output is the instantaneous phase difference between the two inputs, and the magnitude is |A|*|B|. All inputs are signed two’s complement.

Pin Description

A_I Input InputSize bit BIT VECTOR
In-phase (I) part of operand A. Signed, Input Bit Width bits.
Default: Must be connected
A_Q Input InputSize bit BIT VECTOR
Quadrature (Q) part of operand A. Signed, Input Bit Width bits.
Default: Must be connected
B_I Input InputSize bit BIT VECTOR
In-phase (I) part of operand B (conjugated internally). Signed, Input Bit Width bits.
Default: Must be connected
B_Q Input InputSize bit BIT VECTOR
Quadrature (Q) part of operand B (conjugated internally). 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
OUT_I Output 2*InputSize + 1 bit BIT VECTOR
In-phase (I) output = A_IB_I + A_QB_Q. Signed, 2*InputSize + 1 bits.
OUT_Q Output 2*InputSize + 1 bit BIT VECTOR
Quadrature (Q) output = A_QB_I - A_IB_Q. Signed, 2*InputSize + 1 bits.

Properties

Property window

Input Bit Width InputSize

Bit width of each I/Q sample (signed). Output is 2*InputSize+1 (full precision).

Bit width of each signed I / Q input sample. Range 4 to 32, default 16. The output width is 2*InputSize + 1 (full precision).

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

Output Width OutputWidth

M+N+1 = full precision. M+N = drop the guard bit, SATURATE on the rare overflow. max(M,N) = shift right by min(M,N) then SATURATE to the input width (no growth). M=N=Input Bit Width.

Default: M+N+1 (full)

Options: M+N+1 (full) M+N (sat) max(M N)

Usage

Mathematical model

Writing the four real products

      p1 = A_I*B_I     p2 = A_Q*B_Q
    p3 = A_Q*B_I     p4 = A_I*B_Q
  

the outputs are

      OUT_I = p1 + p2       (real part of A*conj(B))
    OUT_Q = p3 - p4       (imag part of A*conj(B))
  

This is the standard “cross-multiply” phase-detector: OUT_Q (or atan2(OUT_Q, OUT_I)) is the loop error in a carrier / timing recovery loop, and OUT_I alone gives the in-phase (matched) correlation.

Bit widths

Data is signed two’s complement.

  • A_I, A_Q, B_I, B_Q : signed InputSize bits.
  • Each product is 2*InputSize bits; the sum / difference of two products needs one extra bit.
  • OUT_I, OUT_Q : signed 2*InputSize + 1 bits (full precision, same growth as the complex Mixer).

Truncate or round downstream if fewer bits are needed.

Latency and throughput

  • #pragma HLS PIPELINE II=1 : one sample pair per clock.
  • 1-clock latency.
  • All data ports use the ap_none interface (no ready/valid handshake); the core is free-running (ap_ctrl_none).

Reset

RESET is the HLS synchronous reset (ap_rst).

Typical applications

  • Phase discriminator : arg(A*conj(B)) = arg(A) - arg(B).
  • Costas loop / PLL carrier recovery and symbol-timing recovery.
  • Differential demodulation : A[n] * conj(A[n-1]).

Resources & Timing

  • Latency: 1 clock cycle

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

Four real multiplies (four DSP48 slices for InputSize <= 18) plus two adders. Implemented with Vitis HLS. Free-running core (ap_ctrl_none), no handshake logic.