MATLAB Examples

Beamforming for MIMO-OFDM Systems

This examples shows how to model a point-to-point MIMO-OFDM system with beamforming. The combination of multiple-input-multiple-output (MIMO) and orthogonal frequency division multiplexing (OFDM) techniques have been adopted in recent wireless standards, such as 802.11x families, to provide higher data rate. Because MIMO uses antenna arrays, beamforming can be adopted to improve the received signal to noise ratio (SNR) which in turn reduces the bit error rate (BER).

This example requires Communications System Toolbox™.



The term MIMO is used to describe a system where multiple transmitters or multiple receivers are present. In practice the system can take many different forms, such as single-input-multiple-output (SIMO) or multiple-input-single-output (MISO) system. This example illustrates a downlink MISO system. An 8-element ULA is deployed at the base station as the transmitter while the mobile unit is the receiver with a single antenna.

The rest of the system is configured as follows. The transmitter power is 8 watts and the transmit gain is -8 dB. The mobile receiver is stationary and located at 2750 meters away, and is 3 degrees off the transmitter's boresight. An interferer with a power of 1 watt and a gain of -20 dB is located at 9000 meters, 20 degrees off the transmitter's boresight.

% Initialize system constants
gc = helperGetDesignSpecsParameters();

% Tunable parameters
tp.txPower = 9;           % watt
tp.txGain = -8;           % dB
tp.mobileRange = 2750;    % m
tp.mobileAngle = 3;       % degrees
tp.interfPower = 1;       % watt
tp.interfGain = -20;      % dB
tp.interfRange = 9000;    % m
tp.interfAngle =   20;    % degrees
tp.numTXElements = 8;
tp.steeringAngle = 0;     % degrees
tp.rxGain = 108.8320 - tp.txGain; % dB

numTx= tp.numTXElements;

The entire scene can be depicted in the figure below.

helperPlotMIMOEnvironment(gc, tp);

Signal Transmission

First, configure the system's transmitter.

    radiator,pilots,numDataSymbols,frmSz] = helperMIMOTxSetup(gc,tp);

There are many components in the transmitter subsystem, such as the convolutional encoder, the scrambler, the QAM modulator, the OFDM modulator, and so on. The message is first converted to an information bit stream and then passed through source coding and modulation stages to prepare for the radiation.

txBits = randi([0, 1], frmSz,1);
coded = encoder(txBits);
bitsS = scrambler(coded);
tx = modulatorRQAM(bitsS);

In an OFDM system, the data is carried by multiple sub-carriers that are orthogonal to each other.

ofdm1 = reshape(tx, gc.numCarriers,numDataSymbols);

Then, the data stream is duplicated to all radiating elements in the transmitting array

ofdmData = repmat(ofdm1,[1, 1, numTx]);
txOFDM = modulatorOFDM(ofdmData, pilots);
txOFDM = txOFDM * ...

% Amplify to achieve peak TX power for each channel
for n = 1:numTx
    txOFDM(:,n) = transmitter(txOFDM(:,n));

In a MIMO system, it is also possible to separate multiple users spatial division multiplexing (SDMA). In these situations, the data stream is often modulated by a weight corresponding to the desired direction so that once radiated, the signal is maximized in that direction. Because in a MIMO channel, the signal radiated from different elements in an array may go through different propagation environments, the signal radiated from each antenna should be propagated individually. This can be achieved by setting CombineRadiatedSignals to false on the phased.Radiator component.

radiator.CombineRadiatedSignals = false;

To achieve precoding, the data stream radiated from each antenna in the array is modulated by a phase shift corresponding to its radiating direction. The goal of this precoding is to ensure these data streams add in phase if the array is steered toward that direction. Precoding can be specified as weights used at the radiator.

wR = steeringvec(gc.fc,[-tp.mobileAngle;0]);

Meanwhile, the array is also steered toward a given steering angle, so the total weights are a combination of both precoding and the steering weights.

wT = steeringvec(gc.fc,[tp.steeringAngle;0]);
weight = wT.* wR;

The transmitted signal is thus given by

txOFDM = radiator(txOFDM,repmat([tp.mobileAngle;0],1,numTx),conj(weight));

