# Hardware Accelerators for NR SIB1 Recovery

This example shows the design of 5G SIB1 accelerators optimized for HDL code generation and hardware implementation.

### Introduction

The Simulink® models described in this example are fixed-point HDL optimized implementations of hardware accelerators for SIB1 recovery for 5G NR. The example details three individual hardware accelerators that perform:

SIB1 grid recovery

CORESET0 decoding

SIB1 LDPC decoding

The SIB1 grid recovery algorithm is designed and optimized for frequency range 1 (FR1). The CORESET0 and SIB1 LDPC decoding algorithms support both frequency ranges. The NR HDL SIB1 Recovery example shows how to integrate hardware accelerators with SSB detection and decoding designs to implement a complete SIB1 recovery model. A design supporting both FR1 and FR2 is implemented in the NR HDL SIB1 Recovery for FR2 example.

This example is one of a related set, for more information see NR HDL Reference Applications Overview.

### File Structure

This example uses these files.

Simulink models

`nrhdlSIB1Demodulation.slx`

: This Simulink model references the`nrhdlDDCFR1Core`

and`nrhdlSIB1DemodulationFR1Core`

models to simulate the SIB1 grid demodulation step of SIB1 recovery.`nrhdlCORESET0Decoding.slx`

: This model references the`nrhdlCORESET0DecodingCore`

and`nrhdlPolarDecodingChainCore`

models to simulate the CORESET0 decoding step of SIB1 recovery.`nrhdlSIB1LDPCDecoding.slx`

: This model references the`nrhdlLDPCDecodingChainCore`

model to simulate the SIB1 LDPC decoding step of SIB1 recovery.`nrhdlDDCFR1Core.slx`

: This model implements a DDC to create sample streams for SIB1 and SSBs.`nrhdlSIB1DemodulationFR1Core.slx`

: This model implements the SIB1 demodulation algorithm.`nrhdlCORESET0DecodingCore.slx`

: This model implements the CORESET0 decoding algorithm.`nrhdlPolarDecodingChainCore.slx`

: This model implements the common polar decoding chain.`nrhdlLDPCDecodingChainCore.slx`

: This model implements the SIB1 LDPC decoding algorithm.

Simulink data dictionary

`nrhdlReceiverData.sldd`

: This Simulink data dictionary contains bus objects that define the buses contained in the example models.

MATLAB code

`runSIB1AcceleratorModels.m`

: This script uses the MATLAB reference to implement the MIB recovery algorithm, then runs the`nrhdlSIB1Demodulation`

,`nrhdlCORESET0Decoding`

, and`nrhdlSIB1LDPCDecoding`

Simulink models. The script verifies the operation of the model using 5G Toolbox™ and the MATLAB reference code.`nrhdlexamples`

: Package containing the MATLAB reference code and utility functions for verifying the implementation models.

### NR HDL SIB1 Demodulation

This figure shows the `nrhdlSIB1Demodulation`

model. The top level of the model reads the signals from the MATLAB base workspace, passes them to the SIB1 Demodulation subsystem, and writes the outputs back to the workspace.

```
models.DemodulationTop = 'nrhdlSIB1Demodulation';
open_system(models.DemodulationTop);
```

### SIB1 Demodulation Subsystem

The SIB1 Demodulation subsystem references the `nrhdlDDCFR1Core`

and `nrhdlSIB1DemodulationFR1Core`

models. The algorithm of the `nrhdlSIB1DemodulationFR1Core`

model is described in the next section. For details about the `nrhdlDDCFR1Core`

model see the NR HDL Cell Search example. The output of the DDC is the input to the SIB1 Demodulation algorithm. The frequency offset applied to the DDC combines the SSB frequency offset estimation term, from a successful MIB recovery, with the SSB to SIB1 offset. The combined frequency offset centers CORESET0 in the received waveform.

set_param([models.DemodulationTop '/SIB1 Demodulation'],'Open','on');

Inputs

