diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 996a66b343..3fc1da8301 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -78,7 +78,7 @@ void nr_ue_layer_mapping(const c16_t *mod_symbs, const int n_layers, const int n \param sample_offset offset within rxdata (points to beginning of subframe) */ -int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, +int nr_slot_fep_ul(const NR_DL_FRAME_PARMS *frame_parms, int32_t *rxdata, int32_t *rxdataF, unsigned char symbol, @@ -111,6 +111,15 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp, int first_symbol, int nsymb); +void nr_ofdm_demod_and_rx_rotation(c16_t **rxdata, + c16_t **rxdataF, + const NR_DL_FRAME_PARMS *fp, + int nb_antennas, + int slot, + int slot_offsetF, + enum nr_Link linktype, + bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]); + void perform_symbol_rotation(NR_DL_FRAME_PARMS *fp, double f0, c16_t *symbol_rotation); void init_symbol_rotation(NR_DL_FRAME_PARMS *fp); diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 6cc8cbe7c5..c3311fb78a 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -326,4 +326,3 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp, } } } - diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 58e47fc13a..c012d39d82 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -135,7 +135,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, return 0; } -int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, +int nr_slot_fep_ul(const NR_DL_FRAME_PARMS *frame_parms, int32_t *rxdata, int32_t *rxdataF, unsigned char symbol, @@ -237,3 +237,27 @@ void apply_nr_rotation_symbol_RX(const NR_DL_FRAME_PARMS *frame_parms, 15); } } + +void nr_ofdm_demod_and_rx_rotation(c16_t **rxdata, + c16_t **rxdataF, + const NR_DL_FRAME_PARMS *fp, + int nb_antennas, + int slot, + int slot_offsetF, + enum nr_Link linktype, + bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]) +{ + for (int aa = 0; aa < nb_antennas; aa++) { + for (uint8_t symbol = 0; symbol < fp->symbols_per_slot; symbol++) { + if (was_symbol_used[symbol] == true) { + nr_slot_fep_ul(fp, (int32_t *)&rxdata[aa][0], (int32_t *)&rxdataF[aa][slot_offsetF], symbol, slot, 0); + apply_nr_rotation_symbol_RX(fp, + &rxdataF[aa][slot_offsetF + symbol * fp->ofdm_symbol_size], + fp->symbol_rotation[linktype], + fp->N_RB_UL, + slot, + symbol); + } + } + } +} diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index ab51d118ff..68904f1fa2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -168,15 +168,14 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /** \brief This function does IFFT for PUSCH */ -uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, - const uint8_t slot, - const NR_DL_FRAME_PARMS *frame_parms, - const uint8_t n_antenna_ports, - c16_t **txdataF, - c16_t **txdata, - uint32_t linktype, - bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT], - bool no_phase_pre_comp); +uint8_t nr_tx_rotation_and_ofdm_mod(const uint8_t slot, + const NR_DL_FRAME_PARMS *frame_parms, + const uint8_t n_antenna_ports, + c16_t **txdataF, + c16_t **txdata, + uint32_t linktype, + bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT], + bool no_phase_pre_comp); bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 310fa7dc5f..8251f278ad 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -1502,15 +1502,14 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, stop_meas_nr_ue_phy(UE, PUSCH_PROC_STATS); } -uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, - const uint8_t slot, - const NR_DL_FRAME_PARMS *frame_parms, - const uint8_t n_antenna_ports, - c16_t **txdataF, - c16_t **txdata, - uint32_t linktype, - bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT], - bool no_phase_pre_comp) +uint8_t nr_tx_rotation_and_ofdm_mod(const uint8_t slot, + const NR_DL_FRAME_PARMS *frame_parms, + const uint8_t n_antenna_ports, + c16_t **txdataF, + c16_t **txdata, + uint32_t linktype, + bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT], + bool no_phase_pre_comp) { int N_RB = (linktype == link_type_sl) ? frame_parms->N_RB_SL : frame_parms->N_RB_UL; diff --git a/openair1/PHY/TOOLS/signal_energy.c b/openair1/PHY/TOOLS/signal_energy.c index a7c314dd44..9b50b947c3 100644 --- a/openair1/PHY/TOOLS/signal_energy.c +++ b/openair1/PHY/TOOLS/signal_energy.c @@ -180,3 +180,32 @@ int32_t interference_power(int32_t *input, uint32_t length) return temp; } +// Computes transmitter energy level +double compute_tx_energy_level(c16_t **txdata, int nb_antennas, int offset, int length, int n_trials) +{ + double txlev_sum = 0, atxlev[nb_antennas]; + for (int aa = 0; aa < nb_antennas; aa++) { + atxlev[aa] = signal_energy((int32_t *)&txdata[aa][offset], length); + + txlev_sum += atxlev[aa]; + + if (n_trials == 1) + printf("txlev[%d] = %f (%f dB) txlev_sum %f\n", aa, atxlev[aa], 10 * log10(atxlev[aa]), txlev_sum); + } + return txlev_sum; +} + +// Computes noise variance from the input transmit energy and SNR +double compute_noise_variance(double txlev_sum, uint16_t ofdm_symbol_size, int N_RB, double SNR, int n_trials) +{ + double sigma_dB = 10 * log10(txlev_sum * ((double)ofdm_symbol_size / (12 * N_RB))) - SNR; + double sigma = pow(10, sigma_dB / 10); + + if (n_trials == 1) + printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n", + sigma, + sigma_dB, + 10 * log10(txlev_sum), + (double)(double)ofdm_symbol_size / (12 * N_RB)); + return sigma; +} diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index c5a8ab13b7..2f7bd438d6 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -927,6 +927,9 @@ double signal_energy_fp(double *s_re[2], double *s_im[2], uint32_t nb_antennas, */ double signal_energy_fp2(struct complexd *s, uint32_t length); +double compute_tx_energy_level(c16_t **txdata, int nb_antennas, int offset, int length, int n_trials); + +double compute_noise_variance(double txlev_sum, uint16_t ofdm_symbol_size, int N_RB, double SNR, int n_trials); int32_t iSqrt(int32_t value); uint8_t log2_approx(uint32_t); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 745f4961bf..bc2a803de8 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -400,15 +400,14 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n const NR_UE_PRACH *prach_var = ue->prach_vars[proc->gNB_id]; if (!prach_var->active) { start_meas_nr_ue_phy(ue, OFDM_MOD_STATS); - nr_ue_pusch_common_procedures(ue, - proc->nr_slot_tx, - &ue->frame_parms, - ue->frame_parms.nb_antennas_tx, - (c16_t **)txdataF, - txp, - link_type_ul, - was_symbol_used, - ue->no_phase_pre_comp); + nr_tx_rotation_and_ofdm_mod(proc->nr_slot_tx, + &ue->frame_parms, + ue->frame_parms.nb_antennas_tx, + (c16_t **)txdataF, + txp, + link_type_ul, + was_symbol_used, + ue->no_phase_pre_comp); stop_meas_nr_ue_phy(ue, OFDM_MOD_STATS); } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c index d1bbb7ae99..40f3a8256b 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c @@ -315,15 +315,14 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc was_symbol_used[i] = true; if (tx_action) { LOG_D(NR_PHY, "Sending Uplink data \n"); - nr_ue_pusch_common_procedures(ue, - proc->nr_slot_tx, - fp, - fp->nb_antennas_tx, - txdataF, - txp, - link_type_sl, - was_symbol_used, - ue->no_phase_pre_comp); + nr_tx_rotation_and_ofdm_mod(proc->nr_slot_tx, + fp, + fp->nb_antennas_tx, + txdataF, + txp, + link_type_sl, + was_symbol_used, + ue->no_phase_pre_comp); } LOG_D(NR_PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); diff --git a/openair1/SIMULATION/NR_PHY/srssim.c b/openair1/SIMULATION/NR_PHY/srssim.c index f83da5941e..6ce6d3b897 100644 --- a/openair1/SIMULATION/NR_PHY/srssim.c +++ b/openair1/SIMULATION/NR_PHY/srssim.c @@ -88,7 +88,6 @@ int main(int argc, char *argv[]) sigaction(SIGINT, &sigint_action, &oldaction); double SNR, snr0 = 0, snr1 = 20.0; - double sigma, sigma_dB; double snr_step = 1; uint8_t snr1set = 0; double **s_re, **s_im, **r_re, **r_im; @@ -105,7 +104,6 @@ int main(int argc, char *argv[]) int srs_comb_offset = 0; int srs_cyclic_shift = 0; int nb_symb_srs = 0; - int32_t txlev_sum = 0, atxlev[4]; int i; int loglvl = OAILOG_WARNING; int print_perf = 0; @@ -502,44 +500,31 @@ int main(int argc, char *argv[]) uint16_t ofdm_symbol_size = fp->ofdm_symbol_size; int slot_offsetF = (slot % RU_RX_SLOT_DEPTH) * NR_SYMBOLS_PER_SLOT * ofdm_symbol_size; - c16_t *txF[fp->nb_antennas_tx]; - for (i = 0; i < fp->nb_antennas_tx; i++) + c16_t *txF[n_tx]; + for (i = 0; i < n_tx; i++) txF[i] = txdataF[i] + slot_offsetF; + c16_t *txd[n_tx]; + for (i = 0; i < n_tx; i++) + txd[i] = txdata[i] + slot_offset; + ue_srs_procedures_nr(UE, &proc, (c16_t **)txF, &phy_data, was_symbol_used); //------------ TX rotation and OFDM Modulation -------------------------- - - for (int aa = 0; aa < fp->nb_antennas_tx; aa++) { - apply_nr_rotation_TX(fp, &txF[aa][0], fp->symbol_rotation[1], slot, fp->N_RB_UL, 0, fp->Ncp == EXTENDED ? 12 : 14); - if (srs_pdu.cyclic_prefix == 1) { - for (i = 0; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP; i++) { - if (was_symbol_used[i] == true) { - PHY_ofdm_mod((int *)&txF[aa][0], - (int *)&txdata[aa][slot_offset + (ofdm_symbol_size + fp->nb_prefix_samples) * i], - ofdm_symbol_size, - 1, - fp->nb_prefix_samples, - CYCLIC_PREFIX); - } - } - } else { - nr_normal_prefix_mod(&txF[aa][0], &txdata[aa][slot_offset], fp->symbols_per_slot, fp, slot, was_symbol_used); - } - } + nr_tx_rotation_and_ofdm_mod(slot, fp, n_tx, txF, txd, link_type_ul, was_symbol_used, false); //----------- Apply propagation channel and add noise ---------------------------- double ts = 1.0 / (fp->subcarrier_spacing * ofdm_symbol_size); for (i = 0; i < slot_length; i++) { - for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) { + for (int aa = 0; aa < n_tx; aa++) { s_re[aa][i] = (double)txdata[aa][slot_offset + i].r; s_im[aa][i] = (double)txdata[aa][slot_offset + i].i; } } - // Compute SRS symbol offset + // Compute SRS symbol offset and length int symbol_offset = slot_offset; int abs_first_symbol = slot * fp->symbols_per_slot; int idx_sym; @@ -547,19 +532,10 @@ int main(int argc, char *argv[]) symbol_offset += (idx_sym % (0x7 << fp->numerology_index)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0; symbol_offset += ofdm_symbol_size * srs_pdu.time_start_position; + int symbol_length = ofdm_symbol_size + (idx_sym % (0x7 << fp->numerology_index)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0; - // Compute transmitter level - txlev_sum = 0; - for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) { - atxlev[aa] = signal_energy( - (int32_t *)&txdata[aa][symbol_offset], - ofdm_symbol_size + (idx_sym % (0x7 << fp->numerology_index)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0); - - txlev_sum += atxlev[aa]; - - if (n_trials == 1) - printf("txlev[%d] = %d (%f dB) txlev_sum %d\n", aa, atxlev[aa], 10 * log10((double)atxlev[aa]), txlev_sum); - } + // Compute transmitter energy level + double txlev_sum = compute_tx_energy_level(txdata, n_tx, symbol_offset, symbol_length, n_trials); for (SNR = snr0; SNR <= snr1 && !stop; SNR += snr_step) { varArray_t *table_rx = initVarArray(1000, sizeof(double)); @@ -573,15 +549,7 @@ int main(int argc, char *argv[]) int tao_ns_count = 0; for (trial = 0; trial < n_trials && !stop; trial++) { // Estimate noise power from the transmitter level and SNR - sigma_dB = 10 * log10(((double)txlev_sum) * ((double)ofdm_symbol_size / (12 * srs_pdu.bwp_size))) - SNR; - sigma = pow(10, sigma_dB / 10); - - if (n_trials == 1) - printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n", - sigma, - sigma_dB, - 10 * log10((double)txlev_sum), - (double)(double)ofdm_symbol_size / (12 * srs_pdu.bwp_size)); + double sigma = compute_noise_variance(txlev_sum, ofdm_symbol_size, srs_pdu.bwp_size, SNR, n_trials); //----------- Apply propagation channel ---------------------------- multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0); @@ -590,34 +558,24 @@ int main(int argc, char *argv[]) add_noise(rxdata, (const double **)r_re, (const double **)r_im, - sigma, + sigma, // noise power slot_length, slot_offset, ts, 0, // delay 0, // pdu_bit_map 0, // PTRS_BITMAP, - fp->nb_antennas_rx); + n_rx); //----------- OFDM Demodulation and RX rotation-------------------------- - - for (uint8_t symbol = 0; symbol < (fp->Ncp == EXTENDED ? 12 : 14); symbol++) { - for (int aa = 0; aa < fp->nb_antennas_rx; aa++) - nr_slot_fep_ul(fp, (int32_t *)&rxdata[aa][0], (int32_t *)&gNB->common_vars.rxdataF[0][aa][slot_offsetF], symbol, slot, 0); - } - - for (int aa = 0; aa < fp->nb_antennas_rx; aa++) { - for (uint8_t symbol = 0; symbol < fp->symbols_per_slot; symbol++) { - if (was_symbol_used[symbol] == true) { - apply_nr_rotation_symbol_RX(fp, - &gNB->common_vars.rxdataF[0][aa][slot_offsetF + symbol * fp->ofdm_symbol_size], - fp->symbol_rotation[1], - fp->N_RB_UL, - slot, - symbol); - } - } - } + nr_ofdm_demod_and_rx_rotation(rxdata, + gNB->common_vars.rxdataF[0], + fp, + n_rx, + slot, + slot_offsetF, + link_type_ul, + was_symbol_used); //----------- UE RX SRS procedures --------------------- @@ -625,18 +583,17 @@ int main(int argc, char *argv[]) NR_gNB_SRS_t *srs = &gNB->srs[0]; uint8_t N_symb_SRS = 1 << srs->srs_pdu.num_symbols; uint8_t N_ap = 1 << srs->srs_pdu.num_ant_ports; - uint8_t nb_antennas_rx = fp->nb_antennas_rx; int16_t snr_per_rb[srs->srs_pdu.bwp_size]; uint16_t timing_advance_offset; - int16_t timing_advance_offset_nsec[nb_antennas_rx]; + int16_t timing_advance_offset_nsec[n_rx]; int srs_est; - c16_t srs_estimated_channel_freq[nb_antennas_rx][N_ap][ofdm_symbol_size * N_symb_SRS] __attribute__((aligned(32))); - c16_t srs_estimated_channel_time[nb_antennas_rx][N_ap][ofdm_symbol_size] __attribute__((aligned(32))); + c16_t srs_estimated_channel_freq[n_rx][N_ap][ofdm_symbol_size * N_symb_SRS] __attribute__((aligned(32))); + c16_t srs_estimated_channel_time[n_rx][N_ap][ofdm_symbol_size] __attribute__((aligned(32))); nr_srs_rx_procedures(gNB, frame, slot, - nb_antennas_rx, + n_rx, N_ap, N_symb_SRS, ofdm_symbol_size, @@ -652,7 +609,7 @@ int main(int argc, char *argv[]) sum_srs_snr += pow(10, (double)gNB->srs->snr / 10.0); int16_t delay_ns = delay * 1e9 / (fp->samples_per_frame * 100); - for (int ant_idx = 0; ant_idx < nb_antennas_rx; ant_idx++) { + for (int ant_idx = 0; ant_idx < n_rx; ant_idx++) { if (n_trials == 1) printf("[RX ant %d] SRS estimated: TA offset %d, TA offset ns %d \n", ant_idx, diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 18f6f3f605..c6e91d78aa 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1460,26 +1460,20 @@ int main(int argc, char *argv[]) UL_INFO.crc_ind.number_crcs = 0; UL_INFO.srs_ind.number_of_pdus = 0; - for(uint8_t symbol = 0; symbol < (gNB->frame_parms.Ncp == EXTENDED ? 12 : 14); symbol++) { - for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) - nr_slot_fep_ul(&gNB->frame_parms, - (int32_t *)rxdata[aa], - (int32_t *)gNB->common_vars.rxdataF[0][aa], - symbol, - slot, - 0); - } + //----------- OFDM Demodulation and RX rotation-------------------------- + bool was_symbol_used[14] = {0}; int offset = (slot & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; - for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { - const unsigned int max_symb = (gNB->frame_parms.Ncp == EXTENDED) ? 12 : 14; - for (int sym = 0; sym < max_symb; sym++) - apply_nr_rotation_symbol_RX(&gNB->frame_parms, - gNB->common_vars.rxdataF[0][aa] + offset + sym * gNB->frame_parms.ofdm_symbol_size, - gNB->frame_parms.symbol_rotation[1], - gNB->frame_parms.N_RB_UL, - slot, - sym); + for (int i = 0; i < 14; i++) { + was_symbol_used[i] = true; } + nr_ofdm_demod_and_rx_rotation(rxdata, + gNB->common_vars.rxdataF[0], + &gNB->frame_parms, + gNB->frame_parms.nb_antennas_rx, + slot, + offset, + link_type_ul, + was_symbol_used); ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot, &UL_INFO);