%% LTE HDL PBCH Transmitter
% This example shows how to implement an LTE transmitter Multiple Input 
% Multiple Output (MIMO) design, including PSS, SSS, CRS, and MIB, 
% optimized for HDL code generation.

% Copyright 2019 The MathWorks, Inc. 

%% Introduction
% The model in this example generates a baseband waveform specified by 
% 3GPP TS 36.211. The waveform includes the primary synchronization
% signal (PSS), secondary synchronization signal (SSS), cell-specific 
% reference signals (CRS), and the master information block (MIB) for
% transmission through the physical broadcast channel (PBCH) for multiple 
% antennas. The model supports dynamic change of NCellID and NDLRB. The
% MIMO transmitter design is optimized for HDL code generation and when 
% implemented on an FPGA, it can be used to transmit MIMO signals in real time
% over the air. The MIMO design aids the decoding process in the presence of
% LTE fading channel. This example supports 1, 2, or 4 antennas
% and uses transmit diversity as specified in the [ <#21 1> ].
%
% The architecture presented in this example is extensible and allows for
% integration of additional physical transmission channels such as physical
% downlink control channel (PDCCH), physical downlink shared channel 
% (PDSCH), physical control format indicator channel (PCFICH), and physical
% HARQ indicator channel (PHICH).

%% Architecture and Configuration
%
% This figure shows the LTE HDL Transmitter architecture with PSS, 
% SSS, CRS, and PBCH transmission chains.
% 
% <<../ltehdlTransmitterBlock.png>>
%
% The input sampling rate is assumed to be at 10.24 MHz. PSS, SSS, PBCH, 
% and CRS signals are generated in parallel, based on the input 
% configuration. A single stream of PSS and SSS signals is used for all 
% the antennas. Multiple streams of PBCH data 
% are generated for multiple antennas through the layer mapping and
% precoding stages. Each antenna is associated with a corresponding LTE
% memory bank, which is sized to store one subframe of LTE data samples. 
% These generated data streams are written into LTE memory bank corresponding
% to indices generated, based on the output _ready_ signal of 
% <docid:whdl_ref#mw_7f636165-0505-4f6e-bede-79a52a497619 LTE OFDM Modulator>. 
% Then, the data is read out of all LTE memory bank in 
% parallel, modulated and transmitted on the antennas simultaneously.
% The <docid:whdl_ref#mw_7f636165-0505-4f6e-bede-79a52a497619 LTE OFDM Modulator>
% block uses a 2048-point FFT to support all NDLRBs.
% 
% In this example, the transmitter transmits LTE MIMO signals for the 
% following configurations:

 F = table(...
    categorical({'Duplex mode'; 'CellRefP'; 'Bandwidth'; 'Cyclic prefix';...
    'Initial subframe'; 'Initial frame'; 'Ng';'PHICH duration'}),...
    categorical({'FDD'; '1/2/4'; '1.4 - 20 MHz'; 'Normal/Extended'; '0';'0';...
    'Sixth/Half/One/Two';'Normal/Extended'}),...
    'VariableNames',{'Property','Value'});

disp(F);

%% Structure of Example Model
%
% The top level structure of the *ltehdlTransmitter* model is shown below. 
% You can generate HDL code for the *HDL LTE MIMO Transmitter* subsystem.

modelname = 'ltehdlTransmitter';
open_system(modelname);
set_param(modelname,'Open','on');

%%
% Input _start_ is a pulse signal to trigger the transmission. You can
% configure other parameters, including _NDLRB_, _NCellID_, _Cyclic prefix_,
% _Ng_, _PHICH duration_ and _CellRefP_ in the workspace after loading or 
% opening the |ltehdlTransmitter.slx| model. 
% The |ltehdlTransmitter_init.m| script is executed automatically by the
% model's |InitFcn| callback. This script configures the individual blocks 
% in the *HDL LTE MIMO Transmitter* subsystem. The default transmitter 
% configuration used by the |ltehdlTransmitter_init.m| script is: 
%
%   enb.NDLRB = 6;                      % {6,15,25,50,75,100}
%
%   enb.CyclicPrefix = 'Normal';        % {'Normal','Extended'}
%
%   enb.Ng = 'Sixth';                   % {'Sixth','Half','One','Two'}
%
%   enb.PHICHDuration = 'Normal';       % {'Normal','Extended'}
%
%   enb.CellRefP = 4;                   % {1,2,4}
%
%   tx_cellids = [390 89 501 231 500];  % {0 to 503}
% 
%   outRate = 1;                        % {1,2}
%
%   TotalSubframes = 45;                % {positive integer}
%
% This default configuration can be changed to use other possible values for 
% each variable, as noted in the comment on each line. 

%% HDL LTE MIMO Transmitter
% 
% The structure of the *HDL LTE MIMO Transmitter* subsystem is shown 
% below. The *Frame Controller* controls the subframe and frame indices. 
% The *Input Sampler* samples the inputs _NDLRB_ and _NCellID_ and then 
% propagates the values to the subsequent blocks. The *PSS & SSS generation*
% generates PSS, SSS, and the corresponding memory address based on 
% NDLRB and subframe index. The *MIB generation* block generates the serial
% MIB data. The *BCH Encoder* and *PBCH Encoder* generate
% information for PBCH channel and memory addresses for all the antennas.
% The *CellRS Chain* generates cell-specific reference 
% signals and corresponding addresses for each antenna. The 
% *Read Write Logic* writes and reads the grid data from each 
% *LTE Memory Bank* and provides the data to the corresponding 
% *LTE OFDM Modulator*. 
% The *Discrete FIR Filter HDL Optimized* filters the modulated data using  
% coefficients that are calculated based on the input configuration.

set_param(modelname,'Open','off');
open_system([modelname '/HDL LTE MIMO Transmitter']);

%%
% *Frame Controller*
%
% This subsystem assumes an input sampling rate of 10.24 MHz. 
% It controls the subframe and radio frame boundaries by providing 
% _cellEnb_ signal to sample _NCellID_. It returns radio frame and subframe 
% indices. It also provides _syncStart_, _bchStart_, and _cellRSStart_ 
% trigger signals to control the downstream blocks. 

set_param([modelname '/HDL LTE MIMO Transmitter'],'Open','off');
open_system([modelname '/HDL LTE MIMO Transmitter/Frame Controller']);

%%
% *PSS & SSS Generation*
%
% This subsystem generates the primary synchronization signal (PSS),
% secondary synchronization signal (SSS), and respective write addresses for
% LTE Memory Bank based on inputs _NDLRB_ and _NCellID_. _syncStart_ 
% triggers the generation of PSS and SSS.
% The PSS and SSS occupy the same central 62 subcarriers of two OFDM 
% symbols in a resource grid [ <#21 1> ]. This subsystem generates both the  
% signals and their corresponding addresses at the same time, so that a 
% single stream of both PSS and SSS can be written to all the LTE Memory 
% Banks corresponding to each antenna simultaneously.
%   
% The PSS sequence is generated from a frequency-domain Zadoff-Chu sequence
% [ <#21 1> ]. The Zadoff-Chu root sequence index depends on
% NCellID2, which is derived from _NCellID_. There are three possible 
% NCellID2 values, so all possible PSS sequences are precalculated and 
% stored in |PSS_LUT|.
%
% * *PSS_generation*: Determines NCellID2 and reads the corresponding 
%  PSS sequence out of |PSS_LUT| sequentially.
% * *PSS_indices*: Computes the memory addresses required to write PSS
% data into LTE Memory Bank. This subsystem is equivalent to the 
% LTE Toolbox(TM) function |ltePSSIndices|. 

set_param([modelname '/HDL LTE MIMO Transmitter/Frame Controller'],'Open','off');
open_system([modelname,'/HDL LTE MIMO Transmitter/PSS & SSS generation/PSS']);

%%
% The SSS sequence is an interleaved concatenation of two 31-bit length binary
% sequences. The concatenated sequence is scrambled with a scrambling 
% sequence given by PSS. The combination of these sequences differs 
% between subframe 0 and subframe 5 [ <#21 1> ]. The indices m0 and m1 
% are derived from the physical-layer cell identity group, NCellID1 [ <#21 1> ].
% These indices and the sequences s(n), c(n), and z(n) are calculated 
% and stored in |m0_LUT|, |m1_LUT|, |S_LUT|, |C_LUT|, and |Z_LUT| respectively.
%
% * *SSS_generation*: Computes m0 and m1 based on the _NCellID_ and calculates
% indices required for sequences s(n), c(n), and z(n) based on the subframe
% index. Generates SSS sequence as specified in [ <#21 1> ].
% * *SSS_indices*: Computes memory addresses required to write SSS data
% into LTE Memory Bank. This subsystem is equivalent to the LTE Toolbox(TM)
% function |lteSSSIndices|.

set_param([modelname '/HDL LTE MIMO Transmitter/PSS & SSS generation/PSS'],'Open','off');
open_system([modelname,'/HDL LTE MIMO Transmitter/PSS & SSS generation/SSS']);

%%
% *BCH Encoder*
%
% Broadcast Channel (BCH) processes the MIB information arriving to the 
% block in the form of a maximum of one transport block for every
% transmission time interval (TTI) of 40 ms. The block implements the
% following coding steps.

set_param([modelname '/HDL LTE MIMO Transmitter/PSS & SSS generation/SSS'],'Open','off');
open_system([modelname '/HDL LTE MIMO Transmitter/BCHEncoder']);

%%
% * *CRC Encoding*: The entire transport block is used to calculate the CRC
% parity bits for a polynomial specified in [ <#21 2> ]. The parity bits 
% are then appended to the transport block. After appending, CRC bits are
% scrambled according to the transmit configuration. The 
% <docid:whdl_ref#mw_a2e94d2b-4e70-4f4a-acf7-fdc5b2e25b01 LTE CRC 
% Encoder> block uses the CRC mask set by the |ltehdlTransmitter_init.m|
% script based on the input configuration.
%
% * *Channel Coding*: The <docid:whdl_ref#mw_26ea16c0-096e-44ff-a865-05c5a0fbd9a1 LTE 
% Convolutional Encoder> block encodes the information bits using tail-biting
% convolutional code with constraint length 7, and polynomial $$ G_0 = 133, G_1 = 171, G_2 = 165
% $$ in octal. Because the coding rate of the encoder is 1/3, the coded 
% bits are then serialized using a <docid:hdlcoder_ref#buhyp0q-933 Serializer1D>
% block and control signals are resampled to 30.72 MHz (3 * 10.24 MHz).
% 
% * *Rate Matching*: The coded bits are interleaved, followed by selection of 
% bits for a particular length using an interleaved address [ <#21 2> ].
% For broadcast channel, because the length of the MIB is constant,
% interleaved write and read addresses are precalculated and stored in 
% |wr_addrLUT| and |rd_addrLUT| respectively. Once all serialized coded 
% bits have been written into interleaved addresses of RAM, the bits are 
% read back using interleaved read addresses.
%

set_param([modelname '/HDL LTE MIMO Transmitter/BCHEncoder'],'Open','off');
open_system([modelname '/HDL LTE MIMO Transmitter/BCHEncoder/Rate Matching']);

%%
% *PBCH Encoder*
% 
% The physical broadcast channel processes the coded bits in the following steps.

set_param([modelname '/HDL LTE MIMO Transmitter/BCHEncoder/Rate Matching'],'Open','off');
open_system([modelname '/HDL LTE MIMO Transmitter/PBCH Encoder/PBCH']);

%%
%
% * *Scrambling*: Coded bits from *BCH Encoder* are scrambled with a 
% cell-specific sequence using a <docid:whdl_ref#mw_8c32f35f-ac5d-49d2-a1de-d8432e386bd1
% LTE Gold Sequence Generator> block. The sequence is initialized with
% NCellID in each radio frame($$ n_f $$) fulfilling $$ n_f mod 4 = 0 $$. 
% The generated cell-specific sequence is scrambled with the input coded bits.
% 
% * *QPSK Mapping*: The modulation scheme specified for PBCH channel is 
% QPSK [ <#21 1> ]. The <docid:whdl_ref#lte_symbol_mod LTE Symbol Modulator>
% block generates complex-valued QPSK modulation symbols. 
%
% * *Layer Mapping*: Three subsystems are defined for the layer mapping. 
% These subsystems are placed inside a 
% variant subsystem. Based on the number of antennas used in the input 
% configuration |enb.CellRefP|, the |ltehdlTransmitter_init.m| script 
% selects one of the three subsystems in the variant subsystem. 
% This *Layer Mapping* block separates the input streaming samples into 
% 1, 2, or 4 sequences based on the number of antennas used. The input is
% streamed out without any processing for a single antenna. For multiple 
% antennas, this block generates a valid signal for each antenna. Only one
% of the valid signals will be high for each input sample. 
%
% * *Precoding*: This block also uses variant subsystem to process input
% samples differently based on the number of antennas in the 
% transmitter configuration. For |enb.CellRefP| set to 1 the input is
% streamed out without any processing. For |enb.CellRefP| set to 4 (or 2), 
% every four (or two) consecutive samples X0, X1, X2, X3 (or X0, X1) are 
% processed to generate four (or two) streams of 4 (or 2) samples each in 
% four (or two) time instants.
%
% The subsystem shown generates the output sequence for 4
% antennas as specified in [ <#21 1> ].

set_param([modelname '/HDL LTE MIMO Transmitter/PBCH Encoder/PBCH'],'Open','off');
open_system([modelname '/HDL LTE MIMO Transmitter/PBCH Encoder/PBCH/Precoding/AntPortsNot1/AntPorts4']);

%%
% * *Memory*: Complex modulated symbols corresponding to the physical broadcast
% channel for the initial radio frame are stored in |PBCH_RAM|. For four 
% consecutive radio frames, the number of bits to be transmitted on 
% the physical broadcast channel is 1920 for normal cyclic prefix and
% 1728 for extended cyclic prefix. The Read Write Controller controls 
% read and write addresses based on $$ n_f mod 4 $$, since the periodicity
% of the broadcast channel (BCH) is 40 ms.
%
% * *PBCH Indexing*: Computes the memory addresses required to write PBCH 
% data into LTE Memory Bank. The *PBCH_indices* subsystem is equivalent to 
% the LTE Toolbox(TM) function |ltePBCHIndices|.
%

  set_param([modelname '/HDL LTE MIMO Transmitter/PBCH Encoder/PBCH/Precoding/AntPortsNot1/AntPorts4'],'Open','off');
  open_system([modelname '/HDL LTE MIMO Transmitter/PBCH Encoder/PBCH/PBCH_indices/PBCH Indexing']);

%% 
% *CellRS Chain*
%
% The cell-specific reference sequence is complex modulated values of a
% pseudo-random sequence as defined in [ <#21 1> ]. The pseudo-random 
% sequence generator is initialized with $$ c_{init} $$ at the start of 
% each OFDM symbol,as specified in [ <#21 1> ].
% 
% * *CellRS_generation*: Input _cellRSStart_ triggers the generation of 
% CRS signals. Since the CRS is available in six OFDM symbols (four OFDM 
% symbols in antenna port 0 and port 1, and two OFDM symbols in antenna 
% port 2 and port 3) of a single subframe, this subsystem calculates a 
% 6-element $$ c_{init} $$ vector for every subframe. The 
% <docid:whdl_ref#mw_8c32f35f-ac5d-49d2-a1de-d8432e386bd1 LTE Gold Sequence Generator> 
% block is initialized with vector $$ c_{init} $$ to
% represent multiple channels and provides six different cell-specific
% pseudo-random sequences. The Write Controller controls writing of these
% sequences into six memory banks in |CellRS_RAM|. It also returns _rd_en_,
% which enables reading data out of |CellRS_RAM|. The Read Controller 
% controls reading of CRS data. It reads six OFDM symbols if four antennas 
% are used, and reads only 4 OFDM symbols if one or two antennas are 
% used. It returns _rd_bank_ and _rd_valid_ signals to select an appropriate
% symbol for the six/four OFDM symbols. The sequence is then mapped to 
% complex QPSK modulated symbols.
%
% * *CellRS_indices*: This subsystem computes the addresses for each *LTE Memory Bank* 
% required to write CRS data. It is equivalent to the LTE Toolbox(TM)
% function |lteCellRSIndices|.
 
set_param([modelname '/HDL LTE MIMO Transmitter/PBCH Encoder/PBCH/PBCH_indices/PBCH Indexing'],'Open','off');
open_system([modelname '/HDL LTE MIMO Transmitter/CellRS Chain/CellRS_generation']);

%%
% *Read Write Logic*
% 
% The *Read Write Logic* subsystem contains a Write Selector, Read Selector,
% four LTE Memory Banks with a Grid Bank Select associated with each of the 
% LTE Memory Bank. The LTE Memory Bank storage
% capacity is one subframe of complex modulated symbols at the largest
% supported LTE bandwidth (20 MHz). Each LTE Memory Bank can store
% 14 x 2048 x 16-bit complex values, that is, 14 OFDM symbols, each 
% containing 2048 complex values.
%
% The Write Selector writes subframes of data into the
% memory banks. The PSS and SSS occupy central subcarriers. A single stream
% of PSS and SSS data is used for all the antennas. The PBCH data consists 
% of multiple streams corresponding to each antenna port. The CRS data 
% generated is mapped to the grid based on the four addresses
% generated for each *LTE Memory bank* in *CellRS_indices* block. The Write
%  Selector first writes PSS and SSS simultaneously into corresponding locations in 
% all LTE Memory Banks. Then, it writes PBCH data and CRS data into
% the corresponding LTE Memory Banks and returns _rd_enb_ to indicate that
% the write is complete.
%
% The Read Selector reads the samples from each *LTE Memory Bank* based on 
% _rd_enb_ and _ready_ from the LTE OFDM Modulator block. Each LTE Memory 
% Bank returns a 14 element vector corresponding to a single 
% subcarrier. The *Grid Bank Select* selects the appropriate sample from 
% the 14 element vector to form the resource grid output for each antenna.
%
% Since the scope of this example is limited to PSS, SSS, CRS, and PBCH 
% transmission, all the LTE Memory Banks are erased at the start of every 
% subframe, before writing new data into the memory.

set_param([modelname '/HDL LTE MIMO Transmitter/CellRS Chain/CellRS_generation'],'Open','off');
open_system([modelname '/HDL LTE MIMO Transmitter/Read Write Logic']);

%%
% *OFDM Modulation and Filtering*
% 
% Grid data from LTE Memory Bank is OFDM-modulated using the
% <docid:whdl_ref#mw_7f636165-0505-4f6e-bede-79a52a497619 LTE OFDM Modulator> 
% block with 'Output data sample rate' parameter set to 
% 'Match output data sample rate to NDLRB'. The modulated data is filtered 
% using a <docid:dsp_ref#bvi0_ng-1 Discrete FIR Filter HDL Optimized> block
% with coefficients generated at a sampling rate corresponding to the NDLRB.
% Variant subsystems control the number of OFDM modulators and FIR filters 
% used based on the number of antennas, which reduces the
% resource utilization when a single antenna is used.

%% Verification and Results
% After running the simulation, the |ltehdlTransmitter_PostSim.m| script is
% executed automatically by the |StopFcn| callback of the model. In this 
% example, the transmitter output is verified by the following methods:
%
% *Verification of model's transmitted signal:*
%
% The transmitter output signal in this model is cross-verified with a
% reference transmitter signal that is generated using LTE Toolbox(TM) 
% functions by the following two subplots for each antenna.
% 
% # The first subplot shows the Power Spectral Density (PSD) output of 
% the filtered data. The result is compared with the PSD of the reference
% output signal generated using LTE Toolbox(TM). This comparison
% shows the equivalence of the two signals. The figure shows a 
% transmission bandwidth of BW = 1.4MHz.
% # The second subplot shows the absolute-value of the transmitted 
% waveform. The result is plotted on top of the absolute-value of 
% the reference transmitter signal generated using 
% LTE Toolbox(TM). The plot also shows the difference between the samples
% obtained through HDL implementation and the reference signal. This 
% comparison shows the minimal error between the two transmitter signals.
% 
% <<../ltehdlTransmitterTxsamples.png>>
%
% *Cell Search & MIB Decoding Results:*
% 
% The valid samples of the transmitter output signal are stored to the 
% workspace variable |txSamples|. These samples are passed through an LTE
% fading channel to create the receiver input signal, |rxSamples|. 
% The <docid:lte_ref#bt3f52s lteFadingChannel> function models the LTE fading channel.
%
% This example uses the following channel configuration:
%
%   chcfg.NRxAnts = 1;
%   chcfg.MIMOCorrelation = 'Medium';
%   chcfg.NormalizeTxAnts = 'On';
%   chcfg.DelayProfile = 'EPA';               % {'off','EPA'}
%   % The below model configuration exist only if Delay profile is not set
%   % to 'off'.
%   chcfg.DopplerFreq = 5;
%   chcfg.SamplingRate = 30.72e6;
%   chcfg.InitTime = 0;
%   chcfg.NTerms = 16;
%   chcfg.ModelType = 'GMEDS';
%   chcfg.NormalizePathGains = 'On';
%   chcfg.InitPhase = 'Random';
%   chcfg.Seed = 1;
% 
% To create a fading-free channel, set the |chcfg.DelayProfile| to 'off' in
% the |ltehdlTransmitter_PostSim.m| script.
%
% This channel configuration works with the default |enb| 
% structure, and supports changes only in the |enb.PHICHDuration| and 
% |enb.Ng| fields.
%
% The following figures show the results of the cell search and MIB
% decoding of the channel output, |rxSamples|, using LTE toolbox(TM) 
% functions. These figures verify the transmitter 
% performance and compare the HDL transmitter implementation against the 
% input configuration defined in |tx_cellids| and |enb|.
% 
% * NCellID after Cell Search: Displays the LTE cell search results 
% performed on the fading channel output.
%
% <<../ltehdlTransmitterCellResults.png>>
% 
% * Cell-wide settings after MIB decoding: Displays the fields of MIB after
% MIB decoding - NDLRB, Ng, PHICH duration, and System Frame Number (SFN) 
% performed on the fading channel output.
%
% <<../ltehdlTransmitterMIBResults.png>>
%
% The example model does not support simulation in rapid accelerator mode.

%% Validation with Cell Search and MIB Recovery Example
%
% You can verify the *LTE HDL PBCH Transmitter* example by connecting 
% it to the 
% <docid:whdl_ug#example-ltehdlMIBRecovery ltehdlMIBRecovery> 
% example model and checking
% that the output of the transmitter is decoded correctly. To make the 
% transmitter model compatible with the receiver model, make these changes 
% to the transmitter: 
%
% * Set the |outRate| = 2 (default value 1) before running the model. This
% will set the output rate of each *LTE OFDM Modulator* and generate the fir filter
% coefficients associated with each antennas.
% * Set the |enb.CellRefP| = 2 (default value 4) before running the model.
% * Use the same |NCellID| for all radio frames in the
% transmission. i.e. set |tx_cellids| to a scalar value in the
% range 0-503.
% 
% <<../ltehdlTransmitterMIBRecoveryConnection.png>>
%
% The figure shows the *HDL LTE MIMO Transmitter* and *HDL LTE MIB Recovery* 
% subsystems connected together. It also shows the result of simulating the 
% model. The display blocks show the CellID and MIB fields (NDLRB, Ng, 
% PHICH duration and System Frame Number (SFN)) that the receiver decoded
% from the output of the *HDL LTE MIMO Transmitter* subsystem.
%
% You can also verify the design without using a channel by terminating the 
% output from the second antenna and bypassing the channel system with the 
% output from the first antenna.

%% HDL Code Generation
%
% To check and generate HDL for this example, you must have an HDL Coder(TM)
% license. Use the |makehdl| and |makehdltb| commands to generate the HDL code
% and test bench for the *HDL LTE MIMO Transmitter* subsystem. Because
% the stopTime in this example depends on |TotalSubframes|, the test bench 
% generation time depends on the |TotalSubframes|.
%
% The *HDL LTE MIMO Transmitter* subsystem is synthesized on a Xilinx(R) 
% Zynq(R)-7000 ZC706 evaluation board. The post place and route resource 
% utilization results are shown in the table below.

 F = table(...
    categorical({'Slice Registers'; 'Slice LUT'; 'RAMB36'; 'RAMB18';...
    'DSP'; 'Max. Frequency (MHz)'}),...
    categorical({'12788'; '11984'; '41'; '11'; '49';'210.08'}),...
    categorical({'23839'; '22220'; '82'; '21'; '93';'206.39'}),...
    categorical({'45787'; '42861'; '164'; '41'; '177';'204.75'}),...
    'VariableNames',...
    {'Resources','No. of antennas used = 1','No. of antennas used = 2','No. of antennas used = 4'});

disp(F);

%% References
% # 3GPP TS 36.211 "Physical channels and modulation".
% # 3GPP TS 36.212 "Multiplexing and channel coding".