/* * 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" typedef struct { uint8_t pbch_a[NR_POLAR_PBCH_PAYLOAD_BITS>>3]; uint8_t pbch_a_interleaved[NR_POLAR_PBCH_PAYLOAD_BITS>>3]; uint8_t pbch_a_prime[NR_POLAR_PBCH_PAYLOAD_BITS>>3]; uint8_t pbch_e[NR_POLAR_PBCH_E]; } NR_gNB_PBCH; typedef struct { /// Length of DCI payload in bits uint16_t size; /// Aggregation level uint8_t L; /// HARQ PID uint8_t harq_pid; /// PDCCH parameters nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params; /// CCE list nr_cce_t cce_list[NR_MAX_PDCCH_AGG_LEVEL]; /// DCI pdu uint32_t dci_pdu[4]; } NR_gNB_DCI_ALLOC_t; typedef struct { uint8_t num_dci; NR_gNB_DCI_ALLOC_t dci_alloc[256]; } NR_gNB_PDCCH; typedef struct { /// Nfapi DLSCH PDU nfapi_nr_dl_config_dlsch_pdu dlsch_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[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32))); /// LDPC-code outputs uint8_t *d[MAX_NUM_NR_DLSCH_SEGMENTS]; /// Interleaver outputs uint8_t f[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32))); /// 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[16]; /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding) int32_t *txdataF[8]; /// beamforming weights for UE-spec transmission (antenna ports 5 or 7..14), for each codeword, maximum 4 layers? int32_t **ue_spec_bf_weights[4]; /// 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 subframe_tx[10]; /// 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[10]; /// 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 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; /// Context data structure for RX/TX portion of subframe processing typedef struct { /// Component Carrier index uint8_t CC_id; /// timestamp transmitted to HW openair0_timestamp timestamp_tx; /// subframe to act upon for transmission int subframe_tx; /// subframe to act upon for reception int subframe_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_rxtx; /// pthread structure for RXn-TXnp4 processing thread pthread_t pthread_rxtx; /// pthread attributes for RXn-TXnp4 processing thread pthread_attr_t attr_rxtx; /// condition variable for tx processing thread pthread_cond_t cond_rxtx; /// mutex for RXn-TXnp4 processing thread pthread_mutex_t mutex_rxtx; /// scheduling parameters for RXn-TXnp4 thread struct sched_param sched_param_rxtx; } gNB_rxtx_proc_t; /// Context data structure for eNB subframe processing typedef struct gNB_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; /// subframe to act upon for reception int subframe_rx; /// subframe to act upon for PRACH int subframe_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; /// 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 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; /// mask for RUs serving eNB (PRACH) int RU_mask_prach; /// set of scheduling variables RXn-TXnp4 threads gNB_rxtx_proc_t proc_rxtx[2]; } gNB_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_UE_MAX][2][2]; //! estimated received spatial signal power (dB) unsigned short rx_spatial_power_dB[NUMBER_OF_UE_MAX][2][2]; //! estimated rssi (dBm) short rx_rssi_dBm[NUMBER_OF_UE_MAX]; //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) int rx_correlation[NUMBER_OF_UE_MAX][2]; //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) int rx_correlation_dB[NUMBER_OF_UE_MAX][2]; /// Wideband CQI (= SINR) int wideband_cqi[NUMBER_OF_UE_MAX][MAX_NUM_RU_PER_gNB]; /// Wideband CQI in dB (= SINR dB) int wideband_cqi_dB[NUMBER_OF_UE_MAX][MAX_NUM_RU_PER_gNB]; /// Wideband CQI (sum of all RX antennas, in dB) char wideband_cqi_tot[NUMBER_OF_UE_MAX]; /// Subband CQI per RX antenna and RB (= SINR) int subband_cqi[NUMBER_OF_UE_MAX][MAX_NUM_RU_PER_gNB][100]; /// Total Subband CQI and RB (= SINR) int subband_cqi_tot[NUMBER_OF_UE_MAX][100]; /// Subband CQI in dB and RB (= SINR dB) int subband_cqi_dB[NUMBER_OF_UE_MAX][MAX_NUM_RU_PER_gNB][100]; /// Total Subband CQI and RB int subband_cqi_tot_dB[NUMBER_OF_UE_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_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 (*start_if)(struct RU_t_s *ru,struct PHY_VARS_gNB_s *gNB); uint8_t local_flag; nfapi_nr_config_request_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; NR_gNB_PDCCH pdcch_vars; NR_gNB_PBCH pbch; t_nrPolar_paramsPtr nrPolar_params; nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_type0_params; LTE_eNB_PHICH phich_vars[2]; NR_gNB_COMMON common_vars; LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX]; LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX]; LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX]; LTE_eNB_PRACH prach_vars; NR_gNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX][2]; // Nusers times two spatial streams LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p; NR_gNB_DLSCH_t *dlsch_MCH; NR_gNB_DLSCH_t *dlsch_PCH; LTE_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX]; LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX]; uint8_t pbch_configured; uint8_t pbch_pdu[4]; //PBCH_PDU_SIZE 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]; /// PDCCH DMRS sequence uint32_t ***nr_gold_pdcch_dmrs; /// PDSCH DMRS sequence uint32_t ***nr_gold_pdsch_dmrs; /// Indicator set to 0 after first SR uint8_t first_sr[NUMBER_OF_UE_MAX]; 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_timing_advance[NUMBER_OF_UE_MAX]; 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; // PDSCH Variables PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_UE_MAX]; // PUSCH Varaibles PUSCH_CONFIG_DEDICATED pusch_config_dedicated[NUMBER_OF_UE_MAX]; // PUCCH variables PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_UE_MAX]; // UL-POWER-Control UL_POWER_CONTROL_DEDICATED ul_power_control_dedicated[NUMBER_OF_UE_MAX]; // TPC TPC_PDCCH_CONFIG tpc_pdcch_config_pucch[NUMBER_OF_UE_MAX]; TPC_PDCCH_CONFIG tpc_pdcch_config_pusch[NUMBER_OF_UE_MAX]; // CQI reporting CQI_REPORT_CONFIG cqi_report_config[NUMBER_OF_UE_MAX]; // SRS Variables SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_UE_MAX]; uint8_t ncs_cell[20][7]; // Scheduling Request Config SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_UE_MAX]; // Transmission mode per UE uint8_t transmission_mode[NUMBER_OF_UE_MAX]; /// cba_last successful reception for each group, used for collision detection uint8_t cba_last_reception[4]; // Pointers for active physicalConfigDedicated to be applied in current subframe struct PhysicalConfigDedicated *physicalConfigDedicated[NUMBER_OF_UE_MAX]; uint32_t rb_mask_ul[4]; /// Information regarding TM5 MU_MIMO_mode mu_mimo_mode[NUMBER_OF_UE_MAX]; /// target_ue_dl_mcs : only for debug purposes uint32_t target_ue_dl_mcs; /// target_ue_ul_mcs : only for debug purposes uint32_t target_ue_ul_mcs; /// target_ue_dl_rballoc : only for debug purposes uint32_t ue_dl_rb_alloc; /// target ul PRBs : only for debug uint32_t ue_ul_nb_rb; ///check for Total Transmissions uint32_t check_for_total_transmissions; ///check for MU-MIMO Transmissions uint32_t check_for_MUMIMO_transmissions; ///check for SU-MIMO Transmissions uint32_t check_for_SUMIMO_transmissions; ///check for FULL MU-MIMO Transmissions uint32_t FULL_MUMIMO_transmissions; /// Counter for total bitrate, bits and throughput in downlink uint32_t total_dlsch_bitrate; uint32_t total_transmitted_bits; uint32_t total_system_throughput; int hw_timing_advance; 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 dlsch_rate_matching_stats; time_stats_t dlsch_turbo_encoding_stats; time_stats_t dlsch_interleaving_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; time_stats_t ulsch_tc_init_stats; time_stats_t ulsch_tc_alpha_stats; time_stats_t ulsch_tc_beta_stats; time_stats_t ulsch_tc_gamma_stats; time_stats_t ulsch_tc_ext_stats; time_stats_t ulsch_tc_intl1_stats; time_stats_t ulsch_tc_intl2_stats; #ifdef LOCALIZATION /// time state for localization time_stats_t localization_stats; #endif int32_t pucch1_stats_cnt[NUMBER_OF_UE_MAX][10]; int32_t pucch1_stats[NUMBER_OF_UE_MAX][10*1024]; int32_t pucch1_stats_thres[NUMBER_OF_UE_MAX][10*1024]; int32_t pucch1ab_stats_cnt[NUMBER_OF_UE_MAX][10]; int32_t pucch1ab_stats[NUMBER_OF_UE_MAX][2*10*1024]; int32_t pusch_stats_rb[NUMBER_OF_UE_MAX][10240]; int32_t pusch_stats_round[NUMBER_OF_UE_MAX][10240]; int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX][10240]; int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240]; int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240]; } PHY_VARS_gNB; #endif