Main Content

NR HDL Downlink Receiver MATLAB Reference

This example shows how to model a 5G NR cell search, MIB and SIB1 recovery hardware algorithm in MATLAB® as a step towards developing a Simulink® HDL implementation of a downlink receiver. Use this MATLAB reference to verify the Simulink models in the NR HDL Cell Search, NR HDL MIB Recovery, NR HDL MIB Recovery for FR2, and NR HDL SIB1 Recovery examples.

Introduction

The NR HDL Downlink Receiver MATLAB Reference example bridges the gap between a mathematical algorithm and its hardware implementation by providing a MATLAB model of the algorithms that are implemented in hardware. The MATLAB reference is created to evaluate hardware-friendly algorithms and generate test vectors for verifying the Simulink fixed-point HDL optimized implementation. The workflow for designing and deploying a 5G cell search, MIB and SIB1 recovery algorithm to hardware is shown.

Each step in this workflow is demonstrated by one or more related examples.

  1. The MATLAB Golden Reference Algorithm step consists of the NR Cell Search and MIB and SIB1 Recovery (5G Toolbox) example, which shows the floating-point golden reference algorithm.

  2. The MATLAB Hardware Reference Algorithm step consists of the NR HDL Downlink Receiver MATLAB Reference example (this example), which models hardware friendly algorithms and generates test waveforms. This MATLAB® code operates on vectors and matrices of floating-point data samples and does not support HDL code generation.

  3. The Simulink Fixed-Point Implementation Model step consists of multiple examples. The NR HDL Cell Search example demonstrates a 5G cell search Simulink subsystem that uses the same algorithm as the MATLAB reference. The NR HDL MIB Recovery example adds a broadcast channel decoding and MIB recovery subsystem. The NR HDL SIB1 Recovery example adds a subsystem that recovers the SIB1 resource grid, and shows how to decode its output using MATLAB reference code. The NR HDL MIB Recovery for FR2 example shows cell search and MIB recovery models which have been extended to support FR2. These models operate on fixed-point data and are optimized for HDL code generation.

  4. The Simulink SoC Deployment Model step consists of the Deploy NR HDL Reference Applications on SoCs examples, which build on the fixed-point implementation models and use hardware support packages to deploy the algorithms on hardware.

For a general description of how MATLAB and Simulink can be used together to develop deployable models, see Wireless Communications Design for FPGAs and ASICs.

Downlink Receiver Overview

A block diagram of the Downlink Receiver algorithm is shown. The algorithm detects, demodulates, and decodes 5G NR synchronization signal blocks (SSBs) and recovers SIB1. It is a hardware-friendly version of the corresponding steps in the NR Cell Search and MIB and SIB1 Recovery (5G Toolbox) example. At the top level, the algorithm consists of a Search Controller, an SSB Detector, an SSB Decoder, SIB1 grid demodulator and SIB1 decoder. This example explains each of these blocks in more detail and demonstrates the corresponding MATLAB reference functions, which are used to explore algorithms for hardware implementation and to verify the streaming fixed-point Simulink models. This example focuses on 5G NR frequency range 1 (FR1). See NR HDL MIB Recovery for FR2 for an example of how to use the MATLAB reference for FR2 MIB Recovery.

Cell Search

Cell search consists of carrier frequency recovery, primary synchronization signal (PSS) search, OFDM demodulation, and secondary synchronization signal (SSS) search. The Search Controller and the SSB Detector work together to perform these processing steps. The SSB Detector performs all of the high-speed signal processing tasks, making it well suited for FPGA or ASIC implementation. The Search Controller coordinates the search and operates at a low rate, making it well suited for software implementation on an embedded processor.

