diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 465679d002..ac473f19a2 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -198,8 +198,8 @@ int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, f = k; else { int c = k/R; - int r = k%R; - f = (r*C + c + n_shift)%(N_regs/L); + int r = k % R; + f = (r * C + c + n_shift) % (N_regs / L); } return f; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index c6156d63bc..a80389a200 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -77,13 +77,12 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, uint8_t cset_start_symb, cset_nsymb; int k,l,k_prime,dci_idx, dmrs_idx; - // find coreset descriptor - + // fill reg list per symbol + int reg_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE]; + nr_fill_reg_list(reg_list, pdcch_pdu_rel15); + // compute rb_offset and n_prb based on frequency allocation int rb_offset; int n_rb; - // compute rb_offset and n_prb based on frequency allocation - nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL]; - nr_fill_cce_list(cce_list, pdcch_pdu_rel15); get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB; @@ -177,80 +176,65 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, if (cset_start_sc >= frame_parms->ofdm_symbol_size) cset_start_sc -= frame_parms->ofdm_symbol_size; - // Get cce_list indices by reg_idx in ascending order - int reg_list_index = 0; - int N_regs = n_rb*pdcch_pdu_rel15->DurationSymbols; // nb of REGs per coreset - int N_cces = N_regs / NR_NB_REG_PER_CCE; // nb of cces in coreset - int reg_list_order[NR_MAX_PDCCH_AGG_LEVEL] = {}; - for (int p = 0; p < N_cces; p++) { - for(int p2 = 0; p2 < dci_pdu->AggregationLevel; p2++) { - if(cce_list[d][p2].reg_list[0].reg_idx == p * NR_NB_REG_PER_CCE) { - reg_list_order[reg_list_index] = p2; - reg_list_index++; - break; - } - } - } - + int num_regs = dci_pdu->AggregationLevel * NR_NB_REG_PER_CCE / pdcch_pdu_rel15->DurationSymbols; /*Mapping the encoded DCI along with the DMRS */ for(int symbol_idx = 0; symbol_idx < pdcch_pdu_rel15->DurationSymbols; symbol_idx++) { - for (int cce_count = 0; cce_count < dci_pdu->AggregationLevel; cce_count++) { + // allocating rbs per symbol + for (int reg_count = 0; reg_count < num_regs; reg_count++) { + k = cset_start_sc + reg_list[d][reg_count] * NR_NB_SC_PER_RB; + LOG_D(PHY, "REG %d k %d\n", reg_list[d][reg_count], k); + if (k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; - int8_t cce_idx = reg_list_order[cce_count]; + l = cset_start_symb + symbol_idx; - for (int reg_in_cce_idx = symbol_idx; reg_in_cce_idx < NR_NB_REG_PER_CCE; reg_in_cce_idx+=pdcch_pdu_rel15->DurationSymbols) { + // dmrs index depends on reference point for k according to 38.211 7.4.1.3.2 + if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) + dmrs_idx = (reg_list[d][reg_count] + pdcch_pdu_rel15->BWPStart) * 3; + else + dmrs_idx = (reg_list[d][reg_count] + rb_offset) * 3; - k = cset_start_sc + cce_list[d][cce_idx].reg_list[reg_in_cce_idx].start_sc_idx; - LOG_D(PHY,"CCE %d REG %d k %d\n",cce_idx,reg_in_cce_idx,k); - if (k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; + k_prime = 0; - l = cset_start_symb + symbol_idx; - - // dmrs index depends on reference point for k according to 38.211 7.4.1.3.2 - int eff_reg_idx = cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx/pdcch_pdu_rel15->DurationSymbols; - if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) - dmrs_idx = (eff_reg_idx + pdcch_pdu_rel15->BWPStart) * 3; - else - dmrs_idx = (eff_reg_idx + rb_offset) * 3; - - k_prime = 0; - - for (int m = 0; m < NR_NB_SC_PER_RB; m++) { - if (m == (k_prime << 2) + 1) { // DMRS if not already mapped - ((int16_t *) txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] = - (amp * mod_dmrs[l][dmrs_idx << 1]) >> 15; - ((int16_t *) txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] = - (amp * mod_dmrs[l][(dmrs_idx << 1) + 1]) >> 15; + for (int m = 0; m < NR_NB_SC_PER_RB; m++) { + if (m == (k_prime << 2) + 1) { // DMRS if not already mapped + ((int16_t *)txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] = (amp * mod_dmrs[l][dmrs_idx << 1]) >> 15; + ((int16_t *)txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] = (amp * mod_dmrs[l][(dmrs_idx << 1) + 1]) >> 15; #ifdef DEBUG_PDCCH_DMRS - LOG_D(PHY,"PDCCH DMRS %d: l %d position %d => (%d,%d)\n",dmrs_idx,l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1], - ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]); + LOG_I(PHY, + "PDCCH DMRS %d: l %d position %d => (%d,%d)\n", + dmrs_idx, + l, + k, + ((int16_t *)txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1], + ((int16_t *)txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1]); #endif - dmrs_idx++; - k_prime++; + dmrs_idx++; + k_prime++; - } else { // DCI payload - ((int16_t *) txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] = (amp * mod_dci[dci_idx << 1]) >> 15; - ((int16_t *) txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] = - (amp * mod_dci[(dci_idx << 1) + 1]) >> 15; + } else { // DCI payload + ((int16_t *)txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] = (amp * mod_dci[dci_idx << 1]) >> 15; + ((int16_t *)txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] = (amp * mod_dci[(dci_idx << 1) + 1]) >> 15; #ifdef DEBUG_DCI - LOG_D(PHY,"PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1], - ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]); + LOG_I(PHY, + "PDCCH: l %d position %d => (%d,%d)\n", + l, + k, + ((int16_t *)txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1], + ((int16_t *)txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1]); #endif - dci_idx++; - } + dci_idx++; + } - k++; + k++; - if (k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; - - } // m - } // reg_in_cce_idx - } // cce_count + if (k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; + } // m + } // reg_count } // symbol_idx LOG_D(PHY, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index 0bf6932bb5..c36d672d18 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -55,6 +55,6 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB, int slot, nfapi_nr_ul_dci_request_pdus_t *pdcch_pdu); -void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL], nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15); +void nr_fill_reg_list(int cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE], nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15); #endif //__PHY_NR_TRANSPORT_DCI__H diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c index 3d166fd87d..2558861e78 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c @@ -37,12 +37,13 @@ #include "nr_dlsch.h" +int compfunc(const void *a, const void *b) +{ + return (*(int *)a - *(int *)b); +} -void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL], nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15) { - - nr_cce_t* cce; - nr_reg_t* reg; - +void nr_fill_reg_list(int reg_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE], nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15) +{ int bsize = pdcch_pdu_rel15->RegBundleSize; int R = pdcch_pdu_rel15->InterleaverSize; int n_shift = pdcch_pdu_rel15->ShiftIndex; @@ -74,25 +75,25 @@ void nr_fill_cce_list(nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL] if (pdcch_pdu_rel15->dci_pdu[d].RNTI != 0xFFFF) LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", d, bsize, R, pdcch_pdu_rel15->dci_pdu[d].CceIndex); + int list_idx = 0; for (uint8_t cce_idx=0; cce_idxcce_idx = pdcch_pdu_rel15->dci_pdu[d].CceIndex + cce_idx; - LOG_D(PHY, "cce_idx %d\n", cce->cce_idx); - - uint8_t j = cce->cce_idx; + int cce = pdcch_pdu_rel15->dci_pdu[d].CceIndex + cce_idx; + LOG_D(PHY, "cce_idx %d\n", cce); for (uint8_t bundle_idx=0; bundle_idxreg_list[bundle_idx*bsize+reg_idx]; - reg->reg_idx = bsize*f + reg_idx; - reg->start_sc_idx = (reg->reg_idx/dur) * NR_NB_SC_PER_RB; - reg->symb_idx = reg->reg_idx%dur; - LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx); - } + LOG_D(PHY, "Bundle index %d: f(%d) = %d\n", bundle_idx, k, f); + // reg_list contains the regs to be allocated per symbol + // the same rbs are allocated in each symbol + for (uint8_t reg_idx = 0; reg_idx < bsize / dur; reg_idx++) { + reg_list[d][list_idx] = f * bsize / dur + reg_idx; + LOG_D(PHY, "rb %d nb of symbols per rb %d start subcarrier %d\n", reg_list[d][list_idx], dur, reg_list[d][list_idx] * NR_NB_SC_PER_RB); + list_idx++; + } } } + // sorting the elements of the list (smaller goes first) + qsort(reg_list[d], L * NR_NB_REG_PER_CCE / dur, sizeof(int), compfunc); } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 68a0ec56d8..5d88b420bf 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -148,7 +148,8 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t *llr, // for each bundle for (int nb = 0; nb < max_bundles; nb++) { - if (coreset_interleaved == 0) f_bundle_j = nb; + if (coreset_interleaved == 0) + f_bundle_j = nb; else { if (r == coreset_interleaver_size_R) { r = 0; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index c8a063fe19..ee63fe0103 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -197,17 +197,6 @@ typedef struct NR_BWP_PARMS { nr_prg_parms_t prg_parms; } NR_BWP_PARMS; -typedef struct { - uint8_t reg_idx; - uint16_t start_sc_idx; - uint8_t symb_idx; -} nr_reg_t; - -typedef struct { - uint8_t cce_idx; - nr_reg_t reg_list[NR_NB_REG_PER_CCE]; -} nr_cce_t; - typedef struct { /// PRACH format retrieved from prach_ConfigIndex uint16_t prach_format;