LTE Receiver Using Analog Devices AD9361/AD9364

This example shows how to use the Xilinx® Zynq-Based Radio Support Package with MATLAB® and LTE Toolbox™ to decode the master information block (MIB) and recover basic system information from an LTE waveform. A suitable signal for reception can be generated by the companion LTE Transmitter with Analog Devices™ AD9361/AD9364 example if you have a second SDR platform.

Refer to the Getting Started documentation for details on configuring your host computer to work with the Support Package for Xilinx Zynq-Based Radio.

Introduction

LTE Toolbox provides functions and tools to decode LTE waveforms. This example shows how an LTE waveform can be captured with SDR Radio hardware such as Xilinx Zynq-Based Radio, and be decoded to recover basic system information.

In LTE the master information block (MIB) is carried within the broadcast channel (BCH). The MIB provides basic cell-wide settings including the system bandwidth and frame number. This example decodes the MIB for a burst of captured frames, and then decodes the control format indicator (CFI) for each subframe, which informs the user equipment (UE) of the size of the control region. The physical downlink control channel (PDCCH) is then decoded. These steps are the first required for a UE to associate with a cell. A detailed example of a robust cell search and system information acquisition procedure is given in Cell Search, MIB and SIB1 Recovery.

The BCH is transmitted in the middle six resource blocks (RBs) of an LTE transmission, therefore a capture bandwidth of only 1.92 MHz is required to decode the MIB, regardless of the cell bandwidth. Only subframe #0 of a frame is required to decode the MIB but this example will demodulate each entire frame for visualization and analysis.

Setup

This example requires LTE Toolbox to run. Before running the example, ensure you have performed the following steps:

  1. Configure your host computer to work with the Support Package for Xilinx Zynq-Based Radio. See Getting Started for help. Some additional steps may be required if you want to run two radios from a single host computer. See Setup for Two Radios - One Host for help.

  2. Ensure that you have a suitable signal to receive. This example is designed to work in conjunction with the LTE Transmitter with Analog Devices AD9361/AD9364 example.

% Check that LTE Toolbox is installed, and that there is a valid license
if isempty(ver('lte')) % Check for LST install
    error('zynqRadioLTEReceiver:NoLST','Please install LTE Toolbox to run this example.');
elseif ~license('test', 'LTE_Toolbox') % Check that a valid license is present
    error('zynqRadioLTEReceiver:NoLST','A valid license for LTE Toolbox is required to run this example.');
