%% NR HDL Cell Search
% This example shows the design of a 5G NR cell search subsystem optimized
% for HDL code generation and hardware implementation.

% Copyright 2019-2020 The MathWorks, Inc.

%% Introduction
%
% The Simulink model described in this example is an HDL optimized implementation 
% of a synchronization signal block (SSB) detector for 5G NR cell search.
% This example is one of a related set which show the workflow for designing and 
% deploying a 5G NR cell search and MIB recovery algorithm to hardware.
% The figure shows the complete set of examples and the current
% example within the workflow. For more details on the overall algorithm and
% workflow, see the 
% <docid:whdl_ug#example-nrhdlCellSearchAndMIBRecoveryMLref NR HDL Cell Search and MIB Recovery MATLAB Reference>
% example. The
% <docid:xilinxzynqbasedradio_ug#mw_b204ff68-0a8b-46d9-82a9-9e0bd6dc7535 5G NR MIB Recovery Using Analog Devices AD9361/AD9364>
% example shows how to deploy the algorithm to an SoC.
% For a general description of how MATLAB and Simulink can be
% used together to develop deployable models, see
% <docid:comm_ug#mw_d7d1f97b-7349-4122-9ca7-0b687bdd676e Wireless
% Communications Design for FPGAs and ASICs>.
% 
% <<../NRHDLCellSearchWorkflow.png>>
% 
% A block diagram of the SSB detector is shown in the figure.
% This performs all of the high speed signal processing
% tasks associated with the cell search algorithm therefore is well suited for
% FPGA or ASIC implementation.
% The SSB detector searches for SSBs in time at a given
% frequency offset and subcarrier spacing. It is designed to be
% used as part of a larger system that implements
% carrier frequency offset recovery and subcarrier spacing detection.
% A controller must be used co-ordinate the overall cell search
% as shown in the 
% <docid:xilinxzynqbasedradio_ug#mw_b204ff68-0a8b-46d9-82a9-9e0bd6dc7535 5G NR MIB Recovery Using Analog Devices AD9361/AD9364>
% example.
% 
% The SSB detector performs primary synchronization sequence (PSS) search, 
% orthogonal frequency division multiplexing (OFDM) demodulation, and secondary 
% synchronization sequence (SSS) search. It also includes a digital down converter
% (DDC) for correcting frequency offsets in the received signal.
%  
% <<../NRHDLCellSearchSSBDetectorSL.png>>
%

%% File Structure
%
% This example uses these files.
%
% * |nrhdlexamples.runSSBDetectionModel|:
%   This script runs the |nrhdlSSBDetection| model by calling the
%   |nrhdlexamples.ssbDetectSimulink| function and verifies the model by 
%   using 5G Toolbox functions and the <docid:whdl_ug#example-nrhdlCellSearchAndMIBRecoveryMLref NR HDL Cell Search and MIB Recovery MATLAB Reference>.   
% * |nrhdlexamples.ssbDetectSimulink|:
%   This function runs the Simulink model and has the same input and output 
%   arguments as the |nrhdlexamples.ssbDetect| function from the MATLAB reference.
% * |nrhdlSSBDetection|:
%   This top-level Simulink model is a lightweight wrapper that instantiates 
%   the |nrhdlSSBDetectionCore| model reference. 
% * |nrhdlSSBDetectionCore|:
%   This model reference implements the SSB detection algorithm.
%
% This example also uses helper functions from the |nrhdlexamples| package.
% The Simulink models and the |nrhdlexamples| package are on the MATLAB path.
% To open one of the models, enter its name at the MATLAB command prompt.
%
%   nrhdlSSBDetection
%
% To open a function or script from the |nrhdlexamples| package, use the 
% edit command.
% 
%   edit nrhdlexamples.runSSBDetectionModel
%

%% NR HDL Cell Search Model
%
% This figure shows the |nrhdlSSBDetection| model. The top level of the model
% reads signals from the MATLAB base workspace, passes them to
% the SS Block Detection subsystem, and writes the outputs back to the
% workspace. To run the model, call the |nrhdlexamples.runSSBDetectionModel|
% script in MATLAB.

models.top = 'nrhdlSSBDetection';
open_system(models.top);
set_param(models.top,'Open','on');
set(allchild(0),'Visible','off');

%% SS Block Detection Interface
% 
% The SS Block Detection subsystem contains a Model block
% that references the |nrhdlSSBDetectionCore| model.
% This section describes the inputs and outputs of that model.

set_param([models.top '/SS Block Detection'],'Open','on');