Note that the transmitted signal, txOFDM, is a matrix whose columns represent data streams radiated from the corresponding elements in the transmit array.

Signal Propagation

Next, the signal propagates through a MIMO channel. In general, there are two propagation effects on the received signal strength that are of interest: one of them is the spreading loss due to the propagation distance, often termed as the free space path loss; and the other is the fading due to multipath. This example models both effects.

[channel,interferenceTransmitter,toRxAng,spLoss] = ...
[sigFade, chPathG] =  channel(txOFDM);
sigLoss = sigFade/sqrt(db2pow(spLoss(1)));

To simulate a more realistic mobile environment, next section also inserts an interference source. Note that in a wireless communication system, the interference is often a different mobile user.

% Generate interference and apply gain and propagation loss
numBits = size(sigFade,1);
interfSymbols = wgn(numBits,1,1,'linear','complex');
interfSymbols = interferenceTransmitter(interfSymbols);
interfLoss = interfSymbols/sqrt(db2pow(spLoss(2)));

Signal Reception

The receiving antenna collects both the propagated signal as well as the interference and passes them to the receiver to recover the original information embedded in the signal. Just like the transmit end of the system, the receiver used in a MIMO-OFDM system also contains many stages, including OFDM demodulator, QAM demodulator, descrambler, equalizer, and Viterbi decoder.

    descrambler,decoder] = helperMIMORxSetup(gc,tp,numDataSymbols);

rxSig = collector([sigLoss interfLoss],toRxAng);

% Front-end amplifier gain and thermal noise
rxSig = receiver(rxSig);

rxOFDM = rxSig * ...
    (sqrt(gc.FFTLength-sum(gc.NumGuardBandCarriers)-1)) / (gc.FFTLength);

% OFDM Demodulation
rxOFDM = demodulatorOFDM(rxOFDM);

% Channel estimation
hD = helperIdealChannelEstimation(gc,  numDataSymbols, chPathG);

% Equalization
rxEq = helperEqualizer(rxOFDM, hD, numTx);

% Collapse OFDM matrix
rxSymbs = rxEq(:);

rxBitsS = demodulatorRQAM(rxSymbs);
rxCoded = descrambler(rxBitsS);
rxDeCoded = decoder(rxCoded);
rxBits = rxDeCoded(1:frmSz);

A comparison of the decoded output with the original message stream suggests that the resulting BER is too high for a communication system. The constellation diagram is also shown below

ber = comm.ErrorRate;
measures = ber(txBits, rxBits);
fprintf('BER = %.2f%%; No. of Bits = %d; No. of errors = %d\n', ...
    measures(1)*100,measures(3), measures(2));
BER = 32.07%; No. of Bits = 30714; No. of errors = 9850
constdiag = comm.ConstellationDiagram('SamplesPerSymbol', 1,...
    'ReferenceConstellation', [], 'ColorFading',true,...
    'Position', gc.constPlotPosition);
% Display received constellation

The high BER is mainly due to the mobile being off the steering direction of the base station array. If the mobile is aligned with the steering direction, the BER is greatly improved.

tp.steeringAngle = tp.mobileAngle;

% Steer the transmitter main lobe
wT = steeringvec(gc.fc,[tp.steeringAngle;0]);

[txBits, rxBits,rxSymbs] = helperRerunMIMOBeamformingExample(gc,tp,wT);

measures = ber(txBits, rxBits);
fprintf('BER = %.2f%%; No. of Bits = %d; No. of errors = %d\n', ...
    measures(1)*100,measures(3), measures(2));
BER = 0.02%; No. of Bits = 30714; No. of errors = 5

Therefore, the system is very sensitive to the steering error. On the other hand, it is this kind of spatial sensitivity makes SDMA possible to distinguish multiple users in space.

Hybrid Beamforming in MIMO

The trend in 5G wireless communication is to go to higher frequencies at millimeter wave spectrum and use more transmit and receive antennas. Because the path loss in the millimeter wave band is significant, a larger array is needed to provide more beamforming gain to overcome the path loss. In order to be able to control each array element independently to achieve the maximum flexibility in beamforming, a transmit and receive switch, often termed as T/R switch, is needed behind each element. However, in a large array, such arrangement can be difficult due to both cost considerations and space limitations. Therefore, in recent years, hybrid beamforming becomes a popular tradeoff technique to achieve the desired performance.