*dataIn*: 14-bit signed complex-valued signal, sampled at 61.44 Msps.*validIn*: 1-bit control signal to validate*dataIn*.*paramsIn*: Bus of type SIB1GridParamBus.*start*: 1-bit control signal used to start a SIB1 grid recovery operation.*clearStatus*: 1-bit control signal used to clear the state of the status signal.

SIB1GridParamBus

*ssbTimingOffset*: 21-bit unsigned value that is the timing offset of the detected SSB. The timing offset is in samples at 61.44 Msps from 0 to 1228799.*scsSSB*: 2-bit unsigned value specifying the subcarrier spacing (SCS) of the detected SSB. Set this signal to 0 to select 15 kHz, or 1 to select 30 kHz.*ssbIndex3Lsb*: 3-bit unsigned value that is the 3 least significant bits of the SSB index.*pbchPayload*: 32-bit unsigned value that contains the MIB and additional PBCH timing data.*minChanBW*: 2-bit unsigned value specifying the minimum channel bandwidth. A value of 0 indicates 5 MHz, 1 indicates 10 MHz, and 2 indicates 40 MHz.*ssbPattern*: 2-bit unsigned value specifying the SSB pattern. A value of 0 indicates 'Case A', 1 indicates 'Case B', and 2 indicates 'Case C'.*Lmax*: 2-bit unsigned number which indicates the maximum number of SSBs in a burst. A value of 0 indicates 4 SSBs, a value of 1 indicates 8 SSBs, a value of 2 indicates 64 SSBs.

Outputs

*status*: 2-bit unsigned value indicating the progress of the SIB1 demodulation operation.*dataOut*: 16-bit signed complex-valued SIB1 resource grid data. The algorithm outputs the 28 OFDM symbols of the SIB1 grid, one resource element (RE) per cycle.*validOut*: 1-bit control signal that validates the*dataOut*output.*coreset0Resources*: Bus of type coreset0ResourcesBus.*coreset0Occasion*: Bus of type coreset0OccasionBus.*parsedMIB*: Bus of type MIBBus.

coreset0ResourcesBus

*resourceBlocks*: 2-bit unsigned value specifying the number of resource blocks. A value of 0 indicates 24, 1 indicates 48, and 2 indicates 96.*ofdmSymbols*: 2-bit unsigned value that is the number of OFDM symbols CORESET0 spans.*frequencyOffset*: 32-bit signed value specifying the relative frequency offset from the SSB to CORESET0. This signal is connected to an NCO with a 32-bit accumulator. Use this equation to convert the value to Hz:*frequencyOffset_Hz*=*frequencyOffset** 61.44e6 / 2^32.*muxPattern*: 2-bit unsigned value specifying the CORESET0 multiplexing pattern.

coreset0OccasionBus

*slotOffset*: 8-bit unsigned value that is the slot offset from the even frame head to the first monitored slot.*firstSymbol*: 4-bit unsigned value specifying the first occupied OFDM symbol in the slot.

MIBBus

*sfn*: 10-bit unsigned value that is the system frame number (SFN).*scsCommon*: 1-bit unsigned value specifying the common subcarrier spacing. A value of 0 indicates 15 kHz, and 1 indicates 30 kHz.*Kssb*: 5-bit unsigned value that is the offset between the SSB and the overall resource block grid.*drmsTypeAPos*: 1-bit unsigned value specifying the position of the DMRS symbol for PDSCH allocation type A, where 0 represents position 2 and 1 indicates position 3.*pdcchConfigSIB1*: 8-bit unsigned value containing the configuration for CORESET0*cellBarred*: 1-bit value indicating whether the cell is barred.*intraFreqReselection*: 1-bit value indicating whether intra frequency reselection is allowed.*hrf*: 1-bit value that is the half frame bit.*ssbIdx*: 3-bit value that is the index of the SSB.

Status Signal States

`0`

: Initial state. Waiting for start pulse.`1`

: Waiting for the CORESET0 timing occasion.`2`

: OFDM demodulating and outputting the SIB1 grid data.

### SIB1 Demodulation Model

This diagram shows the top level of the `nrhdlSIB1DemodulationFR1Core`

model. The design operates on IQ data at 61.44 MHz sample rate and requires parameters from a successful MIB recovery. The start signal begins a SIB1 demodulation operation, set this signal to 1 when all input ports on the paramsIn bus are valid. You must hold the values on paramsIn constant for the duration of the demodulation.

models.DemodulationCore = 'nrhdlSIB1DemodulationFR1Core'; load_system(models.DemodulationCore); set_param(models.DemodulationCore,'SimulationCommand','Update'); set_param([models.DemodulationCore '/SIB1DemodulationCore'],'Open','on');

When the `OFDM Demod`

subsystem recives a start signal, it OFDM demodulates the input data and outputs the SIB1 grid. The subsystem computes a variable size FFT, with configurable cyclic prefix length and number of guard subcarriers. The FFT size is selected depending on the subcarrier spacing of the SIB1 grid. For SCS 15 a 2048-point FFT is used, and for SCS 30 a 1024-point FFT is used. These values correspond to the sample rate of 30.72 MHz. The cyclic prefix length varies during OFDM demodulation of the SIB1 grid to account for the longer cyclic prefix symbols present at the halfsubframe boundaries. The number of guard subcarriers is used to extract the SIB1 grid from the full demodulation bandwidth.

The `OFDM Demod`

subsystem requires configuration values to successfully demodulate the SIB1 grid. These values are computed from the results of MIB recovery. The `SIB1 Config`

subsystem constructs the MIB from the PBCH payload and parses the `pdcchSIB1Config`

field to determine `coreset0Resources`

and `coreset0TimingOccasion`

. The `coreset0Resources`

signal contains the frequency offset from the SSB to CORESET0 and the bandwidth of the CORESET0 resource grid. The `coreset0TimingOccasion`

signal contains the slot offset from the even SFN frame head to the first monitored slot i.e. the slot within 2 system frames. The monitored slot timing offset subsystem converts the `coreset0TimingOccasion`

slot offset to a timing reference count. The SSB pattern, SSB index, and SSB timing reference are used to compute the timing reference of the even SFN frame head, from which the timing reference value of CORESET0 is computed. A timing reference counter, synchronized with the SSB detection references, is used to track the SIB1 data stream. Once the start signal is asserted, the startController waits for the SIB1 timing reference to reach the target offset computed by the monitored slot timing offset subsystem and then triggers the OFDM demodulation to begin. The diagram shows an example of the timing references for the monitored SSB, the even frame head, and the CORESET0 timing occasion. These offsets depend on the configuration of the transmitting cell.

### NR HDL CORESET0 Decoding

This figure shows the `nrhdlCORESET0Decoding`

model. The top level of the model reads the signals from the MATLAB base workspace, passes them to the CORESET0 Decoding subsystem, and writes the outputs back to the workspace.

```
models.CORESET0Top = 'nrhdlCORESET0Decoding';
open_system(models.CORESET0Top);
```

### CORESET0 Decoding Subsystem

The CORESET0 Decoding subsystem references the `nrhdlCORESET0DecodingCore`

and `nrhdlPolarDecodingChainCore`

models. The algorithm of the `nrhdlCORESET0DecodingCore`

model is described in the next section. The `nrhdlPolarDecodingChainCore`

model is covered in the NR HDL MIB Recovery example. The subsystem performs channel estimation and equalization, QPSK symbol demodulation, descrambling, rate recovery, polar decoding, and CRC decoding of CORESET0 candidates. The design provides back pressure with the nextFrame signal to indicate when it can accept a new candidate. The processing is split over two models to allow for the `nrhdlPolarDecodingChainCore`

to be shared between the SSB decoding and SIB1 CORESET0 decoding in the NR HDL SIB1 Recovery example. This section describes the inputs and outputs for the subsystem.

set_param([models.CORESET0Top '/CORESET0 Decoding'],'Open','on');

Inputs

