Modulate signal using OFDM method
The OFDMModulator
object modulates a signal using the
orthogonal frequency division modulation method. The output is a baseband representation of
the modulated signal.
To modulate a signal using OFDM:
Create the comm.OFDMModulator
object and set its properties.
Call the object with arguments, as if it were a function.
To learn more about how System objects work, see What Are System Objects? (MATLAB).
creates an OFDM
modulator System
object™.ofdmmod
= comm.OFDMModulator
specifies Properties using one of more
name-value pair arguments. Enclose each property name in quotes. For example,
ofdmmod
= comm.OFDMModulator(Name
,Value
)comm.OFDMModulator('NumSymbols',8)
specifies eight OFDM symbols in
the time-frequency grid.
.
sets the OFDM modulator system object properties based on the specified OFDM demodulator
system object ofdmmod
= comm.OFDMModulator(ofdmdemod
)comm.OFDMDemodulator
.
Unless otherwise indicated, properties are nontunable, which means you cannot change their
values after calling the object. Objects lock when you call them, and the
release
function unlocks them.
If a property is tunable, you can change its value at any time.
For more information on changing property values, see System Design in MATLAB Using System Objects (MATLAB).
FFTLength
— Number of FFT points64
(default) | positive integerNumber of Fast Fourier Transform (FFT) points, specified as a positive integer. The length of the FFT, NFFT, must be greater than or equal to 8 and is equivalent to the number of subcarriers.
Data Types: double
NumGuardBandCarriers
— Number of subcarriers to the left and right guard bands[6;5]
(default) | two-element column vector of integersNumber of subcarriers allocated to the left and right guard bands, specified as a two-element column vector of integers. The number of subcarriers must fall within [0, ⌊NFFT/2⌋ − 1]. This vector has the form [NleftG, NrightG], where NleftG and NrightG specify the left and right guard bands, respectively.
Data Types: double
InsertDCNull
— Option to insert DC nullfalse
or 0
(default) | true
or 1
Option to insert DC null, specified as a numeric or logical 0
(false
) or 1
(true
). The DC
subcarrier is the center of the frequency band and has the index value:
(FFTLength
/ 2) + 1 when FFTLength
is even
(FFTLength
+ 1) / 2 when FFTLength
is odd
PilotInputPort
— Option to specify pilot inputfalse
or 0
(default) | true
or 1
Option to specify pilot input, specified as a numeric or logical
0
(false
) or 1
(true
). If this property is 1
(true
), you can assign individual subcarriers for pilot
transmission. If this property is 0
(false
), pilot
information is assumed to be embedded in the input data.
PilotCarrierIndices
— Pilot subcarrier indices[12; 26; 40; 54]
(default) | column vectorPilot subcarrier indices, specified as a column vector. If the PilotCarrierIndices property is set to 1
(true
), you can specify the indices of the pilot subcarriers. You
can assign the indices to the same or different subcarriers for each symbol. Similarly,
the pilot carrier indices can differ across multiple transmit antennas. Depending on the
desired level of control for index assignments, the dimensions of the property vary.
Valid pilot indices fall in the range
where the index value cannot exceed the number of subcarriers. When the pilot indices are the same for every symbol and transmit antenna, the property has dimensions Npilot-by-1. When the pilot indices vary across symbols, the property has dimensions Npilot-by-Nsym. If you transmit only one symbol but multiple transmit antennas, the property has dimensions Npilot-by-1-by-Nt., where Nt. is the number of transmit antennas. If the indices vary across the number of symbols and transmit antennas, the property has dimensions Npilot-by-Nsym-by-Nt. If the number of transmit antennas is greater than one, ensure that the indices per symbol must be mutually distinct across antennas to minimize interference.
To enable this property, set the PilotInputPort
property to
1
(true
).
CyclicPrefixLength
— Length of cyclic prefix16
(default) | positive integer | row vectorLength of cyclic prefix, specified as a positive integer. If you specify a scalar, the prefix length is the same for all symbols through all antennas. If you specify a row vector of length Nsym, the prefix length can vary across symbols but remains the same through all antennas.
Data Types: double
Windowing
— Option to apply raised cosine window between OFDM symbolsfalse
or 0
(default) | true
or 1
Option to apply raised cosine window between OFDM symbols, specified as
true
or false
. Windowing is the process in which
the OFDM symbol is multiplied by a raised cosine window before transmission to more
quickly reduce the power of out-of-band subcarriers. Windowing reduces spectral
regrowth.
WindowLength
— Length of raised cosine window1
(default) | positive scalarLength of raised cosine window, specified as a positive scalar. This value must be less than or equal to the minimum cyclic prefix length. For example, in a configuration of four symbols with cyclic prefix lengths 12, 14, 16, and 18, the window length must be less than or equal to 12.
To enable this property, set the Windowing
property to
1
(true
).
NumSymbols
— Number of OFDM symbols1
(default) | positive integerNumber of OFDM symbols in the time-frequency grid, specified as a positive integer.
NumTransmitAntennnas
— Number of transmit antennas1
(default) | positive integerNumber of transmit antennas, used to transmit the OFDM modulated signal, specified positive integer.
assigns the pilot signal, waveform
= ofdmmod(data
,pilot
)pilot
, into the frequency subcarriers
specified by the PilotCarrierIndices property value of the ofdmmod
system
object. To enable this syntax set the PilotCarrierIndices property to true
.
insignal
— Input baseband signalInput baseband signal, specified as a matrix or 3-D array of numeric values. The input baseband signal must be of size Nf-by-Nsym-by-Nt. where Nf is the number of frequency subcarriers excluding guard bands and DC null.
Data Types: double
Complex Number Support: Yes
data
— Input dataInput data, specified as a matrix or 3-D array. The input must be a numeric of size Nd-by-Nsym-by-Nt. where Nd is the number of data subcarriers in each symbol. For more information on how Nd is calculated, see the to PilotCarrierIndices property.
Data Types: double
Complex Number Support: Yes
pilot
— Pilot signalPilot signal, specified as a 3-D array of numeric values. The pilot signal must be of size Npilot-by-1-by-Nt.
Data Types: double
Complex Number Support: Yes
waveform
— OFDM Modulated baseband signalOFDM Modulated baseband signal, returned as a 3-D array of the same size as the
input signal. If the CyclicPrefixLength
property is a scalar, the
output waveform
is of size ((NFFT+CPlen)⁎Nsym)-by-Nt. Otherwise, the size is (NFFT⁎Nsym+∑(CPlen))-by-Nt.
Data Types: double
Complex Number Support: Yes
To use an object function, specify the
System
object as the first input argument. For
example, to release system resources of a System
object named obj
, use
this syntax:
release(obj)
comm.OFDMModulator
info | Provide dimensioning information for OFDM modulator |
showResourceMapping | Show the subcarrier mapping of the OFDM symbols created by the OFDM modulator System object |
An OFDM modulator System object™ can be constructed using default properties. Once constructed, these properties can be modified.
Construct an OFDM modulator.
ofdmMod = comm.OFDMModulator;
Display the properties of the modulator.
disp(ofdmMod)
comm.OFDMModulator with properties: FFTLength: 64 NumGuardBandCarriers: [2x1 double] InsertDCNull: false PilotInputPort: false CyclicPrefixLength: 16 Windowing: false NumSymbols: 1 NumTransmitAntennas: 1
Modify the number of subcarriers and symbols.
ofdmMod.FFTLength = 128; ofdmMod.NumSymbols = 2;
Verify that the number of subcarriers and the number of symbols changed.
disp(ofdmMod)
comm.OFDMModulator with properties: FFTLength: 128 NumGuardBandCarriers: [2x1 double] InsertDCNull: false PilotInputPort: false CyclicPrefixLength: 16 Windowing: false NumSymbols: 2 NumTransmitAntennas: 1
The showResourceMapping
method shows the mapping of data, pilot, and null subcarriers in the time-frequency space. Apply the showResourceMapping
method.
showResourceMapping(ofdmMod)
An OFDM modulator System object™ can be constructed from an existing OFDM demodulator System object.
Construct an OFDM demodulator, ofdmDemod
and specify pilot indices for a single symbol and two transmit antennas.
Note: You can set the PilotCarrierIndices
property in the demodulator object, which then changes the number of transmit antennas in the modulator object. The number of receive antennas in the demodulator is uncorrelated with the number of transmit antennas.
ofdmDemod = comm.OFDMDemodulator;
ofdmDemod.PilotOutputPort = true;
ofdmDemod.PilotCarrierIndices = cat(3,[12; 26; 40; 54],...
[13; 27; 41; 55]);
Use the demodulator, ofdmDemod
, to construct the OFDM modulator.
ofdmMod = comm.OFDMModulator(ofdmDemod);
Display the properties of the modulator and verify that they match those of the demodulator.
disp(ofdmMod)
comm.OFDMModulator with properties: FFTLength: 64 NumGuardBandCarriers: [2x1 double] InsertDCNull: false PilotInputPort: true PilotCarrierIndices: [4x1x2 double] CyclicPrefixLength: 16 Windowing: false NumSymbols: 1 NumTransmitAntennas: 2
disp(ofdmDemod)
comm.OFDMDemodulator with properties: FFTLength: 64 NumGuardBandCarriers: [2x1 double] RemoveDCCarrier: false PilotOutputPort: true PilotCarrierIndices: [4x1x2 double] CyclicPrefixLength: 16 NumSymbols: 1 NumReceiveAntennas: 1
The showResourceMapping
method displays the time-frequency resource mapping for each transmit antenna.
Construct an OFDM modulator.
mod = comm.OFDMModulator;
Apply the showResourceMapping
method.
showResourceMapping(mod)
Insert a DC null.
mod.InsertDCNull = true;
Show the resource mapping after adding the DC null.
showResourceMapping(mod)
The OFDM modulator enables you to specify the subcarrier indices for the pilot signals. The indices can be specified for each symbol and transmit antenna. When there is more than one transmit antenna, ensure that the pilot indices for each symbol differ between antennas.
Construct an OFDM modulator that has two symbols and insert a DC null.
mod = comm.OFDMModulator('FFTLength',128,'NumSymbols',2,... 'InsertDCNull',true);
Turn on the pilot input port so you can specify the pilot indices.
mod.PilotInputPort = true;
Specify the same pilot indices for both symbols.
mod.PilotCarrierIndices = [12; 56; 89; 100];
Visualize the placement of the pilot signals and nulls in the OFDM time-frequency grid using the showResourceMapping
method.
showResourceMapping(mod)
Concatenate a second column of pilot indices to the PilotCarrierIndices
property to specify different indices for the second symbol.
mod.PilotCarrierIndices = cat(2, mod.PilotCarrierIndices, ...
[17; 61; 94; 105]);
Verify that the pilot subcarrier indices differ between symbols.
showResourceMapping(mod)
Increase the number of transmit antennas to two.
mod.NumTransmitAntennas = 2;
Specify the pilot indices for each of the two transmit antennas. To provide indices for multiple antennas while minimizing interference among the antennas, populate the PilotCarrierIndices
property as a 3-D array such that the indices for each symbol differ among antennas.
mod.PilotCarrierIndices = cat(3,[20; 50; 70; 110], ...
[15; 60; 75; 105]);
Display the resource mapping for the two transmit antennas. The gray lines denote the insertion of custom nulls. The nulls are created by the object to minimize interference among the pilot symbols from different antennas.
showResourceMapping(mod)
Specify the length of the cyclic prefix for each OFDM symbol.
Construct an OFDM modulator having five symbols, four left guard-band subcarriers, and three right guard-band subcarriers. Specify the cyclic prefix length for each OFDM symbol.
mod = comm.OFDMModulator('NumGuardBandCarriers',[4;3],... 'NumSymbols',5,... 'CyclicPrefixLength',[12 10 14 11 13]);
Display the properties of the modulator and verify that the cyclic prefix length changes across symbols.
disp(mod)
comm.OFDMModulator with properties: FFTLength: 64 NumGuardBandCarriers: [2x1 double] InsertDCNull: false PilotInputPort: false CyclicPrefixLength: [12 10 14 11 13] Windowing: false NumSymbols: 5 NumTransmitAntennas: 1
Determine the OFDM modulator data dimensions by using the info
method.
Construct an OFDM modulator System object™ with user-specified pilot indices, insert a DC null, and specify two transmit antennas.
hMod = comm.OFDMModulator('NumGuardBandCarriers',[4;3], ... 'PilotInputPort',true, ... 'PilotCarrierIndices',cat(3,[12; 26; 40; 54], ... [11; 25; 39; 53]), ... 'InsertDCNull',true, ... 'NumTransmitAntennas',2);
Use the info
method to find the modulator input data, pilot input data, and output data sizes.
info(hMod)
ans = struct with fields:
DataInputSize: [48 1 2]
PilotInputSize: [4 1 2]
OutputSize: [80 2]
Generate OFDM modulated symbols for use in link-level simulations.
Construct an OFDM modulator with an inserted DC null, seven guard-band subcarriers, and two symbols having different pilot indices for each symbol.
mod = comm.OFDMModulator('NumGuardBandCarriers',[4;3],... 'PilotInputPort',true, ... 'PilotCarrierIndices',[12 11; 26 27; 40 39; 54 55], ... 'NumSymbols',2, ... 'InsertDCNull',true);
Determine input data, pilot, and output data dimensions.
modDim = info(mod);
Generate random data symbols for the OFDM modulator. The structure variable, modDim
, determines the number of data symbols.
dataIn = complex(randn(modDim.DataInputSize),randn(modDim.DataInputSize));
Create a pilot signal that has the correct dimensions.
pilotIn = complex(rand(modDim.PilotInputSize),rand(modDim.PilotInputSize));
Apply OFDM modulation to the data and pilot signals.
modData = step(mod,dataIn,pilotIn);
Use the OFDM modulator object to create the corresponding OFDM demodulator.
demod = comm.OFDMDemodulator(mod);
Demodulate the OFDM signal and output the data and pilot signals.
[dataOut, pilotOut] = step(demod,modData);
Verify that, within a tight tolerance, the input data and pilot symbols match the output data and pilot symbols.
isSame = (max(abs([dataIn(:) - dataOut(:); ...
pilotIn(:) - pilotOut(:)])) < 1e-10)
isSame = logical
1
Orthogonal frequency division modulation (OFDM) divides a high-rate transmit data stream into N lower-rate streams, each of which has a symbol duration larger than the channel delay spread and, therefore, mitigates intersymbol interference (ISI). The individual substreams are sent over N parallel subchannels which are orthogonal to each other. Through the use of an inverse fast Fourier transform (IFFT), OFDM can be transmitted using a single radio. The output is a baseband representation of the modulated signal:
where {Xk} are data symbols, N is the number of subcarriers, and T is the OFDM symbol time. The subcarrier spacing of Δf = 1/T makes the symbols orthogonal over each symbol period. This orthogonality is expressed as:
The data symbols, Xk, are usually complex and can be from any modulation alphabet such as QPSK, 16-QAM, or 64-QAM.
This figure shows an OFDM modulator consisting of a bank of N complex modulators, where each modulator corresponds to one OFDM subcarrier.
OFDM has three types of subcarriers: data, pilot, and null. Data subcarriers are used for transmitting data, and pilot subcarriers are used for channel estimation. Null subcarriers, which provide a DC null and provide buffers between OFDM resource blocks, are not transmitted. These buffers are referred to as guard bands whose purpose is to prevent intersymbol interference. The allocation of nulls and guard bands vary depending on the applicable standard such as 802.11n differs from LTE.
Analogous to the concept of guard bands, the OFDM also supports guard intervals, which to provide temporal separation between OFDM symbols so that the signal does not lose orthogonality due to time-dispersive channels. As long as the guard interval is longer than the delay spread, symbols do not interfere with other symbols. Guard intervals are created by using cyclic prefixes in which the last part of an OFDM symbol is copied and inserted as the first part of the OFDM symbol. The benefit of cyclic prefix insertion is maintained as long as the span of the time dispersion does not exceed the duration of the cyclic prefix. Using a cyclic prefix increases overhead.
While the cyclic prefix creates a guard period in time domain to preserve orthogonality, an OFDM symbol rarely begins with the same amplitude and phase exhibited at the end of the prior OFDM symbol causing spectral regrowth and therefore, spreading of signal bandwidth due to intermodulation distortion. To limit this spectral regrowth, it is desired to create a smooth transition between the last sample of a symbol and the first sample of the next symbol. This can be done by using a cyclic suffix and raised cosine windowing.
To create the cyclic suffix, the first NWIN samples of a given symbol are appended to the end of that symbol. However, in order to comply with the 802.11g standard, for example, the length of a symbol cannot be arbitrarily lengthened. Instead, the cyclic suffix must overlap in time and is effectively summed with the cyclic prefix of the following symbol. This overlapped segment is where windowing is applied. Two windows are applied, one of which is the mathematical inverse of the other. The first raised cosine window is applied to the cyclic suffix of symbol k and decreases from 1 to 0 over its duration. The second raised cosine window is applied to the cyclic prefix of symbol k+1 and increases from 0 to 1 over its duration. This process provides a smooth transition from one symbol to the next.
The raised cosine window, w(t), in the time domain can be expressed as:
where:
T is the OFDM symbol duration including the guard interval.
TW is the duration of the window.
Adjust the length of the cyclic suffix via the window length setting property, with suffix lengths set between 1 and the minimum cyclic prefix length. While windowing improves spectral regrowth, it does so at the expense of multipath fading immunity. This occurs because redundancy in the guard band is reduced because the guard band sample values are compromised by the smoothing.
The following figures display the application of raised cosine windowing.
[1] Dahlman, Erik, Stefan Parkvall, and Johan Sköld. 4G LTE/LTE-Advanced for Mobile Broadband. Amsterdam: Elsevier, Acad. Press, 2011.
[2] Andrews, J. G., A. Ghosh, and R. Muhamed. Fundamentals of WiMAX. Upper Saddle River, NJ: Prentice Hall, 2007.
[3] Agilent Technologies, Inc., “OFDM Raised Cosine Windowing”, http://wireless.agilent.com/rfcomms/n4010a/n4010aWLAN/onlineguide/ofdm_raised_cosine_windowing.htm.
[4] Montreuil, L., R. Prodan, and T. Kolze. “OFDM TX Symbol Shaping 802.3bn”, http://www.ieee802.org/3/bn/public/jan13/montreuil_01a_0113.pdf. Broadcom, 2013.
[5] “IEEE Standard 802.16TM-2009,” New York: IEEE, 2009.
Usage notes and limitations:
See System Objects in MATLAB Code Generation (MATLAB Coder).
You have a modified version of this example. Do you want to open this example with your edits?