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:
Figure 458: Block diagram depicting the bit widths around each operation for the CMA configuration.
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_gby 4 internally when using the MMA estimator, so thatstep_size_ghas the same meaning for both estimators. The 2 least significant bits ofstep_size_gare therefore ignored when using MMA.Overflow is prevented by saturating values after complex conjugation when required.
The
step_size_gparameter 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_ghalf-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 whenresetis high. Clears the pipeline and sample history and restores the default tap values.
clear_data(std_logic), in: Clears the pipeline and sample history likereset, 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_gbits), in: Tap data input.
tap_valid_in(std_logic), in:tap_data_inis valid whentap_valid_inis high, hold previous values when low.
tap_imag_in(std_logic), in:tap_data_inis for imaginary taps whentap_imag_inis 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*2bits), 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*2bits), out: In-phase and quadrature output from the primitive.
output_valid_out(std_logic), out: In-phase and quadrature outputs are valid whenoutput_valid_outis 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_gthat 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.