The algorithm starts by using the PSS to search for SSBs with subcarrier spacings of 15 kHz and 30 kHz across a range of coarse frequency offsets. The subcarrier spacing and coarse frequency offset search ranges are configurable. If SSBs are detected, the receiver OFDM demodulates the resource grid of the SSB with the strongest PSS and determines its cell ID using the SSS. The residual fine frequency offset is corrected during the OFDM demodulation phase.

  • SSB Detector: Searches for and OFDM-demodulates SSBs at a given carrier frequency offset and subcarrier spacing and measures the residual fine carrier frequency offset.

  • Digital Down Converter (DDC): Performs frequency translation to correct frequency offsets in the received waveform and then decimates the signal from 61.44 Msps to 7.68 Msps.

  • PSS search: Searches for PSS symbols within the waveform.

  • OFDM demodulation: OFDM-demodulates an SSB resource grid.

  • SSS search: Searches for SSS and determines the overall cell ID.

  • Search Controller: Coordinates the cell search by directing the SSB Detector to search for PSS symbols at different coarse frequency offsets and subcarrier spacings and to demodulate the SSB with the strongest PSS.

In the MATLAB reference, the nrhdlexamples.cellSearch function implements the cell search algorithm. This function implements the Search Controller shown in the diagram, and calls the nrhdlexamples.ssbDetect function, which implements the SSB Detector. The NR HDL Cell Search example shows the streaming fixed-point Simulink HDL implementation of the SSB Detector. In the 5G NR MIB Recovery Using Analog Devices AD9361/AD9364 (Communications Toolbox Support Package for Xilinx Zynq-Based Radio) example, the SSB Detector is implemented in programmable logic while the Search Controller is implemented in software on the integrated processing system.

Search Controller

The Search Controller is responsible for coordinating the overall search. The algorithm follows these steps.

  1. For each subcarrier spacing, step through each coarse frequency offset and use the SSB Detector to search for SSBs until one or more is detected. The coarse frequency offset step size is half the subcarrier spacing. When SSBs are detected at a given frequency, record the residual fine carrier frequency offset of the strongest SSB that is returned.

  2. Move to the next coarse frequency step and search for SSBs again. If the search detects SSBs, choose the coarse frequency offset that resulted in the smallest fine frequency offset measurement. Otherwise, pick the last coarse frequency offset.

  3. Compute the total frequency offset by adding the coarse and fine frequency offsets together.

  4. Use the SSB Detector to correct the frequency offset and perform one more search for SSBs.

  5. Pick the SSB with the strongest PSS correlation. Use the SSB Detector in demodulation mode to find and demodulate the SSB and determine its cell ID.

SSB Detector

These diagrams show the SSB Detector structure for FR1, and the parameters and data passed to and from the Search Controller. The SSB Detector is subdivided into two functions: SSB Detector DDC (nrhdlexamples.ssbDetectDDC) and SSB Detection Search and Demod (nrhdlexamples.ssbDetectSearchDemod). The DDC accepts samples at 61.44 Msps and performs a frequency shift followed by decimation by a factor of 8 using halfband filters. The frequency offset, in Hz, is provided by the search controller and is used by the algorithm to compensate for both coarse and fine frequency offsets.

SSB Detection Search and Demod accepts samples at 7.68 Msps. For 30 kHz subcarrier spacing, it uses the samples at this rate. For 15 kHz subcarrier spacing, it decimates the input by a factor of two, operating at 3.84 Msps. SSB Detection Search and Demod has two modes of operation: search and demodulation.

In search mode, the function searches for SSBs at the specified subcarrier spacing using the PSS, and returns a list of those detected. For each SSB that is found, the function returns these parameters:

  • NCellID2: Indicates which of the three possible PSS sequences (0,1, or 2) was detected.

  • timing offset: The timing offset from the start of the waveform to the start of the SSB.

  • fine frequency offset: The residual fine frequency offset in Hz measured by using the cyclic prefixes of all four OFDM symbols in the SSB.

  • correlation strength: The measured PSS correlation level.

  • signal energy: The total energy in the samples in which the PSS was detected.

In demodulation mode, the function attempts to find a specific SSB by using its timing offset and NCellID2. If the function finds the specified PSS, the receiver OFDM demodulates the SSB resource grid and attempts to detect its SSS. In demodulation mode, the function returns these results.

  • Updated parameters for only the specified SSB if the PSS is found.

  • The demodulated SSB resource grid if the PSS is found.

  • The cell ID if the SSS is found.

