End-to-End VHT Simulation with Frequency Correction
This example shows how to generate, transmit, recover and view a VHT MIMO waveform.
Steps in the example:
Transmit a VHT waveform through a MIMO channel with AWGN
Perform a two-stage process to estimate and correct for a frequency offset
Estimate the channel response
Recover the VHT data field
Compare the transmitted and received PSDUs to determine if bit errors occurred
Set the parameters used throughout the example.
cbw = 'CBW160'; % Channel bandwidth fs = 160e6; % Sample rate (Hz) ntx = 2; % Number of transmit antennas nsts = 2; % Number of space-time streams nrx = 2; % Number of receive antennas
Create a VHT configuration object that supports a 2x2 MIMO transmission and has an APEP length of 2000.
vht = wlanVHTConfig('ChannelBandwidth',cbw,'APEPLength',2000, ... 'NumTransmitAntennas',ntx,'NumSpaceTimeStreams',nsts, ... 'SpatialMapping','Direct','STBC',false);
Generate a VHT waveform containing a random PSDU.
txPSDU = randi([0 1],vht.PSDULength*8,1); txPPDU = wlanWaveformGenerator(txPSDU,vht);
Create a 2x2 TGac channel and an AWGN channel.
tgacChan = wlanTGacChannel('SampleRate',fs,'ChannelBandwidth',cbw, ... 'NumTransmitAntennas',ntx,'NumReceiveAntennas',nrx, ... 'LargeScaleFadingEffect','Pathloss and shadowing', ... 'DelayProfile','Model-C'); awgnChan = comm.AWGNChannel('NoiseMethod','Variance', ... 'VarianceSource','Input port');
Create a phase/frequency offset object.
pfOffset = comm.PhaseFrequencyOffset('SampleRate',fs,'FrequencyOffsetSource','Input port');
Calculate the noise variance for a receiver with a 9 dB noise figure. Pass the transmitted waveform through the noisy TGac channel.
nVar = 10^((-228.6 + 10*log10(290) + 10*log10(fs) + 9)/10); rxPPDU = awgnChan(tgacChan(txPPDU), nVar);
Introduce a frequency offset of 500 Hz.
rxPPDUcfo = pfOffset(rxPPDU,500);
Find the start and stop indices for all component fields of the PPDU.
ind = wlanFieldIndices(vht);
Extract the L-STF. Estimate and correct for the carrier frequency offset.
rxLSTF = rxPPDUcfo(ind.LSTF(1):ind.LSTF(2),:); foffset1 = wlanCoarseCFOEstimate(rxLSTF,cbw); rxPPDUcorr = pfOffset(rxPPDUcfo,-foffset1);
Extract the L-LTF from the corrected signal. Estimate and correct for the residual frequency offset.
rxLLTF = rxPPDUcorr(ind.LLTF(1):ind.LLTF(2),:); foffset2 = wlanFineCFOEstimate(rxLLTF,cbw); rxPPDU2 = pfOffset(rxPPDUcorr,-foffset2);
Extract and demodulate the VHT-LTF. Estimate the channel coefficients.
rxVHTLTF = rxPPDU2(ind.VHTLTF(1):ind.VHTLTF(2),:); dLTF = wlanVHTLTFDemodulate(rxVHTLTF,vht); chEst = wlanVHTLTFChannelEstimate(dLTF,vht);
Extract the VHT data field from the received and frequency-corrected PPDU. Recover the data field.
rxVHTData = rxPPDU2(ind.VHTData(1):ind.VHTData(2),:); rxPSDU = wlanVHTDataRecover(rxVHTData,chEst,nVar,vht);
Calculate the number of bit errors in the received packet.
numErr = biterr(txPSDU,rxPSDU)
numErr = 0