diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index a4cdd91381..67365a26f7 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -52,120 +52,47 @@ static void nr_pdsch_codeword_scrambling(uint8_t *in, uint32_t size, uint8_t q, nr_codeword_scrambling(in, size, q, Nid, n_RNTI, out); } -void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) +static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch, int slot) { - PHY_VARS_gNB *gNB = msgTx->gNB; const int16_t amp = gNB->TX_AMP; NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - time_stats_t *dlsch_encoding_stats = &gNB->dlsch_encoding_stats; + time_stats_t *dlsch_scrambling_stats = &gNB->dlsch_scrambling_stats; time_stats_t *dlsch_modulation_stats = &gNB->dlsch_modulation_stats; - time_stats_t *tinput = &gNB->tinput; - time_stats_t *tprep = &gNB->tprep; - time_stats_t *tparity = &gNB->tparity; - time_stats_t *toutput = &gNB->toutput; - time_stats_t *dlsch_rate_matching_stats = &gNB->dlsch_rate_matching_stats; - time_stats_t *dlsch_interleaving_stats = &gNB->dlsch_interleaving_stats; - time_stats_t *dlsch_segmentation_stats = &gNB->dlsch_segmentation_stats; + NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; + const int layerSz = frame_parms->N_RB_DL * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB; + const int dmrs_Type = rel15->dmrsConfigType; + const int nb_re_dmrs = rel15->numDmrsCdmGrpsNoData * (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4); + const int amp_dmrs = (int)((double)amp * sqrt(rel15->numDmrsCdmGrpsNoData)); // 3GPP TS 38.214 Section 4.1: Table 4.1-1 + 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->BWPStart + rel15->rbStart + rel15->rbSize) * nb_re_dmrs; - size_t size_output = 0; + const int dmrs_symbol_map = rel15->dlDmrsSymbPos; // single DMRS: 010000100 Double DMRS 110001100 + const int xOverhead = 0; + const int nb_re = + (12 * rel15->NrOfSymbols - nb_re_dmrs * get_num_dmrs(rel15->dlDmrsSymbPos) - xOverhead) * rel15->rbSize * rel15->nrOfLayers; + const int Qm = rel15->qamModOrder[0]; + const int encoded_length = nb_re * Qm; - for (int dlsch_id=0; dlsch_idnum_pdsch_slot; dlsch_id++) { - NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id]; - NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; - - LOG_D(PHY,"pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbsize %d\n", - rel15->BWPStart,rel15->BWPSize,rel15->rbStart,rel15->rbSize); - - const int Qm = rel15->qamModOrder[0]; - - /* PTRS */ - uint16_t dlPtrsSymPos = 0; - int n_ptrs = 0; - uint32_t ptrsSymbPerSlot = 0; - if(rel15->pduBitmap & 0x1) { - set_ptrs_symb_idx(&dlPtrsSymPos, - rel15->NrOfSymbols, - rel15->StartSymbolIndex, - 1 << rel15->PTRSTimeDensity, - rel15->dlDmrsSymbPos); - n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity; - ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, rel15->StartSymbolIndex, rel15->NrOfSymbols); - } - harq->unav_res = ptrsSymbPerSlot * n_ptrs; - - /// CRC, coding, interleaving and rate matching - AssertFatal(harq->pdu != NULL, "%4d.%2d no HARQ PDU for PDSCH generation\n", msgTx->frame, msgTx->slot); - - /* output and its parts for each dlsch should be aligned on 64 bytes - * => size_output is a sum of parts sizes rounded up to a multiple of 64 - */ - size_t size_output_tb = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers; - size_output += ceil_mod(size_output_tb, 64); + /* PTRS */ + uint16_t dlPtrsSymPos = 0; + int n_ptrs = 0; + uint32_t ptrsSymbPerSlot = 0; + if (rel15->pduBitmap & 0x1) { + set_ptrs_symb_idx(&dlPtrsSymPos, + rel15->NrOfSymbols, + rel15->StartSymbolIndex, + 1 << rel15->PTRSTimeDensity, + rel15->dlDmrsSymbPos); + n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity; + ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, rel15->StartSymbolIndex, rel15->NrOfSymbols); } - - unsigned char output[size_output] __attribute__((aligned(64))); - - bzero(output, size_output); - - size_t offset_output = 0; - - start_meas(dlsch_encoding_stats); - if (nr_dlsch_encoding(gNB, - msgTx, - frame, - slot, - frame_parms, - output, - tinput, - tprep, - tparity, - toutput, - dlsch_rate_matching_stats, - dlsch_interleaving_stats, - dlsch_segmentation_stats) == -1) { - return; - } - stop_meas(dlsch_encoding_stats); - - for (int dlsch_id=0; dlsch_idnum_pdsch_slot; dlsch_id++) { - NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id]; - - NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; - const int layerSz = frame_parms->N_RB_DL * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB; - const int dmrs_Type = rel15->dmrsConfigType; - const int nb_re_dmrs = rel15->numDmrsCdmGrpsNoData * (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4); - const int amp_dmrs = (int)((double)amp * sqrt(rel15->numDmrsCdmGrpsNoData)); // 3GPP TS 38.214 Section 4.1: Table 4.1-1 - 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->BWPStart + rel15->rbStart + rel15->rbSize) * nb_re_dmrs; - - const int dmrs_symbol_map = rel15->dlDmrsSymbPos; // single DMRS: 010000100 Double DMRS 110001100 - const int xOverhead = 0; - const int nb_re = - (12 * rel15->NrOfSymbols - nb_re_dmrs * get_num_dmrs(rel15->dlDmrsSymbPos) - xOverhead) * rel15->rbSize * rel15->nrOfLayers; - const int Qm = rel15->qamModOrder[0]; - const int encoded_length = nb_re * Qm; - - /* PTRS */ - uint16_t dlPtrsSymPos = 0; - int n_ptrs = 0; - uint32_t ptrsSymbPerSlot = 0; - if (rel15->pduBitmap & 0x1) { - set_ptrs_symb_idx(&dlPtrsSymPos, - rel15->NrOfSymbols, - rel15->StartSymbolIndex, - 1 << rel15->PTRSTimeDensity, - rel15->dlDmrsSymbPos); - n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity; - ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, rel15->StartSymbolIndex, rel15->NrOfSymbols); - } harq->unav_res = ptrsSymbPerSlot * n_ptrs; #ifdef DEBUG_DLSCH @@ -178,14 +105,14 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) printf("\nEncoded payload:\n"); for (int i = 0; i < encoded_length; i += 8) { for (int j = 0; j < 8; j++) - printf("%d", output[offset_output + i + j]); + printf("%d", input_ptr[i + j]); printf("\t"); } printf("\n"); #endif if (IS_SOFTMODEM_DLSIM) - memcpy(harq->f, &output[offset_output], encoded_length); + memcpy(harq->f, input_ptr, encoded_length); c16_t mod_symbs[rel15->NrOfCodewords][encoded_length] __attribute__((aligned(64))); for (int codeWord = 0; codeWord < rel15->NrOfCodewords; codeWord++) { @@ -194,7 +121,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) uint32_t scrambled_output[(encoded_length >> 5) + 4]; // modulator acces by 4 bytes in some cases memset(scrambled_output, 0, sizeof(scrambled_output)); if ( encoded_length > rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers) abort(); - nr_pdsch_codeword_scrambling(&output[offset_output], encoded_length, codeWord, rel15->dataScramblingId, rel15->rnti, scrambled_output); + nr_pdsch_codeword_scrambling(input_ptr, encoded_length, codeWord, rel15->dataScramblingId, rel15->rnti, scrambled_output); #ifdef DEBUG_DLSCH printf("PDSCH scrambling:\n"); @@ -222,12 +149,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) #endif } /// Resource mapping - - /* output and its parts for each dlsch should be aligned on 64 bytes - * => offset_output should remain a multiple of 64 with enough offset to fit each dlsch - */ - uint32_t size_output_tb = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers; - offset_output += ceil_mod(size_output_tb, 64); // Non interleaved VRB to PRB mapping uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart + rel15->BWPStart) * NR_NB_SC_PER_RB; @@ -1832,8 +1753,93 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) } // port loop stop_meas(&gNB->dlsch_precoding_stats); + /* output and its parts for each dlsch should be aligned on 64 bytes + * should remain a multiple of 64 with enough offset to fit each dlsch + */ + uint32_t size_output_tb = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers; + return ceil_mod(size_output_tb, 64); +} - } // dlsch loop +void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) +{ + PHY_VARS_gNB *gNB = msgTx->gNB; + NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; + time_stats_t *dlsch_encoding_stats = &gNB->dlsch_encoding_stats; + time_stats_t *tinput = &gNB->tinput; + time_stats_t *tprep = &gNB->tprep; + time_stats_t *tparity = &gNB->tparity; + time_stats_t *toutput = &gNB->toutput; + time_stats_t *dlsch_rate_matching_stats = &gNB->dlsch_rate_matching_stats; + time_stats_t *dlsch_interleaving_stats = &gNB->dlsch_interleaving_stats; + time_stats_t *dlsch_segmentation_stats = &gNB->dlsch_segmentation_stats; + + size_t size_output = 0; + + for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) { + NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id]; + NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; + + LOG_D(PHY, + "pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbsize %d\n", + rel15->BWPStart, + rel15->BWPSize, + rel15->rbStart, + rel15->rbSize); + + const int Qm = rel15->qamModOrder[0]; + + /* PTRS */ + uint16_t dlPtrsSymPos = 0; + int n_ptrs = 0; + uint32_t ptrsSymbPerSlot = 0; + if (rel15->pduBitmap & 0x1) { + set_ptrs_symb_idx(&dlPtrsSymPos, + rel15->NrOfSymbols, + rel15->StartSymbolIndex, + 1 << rel15->PTRSTimeDensity, + rel15->dlDmrsSymbPos); + n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity; + ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, rel15->StartSymbolIndex, rel15->NrOfSymbols); + } + harq->unav_res = ptrsSymbPerSlot * n_ptrs; + + /// CRC, coding, interleaving and rate matching + AssertFatal(harq->pdu != NULL, "%4d.%2d no HARQ PDU for PDSCH generation\n", msgTx->frame, msgTx->slot); + + /* output and its parts for each dlsch should be aligned on 64 bytes + * => size_output is a sum of parts sizes rounded up to a multiple of 64 + */ + size_t size_output_tb = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers; + size_output += ceil_mod(size_output_tb, 64); + } + + unsigned char output[size_output] __attribute__((aligned(64))); + bzero(output, size_output); + + start_meas(dlsch_encoding_stats); + if (nr_dlsch_encoding(gNB, + msgTx, + frame, + slot, + frame_parms, + output, + tinput, + tprep, + tparity, + toutput, + dlsch_rate_matching_stats, + dlsch_interleaving_stats, + dlsch_segmentation_stats) + == -1) { + return; + } + stop_meas(dlsch_encoding_stats); + + unsigned char *output_ptr = output; + for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) { + output_ptr += do_one_dlsch(output_ptr, gNB, msgTx->dlsch[dlsch_id], slot); + } } void dump_pdsch_stats(FILE *fd, PHY_VARS_gNB *gNB)