The OFDM demodulator uses a 256-point FFT to demodulate the SSB resource grid, which contains 240 active subcarriers.

Timing Offsets

The cell search algorithm uses timing offsets to identify positions within the received waveform and intermediate signals. A timing offset is the number of samples from the start of the waveform to a given position, such as the start of an SSB. Timing offsets are given in samples at 61.44 Msps and wrap around every 20 ms, or 1228800 samples. In 5G NR, receivers can assume that the SS burst periodicity is 20 ms or less for cell search purposes, hence the reason for this choice of timing reference periodicity.

The figure shows two 5G waveforms with different SS burst periodicities (5 ms and 20 ms) and the receiver timing reference. The MATLAB reference can detect SSBs at any position within the received waveform. However, if the waveform is longer than 20 ms, ambiguity in the returned timing offsets exists because the timing reference wraps around every 20 ms. Additionally, the receiver can demodulate only SSBs that begin within the first 20 ms of the waveform.

SSB Decoding

The diagram shows the structure of the SSB decoder, which is implemented by the nrhdlexamples.ssbDecode function. The algorithm takes the SSB resource grid from the OFDM demodulation phase of the SSB detector, processes it through PBCH and BCH decoding, and outputs MIB parameters and PBCH timing information.

PBCH decoding takes the demodulated OFDM symbols of the resource grid and processes using these steps:

  • DMRS Search: Searches for the index used for demodulation reference symbol (DMRS) generation.

  • Channel Estimation: Calculates an estimate of the channel using the DMRS.

  • Channel Equalization: Equalizes the received data using the channel estimate.

  • Symbol Demod: Performs QPSK demodulation to get the PBCH soft bits.

  • Descramble: Descrambles the soft bits.

BCH Decode then processes the descrambled soft bits to recover the MIB data using these steps:

  • Rate Recovery: Combines repeated soft bits then performs scaling and quantization.

  • Polar Decode + CRC: Performs polar decoding to get the message bits and CRC decoding to check for errors.

  • MIB Message Parse: Interprets the decoded message bits to produce the MIB parameter outputs.

SIB1 Demodulation

The diagram shows the structure of the SIB1 Demodulator algorithm, which is implemented by the nrhdlexamples.sib1Demodulate function. The algorithm accepts samples at 61.44 MHz, and uses the results from the previous processing stages to locate and demodulate a grid containing CORESET0 and the scheduled SIB1 transmission. The MIB results are used to calculate the parameters of CORESET0, which includes the frequency offset, number of resource blocks, and the monitoring occasion. The frequency offset is relative to the location of the detected SSB. The first stage of data processing is a DDC which performs a frequency shift to center the SIB1 grid and then downsamples to 30.72 MHz - the maximum bandwidth for CORESET0 in FR1. The next stage is to wait for the CORESET0 monitoring occasion - the algorithm contains a timing reference that is synchronized with the SSB Detector timing references to identify the next occurance of the monitioring occasion. Once the monitoring occasion is reached the received samples are OFDM demodulated to produce a grid CORESET0 resource blocks wide and two slots in duration.

SIB1 Decoding

SIB1 decoding is performed on the SIB1 grid output by SIB1 demodulation. SIB1 decoding requires decoding of PDCCH to recover the SI-RNTI encoded DCI message, and decoding PDSCH to recover SIB1 message. nrhdlexamples.pdcchDecoding uses the SIB1 grid and the parameters recovered from the previous decoding stages to locate and decode the PDCCH for CORESET0. This function returns the DCI message which signals the location of the PDSCH resources allocated to SIB1, and returns a flag indicating whether the DCI was found in the first or second slot of the SIB1 grid. The slot carrying PDSCH and PDSCH for SIB1 is selected from the SIB1 grid and nrhdlexamples.coreset0PhaseAdjustment corrects for the phase offset applied on an OFDM symbol basis by the transmitter, as detailed in TS 38.211 section 5.4. nrhdlexamples.pdschDecoding uses the phase corrected slot grid, the DCI message, and other information from the previous decoding stages to locate and decode the PDSCH resources carrying the SIB1 message. This funtion returns the SIB1 message bits and the result of the SIB1 CRC check. A CRC value of 0 indicates successful recovery of the SIB1.

