The document describes configuring and simulating an LTE downlink communication system with channel estimation and equalization. Key steps include:
1) Generating random input data, modulating it to QPSK symbols, and mapping to resource blocks to create a transmission grid.
2) Passing the data through Rayleigh fading and adding noise to simulate transmission over the channel.
3) Performing channel estimation on the received grid and using MMSE equalization.
4) Computing the EVM between transmitted and received/equalized grids and plotting results.
The document describes configuring and simulating an LTE downlink communication system with channel estimation and equalization. Key steps include:
1) Generating random input data, modulating it to QPSK symbols, and mapping to resource blocks to create a transmission grid.
2) Passing the data through Rayleigh fading and adding noise to simulate transmission over the channel.
3) Performing channel estimation on the received grid and using MMSE equalization.
4) Computing the EVM between transmitted and received/equalized grids and plotting results.
The document describes configuring and simulating an LTE downlink communication system with channel estimation and equalization. Key steps include:
1) Generating random input data, modulating it to QPSK symbols, and mapping to resource blocks to create a transmission grid.
2) Passing the data through Rayleigh fading and adding noise to simulate transmission over the channel.
3) Performing channel estimation on the received grid and using MMSE equalization.
4) Computing the EVM between transmitted and received/equalized grids and plotting results.
The document describes configuring and simulating an LTE downlink communication system with channel estimation and equalization. Key steps include:
1) Generating random input data, modulating it to QPSK symbols, and mapping to resource blocks to create a transmission grid.
2) Passing the data through Rayleigh fading and adding noise to simulate transmission over the channel.
3) Performing channel estimation on the received grid and using MMSE equalization.
4) Computing the EVM between transmitted and received/equalized grids and plotting results.
sampleRate500kHz = 500e3; % Sample rate of 500K Hz
sampleRate20kHz = 20e3; % Sample rate of 20K Hz
maxDopplerShift = 200; % Maximum Doppler shift of diffuse components (Hz) delayVector = (0:5:15)*1e-6; % Discrete delays of four-path channel (s) gainVector = [0 -3 -6 -9]; % Average path gains (dB) KFactor = 10; % Linear ratio of specular power to diffuse power specDopplerShift = 100; % Doppler shift of specular component (Hz) % Configure a Rayleigh channel object rayChan = comm.RayleighChannel( ... 'SampleRate', sampleRate500kHz, ... 'PathDelays', delayVector, ... 'AveragePathGains', gainVector, ... 'MaximumDopplerShift', maxDopplerShift, ... 'RandomStream', 'mt19937ar with seed', ... 'Seed', 10, ... 'PathGainsOutputPort', true); % Configure a Rician channel object ricChan = comm.RicianChannel( ... 'SampleRate', sampleRate500kHz, ... 'PathDelays', delayVector, ... 'AveragePathGains', gainVector, ... 'KFactor', KFactor, ... 'DirectPathDopplerShift', specDopplerShift, ... 'MaximumDopplerShift', maxDopplerShift, ... 'RandomStream', 'mt19937ar with seed', ... 'Seed', 100, ... 'PathGainsOutputPort', true); qpskMod = comm.QPSKModulator( ... 'BitInput', true, ... 'PhaseOffset', pi/4); % Number of bits transmitted per frame is set to be 1000. For QPSK % modulation, this corresponds to 500 symbols per frame. bitsPerFrame = 1000; msg = randi([0 1],bitsPerFrame,1); % Modulate data for transmission over channel modSignal = qpskMod(msg); % Apply Rayleigh or Rician channel object on the modulated data rayChan(modSignal); ricChan(modSignal); release(rayChan); release(ricChan); rayChan.Visualization = 'Impulse and frequency responses'; rayChan.SamplesToDisplay = '100%'; numFrames = 2; for i = 1:numFrames % Display impulse and frequency responses for 2 frames % Create random data msg = randi([0 1],bitsPerFrame,1); % Modulate data modSignal = qpskMod(msg); % Filter data through channel and show channel responses rayChan(modSignal); end release(rayChan); rayChan.Visualization = 'Doppler spectrum'; numFrames = 5000; for i = 1:numFrames % Display Doppler spectrum from 5000 frame transmission msg = randi([0 1],bitsPerFrame,1); modSignal = qpskMod(msg); rayChan(modSignal); end release(rayChan); rayChan.Visualization = 'Impulse and frequency responses'; rayChan.SampleRate = sampleRate20kHz; rayChan.SamplesToDisplay = '25%'; % Display one of every four samples numFrames = 2; for i = 1:numFrames % Display impulse and frequency responses for 2 frames msg = randi([0 1],bitsPerFrame,1); modSignal = qpskMod(msg); rayChan(modSignal); end release(rayChan); rayChan.PathDelays = 0; % Single fading path with zero delay rayChan.AveragePathGains = 0; % Average path gain of 1 (0 dB) for i = 1:numFrames % Display impulse and frequency responses for 2 frames msg = randi([0 1],bitsPerFrame,1); modSignal = qpskMod(msg); rayChan(modSignal); end release(rayChan); rayChan.Visualization = 'Off'; % Turn off System object's visualization ricChan.Visualization = 'Off'; % Turn off System object's visualization % Same sample rate and delay profile for the Rayleigh and Rician objects ricChan.SampleRate = rayChan.SampleRate; ricChan.PathDelays = rayChan.PathDelays; ricChan.AveragePathGains = rayChan.AveragePathGains; % Configure a Time Scope System object to show path gain magnitude gainScope = dsp.TimeScope( ... 'SampleRate', rayChan.SampleRate, ... 'TimeSpan', bitsPerFrame/2/rayChan.SampleRate, ... % One frame span 'Name', 'Multipath Gain', ... 'ShowGrid', true, ... 'YLimits', [-40 10], ... 'YLabel', 'Gain (dB)'); % Compare the path gain outputs from both objects for one frame msg = randi([0 1],bitsPerFrame,1); modSignal = qpskMod(msg); [~, rayPathGain] = rayChan(modSignal); [~, ricPathGain] = ricChan(modSignal); % Form the path gains as a two-channel input to the time scope gainScope(10*log10(abs([rayPathGain, ricPathGain]).^2)); enb.NDLRB = 15; % Number of resource blocks enb.CellRefP = 1; % One transmit antenna port enb.NCellID = 10; % Cell ID enb.CyclicPrefix = 'Normal'; % Normal cyclic prefix enb.DuplexMode = 'FDD'; % FDD SNRdB = 22; % Desired SNR in dB SNR = 10^(SNRdB/20); % Linear SNR rng('default'); % Configure random number generators cfg.Seed = 1; % Channel seed cfg.NRxAnts = 1; % 1 receive antenna cfg.DelayProfile = 'EVA'; % EVA delay spread cfg.DopplerFreq = 120; % 120Hz Doppler frequency cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation cfg.InitTime = 0; % Initialize at time zero cfg.NTerms = 16; % Oscillators used in fading model cfg.ModelType = 'GMEDS'; % Rayleigh fading model type cfg.InitPhase = 'Random'; % Random initial phases cfg.NormalizePathGains = 'On'; % Normalize delay profile power cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas cec.PilotAverage = 'UserDefined'; % Pilot averaging method cec.FreqWindow = 9; % Frequency averaging window in REs cec.TimeWindow = 9; % Time averaging window in REs cec.InterpType = 'Cubic'; % Cubic interpolation cec.InterpWinSize = 3; % Interpolate up to 3 subframes % simultaneously cec.InterpWindow = 'Centred'; % Interpolation windowing method gridsize = lteDLResourceGridSize(enb); K = gridsize(1); % Number of subcarriers L = gridsize(2); % Number of OFDM symbols in one subframe P = gridsize(3); % Number of transmit antenna ports txGrid = []; % Number of bits needed is size of resource grid (K*L*P) * number of bits % per symbol (2 for QPSK) numberOfBits = K*L*P*2;
% Create random bit stream
inputBits = randi([0 1], numberOfBits, 1);
% Modulate input bits
inputSym = lteSymbolModulate(inputBits,'QPSK'); % For all subframes within the frame for sf = 0:10
% Generate cell specific reference signal symbols and
indices cellRsSym = lteCellRS(enb); cellRsInd = lteCellRSIndices(enb);
% Map cell specific reference signal to grid
subframe(cellRsInd) = cellRsSym;
% Append subframe to grid to be transmitted
txGrid = [txGrid subframe]; %#ok
end [txWaveform,info] = lteOFDMModulate(enb,txGrid); txGrid = txGrid(:,1:140); cfg.SamplingRate = info.SamplingRate;
% Pass data through the fading channel model
rxWaveform = lteFadingChannel(cfg,txWaveform); % Calculate noise gain N0 = 1/(sqrt(2.0*enb.CellRefP*double(info.Nfft))*SNR);
% Create additive white Gaussian noise
noise = N0*complex(randn(size(rxWaveform)),randn(size(rxWaveform))) ; % Add noise to the received time domain waveform rxWaveform = rxWaveform + noise; offset = lteDLFrameOffset(enb,rxWaveform); rxWaveform = rxWaveform(1+offset:end,:); rxGrid = lteOFDMDemodulate(enb,rxWaveform); enb.NSubframe = 0; [estChannel, noiseEst] = lteDLChannelEstimate(enb,cec,rxGrid); eqGrid = lteEqualizeMMSE(rxGrid, estChannel, noiseEst); % Calculate error between transmitted and equalized grid eqError = txGrid - eqGrid; rxError = txGrid - rxGrid;
% Compute EVM across all input values
% EVM of pre-equalized receive signal EVM = comm.EVM; EVM.AveragingDimensions = [1 2]; preEqualisedEVM = EVM(txGrid,rxGrid); fprintf('Percentage RMS EVM of Pre-Equalized signal: %0.3f%%\n', ... preEqualisedEVM); % EVM of post-equalized receive signal postEqualisedEVM = EVM(txGrid,eqGrid); fprintf('Percentage RMS EVM of Post-Equalized signal: %0.3f%%\n', ... postEqualisedEVM); % Plot the received and equalized resource grids hDownlinkEstimationEqualizationResults(rxGrid,eqGrid); M = 16; % Modulation order k = log2(M); % Number of bits per symbol numBits = 3e5; % Number of bits to process sps = 4; % Number of samples per symbol (oversampling factor) filtlen = 10; % Filter length in symbols rolloff = 0.25; % Filter rolloff factor rrcFilter = rcosdesign(rolloff,filtlen,sps); fvtool(rrcFilter,'Analysis','Impulse') rng default; % Use default random number generator dataIn = randi([0 1],numBits,1); % Generate vector of binary data dataInMatrix = reshape(dataIn,length(dataIn)/k,k); % Reshape data into binary 4-tuples dataSymbolsIn = bi2de(dataInMatrix); % Convert to integers dataMod = qammod(dataSymbolsIn,M); txFiltSignal = upfirdn(dataMod,rrcFilter,sps,1); EbNo = 10; snr = EbNo + 10*log10(k) - 10*log10(sps); rxSignal = awgn(txFiltSignal,snr,'measured'); rxFiltSignal = upfirdn(rxSignal,rrcFilter,1,sps); % Downsample and filter rxFiltSignal = rxFiltSignal(filtlen + 1:end - filtlen); % Account for delay dataSymbolsOut = qamdemod(rxFiltSignal,M); dataOutMatrix = de2bi(dataSymbolsOut,k); dataOut = dataOutMatrix(:); % Return data in column vector [numErrors,ber] = biterr(dataIn,dataOut); fprintf('\nFor an EbNo setting of %3.1f dB,the bit error rate is %5.2e, based on %d errors.\n', ... EbNo,ber,numErrors) EbNo = 20; snr = EbNo + 10*log10(k) - 10*log10(sps); rxSignal = awgn(txFiltSignal,snr,'measured'); rxFiltSignal = upfirdn(rxSignal,rrcFilter,1,sps); % Downsample and filter rxFiltSignal = rxFiltSignal(filtlen + 1:end - filtlen); % Account for delay eyediagram(txFiltSignal(1:2000),sps*2); eyediagram(rxSignal(1:2000),sps*2); eyediagram(rxFiltSignal(1:2000),2); scatplot = scatterplot(sqrt(sps)*... rxSignal(1:sps*5e3),... sps,0,'g.'); hold on; scatterplot(rxFiltSignal(1:5e3),1,0,'kx',scatplot); title('Received Signal, Before and After Filtering'); legend('Before Filtering','After Filtering'); axis([-5 5 -5 5]); % Set axis ranges hold off; %========================================================== ================ % The mfile investigates the generation, transmission and reception of % the OFDM signal without channel noise or HPA effect %========================================================== ================ clear all clc close % --------------- % A: Setting Parameters % --------------- M = 4; % QPSK signal constellation no_of_data_points = 64; % have 64 data points block_size = 8; % size of each ofdm block cp_len = ceil(0.1*block_size); % length of cyclic prefix no_of_ifft_points = block_size; % 8 points for the FFT/IFFT no_of_fft_points = block_size; % --------------------------------------------- % B: % +++++ TRANSMITTER +++++ % --------------------------------------------- % 1. Generate 1 x 64 vector of data points phase representations data_source = randsrc(1, no_of_data_points, 0:M-1); figure(1) stem(data_source); grid on; xlabel('data points'); ylabel('transmitted data phase representation') title('Transmitted Data "O"') % 2. Perform QPSK modulation qpsk_modulated_data = pskmod(data_source, M); scatterplot(qpsk_modulated_data); title('qpsk modulated transmitted data') % 3. Do IFFT on each block % Make the serial stream a matrix where each column represents a pre-OFDM % block (w/o cyclic prefixing) % First: Find out the number of colums that will exist after reshaping num_cols=length(qpsk_modulated_data)/block_size; data_matrix = reshape(qpsk_modulated_data, block_size, num_cols); % Second: Create empty matix to put the IFFT'd data cp_start = block_size-cp_len; cp_end = block_size; % Third: Operate columnwise & do CP for i=1:num_cols ifft_data_matrix(:,i) = ifft((data_matrix(:,i)),no_of_ifft_points); % Compute and append Cyclic Prefix for j=1:cp_len actual_cp(j,i) = ifft_data_matrix(j+cp_start,i); end % Append the CP to the existing block to create the actual OFDM block ifft_data(:,i) = vertcat(actual_cp(:,i),ifft_data_matrix(:,i)); end % 4. Convert to serial stream for transmission [rows_ifft_data cols_ifft_data]=size(ifft_data); len_ofdm_data = rows_ifft_data*cols_ifft_data; % Actual OFDM signal to be transmitted ofdm_signal = reshape(ifft_data, 1, len_ofdm_data); figure(3) plot(real(ofdm_signal)); xlabel('Time'); ylabel('Amplitude'); title('OFDM Signal');grid on; % ------------------------------------------ % E: % +++++ RECEIVER +++++ % ------------------------------------------ % 1. Pass the ofdm signal through the channel recvd_signal = ofdm_signal; % 4. Convert Data back to "parallel" form to perform FFT recvd_signal_matrix = reshape(recvd_signal,rows_ifft_data, cols_ifft_data); % 5. Remove CP recvd_signal_matrix(1:cp_len,:)=[]; % 6. Perform FFT for i=1:cols_ifft_data % FFT fft_data_matrix(:,i) = fft(recvd_signal_matrix(:,i),no_of_fft_points); end % 7. Convert to serial stream recvd_serial_data = reshape(fft_data_matrix, 1,(block_size*num_cols)); % 8. Demodulate the data qpsk_demodulated_data = pskdemod(recvd_serial_data,M); scatterplot(qpsk_modulated_data); title('qpsk modulated received data') figure(5) stem(qpsk_demodulated_data,'rx'); grid on; xlabel('data points'); ylabel('received data phase representation'); title('Received Data "X"') a