This example shows how to a model a communication link with PSK modulation, raised cosine pulse shaping, multipath fading, and adaptive equalization.

The example sets up three equalization scenarios, and calls a separate script to execute the processing loop multiple times for each scenario. Each call corresponds to a transmission block. The pulse shaping and multipath fading channel retain state information from one block to the next. For visualizing the impact of channel fading on adaptive equalizer convergence, the simulation resets the equalizer state every block.

To experiment with different simulation settings, you can edit the example. For
instance, you can set the `ResetBeforeFiltering`

property of the
equalizer object to 0, which will cause the equalizer to retain state from one block
to the next.

Simulation 2: Linear Equalization for Frequency-Selective Fading

Simulation 3: Decision feedback Equalization (DFE) for Frequency-Selective Fading

Set parameters related to the transmission block which is composed of three parts: training sequence, payload, and tail sequence. All three use the same PSK scheme; the training and tail sequences are used for equalization. We use the default random number generator to ensure the repeatability of the results.

Rsym = 1e6; % Symbol rate (Hz) nTrain = 100; % Number of training symbols nPayload = 400; % Number of payload symbols nTail = 20; % Number of tail symbols % Set random number generator for repeatability hStream = RandStream.create('mt19937ar', 'seed', 12345);

Configure the PSK modulation and demodulation System objects™.

bitsPerSym = 2; % Number of bits per PSK symbol M = 2^bitsPerSym; % Modulation order hPSKMod = comm.PSKModulator(M, ... 'PhaseOffset',0, ... 'SymbolMapping','Binary'); hPSKDemod = comm.PSKDemodulator(M, ... 'PhaseOffset',0, ... 'SymbolMapping','Binary'); PSKConstellation = constellation(hPSKMod).'; % PSK constellation

Generate the training and tail sequences.

xTrainData = randi(hStream, [0 M-1], nTrain, 1); xTailData = randi(hStream, [0 M-1], nTail, 1); xTrain = step(hPSKMod,xTrainData); xTail = step(hPSKMod,xTailData);

Configure raised cosine transmit and receive filter System objects. The filters incorporate upsampling and downsampling, respectively.

chanFilterSpan = 8; % Filter span in symbols sampPerSymChan = 4; % Samples per symbol through channels hTxFilt = comm.RaisedCosineTransmitFilter( ... 'RolloffFactor',0.25, ... 'FilterSpanInSymbols',chanFilterSpan, ... 'OutputSamplesPerSymbol',sampPerSymChan); hRxFilt = comm.RaisedCosineReceiveFilter( ... 'RolloffFactor',0.25, ... 'FilterSpanInSymbols',chanFilterSpan, ... 'InputSamplesPerSymbol',sampPerSymChan, ... 'DecimationFactor',sampPerSymChan); % Calculate the samples per symbol after the receive filter sampPerSymPostRx = sampPerSymChan/hRxFilt.DecimationFactor; % Calculate the delay in samples from both channel filters chanFilterDelay = chanFilterSpan*sampPerSymPostRx;

Configure an AWGN channel System object with the
`NoiseMethod`

property set to ```
Signal to noise
ratio (Es/No)
```

and `Es/No`

set to
`20`

dB.

hAWGNChan = comm.AWGNChannel( ... 'NoiseMethod','Signal to noise ratio (Es/No)', ... 'EsNo',20, ... 'SamplesPerSymbol',sampPerSymChan);

Begin with single-path, frequency-flat fading channel. For this channel, the receiver uses a simple 1-tap LMS (least mean square) equalizer, which implements automatic gain and phase control.

The script `commadapteqloop.m`

runs multiple times. Each run
corresponds to a transmission block. The equalizer resets its state and weight
every transmission block. To retain state from one block to the next, you can
set the `ResetBeforeFiltering`

property of the equalizer
object to `false`

.

Before the first run, `commadapteqloop.m`

displays the
Rayleigh channel System object and the properties of the equalizer object. For
each run, a MATLAB figure shows signal processing visualizations. The red
circles in the signal constellation plots correspond to symbol errors. In the
"Weights" plot, blue and magenta lines correspond to real and imaginary parts,
respectively.

simName = 'Linear equalization for frequency-flat fading'; % Used to label figure window % Configure a frequency-flat Rayleigh channel System object with the % RandomStream property set to 'mt19937ar with seed' for repeatability. hRayleighChan = comm.RayleighChannel( ... 'SampleRate',Rsym*sampPerSymChan, ... 'MaximumDopplerShift',30); % Configure an adaptive equalizer object nWeights = 1; % Single weight stepSize = 0.1; % Step size for LMS algorithm alg = lms(stepSize); % Adaptive algorithm object eqObj = lineareq(nWeights,alg,PSKConstellation); % Equalizer object % Delay in symbols from the equalizer eqDelayInSym = (eqObj.RefTap-1)/sampPerSymPostRx; % Link simulation nBlocks = 50; % Number of transmission blocks in simulation for block = 1:nBlocks commadapteqloop; end

