Estimate Channel Using Input Data and Reference Subcarriers
This example shows how to use the OFDM Channel Estimator block to estimate a channel using input data and reference subcarriers. In this example model, the averaging and interpolation features are enabled. The HDL Algorithm
subsystem in this example model supports HDL code generation.
Set Input Data Parameters
Set up these workspace variables for the model to use. You can modify these values according to your requirement.
rng('default');
numOFDMSym = 980;
numOFDMSymToBeAvg = 14;
interpolFac = 3;
maxNumScPerSym = 72;
numOFDMSymPerFrame = 140;
numScPerSym = 72;
Generate Sinusoidal Input Data Subcarriers
Use the numScPerSym
and numOFDMSym
variables to generate complex sinusoidal input data subcarriers with their real and imaginary parts generated separately.
dataInGrid = zeros(numScPerSym,numOFDMSym); for numScPerSymCount = 0:numScPerSym - 1 for numOFDMSymCount = 0:numOFDMSym - 1 realXgain = 1 + .2*sin(2*pi*numScPerSymCount/numScPerSym); realYgain = 1 + .5*sin(2*pi*numOFDMSymCount/numOFDMSymPerFrame); imagXgain = 1 + .3*sin(2*pi*numScPerSymCount/numScPerSym); imagYgain = 1 + .4*sin(2*pi*numOFDMSymCount/numOFDMSymPerFrame); dataInGrid(numScPerSymCount+1,numOFDMSymCount+1) = realXgain*realYgain + 1i*(imagXgain*imagYgain); end end validIn = true(1,length(dataInGrid(:))); figure(1); surf(real(dataInGrid)) xlabel('OFDM Symbols') ylabel('Subcarriers') zlabel('Magnitude') title('Input Data Grid (Real Part)') figure(2); surf(imag(dataInGrid)) xlabel('OFDM Symbols') ylabel('Subcarriers') zlabel('Magnitude') title('Input Data Grid (Imaginary Part)')
Generate Reference Data Subcarriers
Generate reference data subcarriers.
refDataIn = randsrc(size(dataInGrid(:),1),size(dataInGrid(:),2),[1 1]); refValidIn = boolean(zeros(1,numOFDMSym*numScPerSym)); startRefValidIndex = randi(interpolFac,1,1); for numOFDMSymCount = 1:numOFDMSym refValidIn(startRefValidIndex+(numOFDMSymCount-1)*numScPerSym:interpolFac:numScPerSym*numOFDMSymCount) = true; end
Generate Signal with Number of Subcarriers per Symbol
Generate a signal with the number of subcarriers per symbol.
numScPerSymIn = numScPerSym*true(1,length(dataInGrid(:))); resetSig = false(1,length(dataInGrid(:)));
Run Simulink® Model
Run the model. Running the model imports the input signal variables from the MATLAB workspace to the OFDM Channel Estimator block in the model.
modelname = 'genhdlOFDMChannelEstimatorModel';
open_system(modelname);
out = sim(modelname);
Export Stream of Channel Estimates from Simulink to MATLAB® Workspace
Export the output of the OFDM Channel Estimator block to the MATLAB workspace. Plot the real part and imaginary part of the exported block output.
simOut = out.dataOut.Data(out.validOut.Data); N = length(simOut) - mod(length(simOut),numScPerSym); temp = simOut(1:N); channelEstimateSimOut = reshape(temp,numScPerSym,length(temp)/numScPerSym); figure(3); surf(real(channelEstimateSimOut)) xlabel('OFDM Symbols') ylabel('Subcarriers') zlabel('Magnitude') title('Channel Estimator Output (Real Part)') figure(4); surf(imag(channelEstimateSimOut)) xlabel('OFDM Symbols') ylabel('Subcarriers') zlabel('Magnitude') title('Channel Estimator Output (Imaginary Part)')
Estimate Channel Using MATLAB Function
Estimate the channel by using the channelEstReference
function with the sinusoidal input data subcarriers.
dataOut1 = channelEstReference(... numOFDMSymToBeAvg,interpolFac,numScPerSym,numOFDMSym, ... dataInGrid(:),validIn,refDataIn,refValidIn,numScPerSymIn); matlabOut = dataOut1(:); matOut = zeros(numel(matlabOut)*numScPerSym,1); for ii= 1:numel(matlabOut) loadArray = [matlabOut(ii).dataOut; zeros((numel(matlabOut)-1)*numScPerSym,1)]; shiftArray = circshift(loadArray,(ii-1)*numScPerSym); matOut = matOut + shiftArray; end
Compare Simulink Block Output with MATLAB Function Output
Compare the OFDM Channel Estimator block output with channelEstReference
function output. Plot the output comparison as a real part and an imaginary part using separate plots.
figure('units','normalized','outerposition',[0 0 1 1]) subplot(2,1,1) plot(real(matOut(:))); hold on; plot(real(simOut(:))); grid on legend('MATLAB reference output','Simulink block output') xlabel('Sample Index') ylabel('Magnitude') title('Comparison of Simulink Block and MATLAB Function (Real Part)') subplot(2,1,2) plot(imag(matOut(:))); hold on; plot(imag(simOut(:))); grid on legend('MATLAB reference output','Simulink block output') xlabel('Sample Index') ylabel('Magnitude') title('Comparison of Simulink Block and MATLAB Function (Imaginary Part)') sqnrRealdB = 10*log10(double(var(real(simOut(:)))/abs(var(real(simOut(:)))-var(real(matOut(:)))))); sqnrImagdB = 10*log10(double(var(imag(simOut(:)))/abs(var(imag(simOut(:)))-var(imag(matOut(:)))))); fprintf('\n OFDM Channel Estimator \n SQNR of real part: %.2f dB',sqnrRealdB); fprintf('\n SQNR of imaginary part: %.2f dB\n',sqnrImagdB);
OFDM Channel Estimator SQNR of real part: 38.54 dB SQNR of imaginary part: 37.77 dB