Next section explains how to simulate a hybrid beamforming scheme using the system described above. Although an 8-element array is not a large array, the concept is the same.

Hybrid beamforming does not put a T/R switch behind each element. Instead, it groups the elements in an array into subarrays. There is a T/R switch behind each subarray but within each subarray, there is only a phase shifter behind each element. This means that one can control the signal in both amplitude and phase at the subarray level but only in phase at the element level. The phase shifter is in general done with analog components and the subarray weights can be applied digitally, thus the name of hybrid beamforming. The following diagram shows a typical hybrid beamforming configuration.

Since for this particular MISO example, the antenna array is only available at the transmitter side, the focus will be on the hybrid precoding.

The code snippet below divides the transmit array into two subarrays and computes the corresponding positions of the subarrays and of the elements within each subarray.

numSubarray = 2;
numSubElem = numTx/numSubarray;

subpos = (-(numSubarray-1)/2:(numSubarray-1)/2)*(0.5*numSubElem);
subelempos = (-(numSubElem-1)/2:(numSubElem-1)/2)*0.5;

Next section divides the previously derived precoding weights into two parts: the digital part used at the subarray level for baseband precoding, and the analog part used within each subarray for RF precoding. Note that the analog weights are phase shifts only.

% complex weights used as part of digital baseband precoding
wT_digital = steervec(subpos,[tp.steeringAngle;0]);

% analog phase shift values used as part of RF precoding
wT_analog = exp(1i*angle(steervec(subelempos,[tp.steeringAngle;0])));

From the system perspective, the effect of the hybrid beamforming can be represented by hybrid weights as shown below.

wT_hybrid = kron(wT_digital,wT_analog);

The following figure shows the constellation when the hybrid precoding weights are used in the simulation. In this MISO case, the hybrid weights behave as well as a system which uses the all digital weights.

[txBits, rxBits,rxSymbs] = helperRerunMIMOBeamformingExample(...

measures = ber(txBits, rxBits);
fprintf('BER = %.2f%%; No. of Bits = %d; No. of errors = %d\n', ...
    measures(1)*100,measures(3), measures(2));

constdiag = comm.ConstellationDiagram('SamplesPerSymbol', 1,...
    'ReferenceConstellation', [], 'ColorFading',true,...
    'Position', gc.constPlotPosition);
BER = 0.02%; No. of Bits = 30714; No. of errors = 5

Phase Shifter Quantization Effect

The previous figure shows that the hybrid beamforming can achieve similar performance compared to that of the all digital beamforming can offer in the simulated scenario. This can be a bit misleading because the computation assumes that the analog phase shifters have infinite precisions. In reality, the analog phase shifters have only limited precision and are often categorized by the number of bits used in phase shifts. For example, a 3-bit phase shifter can only represent 8 different angles within 360 degrees. Thus, if such quantization is included in the simulation, the system performance degrades, which can be observed from the constellation plot.

% analog phase shifter with quantization effect
nbits = 4;
wTq_analog = exp(1i*angle(...

wTq_hybrid = kron(wT_digital,wTq_analog);

[txBits, rxBits,rxSymbs] = helperRerunMIMOBeamformingExample(...

measures = ber(txBits, rxBits);
fprintf('BER = %.2f%%; No. of Bits = %d; No. of errors = %d\n', ...
    measures(1)*100,measures(3), measures(2));

constdiag = comm.ConstellationDiagram('SamplesPerSymbol', 1,...
    'ReferenceConstellation', [], 'ColorFading',true,...
    'Position', gc.constPlotPosition);
BER = 2.72%; No. of Bits = 30714; No. of errors = 836


This example shows a system level simulation of a point-to-point MIMO-OFDM system employing beamforming. The simulation models many system components such as encoding, transmit beamforming, precoding, multipath fading, channel estimation, equalization, and decoding. The simulation also introduces the basic concept of hybrid beamforming. The system performance is measured using BER and constellation diagrams.


[1] Houman Zarrinkoub, Understanding LTE with MATLAB, Wiley, 2014

[2] Theodore S. Rappaport et al. Millimeter Wave Wireless Communications, Prentice Hall, 2014