System: comm.RayleighChannel Properties: SampleRate: 4000000 PathDelays: 0 AveragePathGains: 0 NormalizePathGains: true MaximumDopplerShift: 30 DopplerSpectrum: [1x1 struct] RandomStream: 'mt19937ar with seed' Seed: 73 PathGainsOutputPort: false EqType: 'Linear Equalizer' AlgType: 'LMS' nWeights: 1 nSampPerSym: 1 RefTap: 1 SigConst: [1.0000 + 0.0000i 0.0000 + 1.0000i -1.0000 + 0.0000i -0.0000 - 1.0000i] StepSize: 0.1000 LeakageFactor: 1 Weights: 0 WeightInputs: 0 ResetBeforeFiltering: 1 NumSamplesProcessed: 0

Simulate a three-path, frequency-selective Rayleigh fading channel. The receiver uses an 8-tap linear RLS (recursive least squares) equalizer with symbol-spaced taps.

simName = 'Linear equalization for frequency-selective fading'; % Reset transmit and receive filters reset(hTxFilt); reset(hRxFilt); % Set the Rayleigh channel System object to be frequency-selective release(hRayleighChan); hRayleighChan.PathDelays = [0 0.9 1.5]/Rsym; hRayleighChan.AveragePathGains = [0 -3 -6]; % Configure an adaptive equalizer nWeights = 8; forgetFactor = 0.99; % RLS algorithm forgetting factor alg = rls(forgetFactor); % RLS algorithm object eqObj = lineareq(nWeights,alg,PSKConstellation); eqObj.RefTap = 3; % Reference tap eqDelayInSym = (eqObj.RefTap-1)/sampPerSymPostRx; % Link simulation and store BER values BERvect = zeros(1,nBlocks); for block = 1:nBlocks commadapteqloop; BERvect(block) = BEREq; end avgBER2 = mean(BERvect)

System: comm.RayleighChannel Properties: SampleRate: 4000000 PathDelays: [0 9e-07 1.5e-06] AveragePathGains: [0 -3 -6] NormalizePathGains: true MaximumDopplerShift: 30 DopplerSpectrum: [1x1 struct] RandomStream: 'mt19937ar with seed' Seed: 73 PathGainsOutputPort: false EqType: 'Linear Equalizer' AlgType: 'RLS' nWeights: 8 nSampPerSym: 1 RefTap: 3 SigConst: [1.0000 + 0.0000i 0.0000 + 1.0000i -1.0000 + 0.0000i -0.0000 - 1.0000i] ForgetFactor: 0.9900 InvCorrInit: 0.1000 InvCorrMatrix: [8x8 double] Weights: [0 0 0 0 0 0 0 0] WeightInputs: [0 0 0 0 0 0 0 0] ResetBeforeFiltering: 1 NumSamplesProcessed: 0 avgBER2 = 3.0000e-04

The receiver uses a DFE with a six-tap fractionally spaced forward filter (two samples per symbol) and two feedback weights. The DFE uses the same RLS algorithm as in Simulation 2. The receive filter structure is reconstructed to account for the increased number of samples per symbol.

simName = 'Decision feedback equalization (DFE) for frequency-selective fading'; % Reset transmit filter and adjust receive filter decimation factor reset(hTxFilt); release(hRxFilt); hRxFilt.DecimationFactor = 2; sampPerSymPostRx = sampPerSymChan/hRxFilt.DecimationFactor; chanFilterDelay = chanFilterSpan*sampPerSymPostRx; % Reset fading channel reset(hRayleighChan); % Configure an adaptive equalizer object nFwdWeights = 6; % Number of feedforward equalizer weights nFbkWeights = 2; % Number of feedback filter weights eqObj = dfe(nFwdWeights, nFbkWeights,alg,PSKConstellation,sampPerSymPostRx); eqObj.RefTap = 3; eqDelayInSym = (eqObj.RefTap-1)/sampPerSymPostRx; for block = 1:nBlocks commadapteqloop; BERvect(block) = BEREq; end avgBER3 = mean(BERvect)

System: comm.RayleighChannel Properties: SampleRate: 4000000 PathDelays: [0 9e-07 1.5e-06] AveragePathGains: [0 -3 -6] NormalizePathGains: true MaximumDopplerShift: 30 DopplerSpectrum: [1x1 struct] RandomStream: 'mt19937ar with seed' Seed: 73 PathGainsOutputPort: false EqType: 'Decision Feedback Equalizer' AlgType: 'RLS' nWeights: [6 2] nSampPerSym: 2 RefTap: 3 SigConst: [1.0000 + 0.0000i 0.0000 + 1.0000i -1.0000 + 0.0000i -0.0000 - 1.0000i] ForgetFactor: 0.9900 InvCorrInit: 0.1000 InvCorrMatrix: [8x8 double] Weights: [0 0 0 0 0 0 0 0] WeightInputs: [0 0 0 0 0 0 0 0] ResetBeforeFiltering: 1 NumSamplesProcessed: 0 avgBER3 = 0

This example showed the relative performance of linear and decision feedback equalizers in both frequency-flat and frequency-selective fading channels. It showed how a one-tap equalizer is sufficient to compensate for a frequency-flat channel, but that a frequency-selective channel requires an equalizer with multiple taps. Finally, it showed that a decision feedback equalizer is superior to a linear equalizer in a frequency-selective channel.

This example uses the following script and helper functions: