Main Content

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

The NR HDL Cell Search and MIB Recovery 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 and MIB recovery algorithm to hardware is shown.

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

*MATLAB Golden Reference Algorithm*: The NR Cell Search and MIB and SIB1 Recovery (5G Toolbox) example shows the floating-point golden reference algorithm.*MATLAB Hardware Reference Algorithm*: The NR HDL Cell Search and MIB Recovery MATLAB Reference (this example) 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.*Simulink Fixed-Point Implementation Model*: 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 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.*Simulink SoC Deployment Model*: The Deploy NR HDL Reference Applications on SoCs examples 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.

A block diagram of the cell search and MIB recovery algorithm is shown. The algorithm detects, demodulates, and decodes 5G NR synchronization signal blocks (SSBs) and 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 and an SSB 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) however the MATLAB reference code supports both FR1 and FR2. See NR HDL MIB Recovery for FR2 for an example of how to use the MATLAB reference for FR2.

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.

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

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.

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.

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

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

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.

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.

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, UEs 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.

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.

This section shows how to use the MATLAB reference functions to search for SSBs in a waveform.

Use the `nrhdlexamples.generateFR1SSBurstWaveform`

function to generate an SS burst waveform. This function is based on the Synchronization Signal Blocks and Bursts (5G Toolbox) example. The burst has these parameters.

SSB pattern is case B.

Subcarrier spacing is 30 kHz.

NCellID is 249.

Active SSBs within the burst is 8.

```
rng('default');
[rxWaveform,txGrid,txMIB] = nrhdlexamples.generateFR1SSBurstWaveform();
```

Plot the resource grid of the burst waveform. The amplitude of each resource element is indicated by its color. The plot shows eight SSBs. The SSBs are generated with different power levels to model what a UE typically receives.

figure(1); clf; imagesc(abs(txGrid)); colorbar; axis xy; xlabel('OFDM symbol'); ylabel('Subcarrier'); title('SS Burst - Block Pattern Case B');

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 of 30. The function corrects the coarse frequency offset and measures the residual fine frequency offset of each SSB. Frequency offset input and output are give 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.

FoCoarse = 0; scs = 30; [pssList,diagnostics] = nrhdlexamples.ssbDetect(rxWaveform,FoCoarse,scs); disp(struct2table(pssList));

NCellID2 timingOffset pssCorrelation pssEnergy frequencyOffset ________ ____________ ______________ _________ _______________ 0 6608 0.69435 0.70703 7 0 15376 1.3933 1.4119 -51 0 32944 0.43994 0.44712 -207 0 41712 7.1226 7.2182 -154 0 68048 0.84535 0.88463 204 0 76816 2.1805 2.245 140 0 94384 0.2794 0.28375 488 0 1.0315e+05 0.8552 0.89668 132

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); FoFine = chosenPSS.frequencyOffset; FoEst = FoCoarse + FoFine; [ssBlockInfo,ssGrid,diagnostics] = nrhdlexamples.ssbDetect(rxWaveform,FoEst,scs,chosenPSS);

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(ssBlockInfo);

NCellID2: 0 timingOffset: 41712 pssCorrelation: 7.1219 pssEnergy: 7.2185 NCellID1: 83 sssCorrelation: 7.1383 sssEnergy: 7.1743 NCellID: 249 frequencyOffset: 0

Display the resulting resource grid.

figure(3); clf; imagesc(abs(ssGrid)); colorbar; axis xy; xlabel('OFDM symbol'); ylabel('Subcarrier'); title('Rx 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')
```

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; rxWaveformFo = 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,ssGrid] = nrhdlexamples.cellSearch(rxWaveformFo,frequencyRange,subcarrierSpacings,struct(... 'DisplayPlots',false,... 'DisplayCommandWindowOutput',true));

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: 9846 Hz) Correcting frequency offset and searching for PSS again. Found the following PSS symbols: NCellID2 timingOffset pssCorrelation pssEnergy frequencyOffset ________ ____________ ______________ _________ _______________ 0 6608 0.69422 0.70705 161 0 15376 1.3933 1.412 103 0 32944 0.43981 0.44714 -53 0 41712 7.1219 7.2185 0 0 68048 0.84567 0.88466 358 0 76816 2.1812 2.2451 294 0 94384 0.2793 0.28376 642 0 1.0315e+05 0.85524 0.89673 286 Strongest PSS: NCellID2: 0 timingOffset: 41712 pssCorrelation: 7.1219 pssEnergy: 7.2185 frequencyOffset: 0 Attempting to reacquire strongest PSS and demodulate the corresponding SS block. NCellID2: 0 timingOffset: 41712 pssCorrelation: 7.1219 pssEnergy: 7.2185 NCellID1: 83 sssCorrelation: 7.1383 sssEnergy: 7.1743 NCellID: 249 frequencyOffset: 9846 subcarrierSpacing: 30 Cell search summary: Subcarrier spacing: 30 kHz Frequency offset: 9846 Hz Timing offset: 41712 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.

Use the `nrhdlexamples.ssbDecode`

function to decode the 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(ssGrid,ssBlockInfo.NCellID,8);

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'); 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: 218103952 ssbIndex: 3 hrf: 0 err: 0 mib: [1×1 struct] Decoded MIB NFrame: 105 SubcarrierSpacingCommon: 30 k_SSB: 0 DMRSTypeAPosition: 2 PDCCHConfigSIB1: 0 CellBarred: 0 IntraFreqReselection: 0 Expected MIB NFrame: 105 SubcarrierSpacingCommon: 30 k_SSB: 0 DMRSTypeAPosition: 2 PDCCHConfigSIB1: 0 CellBarred: 0 IntraFreqReselection: 0