*gridDataIn*: 16-bit signed CORESET0 candidate OFDM grid data.*gridCtrlIn*: Sample control bus signal to validate*gridDataIn*.*NSym*: 4-bit OFDM symbol number for the current resource element group (REG).*baseRBIdx*: 7-bit base CORESET0 resource block index for the current REG.*searchSpaces*: 3-bit unsigned vector of length 3 indicating the number of search spaces at aggregation levels 4, 8, and 16.*coreset0Syms*: 2-bit unsigned value that is the number of OFDM symbols CORESET0 spans.*coreset0RBs*: 2-bit unsigned value specifying the number of resource blocks. A value of 0 indicates 24, 1 indicates 48, and 2 indicates 96.*NSlot*: 7-bit unsigned value that specifies the slot number for the first monitored CORESET0 slot.*NCellID*: 10-bit unsigned value that is the cell ID of the demodulated SSB.*restart*: 1-bit control signal to restart the processing.

Outputs

*status*: 3-bit unsigned value indicating the progress of the CORESET0 decoding process.*dciData*: 41-bit unsigned data that contains the final decoded DCI.*firstOrSecondSlot*: 1-bit value indicating if the decoded DCI was found in the first (0) or second (1) monitored slot.*searchFailed*: 1-bit value indicating that the CORESET0 DCI search failed.*dciValid*: 1-bit value indicating the search is complete.*nextFrame*: 1-bit signal to provide back pressure to signal when the next candidate can be input.

Status Signal States

`0`

: Initial state. Waiting for start pulse.`1`

: Performing channel estimation, equalization, symbol demodulation and descrambling.`2`

: Performing polar rate recovery.`3`

: Performing polar and CRC decoding.`4`

: Candidate decode failed, waiting for next attempt.`5`

: Decoded all candidates with no successes.`6`

: Successfully decoded the DCI from a candidate.

### CORESET0 Decoding Model

This diagram shows the top level of the `nrhdlCORESET0DecodingCore`

model. To decode CORESET0 a blind search is performed over multiple candidates. The correct candidate is determined by the CRC remainder equaling the SIB1 RNTI 65535. The design coordinates each search step and generates the required parameters to decode the candidate with the `nrhdlPolarDecodingChainCore`

model. After a candidate is decoded, the CRC result is checked. If the CRC passes, the decoded data is output on the *dciData* port. If the CRC fails, the algorithm signals with *nextFrame* that it is ready for the next candidate. If all candidates are decoded with no success then *searchFailed* is set high. The number of search candidates per slot is determined from the *searchSpaces* input, this signal is a vector of 3 values correpsonding to the number of candidates for the three possible aggregation values [4 8 16]. The design expects candidates to be input in decreasing order of aggregation level. The total number of searches is twice the search spaces since two slots are monitored for decoding. The *firstOrSecondSlot* output signals which slot the DCI was decoded in. The status signal can be used to monitor the progress of the decoding. Each candidate failure is indicated by state `4`

and the final result is signalled by either state `5`

(failure) or state `6`

(success).

models.coreset0Decoding = 'nrhdlCORESET0DecodingCore'; load_system(models.coreset0Decoding); set_param(models.coreset0Decoding,'SimulationCommand','Update'); set_param(models.coreset0Decoding,'Open','on');

### NR HDL SIB1 LDPC Decoding

This figure shows the `nrhdlSIB1LPDCDecoding`

model. The top level of the model reads the signals from the MATLAB base workspace, passes them to the SIB1 LDPC Decoding subsystem, and writes the outputs back to the workspace.

```
models.LDPCTop = 'nrhdlSIB1LDPCDecoding';
open_system(models.LDPCTop);
```

### SIB1 LDPC Decoding Subsystem

The `SIB1 LDPC Decoding`

subsystem references the `nrhdlLDPCDecodingChainCore`

model. The subsystem performs LDPC decoding, codeblock desegmentation, and CRC decoding. This section describes the inputs and outputs for the subsystem.

set_param([models.LDPCTop '/SIB1 LDPC Decoding'],'Open','on');

Inputs