Generate a Test Waveform

This section shows how to use the MATLAB reference functions to search for SSBs in a waveform, demodulate and decode an SSB to recover the MIB, and recover the scheduled SIB1.

Use the nrhdlexamples.generateFR1RxWaveform function to generate a 5G FR1 waveform containing SSB bursts and the corresponding SIB1 transmissions. Change the simulationCase to explore different parameter sets. The full set of simulation cases is shown.

disp('Test waveform configurations:')
disp(nrhdlexamples.generateFR1RxWaveform('list'));

rng('default');

simulationCase = "SimCase 1";
[rxWaveform,ssbPattern,minChanBW,Lmax,txMIB,simCase] = nrhdlexamples.generateFR1RxWaveform(simulationCase);

disp("Selected Simulation case:" + newline);
disp(simCase);

FoCoarse = 0;

if ssbPattern == "Case A"
    scsSSB = 15;
else
    scsSSB = 30;
end
Test waveform configurations:
    Simulation Case    SSB Pattern    Subcarrier Spacing Common    PDCCH Config SIB1    SNR dB    Strongest SSB index    Lmax
    _______________    ___________    _________________________    _________________    ______    ___________________    ____

      "SimCase 1"       "Case C"                 30                       164             50               4              8  
      "SimCase 2"       "Case B"                 15                       100              5               7              8  
      "SimCase 3"       "Case A"                 30                         4             20               2              8  
      "SimCase 4"       "Case A"                 15                        84              7               0              4  

Selected Simulation case:

    Simulation Case    SSB Pattern    Subcarrier Spacing Common    PDCCH Config SIB1    SNR dB    Strongest SSB index    Lmax
    _______________    ___________    _________________________    _________________    ______    ___________________    ____

      "SimCase 1"       "Case C"                 30                       164             50               4              8  

Plot the spectogram of the waveform.

The plot shows a spectogram of the SSBs, CORESET0s, and PDSCH regions carrying SIB1. These regions are generated with different power levels. The amplitude of each resource element is indicated by its color.

figure(1); clf;
rxSampleRate = 61.44e6;
nfft = rxSampleRate/(scsSSB*1e3);
spectrogram(rxWaveform(:,1),ones(nfft,1),0,nfft,'centered',rxSampleRate,'yaxis','MinThreshold',-110);
title('Spectrogram of the Received Waveform')

Detect SSBs

Use the nrhdlexamples.ssbDetect function to find SSBs in the waveform by searching for PSS symbols. This example calls the function with a coarse carrier frequency offset estimate of zero and a subcarrier spacing determined from the SSB pattern of the generated waveform. The function corrects the coarse frequency offset and measures the residual fine frequency offset of each SSB. Frequency offset input and output are given in Hz. The function returns a list of detected PSS symbols as a structure array. Display the structure array contents by converting it to a table.

[pssList,diagnostics] = nrhdlexamples.ssbDetect(rxWaveform,FoCoarse,scsSSB);

% Check if any PSS have been detected
if isempty(pssList)
    disp('No PSS found during SSB detection.');
    return;
end

disp('Detected PSS list:')
disp(struct2table(pssList));
Detected PSS list:
    NCellID2    timingOffset    pssCorrelation    pssEnergy    frequencyOffset
    ________    ____________    ______________    _________    _______________

       0               4416          0.742         0.74608            58      
       0              17568        0.59033         0.59277            -4      
       0              35136         1.4877          1.4951            15      
       0              48288         1.1708          1.1808            34      
       0              65856         4.6852          4.7073           -62      
       0              79008         1.0462          1.0523             3      
       0              96576          1.872          1.8807            14      
       0         1.0973e+05        0.93222         0.93665            -9      

The nrhdlexamples.ssbDetect function also returns a structure containing diagnostic signals. Use this output to plot the PSS correlation results. Each peak in the correlator output shown corresponds to an entry in the PSS list.

figure(2); clf;
nrhdlexamples.plotUtils.PSSCorrelation(diagnostics,'PSS Correlation');