%%
% *Inputs*
% 
% * _dataIn_: 14-bit signed complex-valued signal, sampled at 61.44 Msps.
% * _validIn_: 1-bit control signal to validate _dataIn_.
% * _frequencyOffset_: 32-bit signed value specifying the frequency offset to
%   be corrected. 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; 
% * _subcarrierSpacing_: 1-bit unsigned value specifying the subcarrier spacing.
%   Set this signal to 0 to select 15kHz, or 1 to select 30kHz.
% * _mode_: 1-bit unsigned value specifying the operation mode. Set this signal to 0 for search mode, or 1 for demod mode.
% * _timingOffset_: 21-bit unsigned value specifying the timing offset of the start of 
%   the SSB to be demodulated. Specify the timing offset in samples at 
%   61.44 Msps, from 0 to 1228799. This parameter applies only for demod mode.
% * _NCellID2_: 2-bit unsigned value specifying the PSS (0, 1, or 2) of
%   the SSB to be demodulated. This parameter applies only for demod mode.
% * _start_: 1-bit control signal used to start a search or demodulation operation.
%   To start an operation, set _frequencyOffset_, _subcarrierSpacing_, 
%   _mode_, _timingOffset_, and _NCellID2_ to the desired values and
%   set _start_ to _1_ (_true_) for one or more cycles.
%   If an operation is already in progress, that operation is cancelled when
%   _start_ is set to _1_ (_true_). The new operation begins when _start_ is returned to _0_ (_false_).
%
% *Outputs*
%
% * _status_: 4-bit unsigned value that indicates the progress of the current
%   operation. See the next section for the possible values of this signal.
% * _pssNCellID2_: 2-bit unsigned value that is the PSS (0, 1 or 2) of the detected SSB.
% * _pssTimingOffset_: 21-bit unsigned value that is the timing offset of the detected SSB.
%   The timing offset is in samples at 61.44 Msp from 0 to 1228799.
% * _pssFrequencyOffset_: 32-bit signed value that is the frequency offset of the detected SSB.
%   This signal has the same units as the _frequencyOffset_ input.
% * _pssCorrelation_: 32-bit unsigned value that is the strength of the PSS correlation.
% * _pssThreshold_: 32-bit unsigned value that is the threshold value when PSS was detected.
% * _NCellID_: 10-bit unsigned value that is the cell ID of the demodulated SSB.
%   This value is returned only in demod mode.
% * _sssCorrelation_: 32-bit unsigned value that is the SSS correlation strength.
%   This signal is returned only in demod mode.
% * _sssThreshold_: 32-bit unsigned value that is the SSS threshold.
%   This value is returned only in demod mode.
% * _reportValid_: 1-bit control signal. In search mode, this signal validates _pssNCellID2_, _pssTimingOffset_, 
%   _pssFrequencyOffset_, _pssCorrelation_, and _pssThreshold_ for each PSS that is detected.
%   In demod mode, this signal also validates _NCellID_, _sssCorrelation_, and 
%   _sssThreshold_. In demod mode, _sssCorrelation_ and _sssThreshold_ are only valid if
%   the specified SSB was found using its PSS, and _NCellID_ is only valid if the SSS was detected.
% * _gridData_: 16-bit signed complex-values that are the resource grid data. The receiver returns all four symbols of the SSB resource grid. Values are returned
%   one resource element at a time. The resource grid is only returned in demod mode.
% * _gridValid_: 1-bit control signal that validates the _gridData_ output.
%   Data is only returned if the specified SSB was found using its PSS.
%   This signal is returned only in demod mode.
% * _diagnostics_: Bus containing diagnostic signals.
%
% *Status Signal States*
%
% * |0| Idle.
% * |1| Search mode -- Searching for PSS.
% * |2| Search mode -- Operation complete, no PSS found.
% * |3| Search mode -- Operation complete, found one or more PSSs.
% * |4| Demod mode -- Waiting for specified PSS timing offset.
% * |5| Demod mode -- Operation complete, PSS not found.
% * |6| Demod mode -- Found specified PSS. Demodulating the resource grid and looking for SSS.
% * |7| Demod mode -- Operation complete, no SSS found. Returned demodulated resource
%   grid.
% * |8| Demod mode -- Operation complete, found SSS. Returned demodulated resource
%   grid.
%


%% SSB Detection Model Reference Structure
%
% This diagram shows the top level of the |nrhdlSSBDetectionCore| model.
% The input signal (_dataIn_) is 14-bit signed complex-valued data sampled
% at 61.44 Msps.
% The Input Scaling subsystem increases the word length to 16 bits
% by sign-extending the values by one bit and adding one LSB.
% This increase provides headroom and extra accuracy for subsequent processing stages.
% The DDC corrects the frequency offset and decimates the samples 
% by eight (to 7.68 Msps) by using halfband filters. The output
% of the DDC is the input to the SS Block Core subsystem.
% The Detection Status block keeps track of progress and
% generates the status output.

models.ssbDetection = 'nrhdlSSBDetectionCore';
open_system(models.ssbDetection);
set_param(models.ssbDetection,'SimulationCommand','Update');
set_param(models.ssbDetection,'Open','on');

%% SS Block Core Subsystem Structure
%
% The SS Block Core subsystem performs SSB detection and demodulation.
% Its internal sampling rate varies depending on the subcarrier spacing
% (SCS). The subsystem uses 7.68 Msps for 30kHz SCS and 3.84 Msps for 15kHz SCS.
% The subcarrier spacing selection logic on the left is responsible for 
% changing the sampling rate. 
% The rate can change only when a new operation is triggered by the
% _start_ input.
% 
% The receiver has an internal timing reference system that 
% keeps track of time by using counters at key points in the datapath.
% The timing reference counts 20ms periods - the assumed SSB periodicity 
% for cell search as defined by the 5G NR standard. Time is measured in
% samples at 61.44 Msps modulo 1228800 to create the 20ms period.
% Since the actual sampling rate is either 7.84 Msps or 3.84 Msps,
% the timing reference counters increment by either 8 or 16, respectively,
% for each sample.
% When a new operation is triggered by the _start_ input, the Start Controller records the start time
% and passes the time to the other timing references in the model.
% This signal tells the other timing references when a new subcarrier spacing
% and corresponding sampling rate applies.
% The other timing references wait until the start time before changing their increment.
% This design is possible only because hardware latency means the other timing references lag behind
% the Start Controller.  This architecture enables
% the receiver to keep track of time consistently, even when a sampling rate change occurs.

set_param([models.ssbDetection '/SS Block Core'],'Open','on');

