From 25dde24d1ea479bc07c944c3aca121d07c25b670 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 5 Nov 2024 14:29:15 +0100 Subject: [PATCH 1/4] Fix formatting in nr_ul_channel_estimation.c --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 312 +++++++++--------- 1 file changed, 160 insertions(+), 152 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index b8b44eceb6..3528dd641f 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -19,7 +19,6 @@ * contact@openairinterface.org */ - #include #include "nr_ul_estimation.h" @@ -35,13 +34,12 @@ #include "executables/softmodem-common.h" #include "nr_phy_common.h" - //#define DEBUG_CH //#define DEBUG_PUSCH //#define SRS_DEBUG #define NO_INTERP 1 -#define dBc(x,y) (dB_fixed(((int32_t)(x))*(x) + ((int32_t)(y))*(y))) +#define dBc(x, y) (dB_fixed(((int32_t)(x)) * (x) + ((int32_t)(y)) * (y))) __attribute__((always_inline)) inline c16_t c32x16cumulVectVectWithSteps(c16_t *in1, int *offset1, @@ -50,18 +48,18 @@ __attribute__((always_inline)) inline c16_t c32x16cumulVectVectWithSteps(c16_t * int *offset2, const int step2, const int modulo2, - const int N) { - - int localOffset1=*offset1; - int localOffset2=*offset2; - c32_t cumul={0}; - for (int i=0; ipusch_vars[ul_id]; c16_t **ul_ch_estimates = (c16_t **)pusch_vars->ul_ch_estimates; @@ -93,7 +91,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, const int k0 = bwp_start_subcarrier; const int nb_rb_pusch = pusch_pdu->rb_size; - LOG_D(PHY, "symbol_offset %d, slot_offset %d, OFDM size %d, Ns = %d, k0 = %d, symbol %d\n", + LOG_D(PHY, + "symbol_offset %d, slot_offset %d, OFDM size %d, Ns = %d, k0 = %d, symbol %d\n", symbol_offset, slot_offset, symbolSize, @@ -127,13 +126,15 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, const uint8_t u = pusch_pdu->dfts_ofdm.low_papr_group_number; const uint8_t v = pusch_pdu->dfts_ofdm.low_papr_sequence_number; c16_t *dmrs_seq = gNB_dmrs_lowpaprtype1_sequence[u][v][index]; - LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index); - AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); + LOG_D(PHY, "Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index); + AssertFatal(index >= 0, + "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs " + "cannot be multiple of any other primenumber other than 2,3,5\n"); AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); #ifdef DEBUG_PUSCH - printf ("NR_UL_CHANNEL_EST: index %d, u %d,v %d\n", index, u, v); - LOG_M("gNb_DMRS_SEQ.m","gNb_DMRS_SEQ", dmrs_seq,6*nb_rb_pusch,1,1); + printf("NR_UL_CHANNEL_EST: index %d, u %d,v %d\n", index, u, v); + LOG_M("gNb_DMRS_SEQ.m", "gNb_DMRS_SEQ", dmrs_seq, 6 * nb_rb_pusch, 1, 1); #endif } //------------------------------------------------// @@ -141,7 +142,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #ifdef DEBUG_PUSCH for (int i = 0; i < (6 * nb_rb_pusch); i++) { - LOG_I(PHY, "In %s: %d + j*(%d)\n", __FUNCTION__, pilot[i].r,pilot[i].i); + LOG_I(PHY, "In %s: %d + j*(%d)\n", __FUNCTION__, pilot[i].r, pilot[i].i); } #endif @@ -153,7 +154,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, delay_t *delay = &gNB->ulsch[ul_id].delay; memset(delay, 0, sizeof(*delay)); - for (int aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + for (int aarx = 0; aarx < gNB->frame_parms.nb_antennas_rx; aarx++) { c16_t *rxdataF = (c16_t *)&gNB->common_vars.rxdataF[beam_nb][aarx][symbol_offset + slot_offset]; c16_t *ul_ch = &ul_ch_estimates[nl * gNB->frame_parms.nb_antennas_rx + aarx][symbol_offset]; @@ -171,9 +172,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #endif if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1 && chest_freq == 0) { - c16_t *pil = pilot; + c16_t *pil = pilot; int re_offset = k0; - LOG_D(PHY,"PUSCH estimation DMRS type 1, Freq-domain interpolation"); + LOG_D(PHY, "PUSCH estimation DMRS type 1, Freq-domain interpolation"); int pilot_cnt = 0; for (int n = 0; n < 3 * nb_rb_pusch; n++) { @@ -203,11 +204,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #endif pilot_cnt = 0; - for (int n = 0; n < 3*nb_rb_pusch; n++) { - + for (int n = 0; n < 3 * nb_rb_pusch; n++) { // Channel interpolation for (int k_line = 0; k_line <= 1; k_line++) { - // Apply delay int k = pilot_cnt << 1; c16_t ch16 = c16mulShift(ul_ls_est[k], ul_delay_table[k], 8); @@ -216,7 +215,13 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, re_offset = (k0 + (n << 2) + (k_line << 1)) % symbolSize; c16_t *rxF = &rxdataF[re_offset]; printf("pilot %4d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d)\n", - pilot_cnt, pil->r, pil->i, rxF->r, rxF->i, ch16.r, ch16.i); + pilot_cnt, + pil->r, + pil->i, + rxF->r, + rxF->i, + ch16.r, + ch16.i); #endif if (pilot_cnt == 0) { @@ -258,7 +263,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } } - } else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type2 && chest_freq == 0) { // pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d| + } else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type2 + && chest_freq == 0) { // pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d| LOG_D(PHY, "PUSCH estimation DMRS type 2, Freq-domain interpolation\n"); c16_t *pil = pilot; c16_t *rx = &rxdataF[delta]; @@ -285,9 +291,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } } - // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 6 DMRS REs and use a common value for the whole PRB + // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 6 DMRS REs and use a + // common value for the whole PRB else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1) { - LOG_D(PHY,"PUSCH estimation DMRS type 1, no Freq-domain interpolation\n"); + LOG_D(PHY, "PUSCH estimation DMRS type 1, no Freq-domain interpolation\n"); c16_t *rxF = &rxdataF[delta]; int pil_offset = 0; int re_offset = k0; @@ -297,8 +304,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch = c32x16cumulVectVectWithSteps(pilot, &pil_offset, 1, rxF, &re_offset, 2, symbolSize, 6); #if NO_INTERP - for (c16_t *end=ul_ch+12; ul_ch>15; // 1/12*16384 - ul_ch[3].i += (ch.i * 1365)>>15; // 1/12*16384 + ul_ch[3].r += (ch.r * 1365) >> 15; // 1/12*16384 + ul_ch[3].i += (ch.i * 1365) >> 15; // 1/12*16384 ul_ch += 4; c16multaddVectRealComplex(filt8_avlip3, &ch, ul_ch, 8); @@ -329,26 +336,27 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #endif } // Last PRB - ch=c32x16cumulVectVectWithSteps(pilot, &pil_offset, 1, rxF, &re_offset, 2, symbolSize, 6); + ch = c32x16cumulVectVectWithSteps(pilot, &pil_offset, 1, rxF, &re_offset, 2, symbolSize, 6); #if NO_INTERP - for (c16_t *end=ul_ch+12; ul_ch>15; // 1/12*16384 - ul_ch[3].i += (ch.i * 1365)>>15; // 1/12*16384 + ul_ch[3].r += (ch.r * 1365) >> 15; // 1/12*16384 + ul_ch[3].i += (ch.i * 1365) >> 15; // 1/12*16384 ul_ch += 4; c16multaddVectRealComplex(filt8_avlip3, &ch, ul_ch, 8); ul_ch += 8; c16multaddVectRealComplex(filt8_avlip6, &ch, ul_ch, 8); #endif - } else { // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 4 DMRS REs and use a common value for the whole PRB - LOG_D(PHY,"PUSCH estimation DMRS type 2, no Freq-domain interpolation"); + } else { // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 4 DMRS REs + // and use a common value for the whole PRB + LOG_D(PHY, "PUSCH estimation DMRS type 2, no Freq-domain interpolation"); c16_t *pil = pilot; int re_offset = (k0 + delta) % symbolSize; c32_t ch0 = {0}; - //First PRB + // First PRB ch0 = c32x16mulShift(*pil, rxdataF[re_offset], 15); pil++; re_offset = (re_offset + 1) % symbolSize; @@ -361,10 +369,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, pil++; re_offset = (re_offset + 5) % symbolSize; - c16_t ch=c16x32div(ch0, 4); + c16_t ch = c16x32div(ch0, 4); #if NO_INTERP - for (c16_t *end=ul_ch+12; ul_chframe_parms.nb_antennas_rx + aarx][symbol_offset]; for (int idxP = 0; idxP < ceil((float)nb_rb_pusch * 12 / 8); idxP++) { for (int idxI = 0; idxI < 8; idxI++) { - printf("%d\t%d\t", ul_ch[idxP * 8 + idxI].r, ul_ch[idxP * 8 + idxI].i); + printf("%d\t%d\t", ul_ch[idxP * 8 + idxI].r, ul_ch[idxP * 8 + idxI].i); } printf("%d\n", idxP); } #endif - } #ifdef DEBUG_CH @@ -463,7 +470,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, return 0; } - /******************************************************************* * * NAME : nr_pusch_ptrs_processing @@ -495,51 +501,46 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, uint32_t nb_re_pusch) { NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ulsch_id]; - int32_t *ptrs_re_symbol = NULL; - int8_t ret = 0; - uint8_t symbInSlot = rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols; - uint8_t *startSymbIndex = &rel15_ul->start_symbol_index; - uint8_t *nbSymb = &rel15_ul->nr_of_symbols; - uint8_t *L_ptrs = &rel15_ul->pusch_ptrs.ptrs_time_density; - uint8_t *K_ptrs = &rel15_ul->pusch_ptrs.ptrs_freq_density; - uint16_t *dmrsSymbPos = &rel15_ul->ul_dmrs_symb_pos; + int32_t *ptrs_re_symbol = NULL; + int8_t ret = 0; + uint8_t symbInSlot = rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols; + uint8_t *startSymbIndex = &rel15_ul->start_symbol_index; + uint8_t *nbSymb = &rel15_ul->nr_of_symbols; + uint8_t *L_ptrs = &rel15_ul->pusch_ptrs.ptrs_time_density; + uint8_t *K_ptrs = &rel15_ul->pusch_ptrs.ptrs_freq_density; + uint16_t *dmrsSymbPos = &rel15_ul->ul_dmrs_symb_pos; uint16_t *ptrsSymbPos = &pusch_vars->ptrs_symbols; uint8_t *ptrsSymbIdx = &pusch_vars->ptrs_symbol_index; - uint16_t *nb_rb = &rel15_ul->rb_size; - uint8_t *ptrsReOffset = &rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset; + uint16_t *nb_rb = &rel15_ul->rb_size; + uint8_t *ptrsReOffset = &rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset; /* loop over antennas */ - for (int aarx=0; aarxnb_antennas_rx; aarx++) { + for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { c16_t *phase_per_symbol = (c16_t *)pusch_vars->ptrs_phase_per_slot[aarx]; ptrs_re_symbol = &pusch_vars->ptrs_re_per_slot; *ptrs_re_symbol = 0; - phase_per_symbol[symbol].i = 0; + phase_per_symbol[symbol].i = 0; /* set DMRS estimates to 0 angle with magnitude 1 */ - if(is_dmrs_symbol(symbol,*dmrsSymbPos)) { + if (is_dmrs_symbol(symbol, *dmrsSymbPos)) { /* set DMRS real estimation to 32767 */ - phase_per_symbol[symbol].r=INT16_MAX; // 32767 + phase_per_symbol[symbol].r = INT16_MAX; // 32767 #ifdef DEBUG_UL_PTRS - printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[symbol].r,phase_per_symbol[symbol].i); + printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[symbol].r, phase_per_symbol[symbol].i); #endif - } - else {// real ptrs value is set to 0 - phase_per_symbol[symbol].r = 0; + } else { // real ptrs value is set to 0 + phase_per_symbol[symbol].r = 0; } - if(symbol == *startSymbIndex) { + if (symbol == *startSymbIndex) { *ptrsSymbPos = 0; - set_ptrs_symb_idx(ptrsSymbPos, - *nbSymb, - *startSymbIndex, - 1<< *L_ptrs, - *dmrsSymbPos); + set_ptrs_symb_idx(ptrsSymbPos, *nbSymb, *startSymbIndex, 1 << *L_ptrs, *dmrsSymbPos); } /* if not PTRS symbol set current ptrs symbol index to zero*/ *ptrsSymbIdx = 0; /* Check if current symbol contains PTRS */ - if(is_ptrs_symbol(symbol, *ptrsSymbPos)) { + if (is_ptrs_symbol(symbol, *ptrsSymbPos)) { *ptrsSymbIdx = symbol; /*------------------------------------------------------------------------------------------------------- */ /* 1) Estimate common phase error per PTRS symbol */ @@ -564,27 +565,27 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, } /* For last OFDM symbol at each antenna perform interpolation and compensation for the slot*/ - if(symbol == (symbInSlot -1)) { + if (symbol == (symbInSlot - 1)) { /*------------------------------------------------------------------------------------------------------- */ /* 2) Interpolate PTRS estimated value in TD */ /*------------------------------------------------------------------------------------------------------- */ /* If L-PTRS is > 0 then we need interpolation */ - if(*L_ptrs > 0) { - ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, (int16_t*)phase_per_symbol, *startSymbIndex, *nbSymb); - if(ret != 0) { - LOG_W(PHY,"[PTRS] Compensation is skipped due to error in PTRS slot processing !!\n"); + if (*L_ptrs > 0) { + ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, (int16_t *)phase_per_symbol, *startSymbIndex, *nbSymb); + if (ret != 0) { + LOG_W(PHY, "[PTRS] Compensation is skipped due to error in PTRS slot processing !!\n"); } } /*------------------------------------------------------------------------------------------------------- */ /* 3) Compensated DMRS based estimated signal with PTRS estimation */ /*--------------------------------------------------------------------------------------------------------*/ - for(uint8_t i = *startSymbIndex; i < symbInSlot; i++) { + for (uint8_t i = *startSymbIndex; i < symbInSlot; i++) { /* DMRS Symbol has 0 phase so no need to rotate the respective symbol */ /* Skip rotation if the slot processing is wrong */ - if((!is_dmrs_symbol(i,*dmrsSymbPos)) && (ret == 0)) { + if ((!is_dmrs_symbol(i, *dmrsSymbPos)) && (ret == 0)) { #ifdef DEBUG_UL_PTRS - printf("[PHY][UL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i); + printf("[PHY][UL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r, phase_per_symbol[i].i); #endif rotate_cpx_vector((c16_t *)&pusch_vars->rxdataF_comp[aarx][i * nb_re_pusch], &phase_per_symbol[i], @@ -613,22 +614,22 @@ int nr_srs_channel_estimation( int8_t *snr) { #ifdef SRS_DEBUG - LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__); + LOG_I(NR_PHY, "Calling %s function\n", __FUNCTION__); #endif const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB; + const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB; - const uint8_t N_ap = 1<num_ant_ports; - const uint8_t K_TC = 2<comb_size; + const uint8_t N_ap = 1 << srs_pdu->num_ant_ports; + const uint8_t K_TC = 2 << srs_pdu->comb_size; const uint16_t m_SRS_b = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index); - const uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB/K_TC; + const uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB / K_TC; uint8_t fd_cdm = N_ap; if (N_ap == 4 && ((K_TC == 2 && srs_pdu->cyclic_shift >= 4) || (K_TC == 4 && srs_pdu->cyclic_shift >= 6))) { fd_cdm = 2; } - c16_t srs_ls_estimated_channel[frame_parms->ofdm_symbol_size*(1<num_symbols)]; + c16_t srs_ls_estimated_channel[frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)]; uint32_t noise_power_per_rb[srs_pdu->bwp_size]; const uint32_t arr_len = frame_parms->nb_antennas_rx * N_ap * M_sc_b_SRS; @@ -639,7 +640,8 @@ int nr_srs_channel_estimation( c16_t noise[arr_len]; memset(noise, 0, arr_len * sizeof(c16_t)); - uint8_t mem_offset = ((16 - ((long)&srs_estimated_channel_freq[0][0][subcarrier_offset + nr_srs_info->k_0_p[0][0]])) & 0xF) >> 2; // >> 2 <=> /sizeof(int32_t) + uint8_t mem_offset = ((16 - ((long)&srs_estimated_channel_freq[0][0][subcarrier_offset + nr_srs_info->k_0_p[0][0]])) & 0xF) + >> 2; // >> 2 <=> /sizeof(int32_t) // filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0} // The End of OFDM symbol corresponds to the position of last 16384 in the filter @@ -649,26 +651,23 @@ int nr_srs_channel_estimation( c16_t ls_estimated = {0}; for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { - for (int p_index = 0; p_index < N_ap; p_index++) { - - memset(srs_ls_estimated_channel, 0, frame_parms->ofdm_symbol_size*(1<num_symbols)*sizeof(c16_t)); - memset(srs_est, 0, (frame_parms->ofdm_symbol_size*(1<num_symbols) + mem_offset)*sizeof(int32_t)); + memset(srs_ls_estimated_channel, 0, frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) * sizeof(c16_t)); + memset(srs_est, 0, (frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) + mem_offset) * sizeof(int32_t)); #ifdef SRS_DEBUG - LOG_I(NR_PHY,"====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant); + LOG_I(NR_PHY, "====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant); #endif uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; - if (subcarrier>frame_parms->ofdm_symbol_size) { + if (subcarrier > frame_parms->ofdm_symbol_size) { subcarrier -= frame_parms->ofdm_symbol_size; } c16_t *srs_estimated_channel16 = (c16_t *)&srs_est[subcarrier + mem_offset]; for (int k = 0; k < M_sc_b_SRS; k++) { - - if (k%fd_cdm==0) { + if (k % fd_cdm == 0) { ls_estimated = (c16_t){0, 0}; uint16_t subcarrier_cdm = subcarrier; @@ -676,18 +675,21 @@ int nr_srs_channel_estimation( int16_t generated_real = srs_generated_signal[p_index][subcarrier_cdm].r; int16_t generated_imag = srs_generated_signal[p_index][subcarrier_cdm].i; - int16_t received_real = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].r; - int16_t received_imag = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].i; + int16_t received_real = ((c16_t *)srs_received_signal[ant])[subcarrier_cdm].r; + int16_t received_imag = ((c16_t *)srs_received_signal[ant])[subcarrier_cdm].i; - // We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and generated_imag. - // So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 bits. - ls_estimated.r += (int16_t)(((int32_t)generated_real*received_real + (int32_t)generated_imag*received_imag)>>nr_srs_info->srs_generated_signal_bits); - ls_estimated.i += (int16_t)(((int32_t)generated_real*received_imag - (int32_t)generated_imag*received_real)>>nr_srs_info->srs_generated_signal_bits); + // We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and + // generated_imag. So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 + // bits. + ls_estimated.r += (int16_t)(((int32_t)generated_real * received_real + (int32_t)generated_imag * received_imag) + >> nr_srs_info->srs_generated_signal_bits); + ls_estimated.i += (int16_t)(((int32_t)generated_real * received_imag - (int32_t)generated_imag * received_real) + >> nr_srs_info->srs_generated_signal_bits); // Subcarrier increment subcarrier_cdm += K_TC; if (subcarrier_cdm >= frame_parms->ofdm_symbol_size) { - subcarrier_cdm=subcarrier_cdm-frame_parms->ofdm_symbol_size; + subcarrier_cdm = subcarrier_cdm - frame_parms->ofdm_symbol_size; } } } @@ -695,19 +697,23 @@ int nr_srs_channel_estimation( srs_ls_estimated_channel[subcarrier] = ls_estimated; #ifdef SRS_DEBUG - int subcarrier_log = subcarrier-subcarrier_offset; - if(subcarrier_log < 0) { + int subcarrier_log = subcarrier - subcarrier_offset; + if (subcarrier_log < 0) { subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; } - if(subcarrier_log%12 == 0) { - LOG_I(NR_PHY,"------------------------------------ %d ------------------------------------\n", subcarrier_log/12); - LOG_I(NR_PHY,"\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n"); + if (subcarrier_log % 12 == 0) { + LOG_I(NR_PHY, "------------------------------------ %d ------------------------------------\n", subcarrier_log / 12); + LOG_I(NR_PHY, "\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n"); } - LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", + LOG_I(NR_PHY, + "(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", subcarrier_log, - ((c16_t*)srs_generated_signal[p_index])[subcarrier].r, ((c16_t*)srs_generated_signal[p_index])[subcarrier].i, - ((c16_t*)srs_received_signal[ant])[subcarrier].r, ((c16_t*)srs_received_signal[ant])[subcarrier].i, - ls_estimated.r, ls_estimated.i); + ((c16_t *)srs_generated_signal[p_index])[subcarrier].r, + ((c16_t *)srs_generated_signal[p_index])[subcarrier].i, + ((c16_t *)srs_received_signal[ant])[subcarrier].r, + ((c16_t *)srs_received_signal[ant])[subcarrier].i, + ls_estimated.r, + ls_estimated.i); #endif const uint16_t sc_offset = subcarrier + mem_offset; @@ -722,7 +728,8 @@ int nr_srs_channel_estimation( srs_estimated_channel16 = (c16_t *)&srs_est[subcarrier]; const short *filter = mem_offset == 0 ? filt8_start : filt8_start_shift2; c16multaddVectRealComplex(filter, &ls_estimated, srs_estimated_channel16, 8); - } else if ((subcarrier + K_TC) >= frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases + } else if ((subcarrier + K_TC) >= frame_parms->ofdm_symbol_size + || k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases // filt8_end is {4096,8192,12288,16384,0,0,0,0} const short *filter = mem_offset == 0 || k == (M_sc_b_SRS - 1) ? filt8_end : filt8_end_shift2; c16multaddVectRealComplex(filter, &ls_estimated, srs_estimated_channel16, 8); @@ -742,7 +749,8 @@ int nr_srs_channel_estimation( srs_estimated_channel16 = (c16_t *)&srs_est[sc_offset]; // filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0} c16multaddVectRealComplex(filt16_start, &ls_estimated, srs_estimated_channel16, 16); - } else if ((subcarrier + K_TC) >= frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases + } else if ((subcarrier + K_TC) >= frame_parms->ofdm_symbol_size + || k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases // filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0} c16multaddVectRealComplex(filt16_end, &ls_estimated, srs_estimated_channel16, 16); } else { // Middle case @@ -755,18 +763,18 @@ int nr_srs_channel_estimation( // Subcarrier increment subcarrier += K_TC; if (subcarrier >= frame_parms->ofdm_symbol_size) { - subcarrier=subcarrier-frame_parms->ofdm_symbol_size; + subcarrier = subcarrier - frame_parms->ofdm_symbol_size; } } // for (int k = 0; k < M_sc_b_SRS; k++) memcpy(&srs_estimated_channel_freq[ant][p_index][0], &srs_est[mem_offset], - (frame_parms->ofdm_symbol_size*(1<num_symbols))*sizeof(int32_t)); + (frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)) * sizeof(int32_t)); // Compute noise subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; - if (subcarrier>frame_parms->ofdm_symbol_size) { + if (subcarrier > frame_parms->ofdm_symbol_size) { subcarrier -= frame_parms->ofdm_symbol_size; } uint16_t base_idx = ant * N_ap * M_sc_b_SRS + p_index * M_sc_b_SRS; @@ -782,23 +790,23 @@ int nr_srs_channel_estimation( #ifdef SRS_DEBUG subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; - if (subcarrier>frame_parms->ofdm_symbol_size) { + if (subcarrier > frame_parms->ofdm_symbol_size) { subcarrier -= frame_parms->ofdm_symbol_size; } - for (int k = 0; k < K_TC*M_sc_b_SRS; k++) { - - int subcarrier_log = subcarrier-subcarrier_offset; - if(subcarrier_log < 0) { + for (int k = 0; k < K_TC * M_sc_b_SRS; k++) { + int subcarrier_log = subcarrier - subcarrier_offset; + if (subcarrier_log < 0) { subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; } - if(subcarrier_log%12 == 0) { - LOG_I(NR_PHY,"------------------------------------- %d -------------------------------------\n", subcarrier_log/12); - LOG_I(NR_PHY,"\t __lsRe__________lsIm__|____intRe_______intIm__|____noiRe_______noiIm__\n"); + if (subcarrier_log % 12 == 0) { + LOG_I(NR_PHY, "------------------------------------- %d -------------------------------------\n", subcarrier_log / 12); + LOG_I(NR_PHY, "\t __lsRe__________lsIm__|____intRe_______intIm__|____noiRe_______noiIm__\n"); } - LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", + LOG_I(NR_PHY, + "(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", subcarrier_log, srs_ls_estimated_channel[subcarrier].r, srs_ls_estimated_channel[subcarrier].i, @@ -810,23 +818,23 @@ int nr_srs_channel_estimation( // Subcarrier increment subcarrier++; if (subcarrier >= frame_parms->ofdm_symbol_size) { - subcarrier=subcarrier-frame_parms->ofdm_symbol_size; + subcarrier = subcarrier - frame_parms->ofdm_symbol_size; } } #endif // Convert to time domain freq2time(gNB->frame_parms.ofdm_symbol_size, - (int16_t*) srs_estimated_channel_freq[ant][p_index], - (int16_t*) srs_estimated_channel_time[ant][p_index]); + (int16_t *)srs_estimated_channel_freq[ant][p_index], + (int16_t *)srs_estimated_channel_time[ant][p_index]); memcpy(&srs_estimated_channel_time_shifted[ant][p_index][0], - &srs_estimated_channel_time[ant][p_index][gNB->frame_parms.ofdm_symbol_size>>1], - (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); + &srs_estimated_channel_time[ant][p_index][gNB->frame_parms.ofdm_symbol_size >> 1], + (gNB->frame_parms.ofdm_symbol_size >> 1) * sizeof(int32_t)); - memcpy(&srs_estimated_channel_time_shifted[ant][p_index][gNB->frame_parms.ofdm_symbol_size>>1], + memcpy(&srs_estimated_channel_time_shifted[ant][p_index][gNB->frame_parms.ofdm_symbol_size >> 1], &srs_estimated_channel_time[ant][p_index][0], - (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); + (gNB->frame_parms.ofdm_symbol_size >> 1) * sizeof(int32_t)); } // for (int p_index = 0; p_index < N_ap; p_index++) } // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) @@ -835,7 +843,7 @@ int nr_srs_channel_estimation( uint32_t signal_power = max(signal_energy_nodc(ch, arr_len), 1); #ifdef SRS_DEBUG - LOG_I(NR_PHY,"signal_power = %u\n", signal_power); + LOG_I(NR_PHY, "signal_power = %u\n", signal_power); #endif if (signal_power == 0) { @@ -845,14 +853,13 @@ int nr_srs_channel_estimation( // Compute noise power const uint8_t srs_symbols_per_rb = srs_pdu->comb_size == 0 ? 6 : 3; - const uint8_t n_noise_est = frame_parms->nb_antennas_rx*N_ap*srs_symbols_per_rb; + const uint8_t n_noise_est = frame_parms->nb_antennas_rx * N_ap * srs_symbols_per_rb; uint64_t sum_re = 0; uint64_t sum_re2 = 0; uint64_t sum_im = 0; uint64_t sum_im2 = 0; for (int rb = 0; rb < m_SRS_b; rb++) { - sum_re = 0; sum_re2 = 0; sum_im = 0; @@ -870,12 +877,13 @@ int nr_srs_channel_estimation( } // for (int p_index = 0; p_index < N_ap; p_index++) } // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) - noise_power_per_rb[rb] = max(sum_re2 / n_noise_est - (sum_re / n_noise_est) * (sum_re / n_noise_est) + - sum_im2 / n_noise_est - (sum_im / n_noise_est) * (sum_im / n_noise_est), 1); + noise_power_per_rb[rb] = max(sum_re2 / n_noise_est - (sum_re / n_noise_est) * (sum_re / n_noise_est) + sum_im2 / n_noise_est + - (sum_im / n_noise_est) * (sum_im / n_noise_est), + 1); snr_per_rb[rb] = dB_fixed(signal_power) - dB_fixed(noise_power_per_rb[rb]); #ifdef SRS_DEBUG - LOG_I(NR_PHY,"noise_power_per_rb[%i] = %i, snr_per_rb[%i] = %i dB\n", rb, noise_power_per_rb[rb], rb, snr_per_rb[rb]); + LOG_I(NR_PHY, "noise_power_per_rb[%i] = %i, snr_per_rb[%i] = %i dB\n", rb, noise_power_per_rb[rb], rb, snr_per_rb[rb]); #endif } // for (int rb = 0; rb < m_SRS_b; rb++) @@ -885,7 +893,7 @@ int nr_srs_channel_estimation( *snr = dB_fixed(signal_power) - dB_fixed(noise_power); #ifdef SRS_DEBUG - LOG_I(NR_PHY,"noise_power = %u, SNR = %i dB\n", noise_power, *snr); + LOG_I(NR_PHY, "noise_power = %u, SNR = %i dB\n", noise_power, *snr); #endif return 0; From 5605b0c0c61396750229c0121e28bb552d64d15c Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 5 Nov 2024 14:56:47 +0100 Subject: [PATCH 2/4] Parallelize the PUSCH channel estimation - add new data structures for antenna processing. - create arrays that keep track of certain values (max_ch, noise_amp2, nest_count and delay) per each antenna. These values are processed in order to determine one final output. - add time processing measurements for each antenna, and prints them in nr_ulsim. - make num_antennas_per_thread configurable in nr_ulsim and the gNB config file. Co-authored-by: Nada Bouknana Co-authored-by: Brice Robert --- executables/nr-gnb.c | 3 + .../NR_ESTIMATION/nr_ul_channel_estimation.c | 287 ++++++++++++------ openair1/PHY/defs_gNB.h | 34 +++ openair1/SIMULATION/NR_PHY/ulsim.c | 12 +- openair2/GNB_APP/L1_nr_paramdef.h | 4 + openair2/GNB_APP/gnb_config.c | 1 + 6 files changed, 245 insertions(+), 96 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 4206cfd585..22aa50b9c3 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -354,6 +354,9 @@ void init_gNB_Tpool(int inst) { // ULSCH decoder result FIFO initNotifiedFIFO(&gNB->respPuschSymb); initNotifiedFIFO(&gNB->respDecode); + // PUSCH channel estimation result FIFO + initNotifiedFIFO(&gNB->respPuschAarx); + // L1 RX result FIFO initNotifiedFIFO(&gNB->resp_L1); diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 3528dd641f..f0cc9ca8e5 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -63,25 +63,27 @@ __attribute__((always_inline)) inline c16_t c32x16cumulVectVectWithSteps(c16_t * return c16x32div(cumul, N); } -int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, - unsigned char Ns, - int nl, - unsigned short p, - unsigned char symbol, - int ul_id, - int beam_nb, - unsigned short bwp_start_subcarrier, - nfapi_nr_pusch_pdu_t *pusch_pdu, - int *max_ch, - uint32_t *nvar) +static void nr_pusch_antenna_processing(void *arg) { - c16_t pilot[3280] __attribute__((aligned(32))); - const int chest_freq = gNB->chest_freq; + puschAntennaProc_t *rdata = (puschAntennaProc_t *)arg; -#ifdef DEBUG_CH - FILE *debug_ch_est; - debug_ch_est = fopen("debug_ch_est.txt", "w"); -#endif + PHY_VARS_gNB *gNB = rdata->gNB; + unsigned char Ns = rdata->Ns; + int nl = rdata->nl; + unsigned short p = rdata->p; + unsigned char symbol = rdata->symbol; + int ul_id = rdata->ul_id; + int aarx = rdata->aarx; + int numAntennas = rdata->numAntennas; + unsigned short bwp_start_subcarrier = rdata->bwp_start_subcarrier; + nfapi_nr_pusch_pdu_t *pusch_pdu = rdata->pusch_pdu; + int *max_ch = rdata->max_ch; + c16_t *pilot = rdata->pilot; + uint64_t noise_amp2 = *(rdata->noise_amp2); + int nest_count = *(rdata->nest_count); + delay_t *delay = rdata->delay; + + const int chest_freq = gNB->chest_freq; NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ul_id]; c16_t **ul_ch_estimates = (c16_t **)pusch_vars->ul_ch_estimates; const int symbolSize = gNB->frame_parms.ofdm_symbol_size; @@ -90,75 +92,23 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, const int symbol_offset = symbolSize * symbol; const int k0 = bwp_start_subcarrier; const int nb_rb_pusch = pusch_pdu->rb_size; - - LOG_D(PHY, - "symbol_offset %d, slot_offset %d, OFDM size %d, Ns = %d, k0 = %d, symbol %d\n", - symbol_offset, - slot_offset, - symbolSize, - Ns, - k0, - symbol); - - //------------------generate DMRS------------------// - - if (pusch_pdu->transform_precoding == transformPrecoder_disabled) { - // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - const uint32_t *gold = nr_gold_pusch(fp->N_RB_UL, - fp->symbols_per_slot, - gNB->gNB_config.cell_config.phy_cell_id.value, - pusch_pdu->scid, - Ns, - symbol); - nr_pusch_dmrs_rx(gNB, - Ns, - gold, - pilot, - (1000 + p), - 0, - nb_rb_pusch, - (pusch_pdu->bwp_start + pusch_pdu->rb_start) * NR_NB_SC_PER_RB, - pusch_pdu->dmrs_config_type); - } else { // if transform precoding or SC-FDMA is enabled in Uplink - // NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible - const int index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB / 2)); - const uint8_t u = pusch_pdu->dfts_ofdm.low_papr_group_number; - const uint8_t v = pusch_pdu->dfts_ofdm.low_papr_sequence_number; - c16_t *dmrs_seq = gNB_dmrs_lowpaprtype1_sequence[u][v][index]; - LOG_D(PHY, "Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index); - AssertFatal(index >= 0, - "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs " - "cannot be multiple of any other primenumber other than 2,3,5\n"); - AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); - nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); -#ifdef DEBUG_PUSCH - printf("NR_UL_CHANNEL_EST: index %d, u %d,v %d\n", index, u, v); - LOG_M("gNb_DMRS_SEQ.m", "gNb_DMRS_SEQ", dmrs_seq, 6 * nb_rb_pusch, 1, 1); -#endif - } - //------------------------------------------------// - -#ifdef DEBUG_PUSCH - - for (int i = 0; i < (6 * nb_rb_pusch); i++) { - LOG_I(PHY, "In %s: %d + j*(%d)\n", __FUNCTION__, pilot[i].r, pilot[i].i); - } - -#endif - - int nest_count = 0; - uint64_t noise_amp2 = 0; - c16_t ul_ls_est[symbolSize] __attribute__((aligned(32))); - memset(ul_ls_est, 0, sizeof(c16_t) * symbolSize); - delay_t *delay = &gNB->ulsch[ul_id].delay; - memset(delay, 0, sizeof(*delay)); - - for (int aarx = 0; aarx < gNB->frame_parms.nb_antennas_rx; aarx++) { - c16_t *rxdataF = (c16_t *)&gNB->common_vars.rxdataF[beam_nb][aarx][symbol_offset + slot_offset]; - c16_t *ul_ch = &ul_ch_estimates[nl * gNB->frame_parms.nb_antennas_rx + aarx][symbol_offset]; - + const int beam_nb = rdata->beam_nb; + for (int antenna = aarx; antenna < aarx + numAntennas; antenna++) { + c16_t ul_ls_est[symbolSize] __attribute__((aligned(32))); + memset(ul_ls_est, 0, sizeof(c16_t) * symbolSize); + c16_t *rxdataF = (c16_t *)&gNB->common_vars.rxdataF[beam_nb][antenna][symbol_offset + slot_offset]; + c16_t *ul_ch = &ul_ch_estimates[nl * gNB->frame_parms.nb_antennas_rx + antenna][symbol_offset]; memset(ul_ch, 0, sizeof(*ul_ch) * symbolSize); + + LOG_D(PHY, + "symbol_offset %d, slot_offset %d, OFDM size %d, Ns = %d, k0 = %d, symbol %d\n", + symbol_offset, + slot_offset, + symbolSize, + Ns, + k0, + symbol); + #ifdef DEBUG_PUSCH LOG_I(PHY, "symbol_offset %d, delta %d\n", symbol_offset, delta); LOG_I(PHY, "ch est pilot, N_RB_UL %d\n", gNB->frame_parms.N_RB_UL); @@ -188,14 +138,14 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } c16_t ch16 = {.r = (int16_t)ch.r, .i = (int16_t)ch.i}; - *max_ch = max(*max_ch, max(abs(ch.r), abs(ch.i))); + *max_ch = max(abs(ch.r), abs(ch.i)); for (int k = pilot_cnt << 1; k < (pilot_cnt << 1) + 4; k++) { ul_ls_est[k] = ch16; } pilot_cnt += 2; } - nr_est_delay(gNB->frame_parms.ofdm_symbol_size, ul_ls_est, (c16_t *)pusch_vars->ul_ch_estimates_time[aarx], delay); + nr_est_delay(gNB->frame_parms.ofdm_symbol_size, ul_ls_est, (c16_t *)pusch_vars->ul_ch_estimates_time[antenna], delay); int delay_idx = get_delay_idx(delay->est_delay, MAX_DELAY_COMP); c16_t *ul_delay_table = gNB->frame_parms.delay_table[delay_idx]; @@ -220,8 +170,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, pil->i, rxF->r, rxF->i, - ch16.r, - ch16.i); + ch.r, + ch.i); #endif if (pilot_cnt == 0) { @@ -243,7 +193,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, // Revert delay pilot_cnt = 0; - ul_ch = &ul_ch_estimates[nl * gNB->frame_parms.nb_antennas_rx + aarx][symbol_offset]; + ul_ch = &ul_ch_estimates[nl * gNB->frame_parms.nb_antennas_rx + antenna][symbol_offset]; int inv_delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP); c16_t *ul_inv_delay_table = gNB->frame_parms.delay_table[inv_delay_idx]; for (int n = 0; n < 3 * nb_rb_pusch; n++) { @@ -274,16 +224,16 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, c16_t ch1 = c16mulShift(*pil, rx[(k0 + n + 1) % symbolSize], 15); pil++; c16_t ch = c16addShift(ch0, ch1, 1); - *max_ch = max(*max_ch, max(abs(ch.r), abs(ch.i))); + *max_ch = max(abs(ch.r), abs(ch.i)); multadd_real_four_symbols_vector_complex_scalar(filt8_rep4, &ch, &ul_ls_est[n]); ul_ls_est[n + 4] = ch; ul_ls_est[n + 5] = ch; noise_amp2 += c16amp2(c16sub(ch0, ch)); - nest_count++; + nest_count += 1; } // Delay compensation - nr_est_delay(gNB->frame_parms.ofdm_symbol_size, ul_ls_est, (c16_t *)pusch_vars->ul_ch_estimates_time[aarx], delay); + nr_est_delay(gNB->frame_parms.ofdm_symbol_size, ul_ls_est, (c16_t *)pusch_vars->ul_ch_estimates_time[antenna], delay); int delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP); c16_t *ul_delay_table = gNB->frame_parms.delay_table[delay_idx]; for (int n = 0; n < nb_rb_pusch * NR_NB_SC_PER_RB; n++) { @@ -317,7 +267,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, for (int pilot_cnt = 6; pilot_cnt < 6 * (nb_rb_pusch - 1); pilot_cnt += 6) { ch = c32x16cumulVectVectWithSteps(pilot, &pil_offset, 1, rxF, &re_offset, 2, symbolSize, 6); - *max_ch = max(*max_ch, max(abs(ch.r), abs(ch.i))); + *max_ch = max(abs(ch.r), abs(ch.i)); #if NO_INTERP for (c16_t *end = ul_ch + 12; ul_ch < end; ul_ch++) @@ -401,7 +351,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, re_offset = (re_offset + 5) % symbolSize; ch = c16x32div(ch0, 4); - *max_ch = max(*max_ch, max(abs(ch.r), abs(ch.i))); + *max_ch = max(abs(ch.r), abs(ch.i)); #if NO_INTERP for (c16_t *end = ul_ch + 12; ul_ch < end; ul_ch++) @@ -457,6 +407,153 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, printf("%d\n", idxP); } #endif + // update the values inside the arrays + *(rdata->noise_amp2) = noise_amp2; + *(rdata->nest_count) = nest_count; + } +} + + +int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + unsigned char Ns, + int nl, + unsigned short p, + unsigned char symbol, + int ul_id, + int beam_nb, + unsigned short bwp_start_subcarrier, + nfapi_nr_pusch_pdu_t *pusch_pdu, + int *max_ch, + uint32_t *nvar) +{ + c16_t pilot[3280] __attribute__((aligned(32))); + +#ifdef DEBUG_CH + FILE *debug_ch_est; + debug_ch_est = fopen("debug_ch_est.txt", "w"); +#endif + + const int nb_rb_pusch = pusch_pdu->rb_size; + + //------------------generate DMRS------------------// + + if (pusch_pdu->transform_precoding == transformPrecoder_disabled) { + // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + const uint32_t *gold = nr_gold_pusch(fp->N_RB_UL, + fp->symbols_per_slot, + gNB->gNB_config.cell_config.phy_cell_id.value, + pusch_pdu->scid, + Ns, + symbol); + nr_pusch_dmrs_rx(gNB, + Ns, + gold, + pilot, + (1000 + p), + 0, + nb_rb_pusch, + (pusch_pdu->bwp_start + pusch_pdu->rb_start) * NR_NB_SC_PER_RB, + pusch_pdu->dmrs_config_type); + } else { // if transform precoding or SC-FDMA is enabled in Uplink + // NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible + const int index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB / 2)); + const uint8_t u = pusch_pdu->dfts_ofdm.low_papr_group_number; + const uint8_t v = pusch_pdu->dfts_ofdm.low_papr_sequence_number; + c16_t *dmrs_seq = gNB_dmrs_lowpaprtype1_sequence[u][v][index]; + LOG_D(PHY, "Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index); + AssertFatal(index >= 0, + "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs " + "cannot be multiple of any other primenumber other than 2,3,5\n"); + AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); + nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); +#ifdef DEBUG_PUSCH + printf("NR_UL_CHANNEL_EST: index %d, u %d,v %d\n", index, u, v); + LOG_M("gNb_DMRS_SEQ.m", "gNb_DMRS_SEQ", dmrs_seq, 6 * nb_rb_pusch, 1, 1); +#endif + } + //------------------------------------------------// + +#ifdef DEBUG_PUSCH + + for (int i = 0; i < (6 * nb_rb_pusch); i++) { + LOG_I(PHY, "In %s: %d + j*(%d)\n", __FUNCTION__, pilot[i].r, pilot[i].i); + } + +#endif + + int nbAarx = 0; + int nest_count = 0; + uint64_t noise_amp2 = 0; + delay_t *delay = &gNB->ulsch[ul_id].delay; + memset(delay, 0, sizeof(*delay)); + + int nb_antennas_rx = gNB->frame_parms.nb_antennas_rx; + delay_t delay_arr[nb_antennas_rx]; + uint64_t noise_amp2_arr[nb_antennas_rx]; + int max_ch_arr[nb_antennas_rx]; + int nest_count_arr[nb_antennas_rx]; + + for (int i = 0; i < nb_antennas_rx; ++i) { + max_ch_arr[i] = *max_ch; + nest_count_arr[i] = nest_count; + noise_amp2_arr[i] = noise_amp2; + delay_arr[i] = *delay; + } + + start_meas(&gNB->pusch_channel_estimation_antenna_processing_stats); + int numAntennas = gNB->dmrs_num_antennas_per_thread; + for (int aarx = 0; aarx < gNB->frame_parms.nb_antennas_rx; aarx += numAntennas) { + union puschAntennaReqUnion id = {.s = {ul_id, 0}}; + id.p = 1 + aarx; + notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(puschAntennaProc_t), + id.p, + &gNB->respPuschAarx, + &nr_pusch_antenna_processing); // create a job for Tpool + puschAntennaProc_t *rdata = (puschAntennaProc_t *)NotifiedFifoData(req); // data for the job + + // Local init in the current loop + rdata->gNB = gNB; + rdata->Ns = Ns; + rdata->nl = nl; + rdata->p = p; + rdata->symbol = symbol; + rdata->aarx = aarx; + rdata->numAntennas = numAntennas; + rdata->ul_id = ul_id; + rdata->bwp_start_subcarrier = bwp_start_subcarrier; + rdata->pusch_pdu = pusch_pdu; + rdata->max_ch = &max_ch_arr[rdata->aarx]; + rdata->pilot = pilot; + rdata->nest_count = &nest_count_arr[rdata->aarx]; + rdata->noise_amp2 = &noise_amp2_arr[rdata->aarx]; + rdata->delay = &delay_arr[rdata->aarx]; + rdata->beam_nb = beam_nb; + // Call the nr_pusch_antenna_processing function + pushTpool(&gNB->threadPool, req); + nbAarx++; + + LOG_D(PHY, "Added Antenna (count %d) to process, in pipe\n", nbAarx); + } // Antenna Loop + + while (nbAarx > 0) { + notifiedFIFO_elt_t *req = pullTpool(&gNB->respPuschAarx, &gNB->threadPool); + nbAarx--; + delNotifiedFIFO_elt(req); + } + + stop_meas(&gNB->pusch_channel_estimation_antenna_processing_stats); + for (int aarx = 0; aarx < gNB->frame_parms.nb_antennas_rx; aarx++) { + *max_ch = max(*max_ch, max_ch_arr[aarx]); + noise_amp2 += noise_amp2_arr[aarx]; + nest_count += nest_count_arr[aarx]; + } + // get the maximum delay + *delay = delay_arr[0]; + for (int aarx = 1; aarx < gNB->frame_parms.nb_antennas_rx; aarx++) { + if (delay_arr[aarx].est_delay >= delay->est_delay) { + *delay = delay_arr[aarx]; + } } #ifdef DEBUG_CH diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 7022ad8b23..7de4d24817 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -543,6 +543,7 @@ typedef struct PHY_VARS_gNB_s { time_stats_t ulsch_decoding_stats; time_stats_t ulsch_deinterleaving_stats; time_stats_t ulsch_channel_estimation_stats; + time_stats_t pusch_channel_estimation_antenna_processing_stats; time_stats_t ulsch_llr_stats; time_stats_t rx_srs_stats; time_stats_t generate_srs_stats; @@ -553,6 +554,7 @@ typedef struct PHY_VARS_gNB_s { time_stats_t srs_beam_report_stats; time_stats_t srs_iq_matrix_stats; + notifiedFIFO_t respPuschAarx; notifiedFIFO_t respPuschSymb; notifiedFIFO_t respDecode; notifiedFIFO_t resp_L1; @@ -562,7 +564,10 @@ typedef struct PHY_VARS_gNB_s { notifiedFIFO_t L1_rx_out; notifiedFIFO_t resp_RU_tx; tpool_t threadPool; + int nbSymb; + int nbAarx; int num_pusch_symbols_per_thread; + int dmrs_num_antennas_per_thread; pthread_t L1_rx_thread; int L1_rx_thread_core; pthread_t L1_tx_thread; @@ -585,6 +590,35 @@ union puschSymbolReqUnion { uint64_t p; }; +typedef struct puschAntennaProc_s { + PHY_VARS_gNB *gNB; + unsigned char Ns; + int nl; + unsigned short p; + unsigned char symbol; + int ul_id; + unsigned short bwp_start_subcarrier; + int aarx; + int beam_nb; + int numAntennas; + nfapi_nr_pusch_pdu_t *pusch_pdu; + int *max_ch; + c16_t *pilot; + int *nest_count; + uint64_t *noise_amp2; + delay_t *delay; +} puschAntennaProc_t; + +struct puschAntennaReqId { + uint16_t ul_id; + uint16_t spare; +} __attribute__((packed)); + +union puschAntennaReqUnion { + struct puschAntennaReqId s; + uint64_t p; +}; + typedef struct LDPCDecode_s { PHY_VARS_gNB *gNB; NR_UL_gNB_HARQ_t *ulsch_harq; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 431e4875fc..84fdb18e3c 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -213,6 +213,7 @@ int main(int argc, char *argv[]) int params_from_file = 0; int threadCnt=0; int max_ldpc_iterations = 5; + int num_antennas_per_thread = 1; if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) { exit_fun("[NR_ULSIM] Error, configuration module init failed\n"); } @@ -224,7 +225,7 @@ int main(int argc, char *argv[]) InitSinLUT(); int c; - while ((c = getopt(argc, argv, "--:O:a:b:c:d:ef:g:h:i:k:m:n:op:q:r:s:t:u:v:w:y:z:C:F:G:H:I:M:N:PR:S:T:U:L:ZW:E:X:")) != -1) { + while ((c = getopt(argc, argv, "--:O:a:b:c:d:ef:g:h:i:k:m:n:op:q:r:s:t:u:v:w:y:z:A:C:F:G:H:I:M:N:PR:S:T:U:L:ZW:E:X:")) != -1) { /* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */ /* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */ @@ -395,6 +396,10 @@ int main(int argc, char *argv[]) } break; + case 'A': + num_antennas_per_thread = atoi(optarg); + break; + case 'F': input_fd = fopen(optarg, "r"); if (input_fd == NULL) { @@ -512,6 +517,7 @@ int main(int argc, char *argv[]) printf("-w Start PRB for PUSCH\n"); printf("-y Number of TX antennas used at UE\n"); printf("-z Number of RX antennas used at gNB\n"); + printf("-A Number of antennas per thread for PUSCH channel estimation\n"); printf("-C Specify the number of threads for the simulation\n"); printf("-E {SRS: [0] Disabled, [1] Enabled} e.g. -E 1\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); @@ -559,6 +565,7 @@ int main(int argc, char *argv[]) gNB = RC.gNB[0]; gNB->ofdm_offset_divisor = UINT_MAX; gNB->num_pusch_symbols_per_thread = 1; + gNB->dmrs_num_antennas_per_thread = num_antennas_per_thread; gNB->RU_list[0] = calloc(1, sizeof(**gNB->RU_list)); gNB->RU_list[0]->rfdevice.openair0_cfg = openair0_cfg; @@ -566,6 +573,7 @@ int main(int argc, char *argv[]) initNotifiedFIFO(&gNB->respDecode); initNotifiedFIFO(&gNB->respPuschSymb); + initNotifiedFIFO(&gNB->respPuschAarx); initNotifiedFIFO(&gNB->L1_tx_free); initNotifiedFIFO(&gNB->L1_tx_filled); initNotifiedFIFO(&gNB->L1_tx_out); @@ -952,6 +960,7 @@ int main(int argc, char *argv[]) reset_meas(&gNB->rx_pusch_symbol_processing_stats); reset_meas(&gNB->ulsch_decoding_stats); reset_meas(&gNB->ulsch_channel_estimation_stats); + reset_meas(&gNB->pusch_channel_estimation_antenna_processing_stats); reset_meas(&gNB->rx_srs_stats); reset_meas(&gNB->generate_srs_stats); reset_meas(&gNB->get_srs_signal_stats); @@ -1512,6 +1521,7 @@ int main(int argc, char *argv[]) printDistribution(&gNB->phy_proc_rx,table_rx, "Total PHY proc rx"); printStatIndent(&gNB->rx_pusch_stats, "RX PUSCH time"); printStatIndent2(&gNB->ulsch_channel_estimation_stats, "ULSCH channel estimation time"); + printStatIndent3(&gNB->pusch_channel_estimation_antenna_processing_stats, "Antenna Processing time"); printStatIndent2(&gNB->rx_pusch_init_stats, "RX PUSCH Initialization time"); printStatIndent2(&gNB->rx_pusch_symbol_processing_stats, "RX PUSCH Symbol Processing time"); printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time"); diff --git a/openair2/GNB_APP/L1_nr_paramdef.h b/openair2/GNB_APP/L1_nr_paramdef.h index b6d2e87d9c..e313818ad2 100644 --- a/openair2/GNB_APP/L1_nr_paramdef.h +++ b/openair2/GNB_APP/L1_nr_paramdef.h @@ -59,6 +59,8 @@ #define HLP_L1TX_BO "Backoff from full-scale output at the L1 entity(frequency domain), ex. 12 would corresponding to 14-bit input level (6 dB/bit). Default 36 dBFS for OAI RU entity" #define CONFIG_STRING_L1_PHASE_COMP "phase_compensation" #define HLP_L1_PHASE_COMP "Apply NR symbolwise phase rotation" +#define CONFIG_STRING_NUM_ANTENNAS_PER_THREAD "dmrs_num_antennas_per_thread" +#define HLP_NUM_ARX "Number of antennas per thread for PUSCH channel estimation" /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* L1 configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -84,6 +86,7 @@ {CONFIG_STRING_L1_TX_THREAD_CORE, NULL, 0, .uptr=NULL, .defintval=-1, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_TX_AMP_BACKOFF_dB, HLP_L1TX_BO,0, .uptr=NULL, .defintval=36, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_PHASE_COMP, HLP_L1_PHASE_COMP,PARAMFLAG_BOOL, .uptr=NULL,.defintval=1, TYPE_UINT, 0}, \ + {CONFIG_STRING_NUM_ANTENNAS_PER_THREAD, HLP_NUM_ARX,0, .uptr=NULL, .defintval=1, TYPE_UINT, 0}, \ } // clang-format on #define L1_CC_IDX 0 @@ -105,6 +108,7 @@ #define L1_TX_THREAD_CORE 16 #define L1_TX_AMP_BACKOFF_dB 17 #define L1_PHASE_COMP 18 +#define NUM_ANTENNAS_PER_THREAD 19 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #endif diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 44c402fb8a..184c2d7c5c 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -914,6 +914,7 @@ void RCconfig_NR_L1(void) LOG_I(NR_PHY, "L1_RX_THREAD_CORE %d (%d)\n", *(L1_ParamList.paramarray[j][L1_RX_THREAD_CORE].iptr), L1_RX_THREAD_CORE); gNB->TX_AMP = (int16_t)(32767.0 / pow(10.0, .05 * (double)(*L1_ParamList.paramarray[j][L1_TX_AMP_BACKOFF_dB].uptr))); gNB->phase_comp = *L1_ParamList.paramarray[j][L1_PHASE_COMP].uptr; + gNB->dmrs_num_antennas_per_thread = *(L1_ParamList.paramarray[j][NUM_ANTENNAS_PER_THREAD].uptr); LOG_I(NR_PHY, "TX_AMP = %d (-%d dBFS)\n", gNB->TX_AMP, *L1_ParamList.paramarray[j][L1_TX_AMP_BACKOFF_dB].uptr); AssertFatal(gNB->TX_AMP > 300, "TX_AMP is too small, must be larger than 300 (is %d)\n", gNB->TX_AMP); // Midhaul configuration From fe10c90250a57bad45d3919175efcd7d83278935 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Wed, 6 Nov 2024 12:55:02 +0100 Subject: [PATCH 3/4] Avoid passing gNB pointer to nr_pusch_antenna_processing --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 38 +++++++++---------- openair1/PHY/defs_gNB.h | 6 ++- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index f0cc9ca8e5..a1ff7edc12 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -66,13 +66,10 @@ __attribute__((always_inline)) inline c16_t c32x16cumulVectVectWithSteps(c16_t * static void nr_pusch_antenna_processing(void *arg) { puschAntennaProc_t *rdata = (puschAntennaProc_t *)arg; - - PHY_VARS_gNB *gNB = rdata->gNB; unsigned char Ns = rdata->Ns; int nl = rdata->nl; unsigned short p = rdata->p; unsigned char symbol = rdata->symbol; - int ul_id = rdata->ul_id; int aarx = rdata->aarx; int numAntennas = rdata->numAntennas; unsigned short bwp_start_subcarrier = rdata->bwp_start_subcarrier; @@ -83,11 +80,12 @@ static void nr_pusch_antenna_processing(void *arg) int nest_count = *(rdata->nest_count); delay_t *delay = rdata->delay; - const int chest_freq = gNB->chest_freq; - NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ul_id]; + const int chest_freq = rdata->chest_freq; + NR_gNB_PUSCH *pusch_vars = rdata->pusch_vars; c16_t **ul_ch_estimates = (c16_t **)pusch_vars->ul_ch_estimates; - const int symbolSize = gNB->frame_parms.ofdm_symbol_size; - const int slot_offset = (Ns & 3) * gNB->frame_parms.symbols_per_slot * symbolSize; + NR_DL_FRAME_PARMS *frame_parms = rdata->frame_parms; + const int symbolSize = frame_parms->ofdm_symbol_size; + const int slot_offset = (Ns & 3) * frame_parms->symbols_per_slot * symbolSize; const int delta = get_delta(p, pusch_pdu->dmrs_config_type); const int symbol_offset = symbolSize * symbol; const int k0 = bwp_start_subcarrier; @@ -96,8 +94,8 @@ static void nr_pusch_antenna_processing(void *arg) for (int antenna = aarx; antenna < aarx + numAntennas; antenna++) { c16_t ul_ls_est[symbolSize] __attribute__((aligned(32))); memset(ul_ls_est, 0, sizeof(c16_t) * symbolSize); - c16_t *rxdataF = (c16_t *)&gNB->common_vars.rxdataF[beam_nb][antenna][symbol_offset + slot_offset]; - c16_t *ul_ch = &ul_ch_estimates[nl * gNB->frame_parms.nb_antennas_rx + antenna][symbol_offset]; + c16_t *rxdataF = (c16_t *)&rdata->rxdataF[beam_nb][antenna][symbol_offset + slot_offset]; + c16_t *ul_ch = &ul_ch_estimates[nl * frame_parms->nb_antennas_rx + antenna][symbol_offset]; memset(ul_ch, 0, sizeof(*ul_ch) * symbolSize); LOG_D(PHY, @@ -111,12 +109,12 @@ static void nr_pusch_antenna_processing(void *arg) #ifdef DEBUG_PUSCH LOG_I(PHY, "symbol_offset %d, delta %d\n", symbol_offset, delta); - LOG_I(PHY, "ch est pilot, N_RB_UL %d\n", gNB->frame_parms.N_RB_UL); + LOG_I(PHY, "ch est pilot, N_RB_UL %d\n", frame_parms->N_RB_UL); LOG_I(PHY, "bwp_start_subcarrier %d, k0 %d, first_carrier %d, nb_rb_pusch %d\n", bwp_start_subcarrier, k0, - gNB->frame_parms.first_carrier_offset, + frame_parms->first_carrier_offset, nb_rb_pusch); LOG_I(PHY, "ul_ch addr %p \n", ul_ch); #endif @@ -145,9 +143,9 @@ static void nr_pusch_antenna_processing(void *arg) pilot_cnt += 2; } - nr_est_delay(gNB->frame_parms.ofdm_symbol_size, ul_ls_est, (c16_t *)pusch_vars->ul_ch_estimates_time[antenna], delay); + nr_est_delay(frame_parms->ofdm_symbol_size, ul_ls_est, (c16_t *)pusch_vars->ul_ch_estimates_time[antenna], delay); int delay_idx = get_delay_idx(delay->est_delay, MAX_DELAY_COMP); - c16_t *ul_delay_table = gNB->frame_parms.delay_table[delay_idx]; + c16_t *ul_delay_table = frame_parms->delay_table[delay_idx]; #ifdef DEBUG_PUSCH printf("Estimated delay = %i\n", delay->est_delay >> 1); @@ -193,9 +191,9 @@ static void nr_pusch_antenna_processing(void *arg) // Revert delay pilot_cnt = 0; - ul_ch = &ul_ch_estimates[nl * gNB->frame_parms.nb_antennas_rx + antenna][symbol_offset]; + ul_ch = &ul_ch_estimates[nl * frame_parms->nb_antennas_rx + antenna][symbol_offset]; int inv_delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP); - c16_t *ul_inv_delay_table = gNB->frame_parms.delay_table[inv_delay_idx]; + c16_t *ul_inv_delay_table = frame_parms->delay_table[inv_delay_idx]; for (int n = 0; n < 3 * nb_rb_pusch; n++) { for (int k_line = 0; k_line <= 1; k_line++) { int k = pilot_cnt << 1; @@ -233,9 +231,9 @@ static void nr_pusch_antenna_processing(void *arg) } // Delay compensation - nr_est_delay(gNB->frame_parms.ofdm_symbol_size, ul_ls_est, (c16_t *)pusch_vars->ul_ch_estimates_time[antenna], delay); + nr_est_delay(frame_parms->ofdm_symbol_size, ul_ls_est, (c16_t *)pusch_vars->ul_ch_estimates_time[antenna], delay); int delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP); - c16_t *ul_delay_table = gNB->frame_parms.delay_table[delay_idx]; + c16_t *ul_delay_table = frame_parms->delay_table[delay_idx]; for (int n = 0; n < nb_rb_pusch * NR_NB_SC_PER_RB; n++) { ul_ch[n] = c16mulShift(ul_ls_est[n], ul_delay_table[n % 6], 8); } @@ -513,14 +511,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, puschAntennaProc_t *rdata = (puschAntennaProc_t *)NotifiedFifoData(req); // data for the job // Local init in the current loop - rdata->gNB = gNB; rdata->Ns = Ns; rdata->nl = nl; rdata->p = p; rdata->symbol = symbol; rdata->aarx = aarx; rdata->numAntennas = numAntennas; - rdata->ul_id = ul_id; rdata->bwp_start_subcarrier = bwp_start_subcarrier; rdata->pusch_pdu = pusch_pdu; rdata->max_ch = &max_ch_arr[rdata->aarx]; @@ -529,6 +525,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, rdata->noise_amp2 = &noise_amp2_arr[rdata->aarx]; rdata->delay = &delay_arr[rdata->aarx]; rdata->beam_nb = beam_nb; + rdata->frame_parms = &gNB->frame_parms; + rdata->pusch_vars = &gNB->pusch_vars[ul_id]; + rdata->chest_freq = gNB->chest_freq; + rdata->rxdataF = gNB->common_vars.rxdataF; // Call the nr_pusch_antenna_processing function pushTpool(&gNB->threadPool, req); nbAarx++; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 7de4d24817..f4c21388cc 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -591,12 +591,10 @@ union puschSymbolReqUnion { }; typedef struct puschAntennaProc_s { - PHY_VARS_gNB *gNB; unsigned char Ns; int nl; unsigned short p; unsigned char symbol; - int ul_id; unsigned short bwp_start_subcarrier; int aarx; int beam_nb; @@ -607,6 +605,10 @@ typedef struct puschAntennaProc_s { int *nest_count; uint64_t *noise_amp2; delay_t *delay; + int chest_freq; + NR_gNB_PUSCH *pusch_vars; + NR_DL_FRAME_PARMS *frame_parms; + c16_t ***rxdataF; } puschAntennaProc_t; struct puschAntennaReqId { From ba0cad20e634f3b21258d7170955401ab8f8c3e8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 19 Nov 2024 09:52:51 +0100 Subject: [PATCH 4/4] Move respPuschAarx response queue to stack of nr_pusch_channel_estimation() The queue for finished jobs of PUSCH channel estimation is only used inside nr_pusch_channel_estimation(). Since initialization is fast, it can be declared on the stack in the function where it is used. --- executables/nr-gnb.c | 3 --- openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 6 ++++-- openair1/PHY/defs_gNB.h | 1 - openair1/SIMULATION/NR_PHY/ulsim.c | 1 - 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 22aa50b9c3..4206cfd585 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -354,9 +354,6 @@ void init_gNB_Tpool(int inst) { // ULSCH decoder result FIFO initNotifiedFIFO(&gNB->respPuschSymb); initNotifiedFIFO(&gNB->respDecode); - // PUSCH channel estimation result FIFO - initNotifiedFIFO(&gNB->respPuschAarx); - // L1 RX result FIFO initNotifiedFIFO(&gNB->resp_L1); diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index a1ff7edc12..acdd291343 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -499,6 +499,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, delay_arr[i] = *delay; } + notifiedFIFO_t respPuschAarx; + initNotifiedFIFO(&respPuschAarx); start_meas(&gNB->pusch_channel_estimation_antenna_processing_stats); int numAntennas = gNB->dmrs_num_antennas_per_thread; for (int aarx = 0; aarx < gNB->frame_parms.nb_antennas_rx; aarx += numAntennas) { @@ -506,7 +508,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, id.p = 1 + aarx; notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(puschAntennaProc_t), id.p, - &gNB->respPuschAarx, + &respPuschAarx, &nr_pusch_antenna_processing); // create a job for Tpool puschAntennaProc_t *rdata = (puschAntennaProc_t *)NotifiedFifoData(req); // data for the job @@ -537,7 +539,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } // Antenna Loop while (nbAarx > 0) { - notifiedFIFO_elt_t *req = pullTpool(&gNB->respPuschAarx, &gNB->threadPool); + notifiedFIFO_elt_t *req = pullTpool(&respPuschAarx, &gNB->threadPool); nbAarx--; delNotifiedFIFO_elt(req); } diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index f4c21388cc..14c71bdf17 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -554,7 +554,6 @@ typedef struct PHY_VARS_gNB_s { time_stats_t srs_beam_report_stats; time_stats_t srs_iq_matrix_stats; - notifiedFIFO_t respPuschAarx; notifiedFIFO_t respPuschSymb; notifiedFIFO_t respDecode; notifiedFIFO_t resp_L1; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 84fdb18e3c..b9fac5fe5e 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -573,7 +573,6 @@ int main(int argc, char *argv[]) initNotifiedFIFO(&gNB->respDecode); initNotifiedFIFO(&gNB->respPuschSymb); - initNotifiedFIFO(&gNB->respPuschAarx); initNotifiedFIFO(&gNB->L1_tx_free); initNotifiedFIFO(&gNB->L1_tx_filled); initNotifiedFIFO(&gNB->L1_tx_out);