Use the nrhdlexamples.ssbDetect function to OFDM-demodulate one of the SSBs and attempt SSS detection. For this operation, call the function with an optional 4th argument that specifies the timing offset and NCellID2 of the desired SSB. This example chooses the PSS with the highest correlation metric, however you can choose any of the detected SSBs. Correct the frequency offset by passing in the sum of the coarse and fine frequency offset estimates.

[~,maxCorrIdx] = max(vertcat(pssList.pssCorrelation));
chosenPSS = pssList(maxCorrIdx);

disp('Selected PSS:')
disp(struct2table(chosenPSS));

FoFine = chosenPSS.frequencyOffset;
FoEst = FoCoarse + FoFine;

[ssBlockInfo,ssbGrid,diagnostics] = nrhdlexamples.ssbDetect(rxWaveform,FoEst,scsSSB,chosenPSS);

% Check SSB successfully demodulated
if isempty(ssBlockInfo)
    disp('Failed to demodulate selected SSB.');
    return;
end
Selected PSS:
    NCellID2    timingOffset    pssCorrelation    pssEnergy    frequencyOffset
    ________    ____________    ______________    _________    _______________

       0           65856            4.6852         4.7073            -62      

In demodulation mode, the function returns three outputs instead of two. The ssBlockInfo structure contains further details of the SSB, such as the SSS correlation strength and the overall cell ID. The ssGrid output is a matrix containing the demodulated OFDM symbols. Display the SSB info to confirm that the cell ID is correctly decoded.

disp('SSB info for demodulated SSB:')
disp(ssBlockInfo);
SSB info for demodulated SSB:
           NCellID2: 0
       timingOffset: 65856
     pssCorrelation: 4.6852
          pssEnergy: 4.7074
           NCellID1: 83
     sssCorrelation: 4.7521
          sssEnergy: 4.7523
            NCellID: 249
    frequencyOffset: 0

Display the resulting SSB resource grid.

figure(3); clf;
imagesc(abs(ssbGrid));
colorbar;
axis xy;
xlabel('OFDM symbol');
ylabel('Subcarrier');
title('SSB Resource Grid');

The diagnostics output includes SSS correlation results for all 336 possible sequences. Plot the SSS correlation results.

figure(4); clf;
nrhdlexamples.plotUtils.SSSCorrelation(diagnostics,'SSS Correlation')

Search for Cells

This section shows how to use the nrhdlexamples.cellSearch function to search for and demodulate SSBs when the frequency offset and subcarrier spacing are not known. As described previously, the nrhdlexamples.cellSearch function builds on the nrhdlexamples.ssbDetect function by adding a search controller that looks for SSBs at different subcarrier spacings and frequency offsets.

Apply a frequency offset to test the coarse and fine frequency recovery functionality.

Fo           = 10000;
t            = (0:length(rxWaveform)-1).'/61.44e6;
rxWaveform = rxWaveform .* exp(1i*2*pi*Fo*t);

Define the frequency range endpoints and subcarrier spacing search space and call the nrhdlexamples.cellSearch function. The function displays information on the search progress as it runs. The frequency range endpoints must be multiples of half the maximum subcarrier spacing.

frequencyRange = [-30 30];
subcarrierSpacings = [15 30];

[ssBlockInfo,ssbGrid] = nrhdlexamples.cellSearch(rxWaveform,frequencyRange,subcarrierSpacings,struct(...
    'DisplayPlots',false,...
    'DisplayCommandWindowOutput',true));

% Check cell search successfully found and demodulated SSB.
if isempty(ssBlockInfo)
    disp('Cell search failed to find or demodulate SSB.');
    return;
