Main Content

Synchronize and Demodulate Oversampled Waveform

This example shows how to synchronize, demodulate an oversampled IEEE® 802.11be™ (Wi-Fi™ 7) waveform consisting of extremely high-throughput (EHT) format packets. Processing the oversampled waveform at the receiver front end avoids the complication of designing a downsampling filter. In this example you:

  1. Generate an oversampled EHT waveform for a sequence of bits.

  2. Pass the waveform through a TGax fading channel.

  3. Synchronize and demodulate the waveform using front-end processing functions.

  4. Recover bits from the EHT-Data field and compare them to the bits you transmitted.

Packet Configuration

Use the EHT format configuration object, wlanEHTMUConfig, to configure the transmission properties of an EHT packet. This example configures an EHT waveform for a 320 MHz channel bandwidth.

chanBW = "CBW320";
cfg = wlanEHTMUConfig(chanBW);
cfg.GuardInterval = 0.8; %Guard interval in microseconds
cfg.User{1}.APEPLength = 10000; %APEP length in bytes
cfg.User{1}.MCS = 7;

Waveform Generation

Specify an oversampling factor of two.

osf = 2;

Specify seed 0 for the random number generator. Get the PSDU length of the configuration in bytes.

rng(0);
psdu = psduLength(cfg);

Generate a random sequence of data bits for the configuration. Use these bits with the wlanWaveformGenerator function to generate an oversampled time-domain waveform for the configuration.

data = randi([0 1],psdu*8,1); % Multiply by 8 to convert from bytes to bits
txWaveform = wlanWaveformGenerator(data,cfg,OversamplingFactor=osf);

Obtain and display the baseband sampling rate of the waveform. It is twice the channel bandwidth because the oversampling factor is two.

sr = wlanSampleRate(cfg,OversamplingFactor=osf); 
disp(sr) %Sample rate in Hz
   640000000

Channel and Noise

Create a wlanTGaxChannel System object™, specifying its sample rate as the baseband sampling rate.

chan = wlanTGaxChannel;
chan.DelayProfile = "Model-A";
chan.NumTransmitAntennas = cfg.NumTransmitAntennas;
chan.NumReceiveAntennas = cfg.NumTransmitAntennas;
chan.ChannelBandwidth = chanBW;
chan.SampleRate = sr;
chan.RandomStream = "mt19937ar with seed";

Append zeros at the start and end of the waveform to compensate for the delay that the channel filter introduces.

txWaveform = [zeros(50,1);txWaveform;zeros(100,1)];

Pass the waveform through the channel and add AWGN with a signal-to-noise ratio of 40 dB.

chanOut = chan(txWaveform);
snrVal = 40; 
rxWaveform = awgn(chanOut,snrVal,0);

Front-End Processing

Get field indices for the configuration and the packet offset of the waveform, specifying the oversampling factor.

ind = wlanFieldIndices(cfg,OversamplingFactor=osf);
pktOffset = wlanPacketDetect(rxWaveform,chanBW,OversamplingFactor=osf);

Extract the length of the waveform. Check that:

  • The output of the wlanPacketDetect function is nonempty.

  • The gap between the start of the preamble and the end of the L-SIG field is smaller than the size of the whole waveform.

If either of these conditions are false, the wlanPacketDetect function has not successfully detected a packet.

rxWaveLen = size(rxWaveform,1);
% Adjust packet offset
if isempty(pktOffset) || (pktOffset + ind.LSIG(2) > rxWaveLen)
    error("** No packet detected **");
end

Extract the part of the waveform that corresponds to the legacy short training field (L-STF). Use the L-STF to perform coarse frequency offset estimation. Use the estimate with the frequencyOffset function to correct the offset.

rxLSTF = rxWaveform(pktOffset+(ind.LSTF(1):ind.LSTF(2)), :);
coarseFreqOffset = wlanCoarseCFOEstimate(rxLSTF,chanBW,OversamplingFactor=osf);
rxWaveform = frequencyOffset(rxWaveform,sr,-coarseFreqOffset);

Extract the part of the waveform that corresponds to the L-STF, legacy long training field (L-LTF), and legacy signaling (L-SIG) field. Use the wlanSymbolTimingEstimate function to get the timing offset of the packet. Combine the timing offset with the packet offset.

searchBufferLLTF = rxWaveform(pktOffset+(ind.LSTF(1):ind.LSIG(2)),:);
timeOffset = wlanSymbolTimingEstimate(searchBufferLLTF,chanBW,OversamplingFactor=osf);
pktOffset = pktOffset + timeOffset;

Extract the part of the waveform that corresponds to the L-LTF. Use the L-LTF to perform fine frequency offset estimation. Use the estimate with the frequencyOffset function to correct the offset.

rxLLTF = rxWaveform(pktOffset+(ind.LLTF(1):ind.LLTF(2)),:);
fineFreqOffset = wlanFineCFOEstimate(rxLLTF,chanBW,OversamplingFactor=osf);
rxWaveform = frequencyOffset(rxWaveform,sr,-fineFreqOffset);

Extract the part of the waveform that corresponds to the extremely high-throughput long training field (EHT-LTF). Demodulate the EHT-LTF and use its symbols to estimate the channel.

rxEHTLTF = rxWaveform(pktOffset+(ind.EHTLTF(1):ind.EHTLTF(2)),:);
ehtltfDemod = wlanEHTDemodulate(rxEHTLTF,"EHT-LTF",cfg,OversamplingFactor=osf);
[chanEst,pilotEst] = wlanEHTLTFChannelEstimate(ehtltfDemod,cfg);

Extract the part of the waveform that corresponds to the EHT-Data field. Demodulate the EHT-Data field and perform pilot phase error correction. After demodulation, the waveform is at the nominal baseband sampling rate.

rxData = rxWaveform(pktOffset+(ind.EHTData(1):ind.EHTData(2)),:);
demodSym = wlanEHTDemodulate(rxData,"EHT-Data",cfg,OversamplingFactor=osf);
demodSym = wlanEHTTrackPilotError(demodSym,chanEst,cfg,"EHT-Data");

Get OFDM information for the EHT-Data field. Estimate noise at the pilot symbols.

ofdmInfo = wlanEHTOFDMInfo("EHT-Data",cfg);
nVarEst = wlanEHTDataNoiseEstimate(demodSym(ofdmInfo.PilotIndices,:,:),pilotEst,cfg);

Extract the demodulated data symbols and the channel estimate at them.

demodDataSym = demodSym(ofdmInfo.DataIndices,:,:);
chanEstData = chanEst(ofdmInfo.DataIndices,:,:);

Equalize the data symbols and recover the data bits. Check that the received bits are equal to the transmitted bits.

eqSym = wlanEHTEqualize(demodDataSym,chanEstData,nVarEst,cfg,"EHT-Data"); 
rxData = wlanEHTDataBitRecover(eqSym,nVarEst,cfg);
isequal(data,rxData)
ans = logical
   1

See Also

| | |