end
  • Receiver Design: System Architecture

    The general structure of the LTE receiver can be described as follows:

    1. Capture a suitable number of frames of an LTE signal using SDR hardware

    2. Determine and correct the frequency offset of the received signal

    3. Perform a blind cell search to determine the cell identity

    4. Synchronize the captured signal to the start of an LTE frame

    5. OFDM demodulate the received signal to get an LTE resource grid

    6. Perform a channel estimation for the received signal

    7. Decode the MIB for each captured frame to determine cell-wide settings

    8. Decode the CFI and PDCCH for each subframe within the captured signal

    9. Repeat all of the above steps the desired number of times

    This example plots the power spectral density of the captured waveform, and for each frame shows visalizations of the received LTE resource grid, estimated channel, and equalized PBCH symbols.

    Receiver Setup

    The receiver is controlled using the parameters defined in the rx structure. The sample rate of the receiver is 1.92 MHz, which is the standard sample rate for capturing an LTE bandwidth of 6 resource blocks (RBs). 6 RBs is equivalent to a signal bandwidth of 1.4 MHz. You may wish to increase the rx.numBurstCaptures parameter to capture more bursts of frames. Five LTE frames are captured in each burst.

    % User defined parameters
    rxsim.RadioFrontEndSampleRate = 1.92e6; % Configured for 1.92 MHz capture bandwidth
    rxsim.RadioCenterFrequency = 2.45e9;
    rxsim.RadioChannelMapping = 1;
    rxsim.FramesPerBurst = 5;   % Number of LTE frames to capture in each burst
    rxsim.numBurstCaptures = 1; % Number of bursts to capture
    
    % Derived parameters
    samplesPerFrame = 10e-3*rxsim.RadioFrontEndSampleRate; % LTE frames period is 10 ms
    

    This example communicates with the radio hardware using the SDR Receiver system object.

    rxsim.SDRDeviceName = 'AD936x';
    radio = sdrdev(rxsim.SDRDeviceName);
    
    sdrReceiver = sdrrx( ...
        rxsim.SDRDeviceName, ...
        'IPAddress',             '192.168.3.2', ...
        'BasebandSampleRate',    rxsim.RadioFrontEndSampleRate, ...
        'CenterFrequency',       rxsim.RadioCenterFrequency, ...
        'ChannelMapping',        rxsim.RadioChannelMapping, ...
        'SamplesPerFrame',       samplesPerFrame, ...
        'OutputDataType',        'double', ...
        'EnableBurstMode',       true, ...
        'NumFramesInBurst',      rxsim.FramesPerBurst, ...
        'GainSource',            'AGC Fast Attack');
    
    % burstCaptures holds rx.FramesPerBurst number of consecutive frames worth
    % of baseband LTE samples. Each column holds one LTE frame worth of data.
    burstCaptures = zeros(samplesPerFrame,rxsim.FramesPerBurst);
    
    % Spectrum viewer setup
    spectrumScope = dsp.SpectrumAnalyzer( ...
        'SampleRate',      rxsim.RadioFrontEndSampleRate, ...
        'SpectrumType',    'Power density', ...
        'SpectralAverages', 10, ...
        'YLimits',         [-130 -20], ...
        'Title',           'Baseband LTE Signal Spectrum', ...
        'YLabel',          'Power spectral density');
    

    LTE Setup

    The parameters for decoding the MIB are contained in the structure enb. FDD duplexing mode and a normal cyclic prefix length are assumed. Four cell-specific reference ports (CellRefP) are assumed for the MIB decode. The number of actual CellRefP is provided by the MIB.

    enb.DuplexMode = 'FDD';
    enb.CyclicPrefix = 'Normal';
    enb.CellRefP = 4;
    

    The sampling rate of the signal controls the captured bandwidth. The number of RBs captured is obtained from a lookup table using the chosen sampling rate, and is displayed to the command window.

    % Bandwidth: {1.4 MHz, 3 MHz, 5 MHz, 10 MHz, 20 MHz}
    SampleRateLUT = [1.92 3.84 7.68 15.36 30.72]*1e6;
    NDLRBLUT = [6 15 25 50 100];
    enb.NDLRB = NDLRBLUT(SampleRateLUT==rxsim.RadioFrontEndSampleRate);
    if isempty(enb.NDLRB)
        error('Sampling rate not supported. Supported rates are %s.',...
                '1.92 MHz, 3.84 MHz, 7.68 MHz, 15.36 MHz, 30.72 MHz');
    end
    fprintf('\nSDR hardware sampling rate configured to capture %d LTE RBs.\n',enb.NDLRB);
    
    SDR hardware sampling rate configured to capture 6 LTE RBs.
    

    Channel estimation configuration using cell-specific reference signals. A conservative 9-by-9 averaging window is used to minimize the effect of noise.

    cec.FreqWindow = 9;               % Frequency averaging window in Resource Elements (REs)
    cec.TimeWindow = 9;               % Time averaging window in REs
    cec.InterpType = 'Cubic';         % Cubic interpolation
    cec.PilotAverage = 'UserDefined'; % Pilot averaging method
    cec.InterpWindow = 'Centred';     % Interpolation windowing method
    cec.InterpWinSize = 3;            % Interpolate up to 3 subframes simultaneously
    

    Signal Capture and Processing

    A while loop is used to capture and decode bursts of LTE frames. For each captured frame the MIB is decoded and if successful the CFI and the PDCCH for each subframe are decoded and channel estimate and equalized PDCCH symbols are shown.

    % Setup the constellation diagram viewer for equalized PDCCH symbols
    constellation = comm.ConstellationDiagram('Title','Equalized PDCCH Symbols') ;
    
    % Handle for channel estimate plots
    channelEstimatePlot = figure('Visible','Off');
    
    enbDefault = enb;
    
    while rxsim.numBurstCaptures
        % Set default LTE parameters
        enb = enbDefault;
    
        % SDR Capture
        fprintf('\nStarting a new RF capture.\n')
        len = 0;
        for frame = 1:rxsim.FramesPerBurst
            while len == 0
                % Store one LTE frame worth of samples
                [data,len,lostSamples] = sdrReceiver();
                burstCaptures(:,frame) = data; % channel 1
            end
            if lostSamples
                warning('Dropped samples')
            end
            len = 0;
        end
        rxWaveform = burstCaptures(:);
    
        % Show power spectral density of captured burst
        spectrumScope(rxWaveform);
    
        % Perform frequency offset correction
        frequencyOffset = lteFrequencyOffset(enb,rxWaveform);
        rxWaveform = lteFrequencyCorrect(enb,rxWaveform,frequencyOffset);
        fprintf('Corrected a frequency offset of %g Hz.\n',frequencyOffset)
    
        % Perform the blind cell search to obtain cell identity and timing offset
        %   Use 'PostFFT' SSS detection method to improve speed
        cellSearch.SSSDetection = 'PostFFT'; cellSearch.MaxCellCount = 1;
        [NCellID,frameOffset] = lteCellSearch(enb,rxWaveform,cellSearch);
        fprintf('Detected a cell identity of %i.\n', NCellID);
        enb.NCellID = NCellID; % From lteCellSearch
    
        % Sync the captured samples to the start of an LTE frame, and trim off
        % any samples that are part of an incomplete frame.
        rxWaveform = rxWaveform(frameOffset+1:end);
        tailSamples = mod(length(rxWaveform),samplesPerFrame);
        rxWaveform = rxWaveform(1:end-tailSamples);
        enb.NSubframe = 0;
    
        % OFDM demodulation
        rxGrid = lteOFDMDemodulate(enb,rxWaveform);
    
        % Perform channel estimation for 4 CellRefP as currently we do not
        % know the CellRefP for the eNodeB.
        [hest,nest] = lteDLChannelEstimate(enb,cec,rxGrid);
    
        sfDims = lteResourceGridSize(enb);
        Lsf = sfDims(2); % OFDM symbols per subframe
        LFrame = 10*Lsf; % OFDM symbols per frame
        numFullFrames = length(rxWaveform)/samplesPerFrame;
    
        % For each frame decode the MIB and CFI
        for frame = 0:(numFullFrames-1)
            fprintf('\nPerforming MIB Decode for frame %i of %i in burst...\n', ...
                frame+1,numFullFrames)
    
            % Extract subframe #0 from each frame of the received resource grid
            % and channel estimate.
            enb.NSubframe = 0;
            rxsf = rxGrid(:,frame*LFrame+(1:Lsf));
            hestsf = hest(:,frame*LFrame+(1:Lsf),:,:);
    
            % PBCH demodulation. Extract resource elements (REs)
            % corresponding to the PBCH from the received grid and channel
            % estimate grid for demodulation. Assume 4 cell-specific reference
            % signals for PBCH decode as initially we do not know actual value.
            enb.CellRefP = 4;
            pbchIndices = ltePBCHIndices(enb);
            [pbchRx,pbchHest] = lteExtractResources(pbchIndices,rxsf,hestsf);
            [~,~,nfmod4,mib,CellRefP] = ltePBCHDecode(enb,pbchRx,pbchHest,nest);
    
            % If PBCH decoding successful CellRefP~=0 then update info
            if ~CellRefP
                fprintf('  No PBCH detected for frame.\n');
                continue;
            end
    
            % With successful PBCH decoding, decode the MIB and obtain system
            % information including system bandwidth
            enb = lteMIB(mib,enb);
            enb.CellRefP = CellRefP; % From ltePBCHDecode
            % Incorporate the nfmod4 value output from the function
            % ltePBCHDecode, as the NFrame value established from the MIB
            % is the system frame number modulo 4.
            enb.NFrame = enb.NFrame+nfmod4;
            fprintf('  Successful MIB Decode.\n')
            fprintf('  Frame number: %d.\n',enb.NFrame);
    
            % The eNodeB transmission bandwidth may be greater than the
            % captured bandwidth, so limit the bandwidth for processing
            enb.NDLRB = min(enbDefault.NDLRB,enb.NDLRB);
    
            % Process subframes within frame
            for sf = 0:9
                % Extract subframe
                enb.NSubframe = sf;
                rxsf = rxGrid(:,frame*LFrame+sf*Lsf+(1:Lsf));
    
                % Perform channel estimation with the correct number of CellRefP
                [hestsf,nestsf] = lteDLChannelEstimate(enb,cec,rxsf);
    
                % PCFICH demodulation. Extract REs corresponding to the PCFICH
                % from the received grid and channel estimate for demodulation.
                pcfichIndices = ltePCFICHIndices(enb);
                [pcfichRx,pcfichHest] = lteExtractResources(pcfichIndices,rxsf,hestsf);
                [cfiBits,recsym] = ltePCFICHDecode(enb,pcfichRx,pcfichHest,nestsf);
    
                % CFI decoding
                enb.CFI = lteCFIDecode(cfiBits);
                fprintf('    Subframe %d, decoded CFI value: %d.\n',sf,enb.CFI);
    
                % PDCCH demodulation. Extract REs corresponding to the PDCCH
                % from the received grid and channel estimate for demodulation.
                pdcchIndices = ltePDCCHIndices(enb);
                [pdcchRx,pdcchHest] = lteExtractResources(pdcchIndices,rxsf,hestsf);
                [pdcchBits,pdcchEq] = ltePDCCHDecode(enb,pdcchRx,pdcchHest,nestsf);
                release(constellation);
                constellation(pdcchEq);
                pause(0); % Allow constellation to repaint
            end
    
            % Plot channel estimate between CellRefP 0 and the receive antenna
            focalFrameIdx = frame*LFrame+(1:LFrame);
            set(0,'CurrentFigure',channelEstimatePlot);
            channelEstimatePlot.Visible = 'On';
            surf(abs(hest(:,focalFrameIdx,1,1)));
            xlabel('OFDM symbol index');
            ylabel('Subcarrier index');
            zlabel('Magnitude');
            title('Estimate of Channel Magnitude Frequency Repsonse');
        end
        rxsim.numBurstCaptures = rxsim.numBurstCaptures-1;
    end
    
    Starting a new RF capture.
    ## Establishing connection to hardware. This process can take several seconds.
    Corrected a frequency offset of -2.8406 Hz.
    Detected a cell identity of 17.
    
    Performing MIB Decode for frame 1 of 4 in burst...
      Successful MIB Decode.
      Frame number: 702.
        Subframe 0, decoded CFI value: 3.
        Subframe 1, decoded CFI value: 3.
        Subframe 2, decoded CFI value: 3.
        Subframe 3, decoded CFI value: 3.
        Subframe 4, decoded CFI value: 3.
        Subframe 5, decoded CFI value: 3.
        Subframe 6, decoded CFI value: 3.
        Subframe 7, decoded CFI value: 3.
        Subframe 8, decoded CFI value: 3.
        Subframe 9, decoded CFI value: 3.
    
    Performing MIB Decode for frame 2 of 4 in burst...
      Successful MIB Decode.
      Frame number: 703.
        Subframe 0, decoded CFI value: 3.
        Subframe 1, decoded CFI value: 3.
        Subframe 2, decoded CFI value: 3.
        Subframe 3, decoded CFI value: 3.
        Subframe 4, decoded CFI value: 3.
        Subframe 5, decoded CFI value: 3.
        Subframe 6, decoded CFI value: 3.
        Subframe 7, decoded CFI value: 3.
        Subframe 8, decoded CFI value: 3.
        Subframe 9, decoded CFI value: 3.
    
    Performing MIB Decode for frame 3 of 4 in burst...
      Successful MIB Decode.
      Frame number: 704.
        Subframe 0, decoded CFI value: 3.
        Subframe 1, decoded CFI value: 3.
        Subframe 2, decoded CFI value: 3.
        Subframe 3, decoded CFI value: 3.
        Subframe 4, decoded CFI value: 3.
        Subframe 5, decoded CFI value: 3.
        Subframe 6, decoded CFI value: 3.
        Subframe 7, decoded CFI value: 3.
        Subframe 8, decoded CFI value: 3.
        Subframe 9, decoded CFI value: 3.
    
    Performing MIB Decode for frame 4 of 4 in burst...
      Successful MIB Decode.
      Frame number: 705.
        Subframe 0, decoded CFI value: 3.
        Subframe 1, decoded CFI value: 3.
        Subframe 2, decoded CFI value: 3.
        Subframe 3, decoded CFI value: 3.
        Subframe 4, decoded CFI value: 3.
        Subframe 5, decoded CFI value: 3.
        Subframe 6, decoded CFI value: 3.
        Subframe 7, decoded CFI value: 3.
        Subframe 8, decoded CFI value: 3.
        Subframe 9, decoded CFI value: 3.
    

  • Things to Try

    The companion example LTE Transmitter Using Analog Devices AD9361/AD9364 can be used to transmit a standard compliant LTE waveform which can be partially decoded by this example. In the companion example try changing the cell identity and initial frame number and observe the detected cell identity and frame number in this example.

    This example only decodes basic system information. For an example of how to robustly decode more physical channels see Cell Search, MIB and SIB1 Recovery.

    Troubleshooting the Example

    General tips for troubleshooting SDR hardware can be found in Xilinx Zynq-Based Radio Processing Errors and Fixes.