end
Searching for PSS (subcarrierSpacing: 15 kHz, frequencyOffset: -30 kHz)
Searching for PSS (subcarrierSpacing: 15 kHz, frequencyOffset: -22.5 kHz)
Searching for PSS (subcarrierSpacing: 15 kHz, frequencyOffset: -15 kHz)
Searching for PSS (subcarrierSpacing: 15 kHz, frequencyOffset: -7.5 kHz)
Searching for PSS (subcarrierSpacing: 15 kHz, frequencyOffset: 0 kHz)
Searching for PSS (subcarrierSpacing: 15 kHz, frequencyOffset: 7.5 kHz)
Searching for PSS (subcarrierSpacing: 15 kHz, frequencyOffset: 15 kHz)
Searching for PSS (subcarrierSpacing: 15 kHz, frequencyOffset: 22.5 kHz)
Searching for PSS (subcarrierSpacing: 15 kHz, frequencyOffset: 30 kHz)
Searching for PSS (subcarrierSpacing: 30 kHz, frequencyOffset: -30 kHz)
Searching for PSS (subcarrierSpacing: 30 kHz, frequencyOffset: -15 kHz)
Searching for PSS (subcarrierSpacing: 30 kHz, frequencyOffset: 0 kHz) ... PSS detected.
Searching for PSS (subcarrierSpacing: 30 kHz, frequencyOffset: 15 kHz) ... PSS detected.
Found PSS with (subcarrierSpacing: 30 kHz, frequencyOffsetEstimate: 9938 Hz)
Correcting frequency offset and searching for PSS again.
Found the following PSS symbols:

    NCellID2    timingOffset    pssCorrelation    pssEnergy    frequencyOffset
    ________    ____________    ______________    _________    _______________

       0               4416        0.74199         0.74609           120      
       0              17568        0.59032         0.59278            58      
       0              35136         1.4877          1.4951            77      
       0              48288         1.1708          1.1809            96      
       0              65856         4.6852          4.7074             0      
       0              79008         1.0462          1.0523            65      
       0              96576         1.8721          1.8807            76      
       0         1.0973e+05        0.93221         0.93666            53      

Strongest PSS:
           NCellID2: 0
       timingOffset: 65856
     pssCorrelation: 4.6852
          pssEnergy: 4.7074
    frequencyOffset: 0

Attempting to reacquire strongest PSS and demodulate the corresponding SS block.
             NCellID2: 0
         timingOffset: 65856
       pssCorrelation: 4.6852
            pssEnergy: 4.7074
             NCellID1: 83
       sssCorrelation: 4.7521
            sssEnergy: 4.7523
              NCellID: 249
      frequencyOffset: 9938
    subcarrierSpacing: 30

Cell search summary:
  Subcarrier spacing: 30 kHz
    Frequency offset: 9938 Hz
       Timing offset: 65856
             NCellID: 249

As shown in the summary, the receiver returned the correct subcarrier spacing of 30 kHz, a cell ID of 249, and the measured frequency offset is close to the expected value of 10 kHz.

Decode SSB

Use the nrhdlexamples.ssbDecode function to decode the SSB resource grid and recover the MIB. The nrhdlexamples.ssbDecode function is based on the BCH decoding stages of the NR Cell Search and MIB and SIB1 Recovery (5G Toolbox) example.

[mibInfo,decodeDiags] = nrhdlexamples.ssbDecode(ssbGrid,ssBlockInfo.NCellID,Lmax);

% Check MIB successfully decoded from SSB.
if mibInfo.err
    disp('Failed to decode MIB from SSB.');
    return;
end

Plot the correlation peaks for the DMRS search. DMRS search is performed to determine ibar_ssb and the SSB index.

figure(5); clf;
plot(0:7,decodeDiags.dmrsCorr);
title('DMRS Search Correlation');
xlabel('ibar ssb');
ylabel('Correlation strength');

Plot the PBCH QPSK constellation after phase equalization.

figure(6); clf;
plot(decodeDiags.qpskSymb,'o');
xlim(max(abs(real(decodeDiags.qpskSymb))).*[-1.1 1.1]);
ylim(max(abs(imag(decodeDiags.qpskSymb))).*[-1.1 1.1]);
title('PBCH Symbol Constellation');
xlabel('In-phase');
ylabel('Quadrature');

Display the decoded information and compare the transmitted and received MIB structures. These results show that the information was successfully decoded.

disp(['BCH CRC: ' num2str(mibInfo.err) newline]);

disp('Decoded information');
disp(mibInfo);