*ldpcDta*: 16-bit signed LDPC codeword LLR data.*ldpcCtrl*: Sample control bus for validating*ldpcData*.*G*: 15-bit length of the input codeword.*ldpcZc*: 16-bit unsigned value indicating the lifting size used for the LDPC codeword.*tbs*: 12-bit unsigned value indicating the length of the decoded output data.*clearStatus*: 1-bit control signal used to clear the state of the status signal.

Outputs

*status*: 3-bit unsigned value indicating the progress of the SIB1 decoding process.*sib1Bits*: 1-bit data that is the final decoded SIB1 payload.*sib1BitsCtrl*: Sample control bus for validating*sib1Bits*.*sib1Err*: 1-bit value indicating if the SIB1 CRC failed.*diagnostics*: Bus containing diagnostic signals.

Status Signal States

`0`

: Initial state. Waiting for start pulse.`1`

: Performing LDPC rate recovery.`2`

: Performing LDPC decoding.`3`

: Performing CRC decoding.`4`

: Failed to decode SIB1.`5`

: Successfully decoded SIB1.

### SIB1 LDPC Decoding Model

This diagram shows the top level of the `nrhdlLDPCDecodingChainCore`

model. The design accepts input LLRs along with a sample control bus and additional constants. The first stage performs LDPC rate recovery, this includes signal scaling and wordlength reduction to prepare the data for LDPC decoding.The second stage decodes the LDPC data using min-sum layered belief propagation with lifting factor from input port. For the SIB1 use case only base graph 2 is supported so the **bgn** input is constant. The algorithm then performs codeblock desegmentation. For SIB1 this only requires the removal of the padding bits from the end of the data to produce a length of **tbs** + 16 CRC bits . The final stage performs CRC decoding using CRC16 with no scrambling. The decoded SIB1 bits and the error status are output. Additionally, a status port is provided to show the algorithms progress. The output from the rate recovery stage is provided on the diagnostic port.

models.ldpcDecoding = 'nrhdlLDPCDecodingChainCore'; load_system(models.ldpcDecoding); set_param(models.ldpcDecoding,'SimulationCommand','Update'); set_param([models.ldpcDecoding '/LDPC Decoding Chain'],'Open','on');

### SIB1 Accelerators Simulation Setup

The diagram shows the simulation setup implemented by this example. 5G Toolbox functions are used to generate a test waveform. MATLAB reference code is then used to perform the steps required for MIB recovery - SSB search, demodulation, and decoding. The results provide the input data for the SIB1 demodulation stage. The same input is passed to both MATLAB and Simulink implementations of SIB1 demodulation, and the output grids are directly compared. The CORESET0 candidates are extracted from the grid and decoded using MATLAB and Simulink. The DCI result is used to extract the SIB1 LDPC codeword from the resource grid and the final decode is performed in MATLAB and Simulink. At each stage MATLAB and Simulink results are compared to confirm their equivalence.

### SIB1 Accelerators Simulation

Use the `runSIB1AcceleratorModels`

script to run a SIB1 recovery simulation using the hardware accelerators. The script displays its progress at the MATLAB command prompt, and produces plots of inputs and outputs for analysis. The test bench supports multiple simulation cases. The full set of cases, and their parameters, are shown. This example shows the results of running "SimCase 1". The resource grids produced by MATLAB and Simulink from the SIB1 demodulation are displayed along with the difference between them and their relative mean squared error (MSE). The grid plots are labelled to highlight the decoded PDCCH and PDSCH. The DCI fields from CORESET0 decoding are displayed and the final SIB1 bits are compared. This comparison verifies that the Simulink implementations closely matches the MATLAB reference.

```
disp(nrhdlexamples.generateFR1RxWaveform('list'));
```

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 6 7 8 "SimCase 3" "Case A" 30 4 20 2 8 "SimCase 4" "Case A" 15 84 7 0 4

runSIB1AcceleratorModels;

runSIB1AcceleratorModels;