%% 
% The SS Block Core subsystem contains these main subsystems.
% 
% * _Subcarrier Spacing Selection_: Converts the input to two synchronized
%   sample streams, one at 7.68 Msps and one at 3.84 Msps, and selects
%   which stream to pass to subsequent processing stages according to the 
%   subcarrier spacing.
% * _PSS Detection_: Searches for PSS symbols in the received signal. The
%   next section describes this subsystem in more detail. 
% * _Cyclic Prefix Correlation_: Computes cyclic prefix (CP) correlation
%   values. Each result is averaged across the last four OFDM symbols.
% * _CP Correlation to Frequency_: Converts CP correlation values 
%   to fine frequency offset estimates.
% * _PSS and CP Alignment_: Matches a CP-based frequency estimate with each
%   PSS symbol detection instance. This alignment is necessary
%   because the frequency estimate for a given PSS detection instance is  
%   available only at the end of the corresponding SSB.
% * _PSS Info Serialization_: If PSS is detected on more than one PSS correlator
%   output at the same timing offset, this block serializes
%   the results so that they are returned from the detector
%   one at a time.
% * _OFDM Data Synchronization_: Synchronizes the OFDM demodulator
%   input with the output of the PSS detector. This synchronization enables the PSS
%   detector to trigger the OFDM demodulation process at the correct time. The synchronized 
%   data is one OFDM symbol behind the PSS correlator as the peak detection occurs at the 
%   end of the first OFDM symbol to be demodulated.
% * _OFDM Demodulation_: OFDM-demodulates
%  `all four symbols of the specified SSB.
% * _SSS Detection_: Extracts the SSS resource elements from the OFDM
%   demodulator output and correlates them with all 
%   336 possible sequences to determine the cell ID. 
% * _Create report_: Aligns all of the parameters corresponding to 
%   one SSB detection, so that they are all valid
%   at the same time.
% 

%% Simulation Setup
%
% This block diagram shows the simulation setup implemented by the 
% |nrhdlexamples.runSSBDetectionModel| function. The function uses 5G Toolbox
% functions to generate a test waveform that has these parameters.
% 
% * SSB pattern is case B
% * Subcarrier spacing is 30
% * NCellID is 249
% * Active SSBs within the burst is 8
% * Frequency offset is 10 kHz
% * Channel is modeled with AWGN
% 
% The function passes the test waveform to the MATLAB and
% Simulink implementations of the SSB detector in search
% mode and then in demodulation mode.
% Key diagnostic signals from each detector 
% are compared in terms of their relative mean-squared error
% (MSE) and the final outputs are compared. The function calls 5G Toolbox
% functions to decode the BCH, recover the MIB, and measure the EVM
% of the resource grid returned by the Simulink implementation.
% 
% To run the simulation, call the |nrhdlexamples.runSSBDetectionModel| function. 
% This diagram shows the actions performed by the script.
%
% <<../NRHDLCellSearchSimulationSetup.png>>
%


%% Search Mode Simulation
%
% The simulation starts by generating a test waveform as previously described.
% The plot shows the combined resource grid of all eight
% SSBs in the transmitted waveform.
% 
% <<../NRHDLCellSearchTxGridPlot.png>>
%
% In search mode, the detector looks for PSS symbols within a 20 ms
% time window, which begins after a pulse on the _start_ input triggers the
% search operation. If no PSS symbols are found after 
% 20 ms, the detector sets the _status_ output to |2| - indicating the search has failed.
% In this example, the detector finds all eight SSBs. The _status_
% output is set to |1| during the search, and a _report_ is returned for each 
% SSB by asserting the _reportValid_ signal. View these signals by 
% opening the Simulink Logic Analyzer tool after the search mode simulation is complete.
% The simulation runs for 5 ms. If the simulation ran for more than 20 ms, 
% then the _status_ output is eventually set to |3| - indicating the search has succeeded.
%
% <<../NRHDLCellSearchLASearch.png>>
%
% The script generates a plot that shows the PSS correlation outputs
% and the PSS detection threshold. Tables are displayed at the
% command line showing the parameters of each SSB. The final table shows
% the MSE between the MATLAB and Simulink implementations 
% for each correlator output and for the detection threshold. These results
% show that the MATLAB and Simulink implementations match very closely. The
% small differences between the two implementations are due to quantization
% errors. These errors occur because the MATLAB reference uses floating-point
% data types, and the Simulink model uses fixed-point data types.
% 
% <<../NRHDLCellSearchPSSSearchPlot.png>>
%
% <<../NRHDLCellSearchOutputA.png>>
%


%% Demodulation Mode Simulation
% 
% In demodulation mode, the detector recovers the specified SSB
% by searching for its PSS, OFDM-demodulating the resource grid, 
% and searching for the SSS within the appropriate resource elements.
% If the PSS is not found at the specified timing offset, the detector sets the
% _status_ output to |5| and stops searching.
%
% In this example, the detector recovers the specified SSB.
% The test bench in the |nrhdlexamples.runSSBDetectionModel| function chooses
% the SSB with the strongest PSS from the initial search. The
% frequency offset measurement from this SSB is used as a
% frequency offset estimate and passed back into the detector.
% The Simulink Logic Analyzer tool shows the detector output
% as it progresses through these steps.
%
% # The detector sets _status_ output to |4| while it waits
%   for the specified timing offset and searches for the specified PSS.
% # PSS is found. The detector sets the _status_ output
%   to |6| - the detector is now searching for the SSS within the
%   resource grid. The four demodulated OFDM symbols are output, indicated
%   by asserting _gridValid_.
% # After the SSS is determined, the detector asserts _reportValid_ to indicate that
%   all of the PSS and SSS parameters, including _NCellID_, are valid.
%   The _status_ output changes to |8|, to indicate that the operation is complete and SSS and cell ID are ready.
%
% If the detector is unable to determine the SSS, then it sets the _status_ output
% to |7|.
%
% <<../NRHDLCellSearchLADemod.png>>
%
% These plots show the PSS and SSS correlation signals for both
% detector implementations. The PSS correlation
% levels are stronger in demod mode than in search mode because the
% frequency offset is corrected. The final reports
% are displayed at the command line, showing that both
% detectors returned similar parameters and determined the
% cell ID is 249. The table shows the relative MSE for the
% PSS and SSS correlation signals and the
% resource grid.
% 
% <<../NRHDLCellSearchPSSDemodPlot.png>>
%
% <<../NRHDLCellSearchSSSPlot.png>>
%
% <<../NRHDLCellSearchOutputB.png>>
%


%% Resource Grid Verification
% 
% The plot shows the demodulated resource grids returned by MATLAB and Simulink.
% 
% <<../NRHDLCellSearchRxGridPlot.png>>
%
% As a final verification step, the script decodes the BCH from the Simulink 
% output by calling |nrhdlexamples.ssbDecode|. The command line output shows that the CRC check passed,
% and confirms that the MIB content matches that of the transmitted waveform.
% 
% <<../NRHDLCellSearchOutputC.png>>

%% HDL Code Generation and Implementation Results
% To generate the HDL code for this example, you must have an HDL
% Coder(TM) license. 
% Use the |makehdl| and |makehdltb| commands to generate HDL code 
% and an HDL test bench for the |nrhdlSSBDetection/SS Block Detection|
% subsystem.
% The resulting HDL code was synthesized for a Xilinx(R) Zynq(R)-7000 ZC706
% evaluation board. The table shows the post place and route resource
% utilization results. The design meets timing with a clock frequency of 230 MHz.

T = table(...
    categorical({'Slice Registers'; 'Slice LUTs'; 'RAMB18'; 'RAMB36'; 'DSP48'}),...
    [79357; 37659; 7; 1; 208],...
    'VariableNames',{'Resource','Usage'});

disp(T);

fields = fieldnames(models);
for k=1:length(fields)
    close_system(models.(fields{k}),0);
end