disp('Decoded MIB');
disp(mibInfo.mib);

disp('Expected MIB');
disp(txMIB);
BCH CRC: 0

Decoded information
    pbchPayload: 17637376
       ssbIndex: 4
            hrf: 0
            err: 0
            mib: [1×1 struct]

Decoded MIB
                     NFrame: 0
    SubcarrierSpacingCommon: 30
                      k_SSB: 0
          DMRSTypeAPosition: 3
            PDCCHConfigSIB1: 164
                 CellBarred: 0
       IntraFreqReselection: 0

Expected MIB
                     NFrame: 0
    SubcarrierSpacingCommon: 30
                      k_SSB: 0
          DMRSTypeAPosition: 3
            PDCCHConfigSIB1: 164
                 CellBarred: 0
       IntraFreqReselection: 0

Demodulate the SIB1 Grid

The nrhdlexamples.sib1Demodulate function determines the location of CORESET0, using information decoded from previous stages, and OFDM demodulates the SIB1 grid. The SIB1 grid contains CORESET0 and the PDSCH resources allocated to the SIB1 message.

ssbFrequencyOffset = ssBlockInfo.frequencyOffset;

ssbResults = struct(...
        'SubcarrierSpacing', scsSSB, ...
        'TimingOffset', ssBlockInfo.timingOffset, ...
        'FrequencyOffset', ssbFrequencyOffset);

bandCfg = struct( ...
        'ssbPattern', ssbPattern, ...
        'Lmax', Lmax, ...
        'MinChanBW', minChanBW ...
        );

sib1Grid = nrhdlexamples.sib1Demodulate(rxWaveform,ssbResults,mibInfo,bandCfg);

Plot the OFDM demodulated SIB1 grid.

figure_SIB1grid = figure(7); clf;
imagesc(abs(sib1Grid));
colorbar;
axis xy;
xlabel('OFDM symbol');
ylabel('Subcarrier');
title('SIB1 Grid');

Decode the SIB1 Grid

The SIB1 grid consists of 2 slots. Only one of these slots carries CORESET0 and the PDSCH with SIB1. nrhdlexamples.pdcchDecoding searches within each of the slots for DCI messages encoded with SI-RNTI. Once decoded, the SI-RNTI encoded DCI message provides information on the location of the SIB1 message within the PDSCH. nrhdlexamples.pdschDecoding uses the DCI and information from the previous stages to locate and decode the SIB1 message within the PDSCH. If successfully decoded the sib1CRC will be 0, and the SIB1 message bits output.

% Decode PDCCH and recover DCI message
[dci,dciCRC,NSlot,secondSlotFlag,coresetNRB] = nrhdlexamples.pdcchDecoding(sib1Grid,ssBlockInfo.NCellID,mibInfo.ssbIndex,scsSSB,mibInfo.mib,minChanBW);

% Check DCI successfully decoded from PDCCH.
if dciCRC
    disp('Failed to decode DCI from PDCCH.');
    return;
end

% Update SIB1 grid plot to highlight PDCCH and PDSCH areas
nrhdlexamples.plotUtils.labelSIB1Plot(figure_SIB1grid.Number,size(sib1Grid),ssBlockInfo.NCellID,mibInfo.ssbIndex,scsSSB,mibInfo.mib,minChanBW,secondSlotFlag,dci);

% Select slot containing SIB1 message
slotGrid = sib1Grid(:,(1:14)+(14*secondSlotFlag));

% Adjust for phase offset applied by transmitter
correctedSlotGrid = nrhdlexamples.coreset0PhaseAdjustment(slotGrid,mibInfo.mib,scsSSB,minChanBW,0);

% Decode PDSCH and recover SIB1 message bits
[sib1bits,sib1CRC] = nrhdlexamples.pdschDecoding(correctedSlotGrid,ssBlockInfo.NCellID,mibInfo.mib,coresetNRB,dci,NSlot);

if sib1CRC == 0
    disp('SIB1 successfully decoded');
else
    disp('SIB1 decoding failed');
end
PDCCH RMS EVM: 0.606%
SIB1 successfully decoded

Related Topics