## Orthogonal Frequency Division Multiplexing Modulation

Orthogonal frequency division multiplexing (OFDM) modulation is a linear baseband modulation technique of encoding digital data on multiple carrier frequencies. The transmitter uses an inverse fast Fourier transform (IFFT) to combine (modulate) multiple closely spaced orthogonal subcarrier signals with overlapping spectra to carry data in parallel. The receiver uses an FFT to demodulate the signal.

Communications Toolbox™ software includes these modulation and demodulation functions, System objects, and blocks to model OFDM modulation.

FunctionsSystem objectsBlocks

### OFDM

As described in Proakis ([2]), in an OFDM system with N subchannels, the symbol rate 1/T is reduced by a factor of N relative to the symbol rate on a single-carrier system that employs the entire bandwidth W and transmits data at the same rate as OFDM. Hence, the symbol interval in the OFDM system is T = NTs , where Ts is the symbol interval in the single-carrier system. By selecting N to be sufficiently large, the symbol interval T can be made significantly larger than the time duration of the channel-time dispersion. Thus, intersymbol interference can be made arbitrarily small through the selection of N. In other words, each subchannel appears to have a fixed frequency response C(fk), k = 0, 1, . . . , N - 1.

### OFDM Modulation Examples

These examples demonstrate OFDM modulation techniques.

#### Apply OFDM with User-Specified Pilot Indices

Construct an orthogonal frequency division multiplexing (OFDM) modulator and demodulator pair and specify their pilot indices. The OFDM modulator System object™ enables you to specify pilot subcarrier indices consistent with the constraints described by the `info` object function. In this example, for OFDM transmission over a 3x2 channel, pilot indices are created for each of the three transmit antennas. Additionally, the pilot indices differ between odd and even symbols.

Create an OFDM modulator object having five symbols, three transmit antennas, and length six windowing.

```ofdmMod = comm.OFDMModulator( ... FFTLength=256, ... NumGuardBandCarriers=[12; 11], ... NumSymbols=5, ... NumTransmitAntennas=3, ... PilotInputPort=true, ... Windowing=true, ... WindowLength=6);```

Specify pilot indices for even and odd symbols for the first transmit antenna.

```pilotIndOdd = [20; 58; 96; 145; 182; 210]; pilotIndEven = [35; 73; 111; 159; 197; 225]; pilotIndicesAnt1 = cat(2,pilotIndOdd,pilotIndEven,pilotIndOdd, ... pilotIndEven,pilotIndOdd);```

Generate pilot indices for the second and third antennas based on the indices specified for the first antenna. Concatenate the indices for the three antennas and assign them to the `PilotCarrierIndices` property.

```pilotIndicesAnt2 = pilotIndicesAnt1 + 5; pilotIndicesAnt3 = pilotIndicesAnt1 - 5; ofdmMod.PilotCarrierIndices = ... cat(3,pilotIndicesAnt1,pilotIndicesAnt2,pilotIndicesAnt3);```

Create an OFDM demodulator with two receive antennas based on the existing OFDM modulator System object. Determine the data and pilot dimensions using the `info` function.

```ofdmDemod = comm.OFDMDemodulator(ofdmMod); ofdmDemod.NumReceiveAntennas = 2; dims = info(ofdmMod)```
```dims = struct with fields: DataInputSize: [215 5 3] PilotInputSize: [6 5 3] OutputSize: [1360 3] ```

Generate data and pilot symbols for the OFDM modulator given the array sizes specified in `modDim`.

```dataIn = ... complex(randn(dims.DataInputSize), ... randn(dims.DataInputSize)); pilotIn = ... complex(randn(dims.PilotInputSize), ... randn(dims.PilotInputSize));```

Apply OFDM modulation to the data and pilots.

`modOut = ofdmMod(dataIn,pilotIn);`

Pass the modulated data through a 3x2 random channel.

```chanGain = complex(randn(3,2),randn(3,2)); chanOut = modOut * chanGain;```

Demodulate the received data using the OFDM demodulator object.

`[dataOut,pilotOut] = ofdmDemod(chanOut);`

Show the resource mapping for the three transmit antennas. The gray lines in the figure show the placement of custom nulls to avoid interference among antennas.

`showResourceMapping(ofdmMod)`

For the first transmit and first receive antenna pair, demonstrate that the input pilot signal matches the input pilot signal.

```pilotCompare = ... abs(pilotIn(:,:,1)*chanGain(1,1)) - abs(pilotOut(:,:,1,1)); max(pilotCompare(:) < 1e-10)```
```ans = logical 1 ```

#### Apply OFDM to QPSK Signal Spatially Multiplexed over Two Antennas

