Adaptive Equaliser (Non-Data-Aided) (adaptive_equaliser)

Non-data-aided adaptive equaliser using a feed-forward architecture.

Design

The adaptive equaliser primitive applies either the Constant Modulus Algorithm (CMA) or Multi-Modulus Algorithm (MMA) to correct distortions in complex input samples. The goal is to reduce the deviation of received constellation points from their ideal positions without the use of training data.

Implementation

The primitive receives complex signed samples representing a distorted constellation. The error is calculated from the equalised output and fed back into the tap update logic, adjusting the feed-forward equaliser taps over time.

Bit-True Models

The bit-true behaviour for each estimator is illustrated in the diagrams below:

CMA Bit True Diagram.

Figure 458: Block diagram depicting the bit widths around each operation for the CMA configuration.

MMA Bit True Diagram.

Figure 459: Block diagram depicting the bit widths around each operation for the MMA configuration.

Forward Path

The CMA and MMA configurations share a common forward path:

  • A complex multiplier computes the product of tap values and input samples.

  • The results feed into an adder tree that forms the FIR accumulation (2- or 3-input stages depending on tap count).

  • Bit width grows with the number of taps.

The output of the adder tree is rounded to a data_width_g-bit value, shifting right by 15 bits, using half-even rounding with saturation. This maintains unity gain and preserves dynamic range relative to the initial tap scaling.

CMA/MMA Error Calculation

The error measures how far the equalised output deviates from the target modulus unit_modulus_g (R), which must match the scaling of the input constellation. For CMA, R is the magnitude of the (order-4) constellation points; for MMA it is the innermost per-axis level, with points at \(\pm R, \pm 3R, ..., \pm(\sqrt{order}-1)R\), so R = outermost level / \((\sqrt{order}-1)\).

The error term is computed using a wide multiply to avoid premature loss of precision. Since wide DSP utilisation increases rapidly with the number of taps, wide multiplies are restricted to the error path only.

To control DSP usage:

  • The error value is reduced to 18 bits via a half-even rounding shift (48 bits for CMA, 46 bits for MMA). The smaller MMA shift keeps 2 extra fractional bits so that small MMA error values (which scale with the cube of the unit modulus) survive the reduction to 18 bits. This multiplies the effective MMA step size by 4, which the primitive compensates for by dividing step_size_g by 4 internally when using the MMA estimator, so that step_size_g has the same meaning for both estimators. The 2 least significant bits of step_size_g are therefore ignored when using MMA.

  • Overflow is prevented by saturating values after complex conjugation when required.

  • The step_size_g parameter should be increased if the resulting error value becomes too small relative to the reduced bit width.

Feedback Path

The error value is multiplied and accumulated to update the taps. The accumulator provides 4 bits of growth without overflow protection.

After accumulation:

  • Taps are reduced to 18 bits via a configurable tap_shift_g half-even rounding stage with saturation.

  • Complex conjugation is applied, with saturation ensuring the tap bit width is preserved.

The tap_shift_g setting determines the scaling applied to the taps. Higher values accommodate larger expected error magnitudes. A value of 12 has been shown to perform well in testing; the maximum recommended value is 21, corresponding to the maximum tap bit-growth of 39 bits.

Initial tap values are loaded through tap_data_in as tap_width_g-bit words (16 for Q1.15) and pre-shifted by tap_shift_g to preserve scaling. Tap updates begin once sample data has propagated through the pipeline.

On reset the tap storage is set to the default \([(1+0j), 0, 0, ...]\) in Q1.15 (first real tap 0x7FFF). Tap values loaded via tap_data_in after reset override this default. All-zero initial taps are avoided because they produce an all-zero output and therefore a zero error term, from which tap adaptation can never start.

Interface

Generics

  • num_taps_g (integer): Number of taps.

  • order_g (integer): Constellation order (4, 16 or 64).

  • data_width_g (integer): Data width of I and Q for internal processing.

  • tap_width_g (integer): Bit width of the input tap data.

  • step_size_g (signed): Estimator step size.

  • unit_modulus_g (signed): Target modulus R.

  • tap_shift_g (integer): Tap scaling.

  • estimator_g (string): Estimator type (CMA or MMA).

Ports

  • clk (std_logic), in: Clock. Inputs and outputs registered on rising edge.

  • reset (std_logic), in: Reset the primitive when reset is high. Clears the pipeline and sample history and restores the default tap values.

  • clear_data (std_logic), in: Clears the pipeline and sample history like reset, but preserves the adapted tap values.

  • enable (std_logic), in: Shifts data through the algorithm. Requires sample data to be valid on all enable clock cycles to prevent corruption of the error calculation.

  • tap_data_in (signed, tap_width_g bits), in: Tap data input.

  • tap_valid_in (std_logic), in: tap_data_in is valid when tap_valid_in is high, hold previous values when low.

  • tap_imag_in (std_logic), in: tap_data_in is for imaginary taps when tap_imag_in is high, and real taps when low.

  • tap_address_in (unsigned, log2(num_taps_g) bits), in: Input taps address.

  • input_data_in (std_logic_vector, data_width_g*2 bits), in: In-phase and quadrature input to the primitive.

  • input_last_in (std_logic), in: Last input sample signal.

  • output_data_out (std_logic_vector, data_width_g*2 bits), out: In-phase and quadrature output from the primitive.

  • output_valid_out (std_logic), out: In-phase and quadrature outputs are valid when output_valid_out is high.

  • output_last_out (std_logic), out: Last output sample signal.

Dependencies

The dependencies to other elements in OpenCPI are:

There is also a dependency on:

  • ieee.std_logic_1164

  • ieee.numeric_std

  • ieee.math_real

Limitations

Limitations of adaptive_equaliser are:

  • The pipeline must only advance with valid data on the input due to the algorithm’s feedback loop, so the most recent data (up to the pipeline depth) remain internal until further valid data is clocked in.

  • The tap accumulator has 4 bits of growth but no overflow protection, so a step_size_g that is too large can cause the accumulator to wrap rather than saturate, producing invalid taps.

  • Both estimators are sensitive to the choice of step_size_g: too large risks instability, too small slows convergence.

  • CMA corrects magnitude but not phase, and only supports order-4 constellations.