diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 3fc1da8301..9e8ac3ba3c 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -68,22 +68,22 @@ void nr_layer_mapping(int nbCodes, @param[out] tx_layers, modulated symbols for each layer */ void nr_ue_layer_mapping(const c16_t *mod_symbs, const int n_layers, const int n_symbs, c16_t tx_layers[][n_symbs]); + /*! \brief This function implements the OFDM front end processor on reception (FEP) \param frame_parms Pointer to frame parameters -\param rxdata Pointer to input data in time domain -\param rxdataF Pointer to output data in frequency domain +\param rxdata Pointer to input data in time domain for one frame +\param rxdataF Pointer to output data in frequency domain for one symbol \param symbol symbol within slot (0..12/14) -\param Ns Slot number (0..19) -\param sample_offset offset within rxdata (points to beginning of subframe) +\param slot Slot number +\param sample_offset offset within rxdata (points to beginning of symbol) */ - -int nr_slot_fep_ul(const NR_DL_FRAME_PARMS *frame_parms, - int32_t *rxdata, - int32_t *rxdataF, - unsigned char symbol, - unsigned char Ns, - int sample_offset); +int nr_symbol_fep_ul(const NR_DL_FRAME_PARMS *fp, + const c16_t *rxdata, + c16_t *rxdataF, + unsigned char symbol, + unsigned char slot, + int sample_offset); /*! \brief This function implements the dft transform precoding in PUSCH diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index c012d39d82..c534ed7eea 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -21,6 +21,7 @@ #include "PHY/defs_nr_UE.h" #include "PHY/defs_gNB.h" +#include "PHY/defs_nr_common.h" #include "modulation_UE.h" #include "nr_modulation.h" #include "PHY/LTE_ESTIMATION/lte_estimation.h" @@ -135,61 +136,44 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, return 0; } -int nr_slot_fep_ul(const NR_DL_FRAME_PARMS *frame_parms, - int32_t *rxdata, - int32_t *rxdataF, - unsigned char symbol, - unsigned char Ns, - int sample_offset) +int nr_symbol_fep_ul(const NR_DL_FRAME_PARMS *fp, + const c16_t *rxdata, + c16_t *rxdataF, + unsigned char symbol, + unsigned char slot, + int sample_offset) { - unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples; - unsigned int nb_prefix_samples0 = frame_parms->nb_prefix_samples0; - - dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size); + dft_size_idx_t dftsize = get_dft(fp->ofdm_symbol_size); // This is for misalignment issues - int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); + int32_t tmp_dft_in[fp->ofdm_symbol_size] __attribute__((aligned(32))); // offset of first OFDM symbol - unsigned int rxdata_offset = get_samples_slot_timestamp(frame_parms, Ns); - unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol; - for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++) - rxdata_offset += (idx_symb%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; - rxdata_offset += frame_parms->ofdm_symbol_size * symbol; - + uint32_t prefix_length = get_samples_symbol_duration(fp, slot, symbol, 1) - fp->ofdm_symbol_size; + unsigned int rxdata_offset = + get_samples_slot_timestamp(fp, slot) + get_samples_symbol_timestamp(fp, slot, symbol) + prefix_length; // use OFDM symbol from within 1/8th of the CP to avoid ISI - rxdata_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor); + rxdata_offset -= (fp->nb_prefix_samples / fp->ofdm_offset_divisor); int16_t *rxdata_ptr; + if (rxdata_offset >= sample_offset) + rxdata_offset -= sample_offset; + else + rxdata_offset += fp->samples_per_frame - sample_offset; - if(sample_offset > rxdata_offset) { - - memcpy((void *)&tmp_dft_in[0], - (void *)&rxdata[frame_parms->samples_per_frame - sample_offset + rxdata_offset], - (sample_offset - rxdata_offset) * sizeof(int32_t)); - memcpy((void *)&tmp_dft_in[sample_offset - rxdata_offset], - (void *)&rxdata[0], - (frame_parms->ofdm_symbol_size - sample_offset + rxdata_offset) * sizeof(int32_t)); + if (rxdata_offset + fp->ofdm_symbol_size > fp->samples_per_frame) { + memcpy(&tmp_dft_in[0], + &rxdata[rxdata_offset], + (fp->samples_per_frame - rxdata_offset) * sizeof(int32_t)); + memcpy(&tmp_dft_in[fp->samples_per_frame - rxdata_offset], + &rxdata[0], + (fp->ofdm_symbol_size - fp->samples_per_frame + rxdata_offset) * sizeof(int32_t)); rxdata_ptr = (int16_t *)tmp_dft_in; - - } else if (((rxdata_offset - sample_offset) & 7) != 0) { - - // if input to dft is not 256-bit aligned - memcpy((void *)&tmp_dft_in[0], - (void *)&rxdata[rxdata_offset - sample_offset], - (frame_parms->ofdm_symbol_size) * sizeof(int32_t)); - rxdata_ptr = (int16_t *)tmp_dft_in; - } else { - // use dft input from RX buffer directly - rxdata_ptr = (int16_t *)&rxdata[rxdata_offset - sample_offset]; - + rxdata_ptr = (int16_t *)&rxdata[rxdata_offset]; } - dft(dftsize, - rxdata_ptr, - (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], - 1); + dft(dftsize, rxdata_ptr, (int16_t *)rxdataF, 1); return 0; } @@ -250,7 +234,7 @@ void nr_ofdm_demod_and_rx_rotation(c16_t **rxdata, 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); + nr_symbol_fep_ul(fp, &rxdata[aa][0], &rxdataF[aa][slot_offsetF + symbol * fp->ofdm_symbol_size], symbol, slot, 0); apply_nr_rotation_symbol_RX(fp, &rxdataF[aa][slot_offsetF + symbol * fp->ofdm_symbol_size], fp->symbol_rotation[linktype], diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 0e21f37fde..9e69bda093 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -171,12 +171,13 @@ typedef struct RU_prec_t_s{ } RU_prec_t; typedef struct { - int aid; - int beam; - struct RU_t_s *ru; int startSymbol; int endSymbol; int slot; + const c16_t *rxdata; + c16_t *rxdataF; + const struct NR_DL_FRAME_PARMS *fp; + int32_t sample_offet; task_ans_t *ans; } feprx_cmd_t; diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 03631e3c7e..4cf05d5772 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -31,6 +31,7 @@ */ #include "PHY/defs_gNB.h" +#include "common/platform_types.h" #include "sched_nr.h" #include "PHY/MODULATION/modulation_common.h" #include "PHY/MODULATION/nr_modulation.h" @@ -320,33 +321,21 @@ void nr_feptx_tp(RU_t *ru, int frame_tx, int slot) } // core RX FEP routine, called by threads in RU thread-pool -void nr_fep(void* arg) +void nr_fep(void *arg) { feprx_cmd_t *feprx_cmd = (feprx_cmd_t *)arg; - RU_t *ru = feprx_cmd->ru; - int aid = feprx_cmd->aid; - int beam = feprx_cmd->beam; int slot = feprx_cmd->slot; int startSymbol = feprx_cmd->startSymbol; int endSymbol = feprx_cmd->endSymbol; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - - LOG_D(PHY,"aid %d, frame %d slot %d, startSymbol %d, endSymbol %d\n", aid, ru->proc.frame_rx, slot, startSymbol, endSymbol); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 1); - - int idx = aid + beam * ru->nb_rx; - int offset = (slot % RU_RX_SLOT_DEPTH) * fp->symbols_per_slot * fp->ofdm_symbol_size; - for (int l = startSymbol; l <= endSymbol; l++) - nr_slot_fep_ul(fp, - ru->common.rxdata[idx], - &ru->common.rxdataF[idx][offset], + for (int l = startSymbol; l <= endSymbol; l++) + nr_symbol_fep_ul(feprx_cmd->fp, + feprx_cmd->rxdata, + &feprx_cmd->rxdataF[l * feprx_cmd->fp->ofdm_symbol_size], l, slot, - ru->N_TA_offset); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 0); + feprx_cmd->sample_offet); - // Task completed in // completed_task_ans(feprx_cmd->ans); } @@ -358,39 +347,36 @@ void nr_fep_tp(RU_t *ru, int slot) { start_meas(&ru->ofdm_demod_stats); int nt = ru->nb_rx * ru->num_beams_period; - size_t const sz = nt + (ru->half_slot_parallelization > 0) * nt; + int tasks_per_slot = (ru->half_slot_parallelization > 0) ? 2 : 1; + size_t const sz = nt * tasks_per_slot; feprx_cmd_t arr[sz]; task_ans_t ans; init_task_ans(&ans, sz); + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + int rxdataF_offset = (slot % RU_RX_SLOT_DEPTH) * fp->symbols_per_slot * fp->ofdm_symbol_size; - for (int beam = 0; beam < ru->num_beams_period; beam++) { - for (int aid = 0; aid < ru->nb_rx; aid++) { - feprx_cmd_t *feprx_cmd = &arr[nbfeprx]; - feprx_cmd->ans = &ans; - feprx_cmd->beam = beam; - feprx_cmd->aid = aid; - feprx_cmd->ru = ru; - feprx_cmd->slot = ru->proc.tti_rx; - feprx_cmd->startSymbol = 0; - feprx_cmd->endSymbol = (ru->half_slot_parallelization > 0) ? (ru->nr_frame_parms->symbols_per_slot >> 1) - 1 - : (ru->nr_frame_parms->symbols_per_slot - 1); + int symbols_per_task = fp->symbols_per_slot / tasks_per_slot; - task_t t = {.func = nr_fep, .args = feprx_cmd}; - pushTpool(ru->threadPool, t); - nbfeprx++; - if (ru->half_slot_parallelization > 0) { + for (int task_idx = 0; task_idx < tasks_per_slot; task_idx++) { + int start_symbol = task_idx * symbols_per_task; + int end_symbol = (task_idx + 1) * symbols_per_task - 1; + if (task_idx == tasks_per_slot - 1) + end_symbol = fp->symbols_per_slot - 1; + + for (int beam = 0; beam < ru->num_beams_period; beam++) { + for (int aid = 0; aid < ru->nb_rx; aid++) { feprx_cmd_t *feprx_cmd = &arr[nbfeprx]; feprx_cmd->ans = &ans; - feprx_cmd->beam = beam; - feprx_cmd->aid = aid; - feprx_cmd->ru = ru; + feprx_cmd->fp = fp; feprx_cmd->slot = ru->proc.tti_rx; - feprx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot >> 1; - feprx_cmd->endSymbol = ru->nr_frame_parms->symbols_per_slot - 1; + feprx_cmd->startSymbol = start_symbol; + feprx_cmd->endSymbol = end_symbol; + feprx_cmd->rxdata = (const c16_t *)ru->common.rxdata[aid + beam * ru->nb_rx]; + feprx_cmd->rxdataF = (c16_t *)&ru->common.rxdataF[aid + beam * ru->nb_rx][rxdataF_offset]; + feprx_cmd->sample_offet = ru->N_TA_offset; task_t t = {.func = nr_fep, .args = feprx_cmd}; pushTpool(ru->threadPool, t); - nbfeprx++; } } diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 4dbac5dd7f..58e6321a0b 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -758,7 +758,12 @@ int main(int argc, char **argv){ for (l = 0; l < frame_parms->symbols_per_slot; l++) { for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { - nr_slot_fep_ul(frame_parms, ru->common.rxdata[aa], ru->common.rxdataF[aa], l, slot, ru->N_TA_offset); + nr_symbol_fep_ul(frame_parms, + (c16_t *)ru->common.rxdata[aa], + (c16_t *)&ru->common.rxdataF[aa][frame_parms->ofdm_symbol_size * l], + l, + slot, + ru->N_TA_offset); } }