diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 8f1bb827be..e7478ffac8 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -26,6 +26,7 @@ static void nr_pdsch_codeword_scrambling(uint8_t *in, uint32_t size, uint8_t q, } static int do_ptrs_symbol(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15, + const freq_alloc_bitmap_t *freq_alloc, int start_sc, int symbol_sz, c16_t *txF, @@ -36,19 +37,27 @@ static int do_ptrs_symbol(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15, int ptrs_idx = 0; int k = start_sc; c16_t *in = tx_layer; - for (int i = 0; i < rel15->rbSize * NR_NB_SC_PER_RB; i++) { - /* check for PTRS symbol and set flag for PTRS RE */ - bool is_ptrs_re = - is_ptrs_subcarrier(k, rel15->rnti, rel15->PTRSFreqDensity, rel15->rbSize, rel15->PTRSReOffset, start_sc, symbol_sz); - if (is_ptrs_re) { - /* check if cuurent RE is PTRS RE*/ - uint16_t beta_ptrs = 1; - txF[k] = c16mulRealShift(mod_ptrs[ptrs_idx], beta_ptrs * amp, 15); - ptrs_idx++; + int last_rb = freq_alloc->end[freq_alloc->num_blocks - 1]; + int first_rb = freq_alloc->start[0]; + for (int j = first_rb; j <= last_rb; j++) { + if (check_rb_in_bitmap(freq_alloc, j)) { + for (int i = 0; i < NR_NB_SC_PER_RB; i++) { + /* check for PTRS symbol and set flag for PTRS RE */ + bool is_ptrs_re = + is_ptrs_subcarrier(k, rel15->rnti, rel15->PTRSFreqDensity, freq_alloc->num_rbs, rel15->PTRSReOffset, start_sc, symbol_sz); + if (is_ptrs_re) { + /* check if cuurent RE is PTRS RE*/ + uint16_t beta_ptrs = 1; + txF[k] = c16mulRealShift(mod_ptrs[ptrs_idx], beta_ptrs * amp, 15); + ptrs_idx++; + } else { + txF[k] = c16mulRealShift(*in++, amp, 15); + } + k++; + } } else { - txF[k] = c16mulRealShift(*in++, amp, 15); + k += NR_NB_SC_PER_RB; } - k++; } return in - tx_layer; } @@ -210,9 +219,9 @@ static inline int interleave_signals(c16_t *output, c16_t *signal1, const int am static inline int dmrs_case00(c16_t *output, c16_t *txl, c16_t *mod_dmrs, + const freq_alloc_bitmap_t *freq_alloc, const int16_t amp_dmrs, const int amp, - int sz, int start_sc, int dmrs_port, const int dmrs_Type, @@ -230,21 +239,24 @@ static inline int dmrs_case00(c16_t *output, c16_t *in = txl; uint8_t k_prime = 0; uint16_t n = 0; + int rb_span = freq_alloc->end[freq_alloc->num_blocks - 1] - freq_alloc->start[0] + 1; + int sz = rb_span * NR_NB_SC_PER_RB; for (int i = 0; i < sz; i++) { - if (k == ((start_sc + get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type)) % (symbol_sz))) { - output[k] = c16mulRealShift(mod_dmrs[dmrs_idx], Wt[l_prime] * Wf[k_prime] * amp_dmrs, 15); - dmrs_idx++; - k_prime = (k_prime + 1) & 1; - n += (k_prime ? 0 : 1); - } - /* Map PTRS Symbol */ - /* Map DATA Symbol */ - else if (allowed_xlsch_re_in_dmrs_symbol(k, start_sc, symbol_sz, numDmrsCdmGrpsNoData, dmrs_Type)) { - output[k] = c16mulRealShift(*in++, amp, 15); - } - /* mute RE */ - else { - output[k] = (c16_t){0}; + int rb = freq_alloc->start[0] + (i / NR_NB_SC_PER_RB); + if (check_rb_in_bitmap(freq_alloc, rb)) { + if (k == ((start_sc + get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type)) % (symbol_sz))) { + output[k] = c16mulRealShift(mod_dmrs[dmrs_idx], Wt[l_prime] * Wf[k_prime] * amp_dmrs, 15); + dmrs_idx++; + k_prime = (k_prime + 1) & 1; + n += (k_prime ? 0 : 1); + } else if (allowed_xlsch_re_in_dmrs_symbol(k, start_sc, symbol_sz, numDmrsCdmGrpsNoData, dmrs_Type)) { + /* Map PTRS Symbol */ + /* Map DATA Symbol */ + output[k] = c16mulRealShift(*in++, amp, 15); + } else { + /* mute RE */ + output[k] = (c16_t){0}; + } } k++; } // RE loop @@ -288,13 +300,18 @@ static inline void neg_dmrs(c16_t *in, c16_t *out, int sz) *out++ = i % 2 ? (c16_t){-in[i].r, -in[i].i} : in[i]; } +static uint32_t get_block_start_sc(int block_start, int bwp_start, int symbol_sz) +{ + return (block_start + bwp_start) * NR_NB_SC_PER_RB; +} + static inline void do_onelayer(NR_DL_FRAME_PARMS *frame_parms, int slot, const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15, + const freq_alloc_bitmap_t *freq_alloc, int layer, c16_t *output, c16_t *txl_start, - int start_sc, int symbol_sz, int l_symbol, uint16_t dlPtrsSymPos, @@ -306,7 +323,7 @@ static inline void do_onelayer(NR_DL_FRAME_PARMS *frame_parms, c16_t *dmrs_start) { c16_t *txl = txl_start; - const uint sz = rel15->rbSize * NR_NB_SC_PER_RB; + uint32_t start_sc = get_block_start_sc(freq_alloc->start[0], rel15->BWPStart, symbol_sz); /* calculate if current symbol is PTRS symbols */ int ptrs_symbol = 0; @@ -322,59 +339,65 @@ static inline void do_onelayer(NR_DL_FRAME_PARMS *frame_parms, const uint32_t *gold = nr_gold_pdsch(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, rel15->dlDmrsScramblingId, rel15->SCID, slot, l_symbol); nr_modulation(gold, n_ptrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_ptrs); - txl += do_ptrs_symbol(rel15, start_sc, symbol_sz, output, txl, amp, mod_ptrs); + txl += do_ptrs_symbol(rel15, freq_alloc, start_sc, symbol_sz, output, txl, amp, mod_ptrs); } else if (rel15->dlDmrsSymbPos & (1 << l_symbol)) { /* Map DMRS Symbol */ int dmrs_port = get_dmrs_port(layer, rel15->dmrsPorts); if (l_prime == 0 && dmrs_Type == NFAPI_NR_DMRS_TYPE1) { - if (rel15->numDmrsCdmGrpsNoData == 2) { - switch (dmrs_port & 3) { - case 0: - txl += interleave_with_0_signal_first(output + start_sc, dmrs_start, amp_dmrs, sz); - break; - case 1: { - c16_t dmrs[sz / 2]; - neg_dmrs(dmrs_start, dmrs, sz / 2); - txl += interleave_with_0_signal_first(output + start_sc, dmrs, amp_dmrs, sz); - } break; - case 2: - txl += interleave_with_0_start_with_0(output + start_sc, dmrs_start, amp_dmrs, sz); - break; - case 3: { - c16_t dmrs[sz / 2]; - neg_dmrs(dmrs_start, dmrs, sz / 2); - txl += interleave_with_0_start_with_0(output + start_sc, dmrs, amp_dmrs, sz); - } break; - } - } else if (rel15->numDmrsCdmGrpsNoData == 1) { - switch (dmrs_port & 3) { - case 0: - txl += interleave_signals(output + start_sc, txl, amp, dmrs_start, amp_dmrs, sz); - break; - case 1: { - c16_t dmrs[sz / 2]; - neg_dmrs(dmrs_start, dmrs, sz / 2); - txl += interleave_signals(output + start_sc, txl, amp, dmrs, amp_dmrs, sz); - } break; - case 2: - txl += interleave_signals(output + start_sc, dmrs_start, amp_dmrs, txl, amp, sz); - break; - case 3: { - c16_t dmrs[sz / 2]; - neg_dmrs(dmrs_start, dmrs, sz / 2); - txl += interleave_signals(output + start_sc, dmrs, amp_dmrs, txl, amp, sz); - } break; - } - } else - AssertFatal(false, "rel15->numDmrsCdmGrpsNoData is %d\n", rel15->numDmrsCdmGrpsNoData); + for (int i = 0; i < freq_alloc->num_blocks; i++) { + if (i != 0) + start_sc = get_block_start_sc(freq_alloc->start[i], rel15->BWPStart, symbol_sz); + const int rb_span = freq_alloc->end[i] - freq_alloc->start[i] + 1; + const int sz = rb_span * NR_NB_SC_PER_RB; + if (rel15->numDmrsCdmGrpsNoData == 2) { + switch (dmrs_port & 3) { + case 0: + txl += interleave_with_0_signal_first(output + start_sc, dmrs_start, amp_dmrs, sz); + break; + case 1: { + c16_t dmrs[sz / 2]; + neg_dmrs(dmrs_start, dmrs, sz / 2); + txl += interleave_with_0_signal_first(output + start_sc, dmrs, amp_dmrs, sz); + } break; + case 2: + txl += interleave_with_0_start_with_0(output + start_sc, dmrs_start, amp_dmrs, sz); + break; + case 3: { + c16_t dmrs[sz / 2]; + neg_dmrs(dmrs_start, dmrs, sz / 2); + txl += interleave_with_0_start_with_0(output + start_sc, dmrs, amp_dmrs, sz); + } break; + } + } else if (rel15->numDmrsCdmGrpsNoData == 1) { + switch (dmrs_port & 3) { + case 0: + txl += interleave_signals(output + start_sc, txl, amp, dmrs_start, amp_dmrs, sz); + break; + case 1: { + c16_t dmrs[sz / 2]; + neg_dmrs(dmrs_start, dmrs, sz / 2); + txl += interleave_signals(output + start_sc, txl, amp, dmrs, amp_dmrs, sz); + } break; + case 2: + txl += interleave_signals(output + start_sc, dmrs_start, amp_dmrs, txl, amp, sz); + break; + case 3: { + c16_t dmrs[sz / 2]; + neg_dmrs(dmrs_start, dmrs, sz / 2); + txl += interleave_signals(output + start_sc, dmrs, amp_dmrs, txl, amp, sz); + } break; + } + } else + AssertFatal(false, "rel15->numDmrsCdmGrpsNoData is %d\n", rel15->numDmrsCdmGrpsNoData); + } } else { txl += dmrs_case00(output, txl, dmrs_start, + freq_alloc, amp_dmrs, amp, - sz, start_sc, dmrs_port, dmrs_Type, @@ -383,7 +406,13 @@ static inline void do_onelayer(NR_DL_FRAME_PARMS *frame_parms, rel15->numDmrsCdmGrpsNoData); } // generic DMRS case } else { // no PTRS or DMRS in this symbol - txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, sz); + for (int i = 0; i < freq_alloc->num_blocks; i++) { + if (i != 0) + start_sc = get_block_start_sc(freq_alloc->start[i], rel15->BWPStart, symbol_sz); + const int rb_span = freq_alloc->end[i] - freq_alloc->start[i] + 1; + const int sz = rb_span * NR_NB_SC_PER_RB; + txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, sz); + } } // no DMRS/PTRS in symbol return; } @@ -394,24 +423,25 @@ static inline void do_txdataF(c16_t **txdataF, PHY_VARS_gNB *gNB, const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15, int ant, - int start_sc, + int rb_start, + int rb_size, int txdataF_offset_per_symbol) { NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; int rb = 0; - uint16_t subCarrier = start_sc; + uint16_t subCarrier = get_block_start_sc(rb_start, rel15->BWPStart, symbol_sz); const nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming; - while (rb < rel15->rbSize) { + while (rb < rb_size) { // get pmi info const int pmi = (pb->prg_size > 0) ? (pb->prgs_list[(int)rb / pb->prg_size].pm_idx) : 0; - const int pmi2 = (rb < (rel15->rbSize - 1) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 1) / pb->prg_size].pm_idx) : -1; - const int pmi3 = (rb < (rel15->rbSize - 2) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 2) / pb->prg_size].pm_idx) : -1; - const int pmi4 = (rb < (rel15->rbSize - 3) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 3) / pb->prg_size].pm_idx) : -1; + const int pmi2 = (rb < (rb_size - 1) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 1) / pb->prg_size].pm_idx) : -1; + const int pmi3 = (rb < (rb_size - 2) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 2) / pb->prg_size].pm_idx) : -1; + const int pmi4 = (rb < (rb_size - 3) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 3) / pb->prg_size].pm_idx) : -1; // If pmi of next RB and pmi of current RB are the same, we do 2 RB in a row - // if pmi differs, or current rb is the end (rel15->rbSize - 1), than we do 1 RB in a row + // if pmi differs, or current rb is the end (rb_size - 1), than we do 1 RB in a row int rb_step0 = pmi == pmi2 ? 2 : 1; - const int rb_step = rb_step0==2 && pmi3==pmi && pmi4==pmi ? 4 : rb_step0; + const int rb_step = rb_step0 == 2 && pmi3 == pmi && pmi4 == pmi ? 4 : rb_step0; const int re_cnt = NR_NB_SC_PER_RB * rb_step; if (pmi == 0) { // unitary Precoding if (ant < rel15->nrOfLayers) @@ -446,13 +476,14 @@ static inline void do_txdataF(c16_t **txdataF, } // else { // non-unitary Precoding rb += rb_step; - } // RB loop: while(rb < rel15->rbSize) + } // RB loop: while(rb < rb_size) } typedef struct pdschSymbolProc_s { PHY_VARS_gNB *gNB; NR_DL_FRAME_PARMS *frame_parms; const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15; + freq_alloc_bitmap_t *freq_alloc; unsigned int slot; unsigned int startSymbol; unsigned int numSymbols; @@ -478,14 +509,14 @@ static void nr_pdsch_symbol_processing(void *arg) c16_t *tx_layers[rel15->nrOfLayers]; for (int l = 0; l < rel15->nrOfLayers; l++) tx_layers[l] = rdata->tx_layers[l]; + freq_alloc_bitmap_t *freq_alloc = rdata->freq_alloc; const int nb_re_dmrs = rel15->numDmrsCdmGrpsNoData * (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4); - const int n_dmrs = (rel15->BWPStart + rel15->rbStart + rel15->rbSize) * nb_re_dmrs; + const int n_dmrs = (rel15->BWPStart + freq_alloc->end[freq_alloc->num_blocks - 1] + 1) * nb_re_dmrs; // Loop Over OFDM symbols: c16_t mod_dmrs[(n_dmrs + 63) & ~63] __attribute__((aligned(64))); const int symbol_sz = frame_parms->ofdm_symbol_size; c16_t **txdataF = gNB->common_vars.txdataF[rdata->beam_nb]; - uint16_t start_sc = (rel15->rbStart + rel15->BWPStart) * NR_NB_SC_PER_RB; for (int l_symbol = rdata->startSymbol; l_symbol < rdata->startSymbol + rdata->numSymbols; l_symbol++) { start_meas(&rdata->dlsch_resource_mapping_stats); @@ -513,7 +544,7 @@ static void nr_pdsch_symbol_processing(void *arg) nr_modulation(gold, n_dmrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_dmrs); } - uint32_t dmrs_idx = rel15->rbStart; + uint32_t dmrs_idx = freq_alloc->start[0]; if (rel15->refPoint == 0) dmrs_idx += rel15->BWPStart; dmrs_idx *= rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4; @@ -522,10 +553,10 @@ static void nr_pdsch_symbol_processing(void *arg) do_onelayer(frame_parms, slot, rel15, + freq_alloc, layer, txdataF_precoding[layer], tx_layers[layer] + rdata->re_beginning_of_symbol[l_symbol], - start_sc, symbol_sz, l_symbol, rdata->dlPtrsSymPos, @@ -539,9 +570,20 @@ static void nr_pdsch_symbol_processing(void *arg) stop_meas(&rdata->dlsch_resource_mapping_stats); start_meas(&rdata->dlsch_precoding_stats); + const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz; for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) { - const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz; - do_txdataF(txdataF, symbol_sz, txdataF_precoding, gNB, rel15, ant, start_sc, txdataF_offset_per_symbol); + for (int b = 0; b < freq_alloc->num_blocks; b++) { + int nb_rb_block = freq_alloc->end[b] - freq_alloc->start[b] + 1; + do_txdataF(txdataF, + symbol_sz, + txdataF_precoding, + gNB, + rel15, + ant, + freq_alloc->start[b], + nb_rb_block, + txdataF_offset_per_symbol); + } } stop_meas(&rdata->dlsch_precoding_stats); } @@ -555,20 +597,15 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC time_stats_t *dlsch_scrambling_stats = &gNB->dlsch_scrambling_stats; time_stats_t *dlsch_modulation_stats = &gNB->dlsch_modulation_stats; + freq_alloc_bitmap_t *freq_alloc = &dlsch->freq_alloc; const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15; const int layerSz = frame_parms->N_RB_DL * frame_parms->symbols_per_slot * NR_NB_SC_PER_RB; const int nb_re_dmrs = rel15->numDmrsCdmGrpsNoData * (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4); - LOG_D(PHY, - "pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbsize %d\n", - rel15->BWPStart, - rel15->BWPSize, - rel15->rbStart, - rel15->rbSize); - const int n_dmrs = rel15->rbSize * nb_re_dmrs; + const int n_dmrs = freq_alloc->num_rbs * nb_re_dmrs; const int xOverhead = 0; const int nb_re = - (12 * rel15->NrOfSymbols - nb_re_dmrs * get_num_dmrs(rel15->dlDmrsSymbPos) - xOverhead) * rel15->rbSize * rel15->nrOfLayers; + (12 * rel15->NrOfSymbols - nb_re_dmrs * get_num_dmrs(rel15->dlDmrsSymbPos) - xOverhead) * freq_alloc->num_rbs * rel15->nrOfLayers; const int Qm = rel15->qamModOrder[0]; const int encoded_length = nb_re * Qm; @@ -581,7 +618,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC rel15->StartSymbolIndex, 1 << rel15->PTRSTimeDensity, rel15->dlDmrsSymbPos); - n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity; + n_ptrs = (freq_alloc->num_rbs + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity; } #ifdef DEBUG_DLSCH @@ -692,6 +729,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC rdata->gNB = gNB; rdata->frame_parms = frame_parms; + rdata->freq_alloc = freq_alloc; rdata->rel15 = rel15; rdata->slot = slot; rdata->startSymbol = l_symbol; @@ -706,7 +744,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC rdata->beam_nb = beam_nb; for (int s = l_symbol; s < l_symbol + rdata->numSymbols; s++) { rdata->re_beginning_of_symbol[s] = re_beginning_of_symbol; - re_beginning_of_symbol += rel15->rbSize * NR_NB_SC_PER_RB; + re_beginning_of_symbol += freq_alloc->num_rbs * NR_NB_SC_PER_RB; if (n_ptrs > 0 && is_ptrs_symbol(s, dlPtrsSymPos)) { re_beginning_of_symbol -= n_ptrs; } else if (rel15->dlDmrsSymbPos & (1 << s)) { @@ -733,7 +771,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC /* output and its parts for each dlsch should be aligned on 64 bytes (or 8 * 64 bits) * should remain a multiple of 8 * 64 with enough offset to fit each dlsch */ - uint32_t size_output_tb = rel15->rbSize * frame_parms->symbols_per_slot * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers; + uint32_t size_output_tb = freq_alloc->num_rbs * frame_parms->symbols_per_slot * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers; return ((size_output_tb + 511) >> 9) << 6; } @@ -754,12 +792,19 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr NR_gNB_DLSCH_t *dlsch = &dlsch_array[i]; const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15; + if (rel15->resourceAlloc == 0) { + int alloc_size = (rel15->BWPSize / 8) + (rel15->BWPSize % 8 > 0); + dlsch->freq_alloc = set_start_end_from_bitmap(rel15->BWPSize, alloc_size, rel15->rbBitmap); + } else { + dlsch->freq_alloc = set_bitmap_from_start_size(rel15->rbStart, rel15->rbSize); + } LOG_D(PHY, - "pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbsize %d\n", + "pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbEnd %d rbsize %d\n", rel15->BWPStart, rel15->BWPSize, - rel15->rbStart, - rel15->rbSize); + dlsch->freq_alloc.start[0], + dlsch->freq_alloc.end[dlsch->freq_alloc.num_blocks - 1], + dlsch->freq_alloc.num_rbs); const int Qm = rel15->qamModOrder[0]; @@ -773,7 +818,7 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr rel15->StartSymbolIndex, 1 << rel15->PTRSTimeDensity, rel15->dlDmrsSymbPos); - n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity; + n_ptrs = (dlsch->freq_alloc.num_rbs + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity; ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, rel15->StartSymbolIndex, rel15->NrOfSymbols); } dlsch->unav_res = ptrsSymbPerSlot * n_ptrs; @@ -784,7 +829,7 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr /* output and its parts for each dlsch should be aligned on 64 bytes (or 8 * 64 bits) * => size_output is a sum of parts sizes rounded up to a multiple of 8 * 64 */ - size_t size_output_tb = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers; + size_t size_output_tb = dlsch->freq_alloc.num_rbs * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers; size_output += ceil_mod(size_output_tb, 8 * 64); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index bf63e1cbce..bfe912dac8 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -209,7 +209,8 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, } #endif - TB_parameters->nb_rb = rel15->rbSize; + int rbsize = dlsch->freq_alloc.num_rbs; + TB_parameters->nb_rb = rbsize; TB_parameters->Qm = rel15->qamModOrder[0]; TB_parameters->mcs = rel15->mcsIndex[0]; TB_parameters->nb_layers = rel15->nrOfLayers; @@ -217,7 +218,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, int nb_re_dmrs = (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) ? (6 * rel15->numDmrsCdmGrpsNoData) : (4 * rel15->numDmrsCdmGrpsNoData); - TB_parameters->G = nr_get_G(rel15->rbSize, + TB_parameters->G = nr_get_G(rbsize, rel15->NrOfSymbols, nb_re_dmrs, get_num_dmrs(rel15->dlDmrsSymbPos), @@ -226,7 +227,6 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, rel15->nrOfLayers); TB_parameters->tbslbrm = rel15->maintenance_parms_v3.tbSizeLbrmBytes; - TB_parameters->output = &output[dlsch_offset >> 3]; TB_parameters->segments = &segments[segments_offset]; @@ -245,7 +245,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, /* output and its parts for each dlsch should be aligned on 64 bytes (or 8 * 64 bits) * => dlsch_offset should remain a multiple of 8 * 64 with enough offset to fit each dlsch */ - const size_t dlsch_size = rel15->rbSize * gNB->frame_parms.symbols_per_slot * NR_NB_SC_PER_RB * rel15->qamModOrder[0] * rel15->nrOfLayers; + const size_t dlsch_size = rbsize * gNB->frame_parms.symbols_per_slot * NR_NB_SC_PER_RB * rel15->qamModOrder[0] * rel15->nrOfLayers; dlsch_offset += ceil_mod(dlsch_size, 8 * 64); } diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 6c5b049634..cf83dbe85d 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -5,7 +5,7 @@ #ifndef __NR_ESTIMATION_DEFS__H__ #define __NR_ESTIMATION_DEFS__H__ - +#include "PHY/nr_phy_common/inc/nr_phy_common.h" #include "PHY/defs_nr_UE.h" /** @addtogroup _PHY_PARAMETER_ESTIMATION_BLOCKS_ 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 7de87cc2ee..1aea2146db 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -11,6 +11,7 @@ #include "SCHED_NR_UE/defs.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include +#include "PHY/nr_phy_common/inc/nr_phy_common.h" #define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1 #define NR_PUSCH_y 3 // UCI placeholder bit diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index c57d0c74ce..f269b2694d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -12,15 +12,6 @@ #include "nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h" #include "../NR_TRANSPORT/nr_transport_common_proto.h" -#define MAX_FA_BLOCKS 10 -typedef struct { - int start[MAX_FA_BLOCKS]; - int end[MAX_FA_BLOCKS]; - int num_rbs; - int num_blocks; - uint8_t bitmap[36]; -} freq_alloc_bitmap_t; - typedef struct { /// Index of current HARQ round for this ULSCH uint8_t round; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 3e627c38cd..1ca19deda0 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -11,6 +11,7 @@ #include "common/platform_constants.h" #include "defs_nr_common.h" +#include "PHY/nr_phy_common/inc/nr_phy_common.h" #include "CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" #include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h" @@ -101,6 +102,8 @@ typedef struct { typedef struct { /// Nfapi DLSCH PDU const nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu; + /// freq allocation information + freq_alloc_bitmap_t freq_alloc; /// pointer to pdu from MAC interface (this is "a" in 36.212) uint8_t *pdu; /// Pointer to the payload diff --git a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h index 9f2ac727fb..cc0f43ccf0 100644 --- a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h +++ b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h @@ -377,4 +377,15 @@ int nr_get_ssb_start_sc(int scs, int ssb_sco, frequency_range_t freq_range); +#define MAX_FA_BLOCKS 10 +typedef struct { + int start[MAX_FA_BLOCKS]; + int end[MAX_FA_BLOCKS]; + int num_rbs; + int num_blocks; + uint8_t bitmap[36]; +} freq_alloc_bitmap_t; +bool check_rb_in_bitmap(const freq_alloc_bitmap_t *alloc, int rb); +freq_alloc_bitmap_t set_start_end_from_bitmap(int size, int alloc_size, const uint8_t bitmap[alloc_size]); +freq_alloc_bitmap_t set_bitmap_from_start_size(int start, int size); #endif diff --git a/openair1/PHY/nr_phy_common/src/nr_phy_common.c b/openair1/PHY/nr_phy_common/src/nr_phy_common.c index f7e6592b0e..3fb1d53bdf 100644 --- a/openair1/PHY/nr_phy_common/src/nr_phy_common.c +++ b/openair1/PHY/nr_phy_common/src/nr_phy_common.c @@ -428,6 +428,56 @@ void nr_scale_channel(int size, int ch_estimates_ext[][size], int symb, uint32_t } } +freq_alloc_bitmap_t set_start_end_from_bitmap(int size, int alloc_size, const uint8_t bitmap[alloc_size]) +{ + freq_alloc_bitmap_t alloc = { + .num_rbs = 0, + .num_blocks = 0 + }; + + bool pos_bit = false; + for (int i = 0; i < size; i++) { + if ((bitmap[i / 8] >> i % 8) & 0x1) { + if (!pos_bit) { + pos_bit = true; + alloc.start[alloc.num_blocks] = i; + AssertFatal(alloc.num_blocks < MAX_FA_BLOCKS, "Number of type0 PDSCH RBG exceeting %d\n", MAX_FA_BLOCKS); + alloc.num_blocks++; + } + alloc.num_rbs++; + } else { + if (pos_bit) { + pos_bit = false; + alloc.end[alloc.num_blocks - 1] = i - 1; + } + } + } + if (pos_bit) + alloc.end[alloc.num_blocks - 1] = size - 1; + AssertFatal(alloc.num_blocks > 0, "Frequency allocation bitmap empty\n"); + memcpy(alloc.bitmap, bitmap, alloc_size * sizeof(uint8_t)); + return alloc; +} + +freq_alloc_bitmap_t set_bitmap_from_start_size(int start, int size) +{ + freq_alloc_bitmap_t alloc = { + .num_rbs = size, + .num_blocks = 1, + .start[0] = start, + .end[0] = start + size - 1 + }; + memset(alloc.bitmap, 0, 36 * sizeof(uint8_t)); + for (int i = start; i < size + start; i++) + alloc.bitmap[i / 8] += 1 << (i % 8); + return alloc; +} + +bool check_rb_in_bitmap(const freq_alloc_bitmap_t *alloc, int rb) +{ + return (alloc->bitmap[rb / 8] >> (rb % 8)) & 0x01; +} + void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, const c16_t *rxdata_in, c16_t *rxdata_out, int size) { const double phase_inc = -fo_Hz / (samples_per_ms * 1000); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index f9c8f38b56..b24ba81168 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -486,51 +486,6 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, return ret; } -static freq_alloc_bitmap_t set_start_end_from_bitmap(int size, int alloc_size, const uint8_t bitmap[alloc_size]) -{ - freq_alloc_bitmap_t alloc = { - .num_rbs = 0, - .num_blocks = 0 - }; - - bool pos_bit = false; - for (int i = 0; i < size; i++) { - if ((bitmap[i / 8] >> i % 8) & 0x1) { - if (!pos_bit) { - pos_bit = true; - alloc.start[alloc.num_blocks] = i; - AssertFatal(alloc.num_blocks < MAX_FA_BLOCKS, "Number of type0 PDSCH RBG exceeting %d\n", MAX_FA_BLOCKS); - alloc.num_blocks++; - } - alloc.num_rbs++; - } else { - if (pos_bit) { - pos_bit = false; - alloc.end[alloc.num_blocks - 1] = i - 1; - } - } - } - if (pos_bit) - alloc.end[alloc.num_blocks - 1] = size - 1; - AssertFatal(alloc.num_blocks > 0, "Frequency allocation bitmap empty\n"); - memcpy(alloc.bitmap, bitmap, alloc_size * sizeof(uint8_t)); - return alloc; -} - -static freq_alloc_bitmap_t set_bitmap_from_start_size(int start, int size) -{ - freq_alloc_bitmap_t alloc = { - .num_rbs = size, - .num_blocks = 1, - .start[0] = start, - .end[0] = start + size - 1 - }; - memset(alloc.bitmap, 0, 36 * sizeof(uint8_t)); - for (int i = start; i < size + start; i++) - alloc.bitmap[i / 8] += 1 << (i % 8); - return alloc; -} - static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, NR_UE_DLSCH_t dlsch[2], diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index c06a5529c9..4c3ada67f0 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -410,8 +410,9 @@ int main(int argc, char **argv) dlsch_ue[0].rnti = n_rnti; nr_init_dl_harq_processes(UE->dl_harq_processes, 8, nb_rb); - unsigned char harq_pid = 0; //dlsch->harq_ids[subframe]; + unsigned char harq_pid = 0; //dlsch->harq_ids[subframe]; NR_gNB_DLSCH_t *dlsch = &gNB->dlsch[0]; + dlsch->freq_alloc = set_bitmap_from_start_size(0, nb_rb); //time_stats_t *rm_stats, *te_stats, *i_stats; unsigned int TBS = 8424; uint8_t nb_re_dmrs = 6; // No data in dmrs symbol