/* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * * http://www.openairinterface.org/?page_id=698 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ /*! \file PHY/defs_gNB.h \brief Top-level defines and structure definitions for gNB \author Guy De Souza \date 2018 \version 0.1 \company Eurecom \email: desouza@eurecom.fr \note \warning */ #ifndef __PHY_DEFS_GNB__H__ #define __PHY_DEFS_GNB__H__ #include "defs_eNB.h" #include "defs_nr_common.h" #include "CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/impl_defs_top.h" #include "PHY/defs_common.h" #include "PHY/CODING/nrLDPC_extern.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" #define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB typedef struct { uint32_t pbch_a; uint32_t pbch_a_interleaved; uint32_t pbch_a_prime; uint32_t pbch_e[NR_POLAR_PBCH_E_DWORD]; } NR_gNB_PBCH; typedef struct { uint8_t ssb_start_symbol; uint8_t n_hf; uint8_t Lmax; uint8_t ssb_index; int32_t sfn; } NR_PBCH_parms_t; typedef enum { NR_SCH_IDLE, NR_ACTIVE, NR_CBA_ACTIVE, NR_DISABLED } NR_SCH_status_t; typedef struct { /// Nfapi DLSCH PDU nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu; /// pointer to pdu from MAC interface (this is "a" in 36.212) uint8_t *pdu; /// The payload + CRC size in bits, "B" from 36-212 uint32_t B; /// Pointer to the payload uint8_t *b; /// Pointers to transport block segments uint8_t *c[MAX_NUM_NR_DLSCH_SEGMENTS]; /// Frame where current HARQ round was sent uint32_t frame; /// Subframe where current HARQ round was sent uint32_t subframe; /// Index of current HARQ round for this DLSCH uint8_t round; /// MIMO mode for this DLSCH MIMO_mode_t mimo_mode; /// Concatenated sequences uint8_t *e; /// LDPC-code outputs uint8_t *d[MAX_NUM_NR_DLSCH_SEGMENTS]; /// Interleaver outputs uint8_t *f; /// Number of code segments uint32_t C; /// Number of bits in "small" code segments uint32_t K; /// Number of "Filler" bits uint32_t F; } NR_DL_gNB_HARQ_t; typedef struct { /// Pointers to 16 HARQ processes for the DLSCH NR_DL_gNB_HARQ_t *harq_processes[NR_MAX_NB_HARQ_PROCESSES]; /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding) int32_t *txdataF[NR_MAX_NB_LAYERS]; /// Modulated symbols buffer int32_t *mod_symbs[NR_MAX_NB_CODEWORDS]; /// beamforming weights for UE-spec transmission (antenna ports 5 or 7..14), for each codeword, maximum 4 layers? int32_t **ue_spec_bf_weights[NR_MAX_NB_LAYERS]; /// dl channel estimates (estimated from ul channel estimates) int32_t **calib_dl_ch_estimates; /// Allocated RNTI (0 means DLSCH_t is not currently used) uint16_t rnti; /// Active flag for baseband transmitter processing uint8_t active; /// HARQ process mask, indicates which processes are currently active uint16_t harq_mask; /// Indicator of TX activation per subframe. Used during PUCCH detection for ACK/NAK. uint8_t slot_tx[80]; /// First CCE of last PDSCH scheduling per subframe. Again used during PUCCH detection for ACK/NAK. uint8_t nCCE[10]; /// Process ID's per subframe. Used to associate received ACKs on PUSCH/PUCCH to DLSCH harq process ids uint8_t harq_ids[2][80]; /// Window size (in outgoing transport blocks) for fine-grain rate adaptation uint8_t ra_window_size; /// First-round error threshold for fine-grain rate adaptation uint8_t error_threshold; /// Number of soft channel bits uint32_t G; /// Codebook index for this dlsch (0,1,2,3) uint8_t codebook_index; /// Maximum number of HARQ processes uint8_t Mdlharq; /// Maximum number of HARQ rounds uint8_t Mlimit; /// MIMO transmission mode indicator for this sub-frame uint8_t Kmimo; /// Nsoft parameter related to UE Category uint32_t Nsoft; /// amplitude of PDSCH (compared to RS) in symbols without pilots int16_t sqrt_rho_a; /// amplitude of PDSCH (compared to RS) in symbols containing pilots int16_t sqrt_rho_b; } NR_gNB_DLSCH_t; typedef struct { /// \brief ?. /// first index: ? [0..1023] (hard coded) int16_t *prachF; /// \brief ?. /// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. /// third index: frequency-domain sample [0..ofdm_symbol_size*12[ int16_t **rxsigF; /// \brief local buffer to compute prach_ifft int32_t *prach_ifft; } NR_gNB_PRACH; typedef struct { /// Nfapi ULSCH PDU nfapi_nr_pusch_pdu_t ulsch_pdu; /// Frame where current HARQ round was sent uint32_t frame; /// Subframe where current HARQ round was sent uint32_t subframe; /// Index of current HARQ round for this DLSCH uint8_t round; /// Last TPC command uint8_t TPC; /// MIMO mode for this DLSCH MIMO_mode_t mimo_mode; /// Flag indicating that this ULSCH has been allocated by a DCI (otherwise it is a retransmission based on PHICH NAK) uint8_t dci_alloc; /// Flag indicating that this ULSCH has been allocated by a RAR (otherwise it is a retransmission based on PHICH NAK or DCI) uint8_t rar_alloc; /// Status Flag indicating for this ULSCH (idle,active,disabled) NR_SCH_status_t status; /// Subframe scheduling indicator (i.e. Transmission opportunity indicator) uint8_t subframe_scheduling_flag; /// Subframe cba scheduling indicator (i.e. CBA Transmission opportunity indicator) uint8_t subframe_cba_scheduling_flag; /// PHICH active flag uint8_t phich_active; /// PHICH ACK uint8_t phich_ACK; /// First Allocated RB - previous scheduling. This is needed for PHICH generation which is done after a new scheduling uint16_t previous_first_rb; /// Flag to indicate that the UL configuration has been handled. Used to remove a stale ULSCH when frame wraps around uint8_t handled; /// Flag to indicate that this ULSCH is for calibration information sent from UE (i.e. no MAC SDU to pass up) // int calibration_flag; /// delta_TF for power control int32_t delta_TF; /////////////////////// ulsch decoding /////////////////////// /// Transport block size (This is A from 38.212 V15.4.0 section 5.1) uint32_t TBS; /// Pointer to the payload (38.212 V15.4.0 section 5.1) uint8_t *b; /// The payload + CRC (24 bits) in bits (38.212 V15.4.0 section 5.1) uint32_t B; /// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2) uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS]; /// Number of bits in each code block (38.212 V15.4.0 section 5.2.2) uint32_t K; /// Number of "Filler" bits added in the code block segmentation (38.212 V15.4.0 section 5.2.2) uint32_t F; /// Number of code blocks after code block segmentation (38.212 V15.4.0 section 5.2.2) uint32_t C; /// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2) int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS]; /// LDPC processing buffer t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS]; /// LDPC lifting size (38.212 V15.4.0 table 5.3.2-1) uint32_t Z; /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448]; /// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) uint32_t E; ////////////////////////////////////////////////////////////// /////////////////////////// DMRS ///////////////////////////// /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) uint8_t n_DMRS; /// n_DMRS 2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1) uint8_t n_DMRS2; /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) - previous scheduling /// This is needed for PHICH generation which /// is done after a new scheduling uint8_t previous_n_DMRS; ////////////////////////////////////////////////////////////// ///////////////////// UCI multiplexing /////////////////////// /// CQI CRC status uint8_t cqi_crc_status; /// Pointer to CQI data uint8_t o[MAX_CQI_BYTES]; /// Format of CQI data UCI_format_t uci_format; /// Length of CQI data under RI=1 assumption(bits) uint8_t Or1; /// Length of CQI data under RI=2 assumption(bits) uint8_t Or2; /// Rank information uint8_t o_RI[2]; /// Length of rank information (bits) uint8_t O_RI; /// Pointer to ACK uint8_t o_ACK[4]; /// Length of ACK information (bits) uint8_t O_ACK; /// The value of DAI in DCI format 0 uint8_t V_UL_DAI; /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) int8_t q[MAX_CQI_PAYLOAD]; /// number of coded CQI bits after interleaving uint8_t o_RCC; /// coded and interleaved CQI bits int8_t o_w[(MAX_CQI_BITS+8)*3]; /// coded CQI bits int8_t o_d[96+((MAX_CQI_BITS+8)*3)]; /// coded ACK bits int16_t q_ACK[MAX_ACK_PAYLOAD]; /// coded RI bits int16_t q_RI[MAX_RI_PAYLOAD]; /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled uint8_t h[MAX_NUM_CHANNEL_BITS]; /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) int16_t *w[MAX_NUM_NR_ULSCH_SEGMENTS]; ////////////////////////////////////////////////////////////// } NR_UL_gNB_HARQ_t; typedef struct { /// Pointers to 16 HARQ processes for the ULSCH NR_UL_gNB_HARQ_t *harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES]; /// Current HARQ process id int harq_process_id[NR_MAX_SLOTS_PER_FRAME]; /// HARQ process mask, indicates which processes are currently active uint16_t harq_mask; /// ACK/NAK Bundling flag uint8_t bundling; /// beta_offset_cqi times 8 uint16_t beta_offset_cqi_times8; /// beta_offset_ri times 8 uint16_t beta_offset_ri_times8; /// beta_offset_harqack times 8 uint16_t beta_offset_harqack_times8; /// Flag to indicate that gNB awaits UE Msg3 uint8_t Msg3_active; /// Flag to indicate that gNB should decode UE Msg3 uint8_t Msg3_flag; /// Subframe for Msg3 uint8_t Msg3_subframe; /// Frame for Msg3 uint32_t Msg3_frame; /// Allocated RNTI for this ULSCH uint16_t rnti; /// RNTI type uint8_t rnti_type; /// cyclic shift for DM RS uint8_t cyclicShift; /// for cooperative communication uint8_t cooperation_flag; /// Maximum number of HARQ rounds uint8_t Mlimit; /// Maximum number of LDPC iterations uint8_t max_ldpc_iterations; /// number of iterations used in last LDPC decoding uint8_t last_iteration_cnt; /// num active cba group uint8_t num_active_cba_groups; /// num active cba group uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; } NR_gNB_ULSCH_t; typedef struct { /// \brief Pointers (dynamic) to the received data in the time domain. /// - first index: rx antenna [0..nb_antennas_rx[ /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ int32_t **rxdata; /// \brief Pointers (dynamic) to the received data in the frequency domain. /// - first index: rx antenna [0..nb_antennas_rx[ /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ int32_t **rxdataF; /// \brief holds the transmit data in the frequency domain. /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //? /// - first index: eNB id [0..2] (hard coded) /// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports. /// - third index: sample [0..] int32_t **txdataF; } NR_gNB_COMMON; typedef struct { /// \brief Holds the received data in the frequency domain for the allocated RBs in repeated format. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..2*ofdm_symbol_size[ int32_t **rxdataF_ext; /// \brief Holds the received data in the frequency domain for the allocated RBs in normal format. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ int32_t **rxdataF_ext2; /// \brief Offset for calculating the index of rxdataF_ext for the current symbol uint32_t rxdataF_ext_offset; /// \brief Hold the channel estimates in time domain based on DRS. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..4*ofdm_symbol_size[ int32_t **ul_ch_estimates_time; /// \brief Hold the channel estimates in frequency domain based on DRS. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ int32_t **ul_ch_estimates; /// \brief Uplink channel estimates extracted in PRBS. /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ int32_t **ul_ch_estimates_ext; /// \brief Hold the PTRS phase estimates in frequency domain. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ int32_t **ul_ch_ptrs_estimates; /// \brief Uplink phase estimates extracted in PRBS. /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ int32_t **ul_ch_ptrs_estimates_ext; /// \brief Holds the compensated signal. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ int32_t **rxdataF_comp; /// \brief Magnitude of the UL channel estimates. Used for 2nd-bit level thresholds in LLR computation /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ int32_t **ul_ch_mag; /// \brief Magnitude of the UL channel estimates scaled for 3rd bit level thresholds in LLR computation /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ int32_t **ul_ch_magb; /// \brief Cross-correlation of two UE signals. /// - first index: rx antenna [0..nb_antennas_rx[ /// - second index: symbol [0..] int32_t **rho; /// \f$\log_2(\max|H_i|^2)\f$ int16_t log2_maxh; /// \brief Magnitude of Uplink Channel first layer (16QAM level/First 64QAM level). /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_UL[ int32_t **ul_ch_mag0; /// \brief Magnitude of Uplink Channel second layer (16QAM level/First 64QAM level). /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_UL[ int32_t **ul_ch_mag1[8][8]; /// \brief Magnitude of Uplink Channel, first layer (2nd 64QAM level). /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_UL[ int32_t **ul_ch_magb0; /// \brief Magnitude of Uplink Channel second layer (2nd 64QAM level). /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_UL[ int32_t **ul_ch_magb1[8][8]; /// measured RX power based on DRS int ulsch_power[2]; /// \brief llr values. /// - first index: ? [0..1179743] (hard coded) int16_t *llr; /// DMRS symbol index, to be updated every DMRS symbol within a slot. uint8_t dmrs_symbol; // PTRS symbol index, to be updated every PTRS symbol within a slot. uint8_t ptrs_symbol_index; /// bit mask of PT-RS ofdm symbol indicies uint16_t ptrs_symbols; // PTRS subcarriers per OFDM symbol uint16_t ptrs_sc_per_ofdm_symbol; /// flag to verify if channel level computation is done uint8_t cl_done; } NR_gNB_PUSCH; /// Context data structure for RX/TX portion of slot processing typedef struct { /// Component Carrier index uint8_t CC_id; /// timestamp transmitted to HW openair0_timestamp timestamp_tx; /// slot to act upon for transmission int slot_tx; /// slot to act upon for reception int slot_rx; /// frame to act upon for transmission int frame_tx; /// frame to act upon for reception int frame_rx; /// \brief Instance count for RXn-TXnp4 processing thread. /// \internal This variable is protected by \ref mutex_rxtx. int instance_cnt; /// pthread structure for RXn-TXnp4 processing thread pthread_t pthread; /// pthread attributes for RXn-TXnp4 processing thread pthread_attr_t attr; /// condition variable for tx processing thread pthread_cond_t cond; /// mutex for RXn-TXnp4 processing thread pthread_mutex_t mutex; /// scheduling parameters for RXn-TXnp4 thread struct sched_param sched_param_rxtx; /// \internal This variable is protected by \ref mutex_RUs_tx. int instance_cnt_RUs; /// condition variable for tx processing thread pthread_cond_t cond_RUs; /// mutex for L1 RXTX processing thread pthread_mutex_t mutex_RUs; /// mutex for L1 TX FH synchronization pthread_mutex_t mutex_RUs_tx; } gNB_L1_rxtx_proc_t; /// Context data structure for eNB slot processing typedef struct gNB_L1_proc_t_s { /// Component Carrier index uint8_t CC_id; /// thread index int thread_index; /// timestamp received from HW openair0_timestamp timestamp_rx; /// timestamp to send to "slave rru" openair0_timestamp timestamp_tx; /// slot to act upon for reception int slot_rx; /// slot to act upon for PRACH int slot_prach; /// frame to act upon for reception int frame_rx; /// frame to act upon for transmission int frame_tx; /// frame to act upon for PRACH int frame_prach; /// \internal This variable is protected by \ref mutex_td. int instance_cnt_td; /// \internal This variable is protected by \ref mutex_te. int instance_cnt_te; /// \internal This variable is protected by \ref mutex_prach. int instance_cnt_prach; // instance count for over-the-air gNB synchronization int instance_cnt_synch; /// \internal This variable is protected by \ref mutex_asynch_rxtx. int instance_cnt_asynch_rxtx; /// pthread structure for eNB single processing thread pthread_t pthread_single; /// pthread structure for asychronous RX/TX processing thread pthread_t pthread_asynch_rxtx; /// pthread structure for printing time meas pthread_t L1_stats_thread; /// flag to indicate first RX acquisition int first_rx; /// flag to indicate first TX transmission int first_tx; /// pthread attributes for single gNB processing thread pthread_attr_t attr_single; /// pthread attributes for prach processing thread pthread_attr_t attr_prach; /// pthread attributes for asynchronous RX thread pthread_attr_t attr_asynch_rxtx; /// scheduling parameters for parallel turbo-decoder thread struct sched_param sched_param_td; /// scheduling parameters for parallel turbo-encoder thread struct sched_param sched_param_te; /// scheduling parameters for single eNB thread struct sched_param sched_param_single; /// scheduling parameters for prach thread struct sched_param sched_param_prach; /// scheduling parameters for asynch_rxtx thread struct sched_param sched_param_asynch_rxtx; pthread_cond_t cond_prach; /// condition variable for asynch RX/TX thread pthread_cond_t cond_asynch_rxtx; /// mutex for parallel turbo-decoder thread pthread_mutex_t mutex_td; /// mutex for parallel turbo-encoder thread pthread_mutex_t mutex_te; /// mutex for PRACH thread pthread_mutex_t mutex_prach; /// mutex for asynch RX/TX thread pthread_mutex_t mutex_asynch_rxtx; /// mutex for RU access to eNB processing (PDSCH/PUSCH) pthread_mutex_t mutex_RU; /// mutex for RU_tx access to eNB_tx processing (PDSCH/PUSCH) pthread_mutex_t mutex_RU_tx; /// mutex for RU access to eNB processing (PRACH) pthread_mutex_t mutex_RU_PRACH; /// mutex for RU access to eNB processing (PRACH BR) pthread_mutex_t mutex_RU_PRACH_br; /// mask for RUs serving eNB (PDSCH/PUSCH) int RU_mask, RU_mask_tx; /// mask for RUs serving eNB (PRACH) int RU_mask_prach; /// set of scheduling variables RXn-TXnp4 threads gNB_L1_rxtx_proc_t L1_proc, L1_proc_tx; } gNB_L1_proc_t; typedef struct { // common measurements //! estimated noise power (linear) unsigned int n0_power[MAX_NUM_RU_PER_gNB]; //! estimated noise power (dB) unsigned short n0_power_dB[MAX_NUM_RU_PER_gNB]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! estimated avg noise power (dB) unsigned short n0_power_tot_dB; //! estimated avg noise power (dB) short n0_power_tot_dBm; //! estimated avg noise power per RB per RX ant (lin) unsigned short n0_subband_power[MAX_NUM_RU_PER_gNB][100]; //! estimated avg noise power per RB per RX ant (dB) unsigned short n0_subband_power_dB[MAX_NUM_RU_PER_gNB][100]; //! estimated avg noise power per RB (dB) short n0_subband_power_tot_dB[100]; //! estimated avg noise power per RB (dBm) short n0_subband_power_tot_dBm[100]; // gNB measurements (per user) //! estimated received spatial signal power (linear) unsigned int rx_spatial_power[NUMBER_OF_NR_DLSCH_MAX][2][2]; //! estimated received spatial signal power (dB) unsigned short rx_spatial_power_dB[NUMBER_OF_NR_DLSCH_MAX][2][2]; //! estimated rssi (dBm) short rx_rssi_dBm[NUMBER_OF_NR_DLSCH_MAX]; //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) int rx_correlation[NUMBER_OF_NR_DLSCH_MAX][2]; //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) int rx_correlation_dB[NUMBER_OF_NR_DLSCH_MAX][2]; /// Wideband CQI (= SINR) int wideband_cqi[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB]; /// Wideband CQI in dB (= SINR dB) int wideband_cqi_dB[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB]; /// Wideband CQI (sum of all RX antennas, in dB) char wideband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX]; /// Subband CQI per RX antenna and RB (= SINR) int subband_cqi[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][100]; /// Total Subband CQI and RB (= SINR) int subband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX][100]; /// Subband CQI in dB and RB (= SINR dB) int subband_cqi_dB[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][100]; /// Total Subband CQI and RB int subband_cqi_tot_dB[NUMBER_OF_NR_DLSCH_MAX][100]; /// PRACH background noise level int prach_I0; } PHY_MEASUREMENTS_gNB; /// Top-level PHY Data Structure for gNB typedef struct PHY_VARS_gNB_s { /// Module ID indicator for this instance module_id_t Mod_id; uint8_t CC_id; uint8_t configured; gNB_L1_proc_t proc; int single_thread_flag; int abstraction_flag; int num_RU; RU_t *RU_list[MAX_NUM_RU_PER_gNB]; /// Ethernet parameters for northbound midhaul interface eth_params_t eth_params_n; /// Ethernet parameters for fronthaul interface eth_params_t eth_params; int rx_total_gain_dB; int (*nr_start_if)(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB); uint8_t local_flag; nfapi_nr_config_request_scf_t gNB_config; NR_DL_FRAME_PARMS frame_parms; PHY_MEASUREMENTS_gNB measurements; NR_IF_Module_t *if_inst; NR_UL_IND_t UL_INFO; pthread_mutex_t UL_INFO_mutex; /// NFAPI RX ULSCH information nfapi_rx_indication_pdu_t rx_pdu_list[NFAPI_RX_IND_MAX_PDU]; /// NFAPI RX ULSCH CRC information nfapi_crc_indication_pdu_t crc_pdu_list[NFAPI_CRC_IND_MAX_PDU]; /// NFAPI HARQ information nfapi_harq_indication_pdu_t harq_pdu_list[NFAPI_HARQ_IND_MAX_PDU]; /// NFAPI SR information nfapi_sr_indication_pdu_t sr_pdu_list[NFAPI_SR_IND_MAX_PDU]; /// NFAPI CQI information nfapi_cqi_indication_pdu_t cqi_pdu_list[NFAPI_CQI_IND_MAX_PDU]; /// NFAPI CQI information (raw component) nfapi_cqi_indication_raw_pdu_t cqi_raw_pdu_list[NFAPI_CQI_IND_MAX_PDU]; /// NFAPI PRACH information nfapi_preamble_pdu_t preamble_list[MAX_NUM_RX_PRACH_PREAMBLES]; //Sched_Rsp_t Sched_INFO; nfapi_nr_ul_tti_request_t UL_tti_req; nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu; nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu; nfapi_nr_dl_tti_ssb_pdu ssb_pdu; int num_pdsch_rnti; NR_gNB_PBCH pbch; nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL]; NR_gNB_COMMON common_vars; NR_gNB_PRACH prach_vars; NR_gNB_PUSCH *pusch_vars[NUMBER_OF_NR_ULSCH_MAX]; NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2]; // Nusers times two spatial streams NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX][2]; // [Nusers times][2 codewords] NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p; NR_gNB_DLSCH_t *dlsch_PCH; uint8_t pbch_configured; char gNB_generate_rar; /// NR synchronization sequences int16_t d_pss[NR_PSS_LENGTH]; int16_t d_sss[NR_SSS_LENGTH]; /// PBCH DMRS sequence uint32_t nr_gold_pbch_dmrs[2][64][NR_PBCH_DMRS_LENGTH_DWORD]; /// PBCH interleaver uint8_t nr_pbch_interleaver[NR_POLAR_PBCH_PAYLOAD_BITS]; /// PDCCH DMRS sequence uint32_t ***nr_gold_pdcch_dmrs; /// PDSCH DMRS sequence uint32_t ****nr_gold_pdsch_dmrs; /// PUSCH DMRS uint32_t ****nr_gold_pusch_dmrs; /// Indicator set to 0 after first SR uint8_t first_sr[NUMBER_OF_NR_SR_MAX]; /// PRACH root sequence uint32_t X_u[64][839]; uint32_t max_peak_val; /// \brief sinr for all subcarriers of the current link (used only for abstraction). /// first index: ? [0..N_RB_DL*12[ double *sinr_dB; /// N0 (used for abstraction) double N0; unsigned char first_run_I0_measurements; unsigned char is_secondary_gNB; // primary by default unsigned char is_init_sync; /// Flag to tell if initial synchronization is performed. This affects how often the secondary eNB will listen to the PSS from the primary system. unsigned char has_valid_precoder; /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from, and this B/F vector is created. unsigned char PgNB_id; /// id of Primary eNB /// hold the precoder for NULL beam to the primary user int **dl_precoder_SgNB[3]; char log2_maxp; /// holds the maximum channel/precoder coefficient /// if ==0 enables phy only test mode int mac_enabled; /// counter to average prach energh over first 100 prach opportunities int prach_energy_counter; /* time_stats_t phy_proc; */ time_stats_t phy_proc_tx; /* time_stats_t phy_proc_rx; */ time_stats_t rx_prach; /* time_stats_t ofdm_mod_stats; */ time_stats_t dlsch_encoding_stats; time_stats_t dlsch_modulation_stats; time_stats_t dlsch_scrambling_stats; time_stats_t tinput; time_stats_t tprep; time_stats_t tparity; time_stats_t toutput; time_stats_t dlsch_rate_matching_stats; time_stats_t dlsch_interleaving_stats; time_stats_t dlsch_segmentation_stats; /* time_stats_t rx_dft_stats; time_stats_t ulsch_channel_estimation_stats; time_stats_t ulsch_freq_offset_estimation_stats; time_stats_t ulsch_decoding_stats; time_stats_t ulsch_demodulation_stats; time_stats_t ulsch_rate_unmatching_stats; time_stats_t ulsch_turbo_decoding_stats; time_stats_t ulsch_deinterleaving_stats; time_stats_t ulsch_demultiplexing_stats; time_stats_t ulsch_llr_stats; */ } PHY_VARS_gNB; #endif