Generating test waveform. Searching for SSBs using MATLAB reference. Demodulating the strongest SSB using MATLAB reference. Decoding the demodulated SSB using MATLAB reference. Demodulating the SIB1 grid using MATLAB reference. Demodulating the SIB1 grid using Simulink model. Running nrhdlSIB1Demodulation.slx ### Starting serial model reference simulation build ### Model reference simulation target for nrhdlDDCFR1Core is up to date. ### Model reference simulation target for nrhdlSIB1DemodulationFR1Core is up to date. Build Summary 0 of 2 models built (2 models already up to date) Build duration: 0h 0m 0.76361s ................... MATLAB and Simulink grids relative MSE : -62.453 dB Extracting CORESET0 candidates from the SIB1 grid. Decoding CORESET0 candidates using MATLAB reference. Decoding CORESET0 candidates using Simulink. Running nrhdlCORESET0Decoding.slx ### Starting serial model reference simulation build ### Model reference simulation target for nrhdlCORESET0DecodingCore is up to date. ### Model reference simulation target for nrhdlPolarDecodingChainCore is up to date. Build Summary 0 of 2 models built (2 models already up to date) Build duration: 0h 0m 0.92363s .......... DCI from MATLAB: RIV: 528 TDDIndex: 0 VRBToPRBInterleaving: 0 ModCoding: 0 RV: 0 SIIndicator: 0 Reserved: 0 DCI from Simulink: RIV: 528 TDDIndex: 0 VRBToPRBInterleaving: 0 ModCoding: 0 RV: 0 SIIndicator: 0 Reserved: 0 DCI successfully decoded from Simulink grid with hardware acceleration Extracting LDPC codeword from the SIB1 grid. Decoding SIB1 using MATLAB reference. Decoding SIB1 using Simulink. Running nrhdlSIB1LDPCDecoding.slx ### Starting serial model reference simulation build ### Model reference simulation target for nrhdlLDPCDecodingChainCore is up to date. Build Summary 0 of 1 models built (1 models already up to date) Build duration: 0h 0m 0.61133s .......... SIB1 successfully decoded from Simulink grid with hardware acceleration SIB1 bits from MATLAB and Simulink match

### HDL Code Generation and Implementation Results

To generate the HDL code for this example, you must have an HDL Coder™ license. Use the `makehdl`

and `makehdltb`

commands to generate HDL code and an HDL test bench for the `nrhdlSIB1Demodulation/SIB1 Demodulation`

, `nrhdlCORESET0Decoding/CORESET0 Decoding`

or `nrhdlSIB1LDPCDecoding/SIB1 LDPC Decoding`

subsystems. The resulting HDL code was synthesized for a Xilinx® Zynq®-7000 ZC706 evaluation board. The table shows the post place and route resource utilization results. The design meets timing with a clock frequency of 150 MHz.

Resource utilization for nrhdlSIB1Demodulation model:

T = table(... categorical({'Slice Registers'; 'Slice LUTs'; 'RAMB18'; 'RAMB36'; 'DSP48'}),... [12932; 7338; 19; 10; 35],... 'VariableNames',{'Resource','Usage'}); disp(T);

Resource Usage _______________ _____ Slice Registers 12932 Slice LUTs 7338 RAMB18 19 RAMB36 10 DSP48 35

Resource utilization for nrhdlCORESET0Decoding model:

T = table(... categorical({'Slice Registers'; 'Slice LUTs'; 'RAMB18'; 'RAMB36'; 'DSP48'}),... [8291; 11073; 8; 4; 16],... 'VariableNames',{'Resource','Usage'}); disp(T);

Resource Usage _______________ _____ Slice Registers 8291 Slice LUTs 11073 RAMB18 8 RAMB36 4 DSP48 16

Resource utilization for nrhdlSIB1LDPCDecoding model:

T = table(... categorical({'Slice Registers'; 'Slice LUTs'; 'RAMB18'; 'RAMB36'; 'DSP48'}),... [61821; 42092; 289; 20; 3],... 'VariableNames',{'Resource','Usage'}); disp(T); fields = fieldnames(models); for k=1:length(fields) close_system(models.(fields{k}),0); end

Resource Usage _______________ _____ Slice Registers 61821 Slice LUTs 42092 RAMB18 289 RAMB36 20 DSP48 3