Apply OFDM modulation to a QPSK signal that is spatially multiplexed over two transmit antennas.

Initialize input parameters and generate random data for each antenna.

```M = 4; % Modulation order for QPSK nfft = 64; cplen = 16; nSym = 5; nt = 2; nullIdx = [1:6 33 64-4:64]'; pilotIdx = [12 26 40 54]'; numDataCarrs = nfft-length(nullIdx)-length(pilotIdx); pilots = repmat(pskmod((0:M-1).',M),1,nSym,2); ant1 = randi([0 M-1],numDataCarrs,nSym); ant2 = randi([0 M-1],numDataCarrs,nSym);```

QPSK modulate data individually for each antenna. Perform OFDM modulation.

```qpskSig(:,:,1) = pskmod(ant1,M); qpskSig(:,:,2) = pskmod(ant2,M); y1 = ofdmmod(qpskSig,nfft,cplen,nullIdx,pilotIdx,pilots);```

#### Apply OFDM in MIMO Simulation

Use an OFDM modulator and demodulator in a simple, 2x2 MIMO error rate simulation. The OFDM parameters are based on the 802.11n standard.

Create an OFDM modulator and demodulator pair with user-specified pilot indices, an inserted DC null, two transmit antennas, and two receive antennas. Specify pilot indices that vary across antennas.

```ofdmMod = comm.OFDMModulator(FFTLength=128, ... PilotInputPort=true, ... PilotCarrierIndices= ... cat(3,[12; 40; 54; 76; 90; 118],[13; 39; 55; 75; 91; 117]), ... InsertDCNull=true, ... NumTransmitAntennas=2); ofdmDemod = comm.OFDMDemodulator(ofdmMod); ofdmDemod.NumReceiveAntennas = 2;```

Show the resource mapping of pilot subcarriers for each transmit antenna. The gray lines in the figure denote the insertion of null subcarriers to minimize pilot signal interference.

`showResourceMapping(ofdmMod)`

Determine the dimensions of the OFDM modulator by using the `info` method.

```ofdmModDim = info(ofdmMod); numData = ofdmModDim.DataInputSize(1); % Number of data subcarriers numSym = ofdmModDim.DataInputSize(2); % Number of OFDM symbols numTxAnt = ofdmModDim.DataInputSize(3); % Number of transmit antennas```

Generate data symbols to fill 100 OFDM frames.

```nframes = 100; M = 4; % Modulation order to QPSK data = randi([0 M-1],nframes*numData,numSym,numTxAnt);```

Apply QPSK modulation to the random symbols and reshape the resulting column vector to match the OFDM modulator requirements.

```modData = pskmod(data(:),M,pi/4); modData = reshape(modData,nframes*numData,numSym,numTxAnt);```

Create an error rate counter.

`errorRate = comm.ErrorRate;`

Simulate the OFDM system over 100 frames assuming a flat, 2x2, Rayleigh fading channel. Remove the effects of multipath fading using a simple, least squares solution, and demodulate the OFDM waveform and QPSK data. Generate error statistics by comparing the original data with the demodulated data.

```for k = 1:nframes % Find row indices for kth OFDM frame indData = (k-1)*ofdmModDim.DataInputSize(1)+1:k*numData; % Generate random OFDM pilot symbols pilotData = complex(rand(ofdmModDim.PilotInputSize), ... rand(ofdmModDim.PilotInputSize)); % Modulate QPSK symbols using OFDM dataOFDM = ofdmMod(modData(indData,:,:),pilotData); % Create flat, i.i.d., Rayleigh fading channel 2-by-2 channel chGain = complex(randn(2,2),randn(2,2))/sqrt(2); % Pass OFDM signal through Rayleigh and AWGN channels receivedSignal = awgn(dataOFDM*chGain,30); % Apply least squares solution to remove effects of fading channel rxSigMF = chGain.' \ receivedSignal.'; % Demodulate OFDM data receivedOFDMData = ofdmDemod(rxSigMF.'); % Demodulate QPSK data receivedData = pskdemod(receivedOFDMData(:),M,pi/4); % Compute error statistics dataTmp = data(indData,:,:); errors = errorRate(dataTmp(:),receivedData); end```

Display the error statistics.

`fprintf('\nSymbol error rate = %d from %d errors in %d symbols\n',errors)`
```Symbol error rate = 9.471154e-02 from 1970 errors in 20800 symbols ```

## References

[1] IEEE Standard 802.16-2017. "Part 16: Air Interface for Broadband Wireless Access Systems." March 2018.

[2] Proakis, John G. Digital Communications. 5th ed. New York: McGraw Hill, 2007.