Main Content

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.

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)

Figure OFDM Subcarrier Mapping for Tx Antenna 1 contains an axes object. The axes object with title OFDM Subcarrier Mapping for Tx Antenna 1 contains 5 objects of type image, line.

Figure OFDM Subcarrier Mapping for Tx Antenna 2 contains an axes object. The axes object with title OFDM Subcarrier Mapping for Tx Antenna 2 contains 5 objects of type image, line.

Figure OFDM Subcarrier Mapping for Tx Antenna 3 contains an axes object. The axes object with title OFDM Subcarrier Mapping for Tx Antenna 3 contains 5 objects of type image, line.

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)

Figure OFDM Subcarrier Mapping for Tx Antenna 1 contains an axes object. The axes object with title OFDM Subcarrier Mapping for Tx Antenna 1 contains an object of type image.

Figure OFDM Subcarrier Mapping for Tx Antenna 2 contains an axes object. The axes object with title OFDM Subcarrier Mapping for Tx Antenna 2 contains an object of type image.

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.

See Also

Functions

Objects

Blocks

Related Topics