diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index fea64e3f3e..e342ab0b67 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -1120,6 +1120,7 @@ typedef struct uint16_t ul_dmrs_symb_pos; uint8_t dmrs_config_type; uint16_t ul_dmrs_scrambling_id; + uint16_t pusch_identity; uint8_t scid; uint8_t num_dmrs_cdm_grps_no_data; uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c index daa2346098..42d500ae86 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -197,8 +197,10 @@ decoder_node_t *add_nodes(int level, int first_leaf_index, t_nrPolar_params *pol } for (int i=0;iinformation_bit_pattern[i+first_leaf_index]>0) - all_frozen_below=0; + if (polarParams->information_bit_pattern[i+first_leaf_index]>0) { + all_frozen_below=0; + break; + } } if (all_frozen_below==0) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index ce409de131..8de011acef 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -2006,11 +2006,6 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu return; } - //AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n"); - if(ulsch->harq_processes[harq_pid]->nb_rb == 0) { - LOG_E(PHY, "fill_ulsch UE_id %d nb_rb = 0\n", UE_id); - } - ulsch->harq_processes[harq_pid]->frame = frame; ulsch->harq_processes[harq_pid]->subframe = subframe; ulsch->harq_processes[harq_pid]->handled = 0; diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 3f7c7817f7..9a6f47b01d 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -34,6 +34,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, unsigned char Ns, unsigned short p, unsigned char symbol, + int ul_id, unsigned short bwp_start_subcarrier, nfapi_nr_pusch_pdu_t *pusch_pdu) { @@ -43,8 +44,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, unsigned int pilot_cnt,re_cnt; int16_t ch[2],ch_r[2],ch_l[2],*pil,*rxF,*ul_ch; int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; - int ch_offset,symbol_offset, UE_id = 0; - int32_t **ul_ch_estimates_time = gNB->pusch_vars[UE_id]->ul_ch_estimates_time; + int ch_offset,symbol_offset ; + int32_t **ul_ch_estimates_time = gNB->pusch_vars[ul_id]->ul_ch_estimates_time; __m128i *ul_ch_128; #ifdef DEBUG_CH @@ -55,7 +56,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1]; uint8_t nushift; - int **ul_ch_estimates = gNB->pusch_vars[UE_id]->ul_ch_estimates; + int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates; int **rxdataF = gNB->common_vars.rxdataF; nushift = (p>>1)&1; @@ -338,7 +339,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, 8); } } -#ifdef DEBUG_PDSCH +#ifdef DEBUG_PUSCH ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; for(uint16_t idxP=0; idxPharq_processes[harq_pid]->pdsch_pdu.pdsch_pdu_rel15; uint16_t nb_rb = rel15->rbSize; uint8_t nb_symb_sch = rel15->NrOfSymbols; - uint32_t A, Z, Kb, F=0; + uint32_t A, Kb, F=0; + static uint32_t Z = 0; uint32_t *Zc = &Z; uint8_t mod_order = rel15->qamModOrder[0]; uint16_t Kr=0,r; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 8aa2984a95..4291dfa695 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -67,7 +67,7 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr,uint8_t N_RB_UL) if (ulsch) { if (N_RB_UL != 273) { a_segments = a_segments*N_RB_UL; - a_segments = a_segments/273; + a_segments = a_segments/273 +1; } @@ -119,11 +119,10 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint16_t N_RB_UL, uint if (N_RB_UL != 273) { a_segments = a_segments*N_RB_UL; - a_segments = a_segments/273; + a_segments = a_segments/273 +1; } uint16_t ulsch_bytes = a_segments*1056; // allocated bytes per segment - ulsch = (NR_gNB_ULSCH_t *)malloc16(sizeof(NR_gNB_ULSCH_t)); if (ulsch) { @@ -366,13 +365,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d\n",harq_pid,A,G, mcs, n_layers, nb_rb, Qm, n_layers); - if (harq_process->round == 0) { - - // This is a new packet, so compute quantities regarding segmentation - if (A > 3824) - harq_process->B = A+24; - else - harq_process->B = A+16; if (R<1024) Coderate = (float) R /(float) 1024; @@ -409,6 +401,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } } + if (harq_process->round == 0) { + // This is a new packet, so compute quantities regarding segmentation + if (A > 3824) + harq_process->B = A+24; + else + harq_process->B = A+16; + // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F) nr_segmentation(NULL, NULL, @@ -438,7 +437,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if (nb_rb != 273) { a_segments = a_segments*nb_rb; - a_segments = a_segments/273; + a_segments = a_segments/273 +1; } if (harq_process->C > a_segments) { @@ -479,7 +478,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats); -#ifdef DEBUG_ULSCH_DECODING LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", harq_pid,r, G, Kr*3, @@ -489,7 +487,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, n_layers, pusch_pdu->pusch_data.rv_index, harq_process->round); -#endif ////////////////////////////////////////////////////////////////////////////////////////// @@ -664,8 +661,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, harq_process->status = SCH_IDLE; harq_process->round = 0; harq_process->handled = 0; - ulsch->harq_mask &= ~(1 << harq_pid); } + ulsch->harq_mask &= ~(1 << harq_pid); // LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", // phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS); @@ -675,15 +672,15 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } else { -#ifdef gNB_DEBUG_TRACE +//#ifdef gNB_DEBUG_TRACE LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n", phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS); -#endif +//#endif harq_process->status = SCH_IDLE; harq_process->round = 0; // harq_process->handled = 0; - ulsch->harq_mask &= ~(1 << harq_pid); + ulsch->harq_mask |= (1 << harq_pid); // harq_process->harq_ack.ack = 1; // harq_process->harq_ack.harq_id = harq_pid; // harq_process->harq_ack.send_harq_status = 1; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index a966db5844..0375ce5c4e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1082,6 +1082,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, nr_tti_rx, 0, // p symbol, + ulsch_id, bwp_start_subcarrier, rel15_ul); stop_meas(&gNB->ulsch_channel_estimation_stats); diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 501df8bb35..66e70f8809 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -1047,6 +1047,8 @@ void init_pucch2_luts() { bit = (i&0x80) > 0 ? 0 : 1; *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,7); *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,7); + +#ifdef DEBUG_NR_PUCCH_RX printf("i %d, lut_num (%d,%d,%d,%d,%d,%d,%d,%d)\n",i, ((int16_t *)lut_num_i)[0], ((int16_t *)lut_num_i)[1], @@ -1056,6 +1058,7 @@ void init_pucch2_luts() { ((int16_t *)lut_num_i)[5], ((int16_t *)lut_num_i)[6], ((int16_t *)lut_num_i)[7]); +#endif } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 1a6006c3ba..ff3fc086ce 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -68,7 +68,7 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL) if (dlsch) { if (N_RB_DL != 273) { a_segments = a_segments*N_RB_DL; - a_segments = a_segments/273; + a_segments = a_segments/273 +1; } @@ -409,7 +409,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if (nb_rb != 273) { a_segments = a_segments*nb_rb; - a_segments = a_segments/273; + a_segments = a_segments/273 +1; } if (harq_process->C > a_segments) { @@ -947,7 +947,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, if (nb_rb != 273) { a_segments = a_segments*nb_rb; - a_segments = a_segments/273; + a_segments = a_segments/273 +1; } if (harq_process->C > a_segments) { @@ -1525,7 +1525,7 @@ void nr_dlsch_decoding_process(void *arg) if (nb_rb != 273) { a_segments = a_segments*nb_rb; - a_segments = a_segments/273; + a_segments = a_segments/273 +1; } if (harq_process->C > a_segments) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 7f941e5567..996bd93a76 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -333,9 +333,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch0_harq->pmi_alloc, pdsch_vars[eNB_id_i]->pmi_ext, symbol, - pilots, - start_rb, - nb_rb_pdsch, + pilots, + start_rb, + nb_rb_pdsch, nr_tti_rx, ue->high_speed_flag, frame_parms, @@ -348,9 +348,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch0_harq->pmi_alloc, pdsch_vars[eNB_id_i]->pmi_ext, symbol, - pilots, - start_rb, - nb_rb_pdsch, + pilots, + start_rb, + nb_rb_pdsch, nr_tti_rx, ue->high_speed_flag, frame_parms, @@ -510,7 +510,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL, frame_parms, symbol, - pilots, + pilots, first_symbol_flag, dlsch0_harq->Qm, nb_rb, @@ -1141,7 +1141,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, int **rho, NR_DL_FRAME_PARMS *frame_parms, unsigned char symbol, - uint8_t pilots, + uint8_t pilots, uint8_t first_symbol_flag, unsigned char mod_order, unsigned short nb_rb, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 4b36f91e69..93add646fe 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -57,7 +57,7 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr,unsigned char N_RB_UL) if (N_RB_UL != 273) { a_segments = a_segments*N_RB_UL; - a_segments = a_segments/273; + a_segments = a_segments/273 +1; } @@ -114,7 +114,7 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, if (N_RB_UL != 273) { a_segments = a_segments*N_RB_UL; - a_segments = a_segments/273; + a_segments = a_segments/273 +1; } uint16_t ulsch_bytes = a_segments*1056; // allocated bytes per segment @@ -225,8 +225,9 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, unsigned int crc; NR_UL_UE_HARQ_t *harq_process; uint16_t nb_rb ; - uint32_t A, Z, F; - uint32_t *pz; + uint32_t A, F; + static uint32_t Z = 0; + uint32_t *pz = &Z; uint8_t mod_order; uint16_t Kr,r; uint32_t r_offset; @@ -409,6 +410,8 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, /////////////////////////////////////////////////////////////////////////////// } + F = harq_process->F; + Kr = harq_process->K; for (r=0; rC; r++) { // looping over C segments diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index ddebcc3e06..2870f1d42e 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -160,6 +160,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ gNB->dlsch[i][0]->harq_mask=0; } gNB->pdcch_pdu = NULL; + gNB->ul_dci_pdu = NULL; gNB->pbch_configured=0; for (int i=0;ipdcch_pdu || gNB->ul_dci_pdu) { - LOG_D(PHY, "[gNB %d] Frame %d slot %d Calling nr_generate_dci_top (number of UL/DL DCI %d/%d)\n", + LOG_I(PHY, "[gNB %d] Frame %d slot %d Calling nr_generate_dci_top (number of UL/DL DCI %d/%d)\n", gNB->Mod_id, frame, slot, gNB->ul_dci_pdu==NULL?0:gNB->ul_dci_pdu->pdcch_pdu.pdcch_pdu_rel15.numDlDci, gNB->pdcch_pdu==NULL?0:gNB->pdcch_pdu->pdcch_pdu_rel15.numDlDci); @@ -438,6 +438,9 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) (ulsch_harq->slot == slot_rx) && (ulsch_harq->handled == 0)){ + LOG_I(PHY, "PUSCH generation started in frame %d slot %d\n", + frame_rx,slot_rx); + #ifdef DEBUG_RXDATA NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; RU_t *ru = gNB->RU_list[0]; @@ -445,7 +448,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) slot_offset -= ru->N_TA_offset; char name[128]; FILE *f; - sprintf(name, "rxdata.%d.%d.raw", frame_rx,slot_rx); + sprintf(name, "rxdata.%d.%d.%d.raw", ulsch->rnti,frame_rx,slot_rx); f = fopen(name, "w"); if (f == NULL) exit(1); fwrite(&ru->common.rxdata[0][slot_offset],2,frame_parms->get_samples_per_slot(slot_rx,frame_parms)*2, f); fclose(f); @@ -454,14 +457,18 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index; uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1); - for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { - nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); - } + for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { + no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); + if (no_sig) { + LOG_I(PHY, "ULSCH %d not received\n",ULSCH_id); + return; + } + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,0); //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1); //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX,1); - nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); + nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX,0); break; } diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 389b096d1a..32855616f8 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -104,6 +104,7 @@ int rrc_init_nr_global_param(void){return(0);} // needed for some functions uint16_t n_rnti = 0x1234; openair0_config_t openair0_cfg[MAX_CARDS]; +uint8_t round_rv_map[4] = {1, 0, 2, 3}; int main(int argc, char **argv) { @@ -146,6 +147,7 @@ int main(int argc, char **argv) int print_perf = 0; cpuf = get_cpu_freq_GHz(); int msg3_flag = 0; + uint8_t rv_index = 0; UE_nr_rxtx_proc_t UE_proc; FILE *scg_fd=NULL; @@ -556,6 +558,7 @@ int main(int argc, char **argv) uint16_t n_rb1 = 75; uint8_t mcs_table = 0; uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; // | PUSCH_PDU_BITMAP_PUSCH_PTRS; + uint8_t max_rounds = 4; uint8_t length_dmrs = pusch_len1; // [hna] remove dmrs struct uint16_t l_prime_mask = get_l_prime(nb_symb_sch, typeB, pusch_dmrs_pos0, length_dmrs); // [hna] remove dmrs struct @@ -574,10 +577,18 @@ int main(int argc, char **argv) printf("\n"); - for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0)); + //for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0)); for (SNR = snr0; SNR < snr1; SNR += snr_step) { + varArray_t *table_rx=initVarArray(1000,sizeof(double)); + for (trial = 0; trial < n_trials; trial++) { + uint8_t round = 0; + int error_flag; + gNB->ulsch[0][0]->harq_mask = 0; - varArray_t *table_rx=initVarArray(1000,sizeof(double)); + while (roundulsch[0][0]->harq_mask & 0x1)) { + ulsch_ue[0]->harq_processes[harq_pid]->round = round; + gNB->ulsch[0][0]->harq_processes[harq_pid]->round = round; + rv_index = round_rv_map[round]; reset_meas(&gNB->phy_proc_rx); reset_meas(&gNB->ulsch_decoding_stats); reset_meas(&gNB->ulsch_deinterleaving_stats); @@ -658,9 +669,9 @@ int main(int argc, char **argv) pusch_pdu->uplink_frequency_shift_7p5khz = 0; pusch_pdu->start_symbol_index = start_symbol; pusch_pdu->nr_of_symbols = nb_symb_sch; - pusch_pdu->pusch_data.rv_index = 0; + pusch_pdu->pusch_data.rv_index = rv_index; pusch_pdu->pusch_data.harq_process_id = 0; - pusch_pdu->pusch_data.new_data_indicator = 0; + pusch_pdu->pusch_data.new_data_indicator = trial & 0x1; pusch_pdu->pusch_data.num_cb = 0; pusch_pdu->pusch_ptrs.ptrs_time_density = ptrs_time_density; pusch_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density; @@ -694,8 +705,8 @@ int main(int argc, char **argv) ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs; ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table; ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1; - ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0; - ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = 0; + ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = trial & 0x1; + ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index; ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers; ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_pid; ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density; @@ -762,8 +773,6 @@ int main(int argc, char **argv) errors_scrambling = 0; errors_decoding = 0; - int error_flag; - for (trial = 0; trial < n_trials; trial++) { error_flag = 0; //---------------------------------------------------------- @@ -833,6 +842,9 @@ int main(int argc, char **argv) error_flag = 1; n_errors++; } + printf("end of round %d rv_index %d\n",round, rv_index); + round++; + } // round //---------------------------------------------------------- //----------------- count and print errors ----------------- @@ -868,11 +880,11 @@ int main(int argc, char **argv) if (n_trials == 1) { for (int r=0;rharq_processes[harq_pid]->C;r++) for (int i=0;iharq_processes[harq_pid]->K>>3;i++) { - if ((ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]) != 0) printf("************"); + /*if ((ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]) != 0) printf("************"); printf("r %d: in[%d] %x, out[%d] %x (%x)\n",r, i,ulsch_ue[0]->harq_processes[harq_pid]->c[r][i], i,ulsch_gNB->harq_processes[harq_pid]->c[r][i], - ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]); + ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]);*/ } } if (errors_decoding > 0 && error_flag == 0) { diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 591c2448b8..d8583167dd 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -251,9 +251,8 @@ typedef struct { uint8_t short_messages; //8 bits uint8_t tb_scaling; //2 bits uint8_t pucch_resource_indicator; //3 bits - uint8_t dmrs_sequence_initialization; //1 bit uint8_t system_info_indicator; //1 bit - + uint8_t ulsch_indicator; uint8_t slot_format_indicator_count; uint8_t *slot_format_indicators; @@ -290,6 +289,7 @@ typedef struct { dci_field_t cloded_loop_indicator; //variable dci_field_t ul_sul_indicator; //variable dci_field_t antenna_ports; //variable + dci_field_t dmrs_sequence_initialization; dci_field_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits } dci_pdu_rel15_t; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 074908022c..f40d822b6b 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -31,6 +31,7 @@ */ #include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160}; @@ -1879,7 +1880,8 @@ uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB) { return 1; } -uint16_t nr_dci_size(NR_CellGroupConfig_t *secondaryCellGroup, +uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc, + NR_CellGroupConfig_t *secondaryCellGroup, dci_pdu_rel15_t *dci_pdu, nr_dci_format_t format, nr_rnti_type_t rnti_type, @@ -1887,9 +1889,15 @@ uint16_t nr_dci_size(NR_CellGroupConfig_t *secondaryCellGroup, int bwp_id) { uint16_t size = 0; + uint16_t numRBG = 0; + long rbg_size_config; + int num_entries = 0; + int pusch_antenna_ports = 1; // TODO hardcoded number of antenna ports for pusch NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]; NR_PDSCH_Config_t *pdsch_config = bwp->bwp_Dedicated->pdsch_Config->choice.setup; + NR_PUSCH_Config_t *pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup; + NR_SRS_Config_t *srs_config = ubwp->bwp_Dedicated->srs_Config->choice.setup; switch(format) { /*Only sizes for 0_0 and 1_0 are correct at the moment*/ @@ -1897,30 +1905,199 @@ uint16_t nr_dci_size(NR_CellGroupConfig_t *secondaryCellGroup, /// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20 size += 20; size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment -- hopping scenario to be updated - size += nr_dci_size(secondaryCellGroup,dci_pdu,NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, bwp_id) - size; // Padding to match 1_0 size + size += nr_dci_size(scc,secondaryCellGroup,dci_pdu,NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, bwp_id) - size; // Padding to match 1_0 size // UL/SUL indicator assumed to be 0 break; case NR_UL_DCI_FORMAT_0_1: - /// fixed: Format identifier 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2, SRS request 2 --17 - size += 17; + /// fixed: Format identifier 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2, ULSCH indicator 1 --16 + size += 16; // Carrier indicator + if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL) { + dci_pdu->carrier_indicator.nbits=3; + size += dci_pdu->carrier_indicator.nbits; + } // UL/SUL indicator + if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->supplementaryUplink != NULL) { + dci_pdu->carrier_indicator.nbits=1; + size += dci_pdu->ul_sul_indicator.nbits; + } // BWP Indicator + uint8_t n_ul_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count; + if (n_ul_bwp < 2) + dci_pdu->bwp_indicator.nbits = n_ul_bwp; + else + dci_pdu->bwp_indicator.nbits = 2; + size += dci_pdu->bwp_indicator.nbits; // Freq domain assignment + if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pusch_Config->choice.setup->rbg_Size != NULL) + rbg_size_config = 1; + else + rbg_size_config = 0; + numRBG = getNRBG(NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275), + NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275), + rbg_size_config); + if (pusch_Config->resourceAllocation == 0) + dci_pdu->frequency_domain_assignment.nbits = numRBG; + else if (pusch_Config->resourceAllocation == 1) + dci_pdu->frequency_domain_assignment.nbits = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + else + dci_pdu->frequency_domain_assignment.nbits = ((int)ceil( log2( (N_RB*(N_RB+1))>>1 ) )>numRBG) ? (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) )+1 : numRBG+1; + size += dci_pdu->frequency_domain_assignment.nbits; // Time domain assignment - // VRB to PRB mapping + if (pusch_Config->pusch_TimeDomainAllocationList==NULL) { + if (ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList==NULL) + num_entries = 16; // num of entries in default table + else + num_entries = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count; + } + else + num_entries = pusch_Config->pusch_TimeDomainAllocationList->choice.setup->list.count; + dci_pdu->time_domain_assignment.nbits = (int)ceil(log2(num_entries)); + size += dci_pdu->time_domain_assignment.nbits; // Frequency Hopping flag + if ((pusch_Config->frequencyHopping!=NULL) && (pusch_Config->resourceAllocation != NR_PUSCH_Config__resourceAllocation_resourceAllocationType0)) { + dci_pdu->frequency_hopping_flag.nbits = 1; + size += 1; + } // 1st DAI + if (secondaryCellGroup->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook==NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic) + dci_pdu->dai[0].nbits = 2; + else + dci_pdu->dai[0].nbits = 1; + size += dci_pdu->dai[0].nbits; // 2nd DAI + if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) { //TODO not sure about that + dci_pdu->dai[1].nbits = 2; + size += dci_pdu->dai[1].nbits; + } // SRS resource indicator + if (pusch_Config->txConfig != NULL){ + int count=0; + if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook){ + for (int i=0; isrs_ResourceSetToAddModList->list.count; i++) { + if (srs_config->srs_ResourceSetToAddModList->list.array[i]->usage == NR_SRS_ResourceSet__usage_codebook) + count++; + } + if (count>1) { + dci_pdu->srs_resource_indicator.nbits = 1; + size += dci_pdu->srs_resource_indicator.nbits; + } + } + else { + int lmin,Lmax = 0; + int lsum = 0; + if ( secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig != NULL) { + if ( secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers != NULL) + Lmax = *secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers; + else + AssertFatal(1==0,"MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); + } + else + AssertFatal(1==0,"MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); + for (int i=0; isrs_ResourceSetToAddModList->list.count; i++) { + if (srs_config->srs_ResourceSetToAddModList->list.array[i]->usage == NR_SRS_ResourceSet__usage_nonCodebook) + count++; + if (count < Lmax) lmin = count; + else lmin = Lmax; + for (int k=1;k<=lmin;k++) { + lsum += binomial(count,k); + } + } + dci_pdu->srs_resource_indicator.nbits = (int)ceil(log2(lsum)); + size += dci_pdu->srs_resource_indicator.nbits; + } + } // Precoding info and number of layers + long transformPrecoder; + if (pusch_Config->transformPrecoder == NULL){ + // if transform precoder is null, apply the values from msg3 + if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) + transformPrecoder = 1; + else + transformPrecoder = 0; + } + else + transformPrecoder = *pusch_Config->transformPrecoder; + if (pusch_Config->txConfig != NULL){ + if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook){ + if (pusch_antenna_ports > 1) { + if (pusch_antenna_ports == 4) { + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank>1)) + dci_pdu->precoding_information.nbits = 6-(*pusch_Config->codebookSubset); + else { + if(*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) + dci_pdu->precoding_information.nbits = 2; + else + dci_pdu->precoding_information.nbits = 5-(*pusch_Config->codebookSubset); + } + } + else { + AssertFatal(pusch_antenna_ports==2,"Not valid number of antenna ports"); + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank==2)) + dci_pdu->precoding_information.nbits = 4-(*pusch_Config->codebookSubset); + else + dci_pdu->precoding_information.nbits = 3-(*pusch_Config->codebookSubset); + } + } + } + } + size += dci_pdu->precoding_information.nbits; // Antenna ports + NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = NULL; + int xa=0; + int xb=0; + if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL){ + NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup; + xa = ul_ant_bits(NR_DMRS_UplinkConfig,transformPrecoder); + } + if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB != NULL){ + NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; + xb = ul_ant_bits(NR_DMRS_UplinkConfig,transformPrecoder); + } + if (xa>xb) + dci_pdu->antenna_ports.nbits = xa; + else + dci_pdu->antenna_ports.nbits = xb; + size += dci_pdu->antenna_ports.nbits; + // SRS request + if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->supplementaryUplink==NULL) + dci_pdu->srs_request.nbits = 2; + else + dci_pdu->srs_request.nbits = 3; + size += dci_pdu->srs_request.nbits; // CSI request + if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig != NULL) { + if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup->reportTriggerSize != NULL) { + dci_pdu->csi_request.nbits = *secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup->reportTriggerSize; + size += dci_pdu->csi_request.nbits; + } + } // CBGTI + if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) { + int num = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->codeBlockGroupTransmission->choice.setup->maxCodeBlockGroupsPerTransportBlock; + dci_pdu->cbgti.nbits = 2 + (num<<1); + size += dci_pdu->cbgti.nbits; + } // PTRS - DMRS association + if ( (NR_DMRS_UplinkConfig->phaseTrackingRS == NULL && transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) || + transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled || (*pusch_Config->maxRank==1) ) + dci_pdu->ptrs_dmrs_association.nbits = 0; + else + dci_pdu->ptrs_dmrs_association.nbits = 2; + size += dci_pdu->ptrs_dmrs_association.nbits; // beta offset indicator + if (pusch_Config->uci_OnPUSCH!=NULL){ + if (pusch_Config->uci_OnPUSCH->choice.setup->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_dynamic) { + dci_pdu->beta_offset_indicator.nbits = 2; + size += dci_pdu->beta_offset_indicator.nbits; + } + } // DMRS sequence init + if (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) { + dci_pdu->dmrs_sequence_initialization.nbits = 1; + size += dci_pdu->dmrs_sequence_initialization.nbits; + } break; case NR_DL_DCI_FORMAT_1_0: @@ -1946,10 +2123,10 @@ uint16_t nr_dci_size(NR_CellGroupConfig_t *secondaryCellGroup, dci_pdu->bwp_indicator.nbits = 2; size += dci_pdu->bwp_indicator.nbits; // Freq domain assignment - long rbg_size_config = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rbg_Size; - uint16_t numRBG = getNRBG(NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275), - NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275), - rbg_size_config); + rbg_size_config = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rbg_Size; + numRBG = getNRBG(NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275), + NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275), + rbg_size_config); if (pdsch_config->resourceAllocation == 0) dci_pdu->frequency_domain_assignment.nbits = numRBG; else if (pdsch_config->resourceAllocation == 1) @@ -1958,7 +2135,6 @@ uint16_t nr_dci_size(NR_CellGroupConfig_t *secondaryCellGroup, dci_pdu->frequency_domain_assignment.nbits = ((int)ceil( log2( (N_RB*(N_RB+1))>>1 ) )>numRBG) ? (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) )+1 : numRBG+1; size += dci_pdu->frequency_domain_assignment.nbits; // Time domain assignment (see table 5.1.2.1.1-1 in 38.214 - int num_entries; if (pdsch_config->pdsch_TimeDomainAllocationList==NULL) { if (bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList==NULL) num_entries = 16; // num of entries in default table @@ -2068,6 +2244,27 @@ uint16_t nr_dci_size(NR_CellGroupConfig_t *secondaryCellGroup, return size; } +int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig, long transformPrecoder) { + + uint8_t type,maxl; + if(NR_DMRS_UplinkConfig->dmrs_Type == NULL) + type = 1; + else + type = 2; + if(NR_DMRS_UplinkConfig->maxLength == NULL) + maxl = 1; + else + maxl = 2; + if (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) + return( maxl+type+1); + else { + if (type==1) + return (maxl<<1); + else + AssertFatal(1==0,"DMRS type not valid for this choice"); + } +} + int tdd_period_to_num[8] = {500,625,1000,1250,2000,2500,5000,10000}; int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) { @@ -2208,3 +2405,20 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i AssertFatal(1==0,"Shouldn't get here\n"); return(-1); } + + +int binomial(int n, int k) { + int c = 1, i; + + if (k > n-k) + k = n-k; + + for (i = 1; i <= k; i++, n--) { + if (c/i > UINT_MAX/n) // return 0 on overflow + return 0; + + c = c / i * n + c % i * n / i; + } + return c; +} + diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 2f7f144983..a5e38bf128 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -77,7 +77,8 @@ int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); -uint16_t nr_dci_size(NR_CellGroupConfig_t *secondaryCellGroup, +uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc, + NR_CellGroupConfig_t *secondaryCellGroup, dci_pdu_rel15_t *dci_pdu, nr_dci_format_t format, nr_rnti_type_t rnti_type, @@ -103,6 +104,8 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, uint8_t nb_preambles, uint8_t unpaired); +int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig,long transformPrecoder); + int get_format0(uint8_t index, uint8_t unpaired); uint16_t get_NCS(uint8_t index, uint16_t format, uint8_t restricted_set_config); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index a79b4083e3..53263747fc 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -223,7 +223,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); // NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing; - rel15->dci_length = nr_dci_size(mac->scg,def_dci_pdu_rel15,rel15->dci_format,NR_RNTI_C,rel15->BWPSize,bwp_id); + rel15->dci_length = nr_dci_size(scc,mac->scg,def_dci_pdu_rel15,rel15->dci_format,NR_RNTI_C,rel15->BWPSize,bwp_id); for (int i = 0; i < sps; i++) if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) { rel15->coreset.StartSymbolIndex = i; @@ -243,7 +243,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl rel15->BWPSize = NRRIV2BW(bwp_Common->genericParameters.locationAndBandwidth, 275); rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing; - rel15->dci_length = nr_dci_size(mac->scg,def_dci_pdu_rel15,rel15->dci_format,NR_RNTI_C,rel15->BWPSize,bwp_id); + rel15->dci_length = nr_dci_size(scc,mac->scg,def_dci_pdu_rel15,rel15->dci_format,NR_RNTI_C,rel15->BWPSize,bwp_id); // get UE-specific search space for (ss_id = 0; ss_id < FAPI_NR_MAX_SS_PER_CORESET && mac->SSpace[0][0][ss_id] != NULL; ss_id++){ uss = mac->SSpace[0][0][ss_id]; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 109d4570f4..cd6e6bf6db 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -773,8 +773,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in uint16_t rnti = 0x1234; uint32_t rb_size = 50; uint32_t rb_start = 0; - uint8_t nr_of_symbols = 12; - uint8_t start_symbol_index = 2; + uint8_t nr_of_symbols = 11; + uint8_t start_symbol_index = 0; uint8_t nrOfLayers = 1; uint8_t mcs_index = 9; uint8_t mcs_table = 0; @@ -3530,7 +3530,7 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac, dci_pdu_rel15->cbgfi.val = (*dci_pdu>>(dci_size-pos))&((1<cbgfi.nbits)-1); // DMRS sequence init pos+=1; - dci_pdu_rel15->dmrs_sequence_initialization = (*dci_pdu>>(dci_size-pos))&0x1; + dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&0x1; break; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index b2d952ca3d..ec81ac8532 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -288,6 +288,26 @@ void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) } */ +void nr_schedule_pusch(int Mod_idP, + int UE_id, + frame_t frameP, + sub_frame_t slotP) { + + nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0]; + NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; + NR_sched_pusch *pusch = UE_list->UE_sched_ctrl[UE_id].sched_pusch; + if ((pusch->active == true) && (frameP == pusch->frame) && (slotP == pusch->slot)) { + UL_tti_req->SFN = pusch->frame; + UL_tti_req->Slot = pusch->slot; + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu = pusch->pusch_pdu; + UL_tti_req->n_pdus+=1; + memset((void *) UE_list->UE_sched_ctrl[UE_id].sched_pusch, + 0, sizeof(NR_sched_pusch)); + } +} + void nr_schedule_pucch(int Mod_idP, int UE_id, frame_t frameP, @@ -361,6 +381,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, int UE_id; uint64_t *dlsch_in_slot_bitmap=NULL; uint64_t *ulsch_in_slot_bitmap=NULL; + int pucch_sched; UE_id=0; int bwp_id = 1; @@ -412,93 +433,97 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, *ulsch_in_slot_bitmap = 0x00; } - // Check if there are downlink symbols in the slot, - if (is_nr_DL_slot(cc->ServingCellConfigCommon,slot_txP)) { - memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0 - memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1 - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - //mbsfn_status[CC_id] = 0; - // clear vrb_maps - memset(cc[CC_id].vrb_map, 0, 100); - memset(cc[CC_id].vrb_map_UL, 0, 100); + memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0 + memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1 + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + //mbsfn_status[CC_id] = 0; - clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP); - } + // clear vrb_maps + memset(cc[CC_id].vrb_map, 0, 100); + memset(cc[CC_id].vrb_map_UL, 0, 100); - // refresh UE list based on UEs dropped by PHY in previous subframe - /* - for (i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (UE_list->active[i]) { + clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP); + } - nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id]; + // refresh UE list based on UEs dropped by PHY in previous subframe + /* + for (i = 0; i < MAX_MOBILES_PER_GNB; i++) { + if (UE_list->active[i]) { + + nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id]; - rnti = 0;//UE_RNTI(module_idP, i); - CC_id = 0;//UE_PCCID(module_idP, i); + rnti = 0;//UE_RNTI(module_idP, i); + CC_id = 0;//UE_PCCID(module_idP, i); - } //END if (UE_list->active[i]) - } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++) - */ + } //END if (UE_list->active[i]) + } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++) + */ - // This schedules MIB - if((slot_txP == 0) && (frame_txP & 7) == 0){ - schedule_nr_mib(module_idP, frame_txP, slot_txP); + // This schedules MIB + if((slot_txP == 0) && (frame_txP & 7) == 0){ + schedule_nr_mib(module_idP, frame_txP, slot_txP); + } + + // This schedule PRACH if we are not in phy_test mode + if (get_softmodem_params()->phy_test == 0) + schedule_nr_prach(module_idP, (frame_rxP+1)&1023, slot_rxP); + + // This schedule SR + // TODO + + // This schedule CSI + // TODO + + // This schedule RA procedure if not in phy_test mode + // Otherwise already consider 5G already connected + if (get_softmodem_params()->phy_test == 0) { + nr_schedule_RA(module_idP, frame_txP, slot_txP); + nr_schedule_reception_msg3(module_idP, 0, frame_rxP, slot_rxP); + } + else + UE_list->fiveG_connected[UE_id] = true; + + if (get_softmodem_params()->phy_test) { + + // TbD once RACH is available, start ta_timer when UE is connected + if (ue_sched_ctl->ta_timer) + ue_sched_ctl->ta_timer--; + if (ue_sched_ctl->ta_timer == 0) { + gNB->ta_command = ue_sched_ctl->ta_update; + /* if time is up, then set the timer to not send it for 5 frames + // regardless of the TA value */ + ue_sched_ctl->ta_timer = 100; + /* reset ta_update */ + ue_sched_ctl->ta_update = 31; + /* MAC CE flag indicating TA length */ + gNB->ta_len = 2; } + } - if (get_softmodem_params()->phy_test == 0) - nr_schedule_RA(module_idP, frame_txP, slot_txP); - else - UE_list->fiveG_connected[UE_id] = true; + // This schedules the DCI for Uplink and subsequently PUSCH + if (UE_list->fiveG_connected[UE_id]) { + int tda = 1; // time domain assignment hardcoded for now + schedule_fapi_ul_pdu(module_idP, frame_txP, slot_txP, num_slots_per_tdd, tda); + nr_schedule_pusch(module_idP, UE_id, frame_rxP, slot_rxP); + } - // Phytest scheduling + if (UE_list->fiveG_connected[UE_id] && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot_txP%num_slots_per_tdd))) { + ue_sched_ctl->current_harq_pid = slot_txP % num_slots_per_tdd; + nr_update_pucch_scheduling(module_idP, UE_id, frame_txP, slot_txP, num_slots_per_tdd,&pucch_sched); + nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP, &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL); + // resetting ta flag + gNB->ta_len = 0; + } - if (get_softmodem_params()->phy_test) { - - // TbD once RACH is available, start ta_timer when UE is connected - if (ue_sched_ctl->ta_timer) - ue_sched_ctl->ta_timer--; - - if (ue_sched_ctl->ta_timer == 0) { - gNB->ta_command = ue_sched_ctl->ta_update; - /* if time is up, then set the timer to not send it for 5 frames - // regardless of the TA value */ - ue_sched_ctl->ta_timer = 100; - /* reset ta_update */ - ue_sched_ctl->ta_update = 31; - /* MAC CE flag indicating TA length */ - gNB->ta_len = 2; - } - } - - if (UE_list->fiveG_connected[UE_id] && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot_txP%num_slots_per_tdd))) { - ue_sched_ctl->current_harq_pid = slot_txP % num_slots_per_tdd; - nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP, num_slots_per_tdd, NULL); - // resetting ta flag - gNB->ta_len = 0; - } + if (UE_list->fiveG_connected[UE_id]) + nr_schedule_pucch(module_idP, UE_id, frame_rxP, slot_rxP); /* // Allocate CCEs for good after scheduling is done for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) allocate_CCEs(module_idP, CC_id, subframeP, 0); */ - } //is_nr_DL_slot - - if (is_nr_UL_slot(cc->ServingCellConfigCommon,slot_rxP)) { - - if (get_softmodem_params()->phy_test == 0) { - if (UE_list->fiveG_connected[UE_id]) - nr_schedule_pucch(module_idP, UE_id, frame_rxP, slot_rxP); - schedule_nr_prach(module_idP, (frame_rxP+1)&1023, slot_rxP); - nr_schedule_reception_msg3(module_idP, 0, frame_rxP, slot_rxP); - } - if (get_softmodem_params()->phy_test){ - nr_schedule_pucch(module_idP, UE_id, frame_rxP, slot_rxP); - if (is_xlsch_in_slot(*ulsch_in_slot_bitmap,slot_rxP%num_slots_per_tdd)){ - nr_schedule_uss_ulsch_phytest(module_idP, frame_rxP, slot_rxP); - } - } - } stop_meas(&RC.nrmac[module_idP]->eNB_scheduler); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index db93734a7d..01c18ed997 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -54,115 +54,117 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req[0]; - uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; - uint8_t mu,N_dur,N_t_slot,start_symbol; - uint16_t format; + if (is_nr_UL_slot(scc,slotP)) { - if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) - mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; - else - mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; + uint8_t mu,N_dur,N_t_slot,start_symbol; + uint16_t format; - // prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4 - if ( get_nr_prach_info_from_index(config_index, - (int)frameP, - (int)slotP, - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA, - mu, - cc->frame_type, - &format, - &start_symbol, - &N_t_slot, - &N_dur) ) { + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) + mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; + else + mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; - int fdm = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM; - uint16_t format0 = format&0xff; // first column of format from table - uint16_t format1 = (format>>8)&0xff; // second column of format from table + // prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4 + if ( get_nr_prach_info_from_index(config_index, + (int)frameP, + (int)slotP, + scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA, + mu, + cc->frame_type, + &format, + &start_symbol, + &N_t_slot, + &N_dur) ) { - UL_tti_req->SFN = frameP; - UL_tti_req->Slot = slotP; - for (int n=0; n<(1<pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE; - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t); - nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu; - memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t)); - UL_tti_req->n_pdus+=1; + int fdm = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM; + uint16_t format0 = format&0xff; // first column of format from table + uint16_t format1 = (format>>8)&0xff; // second column of format from table - // filling the prach fapi structure - prach_pdu->phys_cell_id = *scc->physCellId; - prach_pdu->num_prach_ocas = N_t_slot; - prach_pdu->prach_start_symbol = start_symbol; - prach_pdu->num_ra = n; - prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig, - format0, - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig); - // SCF PRACH PDU format field does not consider A1/B1 etc. possibilities - // We added 9 = A1/B1 10 = A2/B2 11 A3/B3 - if (format1!=0xff) { - switch(format0) { - case 0xa1: - prach_pdu->prach_format = 9; - break; - case 0xa2: - prach_pdu->prach_format = 10; - break; - case 0xa3: - prach_pdu->prach_format = 11; - break; - default: - AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); + UL_tti_req->SFN = frameP; + UL_tti_req->Slot = slotP; + for (int n=0; n<(1<pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE; + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t); + nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu; + memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t)); + UL_tti_req->n_pdus+=1; + + // filling the prach fapi structure + prach_pdu->phys_cell_id = *scc->physCellId; + prach_pdu->num_prach_ocas = N_t_slot; + prach_pdu->prach_start_symbol = start_symbol; + prach_pdu->num_ra = n; + prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig, + format0, + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig); + // SCF PRACH PDU format field does not consider A1/B1 etc. possibilities + // We added 9 = A1/B1 10 = A2/B2 11 A3/B3 + if (format1!=0xff) { + switch(format0) { + case 0xa1: + prach_pdu->prach_format = 9; + break; + case 0xa2: + prach_pdu->prach_format = 10; + break; + case 0xa3: + prach_pdu->prach_format = 11; + break; + default: + AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); + } } - } - else{ - switch(format0) { - case 0xa1: - prach_pdu->prach_format = 0; - break; - case 0xa2: - prach_pdu->prach_format = 1; - break; - case 0xa3: - prach_pdu->prach_format = 2; - break; - case 0xb1: - prach_pdu->prach_format = 3; - break; - case 0xb2: - prach_pdu->prach_format = 4; - break; - case 0xb3: - prach_pdu->prach_format = 5; - break; - case 0xb4: - prach_pdu->prach_format = 6; - break; - case 0xc0: - prach_pdu->prach_format = 7; - break; - case 0xc2: - prach_pdu->prach_format = 8; - break; - case 0: - // long formats are handled @ PHY - break; - case 1: - // long formats are handled @ PHY - break; - case 2: - // long formats are handled @ PHY - break; - case 3: - // long formats are handled @ PHY - break; - default: - AssertFatal(1==0,"Invalid PRACH format"); + else{ + switch(format0) { + case 0xa1: + prach_pdu->prach_format = 0; + break; + case 0xa2: + prach_pdu->prach_format = 1; + break; + case 0xa3: + prach_pdu->prach_format = 2; + break; + case 0xb1: + prach_pdu->prach_format = 3; + break; + case 0xb2: + prach_pdu->prach_format = 4; + break; + case 0xb3: + prach_pdu->prach_format = 5; + break; + case 0xb4: + prach_pdu->prach_format = 6; + break; + case 0xc0: + prach_pdu->prach_format = 7; + break; + case 0xc2: + prach_pdu->prach_format = 8; + break; + case 0: + // long formats are handled @ PHY + break; + case 1: + // long formats are handled @ PHY + break; + case 2: + // long formats are handled @ PHY + break; + case 3: + // long formats are handled @ PHY + break; + default: + AssertFatal(1==0,"Invalid PRACH format"); + } } } } } } - void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, uint16_t *msg2_frame, uint16_t *msg2_slot, NR_ServingCellConfigCommon_t *scc, @@ -688,7 +690,7 @@ void nr_generate_Msg2(module_id_t module_idP, pdcch_pdu_rel15->StartSymbolIndex, pdcch_pdu_rel15->DurationSymbols); - fill_dci_pdu_rel15(secondaryCellGroup,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw,ra->bwp_id); + fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw,ra->bwp_id); dl_req->nPDUs+=2; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 52266690c6..99a0083360 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -270,6 +270,7 @@ int configure_fapi_dl_pdu(int Mod_idP, int TBS; int bwp_id=1; int UE_id = 0; + uint8_t rv_round_map[4] = {0, 2, 3, 1}; NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; @@ -315,7 +316,7 @@ int configure_fapi_dl_pdu(int Mod_idP, pdsch_pdu_rel15->qamModOrder[0] = 2; pdsch_pdu_rel15->mcsIndex[0] = mcs; pdsch_pdu_rel15->mcsTable[0] = 0; - pdsch_pdu_rel15->rvIndex[0] = (get_softmodem_params()->phy_test==1) ? 0 : UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round; + pdsch_pdu_rel15->rvIndex[0] = (get_softmodem_params()->phy_test==1) ? 0 : rv_round_map[UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]; pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; @@ -330,7 +331,7 @@ int configure_fapi_dl_pdu(int Mod_idP, pdsch_pdu_rel15->rbStart = (rbStart!=NULL) ? *rbStart : 0; pdsch_pdu_rel15->rbSize = (rbSize!=NULL) ? *rbSize : pdsch_pdu_rel15->BWPSize; pdsch_pdu_rel15->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP - // choose shortest PDSCH + int startSymbolAndLength=0; int time_domain_assignment=2; int StartSymbolIndex,NrOfSymbols; @@ -363,10 +364,10 @@ int configure_fapi_dl_pdu(int Mod_idP, AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n"); // time domain assignment dci_pdu_rel15[0].time_domain_assignment.val = time_domain_assignment; // row index used here instead of SLIV; - // mcs ndi and rv + // mcs and rv dci_pdu_rel15[0].mcs = pdsch_pdu_rel15->mcsIndex[0]; dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0]; - // harq pid + // harq pid and ndi dci_pdu_rel15[0].harq_pid = current_harq_pid; dci_pdu_rel15[0].ndi = UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].ndi; // DAI @@ -382,7 +383,8 @@ int configure_fapi_dl_pdu(int Mod_idP, UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].is_waiting = 1; // antenna ports dci_pdu_rel15[0].antenna_ports.val = 0; // nb of cdm groups w/o data 1 and dmrs port 0 - + // dmrs sequence initialization + dci_pdu_rel15[0].dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID; LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", dci_pdu_rel15[0].frequency_domain_assignment.val, pdsch_pdu_rel15->rbStart, @@ -438,7 +440,7 @@ int configure_fapi_dl_pdu(int Mod_idP, rnti_types[0] = NR_RNTI_C; - fill_dci_pdu_rel15(secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pdsch_pdu_rel15->BWPSize,bwp_id); + fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pdsch_pdu_rel15->BWPSize,bwp_id); LOG_D(MAC, "DCI params: rnti %x, rnti_type %d, dci_format %d\n \ coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", @@ -469,22 +471,70 @@ int configure_fapi_dl_pdu(int Mod_idP, return TBS; //Return TBS in bytes } -void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types) { +void config_uldci(NR_BWP_Uplink_t *ubwp, + nfapi_nr_pusch_pdu_t *pusch_pdu, + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, + dci_pdu_rel15_t *dci_pdu_rel15, + int *dci_formats, int *rnti_types, + int time_domain_assignment, + int n_ubwp, int bwp_id) { - dci_pdu_rel15->frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, - pusch_pdu->rb_start, - NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275)); + switch(dci_formats[(pdcch_pdu_rel15->numDlDci)-1]) { + case NR_UL_DCI_FORMAT_0_0: + dci_pdu_rel15->frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, + pusch_pdu->rb_start, + NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275)); + + dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment; + dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping; + dci_pdu_rel15->mcs = 9; + + dci_pdu_rel15->format_indicator = 0; + dci_pdu_rel15->ndi = 1; + dci_pdu_rel15->rv = 0; + dci_pdu_rel15->harq_pid = 0; + dci_pdu_rel15->tpc = 1; + break; + case NR_UL_DCI_FORMAT_0_1: + dci_pdu_rel15->ndi = pusch_pdu->pusch_data.new_data_indicator; + dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index; + dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id; + dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping; + dci_pdu_rel15->dai[0].val = 0; //TODO + // bwp indicator + if (n_ubwp < 4) + dci_pdu_rel15->bwp_indicator.val = bwp_id; + else + dci_pdu_rel15->bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212 + // frequency domain assignment + if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->resourceAllocation==NR_PUSCH_Config__resourceAllocation_resourceAllocationType1) + dci_pdu_rel15->frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, + pusch_pdu->rb_start, + NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275)); + else + AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n"); + // time domain assignment + dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment; + // mcs + dci_pdu_rel15->mcs = pusch_pdu->mcs_index; + // tpc command for pusch + dci_pdu_rel15->tpc = 1; //TODO + // SRS resource indicator + if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig != NULL) { + if (*ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig == NR_PUSCH_Config__txConfig_codebook) + dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS + else + AssertFatal(1==0,"Non Codebook configuration non supported\n"); + } + // Antenna Ports + dci_pdu_rel15->antenna_ports.val = 0; // TODO for now it is hardcoded, it should depends on cdm group no data and rank + // DMRS sequence initialization + dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid; + break; + default : + AssertFatal(1==0,"Valid UL formats are 0_0 and 0_1 \n"); + } - dci_pdu_rel15->time_domain_assignment.val = 2; // row index used here instead of SLIV; - dci_pdu_rel15->frequency_hopping_flag.val = 0; - dci_pdu_rel15->mcs = 9; - - dci_pdu_rel15->format_indicator = 0; - dci_pdu_rel15->ndi = 1; - dci_pdu_rel15->rv = 0; - dci_pdu_rel15->harq_pid = 0; - dci_pdu_rel15->tpc = 2; - LOG_D(MAC, "[gNB scheduler phytest] ULDCI type 0 payload: PDCCH CCEIndex %d, freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n", pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci], dci_pdu_rel15->frequency_domain_assignment.val, @@ -494,10 +544,6 @@ void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr dci_pdu_rel15->tpc, dci_pdu_rel15->ndi, dci_pdu_rel15->rv); - - dci_formats[pdcch_pdu_rel15->numDlDci] = NR_UL_DCI_FORMAT_0_0; - rnti_types[pdcch_pdu_rel15->numDlDci] = NR_RNTI_C; - pdcch_pdu_rel15->numDlDci++; } @@ -772,16 +818,18 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, } -void nr_schedule_uss_ulsch_phytest(int Mod_idP, - frame_t frameP, - sub_frame_t slotP) { +void schedule_fapi_ul_pdu(int Mod_idP, + frame_t frameP, + sub_frame_t slotP, + int num_slots_per_tdd, + int time_domain_assignment) { gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP]; NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; int bwp_id=1; - + int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; int UE_id = 0; NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n",UE_id); @@ -791,196 +839,281 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]; + int n_ubwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count; NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; - nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0]; - nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0]; + NR_PUSCH_Config_t *pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup; - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, - "searchPsacesToAddModList is empty\n"); + AssertFatal(time_domain_assignmentbwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count, + "time_domain_assignment %d>=%d\n",time_domain_assignment,ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count); - uint16_t rnti = UE_list->rnti[UE_id]; - nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu; + int K2; + if (ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->k2 != NULL) + K2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->k2; + else { + if (mu<2) K2=1; + else if(mu==2) K2=2; + else K2=3; + } - UL_tti_req->SFN = frameP; - UL_tti_req->Slot = slotP; - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); - nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu; - memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t)); - UL_tti_req->n_pdus+=1; + if (is_xlsch_in_slot(UE_list->UE_sched_ctrl[UE_id].ulsch_in_slot_bitmap,(slotP+K2)%num_slots_per_tdd)) { - LOG_D(MAC, "Scheduling UE specific PUSCH\n"); - //UL_tti_req = &nr_mac->UL_tti_req[CC_id]; - /* - // original configuration - rel15_ul->rnti = 0x1234; - rel15_ul->ulsch_pdu_rel15.start_rb = 30; - rel15_ul->ulsch_pdu_rel15.number_rbs = 50; - rel15_ul->ulsch_pdu_rel15.start_symbol = 2; - rel15_ul->ulsch_pdu_rel15.number_symbols = 12; - rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; - rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; - rel15_ul->ulsch_pdu_rel15.Qm = 2; - rel15_ul->ulsch_pdu_rel15.mcs = 9; - rel15_ul->ulsch_pdu_rel15.rv = 0; - rel15_ul->ulsch_pdu_rel15.n_layers = 1; - */ - pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; - pusch_pdu->rnti = rnti; - pusch_pdu->handle = 0; //not yet used + //nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0]; + nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0]; + UL_dci_req->SFN = frameP; + UL_dci_req->Slot = slotP; + nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu; + + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, + "searchPsacesToAddModList is empty\n"); + + uint16_t rnti = UE_list->rnti[UE_id]; + + NR_sched_pusch *pusch_sched = UE_list->UE_sched_ctrl[UE_id].sched_pusch; + pusch_sched->frame = frameP; + pusch_sched->slot = slotP + K2; + pusch_sched->active = true; + nfapi_nr_pusch_pdu_t *pusch_pdu = &pusch_sched->pusch_pdu; + memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t)); + + LOG_D(MAC, "Scheduling UE specific PUSCH\n"); + //UL_tti_req = &nr_mac->UL_tti_req[CC_id]; + + //Resource Allocation in time domain + int startSymbolAndLength=0; + int StartSymbolIndex,NrOfSymbols,mapping_type; + + startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength,&StartSymbolIndex,&NrOfSymbols); + pusch_pdu->start_symbol_index = StartSymbolIndex; + pusch_pdu->nr_of_symbols = NrOfSymbols; + + mapping_type = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType; + + pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + pusch_pdu->rnti = rnti; + pusch_pdu->handle = 0; //not yet used - pusch_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); - pusch_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); - pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing; - pusch_pdu->cyclic_prefix = 0; - //pusch information always include - //this informantion seems to be redundant. with hthe mcs_index and the modulation table, the mod_order and target_code_rate can be determined. - pusch_pdu->mcs_index = 9; - pusch_pdu->mcs_table = 0; //0: notqam256 [TS38.214, table 5.1.3.1-1] - corresponds to nr_target_code_rate_table1 in PHY - pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; - pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; - pusch_pdu->transform_precoding = 0; - pusch_pdu->data_scrambling_id = 0; //It equals the higher-layer parameter Data-scrambling-Identity if configured and the RNTI equals the C-RNTI, otherwise L2 needs to set it to physical cell id.; - pusch_pdu->nrOfLayers = 1; - - //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] - pusch_pdu->resource_alloc = 1; //type 1 - //pusch_pdu->rb_bitmap;// for ressource alloc type 0 - pusch_pdu->rb_start = 0; - pusch_pdu->rb_size = 50; - pusch_pdu->vrb_to_prb_mapping = 0; - pusch_pdu->frequency_hopping = 0; - //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] - pusch_pdu->uplink_frequency_shift_7p5khz = 0; - //Resource Allocation in time domain - pusch_pdu->start_symbol_index = 2; - pusch_pdu->nr_of_symbols = 12; - - // -------------------- - // ------- DMRS ------- - // -------------------- - uint16_t l_prime_mask = get_l_prime(pusch_pdu->nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1); - pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << pusch_pdu->start_symbol_index; - pusch_pdu->dmrs_config_type = 0; // dmrs-type 1 (the one with a single DMRS symbol in the beginning) - pusch_pdu->ul_dmrs_scrambling_id = 0; // If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id - pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1] - // Should match what is sent in DCI 0_1, otherwise set to 0 - pusch_pdu->num_dmrs_cdm_grps_no_data = 1; - //pusch_pdu->dmrs_ports; // DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports - // Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011, - // and for each bit 0: DMRS port not used 1: DMRS port used - // -------------------------------------------------------------------------------------------------------------------------------------------- - - // -------------------- - // ------- PTRS ------- - // -------------------- - uint8_t ptrs_mcs1 = 2; // higher layer parameter in PTRS-UplinkConfig - uint8_t ptrs_mcs2 = 4; // higher layer parameter in PTRS-UplinkConfig - uint8_t ptrs_mcs3 = 10; // higher layer parameter in PTRS-UplinkConfig - uint16_t n_rb0 = 25; // higher layer parameter in PTRS-UplinkConfig - uint16_t n_rb1 = 75; // higher layer parameter in PTRS-UplinkConfig - pusch_pdu->pusch_ptrs.ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_pdu->mcs_index, pusch_pdu->mcs_table); - pusch_pdu->pusch_ptrs.ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_pdu->rb_size); - pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t)); - pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; - - if(1<pusch_ptrs.ptrs_time_density >= pusch_pdu->nr_of_symbols) - pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS - // -------------------------------------------------------------------------------------------------------------------------------------------- - - //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] - //Optional Data only included if indicated in pduBitmap - pusch_pdu->pusch_data.rv_index = 0; - pusch_pdu->pusch_data.harq_process_id = 0; - pusch_pdu->pusch_data.new_data_indicator = 0; - - uint8_t num_dmrs_symb = 0; - - for(int dmrs_counter = pusch_pdu->start_symbol_index; dmrs_counter < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; dmrs_counter++) - num_dmrs_symb += ((pusch_pdu->ul_dmrs_symb_pos >> dmrs_counter) & 1); - - uint8_t N_PRB_DMRS; - if (pusch_pdu->dmrs_config_type == 0) { - N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*6; - } - else { - N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*4; - } - - pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order, - pusch_pdu->target_code_rate, - pusch_pdu->rb_size, - pusch_pdu->nr_of_symbols, - N_PRB_DMRS * num_dmrs_symb, - 0, //nb_rb_oh - 0, - pusch_pdu->nrOfLayers)>>3; - - - pusch_pdu->pusch_data.num_cb = 0; //CBG not supported - //pusch_pdu->pusch_data.cb_present_and_position; - //pusch_pdu->pusch_uci; - //pusch_pdu->pusch_ptrs; - //pusch_pdu->dfts_ofdm; - //beamforming - //pusch_pdu->beamforming; //not used for now - - - ul_dci_request_pdu = &UL_dci_req->ul_dci_pdu_list[UL_dci_req->numPdus]; - memset((void*)ul_dci_request_pdu,0,sizeof(nfapi_nr_ul_dci_request_pdus_t)); - ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; - ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; - - int dci_formats[2]; - int rnti_types[2]; - - NR_SearchSpace_t *ss; - int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, - "searchPsacesToAddModList is empty\n"); - - int found=0; - - for (int i=0;ibwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) { - ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; - AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n"); - AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n"); - if (ss->searchSpaceType->present == target_ss) { - found=1; - break; + pusch_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pusch_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + pusch_pdu->cyclic_prefix = 0; + //pusch information always include + //this informantion seems to be redundant. with hthe mcs_index and the modulation table, the mod_order and target_code_rate can be determined. + pusch_pdu->mcs_index = 9; + pusch_pdu->mcs_table = 0; //0: notqam256 [TS38.214, table 5.1.3.1-1] - corresponds to nr_target_code_rate_table1 in PHY + pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; + pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; + if (pusch_Config->transformPrecoder == NULL) { + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) + pusch_pdu->transform_precoding = 1; + else + pusch_pdu->transform_precoding = 0; } - } - AssertFatal(found==1,"Couldn't find an adequate searchspace\n"); + else + pusch_pdu->transform_precoding = *pusch_Config->transformPrecoder; + if (pusch_Config->dataScramblingIdentityPUSCH != NULL) + pusch_pdu->data_scrambling_id = *pusch_Config->dataScramblingIdentityPUSCH; + else + pusch_pdu->data_scrambling_id = *scc->physCellId; - if (ss->searchSpaceType->choice.ue_Specific->dci_Formats) - dci_formats[0] = NR_UL_DCI_FORMAT_0_1; - else - dci_formats[0] = NR_UL_DCI_FORMAT_0_0; + pusch_pdu->nrOfLayers = 1; - rnti_types[0] = NR_RNTI_C; - LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP); + //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] + if (pusch_Config->resourceAllocation==NR_PUSCH_Config__resourceAllocation_resourceAllocationType1) { + pusch_pdu->resource_alloc = 1; //type 1 + pusch_pdu->rb_start = 0; + if (get_softmodem_params()->phy_test==1) + pusch_pdu->rb_size = 50; + else + pusch_pdu->rb_size = 5; + } + else + AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n"); - int ret = nr_configure_pdcch(nr_mac, - pdcch_pdu_rel15, - UE_list->rnti[UE_id], - 1, // ue-specific, - ss, - scc, - bwp); + pusch_pdu->vrb_to_prb_mapping = 0; - if (ret < 0) { - LOG_I(MAC,"CCE list not empty, couldn't schedule PUSCH\n"); - UL_tti_req->n_pdus-=1; - return; - } - else { - dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET]; - config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types); - fill_dci_pdu_rel15(secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pusch_pdu->bwp_size,bwp_id); + if (pusch_Config->frequencyHopping==NULL) + pusch_pdu->frequency_hopping = 0; + else + pusch_pdu->frequency_hopping = 1; + + //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] + //pusch_pdu->uplink_frequency_shift_7p5khz = 0; + + + // -------------------- + // ------- DMRS ------- + // -------------------- + NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig; + if (mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA) + NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup; + else + NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; + if (NR_DMRS_UplinkConfig->dmrs_Type == NULL) + pusch_pdu->dmrs_config_type = 0; + else + pusch_pdu->dmrs_config_type = 1; + pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1] + if (pusch_pdu->transform_precoding) { // transform precoding disabled + long *scramblingid; + if (pusch_pdu->scid == 0) + scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0; + else + scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID1; + if (scramblingid == NULL) + pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; + else + pusch_pdu->ul_dmrs_scrambling_id = *scramblingid; + } + else { + pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; + if (NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL) + pusch_pdu->pusch_identity = *NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity; + else + pusch_pdu->pusch_identity = *scc->physCellId; + } + pusch_dmrs_AdditionalPosition_t additional_pos; + if (NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL) + additional_pos = 2; + else { + if (*NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3) + additional_pos = 3; + else + additional_pos = *NR_DMRS_UplinkConfig->dmrs_AdditionalPosition; + } + pusch_maxLength_t pusch_maxLength; + if (NR_DMRS_UplinkConfig->maxLength == NULL) + pusch_maxLength = 1; + else + pusch_maxLength = 2; + uint16_t l_prime_mask = get_l_prime(pusch_pdu->nr_of_symbols, mapping_type, additional_pos, pusch_maxLength); + pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << pusch_pdu->start_symbol_index; + + pusch_pdu->num_dmrs_cdm_grps_no_data = 1; + pusch_pdu->dmrs_ports = 1; + // -------------------------------------------------------------------------------------------------------------------------------------------- + + // -------------------- + // ------- PTRS ------- + // -------------------- + if (NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) { + // TODO to be fixed from RRC config + uint8_t ptrs_mcs1 = 2; // higher layer parameter in PTRS-UplinkConfig + uint8_t ptrs_mcs2 = 4; // higher layer parameter in PTRS-UplinkConfig + uint8_t ptrs_mcs3 = 10; // higher layer parameter in PTRS-UplinkConfig + uint16_t n_rb0 = 25; // higher layer parameter in PTRS-UplinkConfig + uint16_t n_rb1 = 75; // higher layer parameter in PTRS-UplinkConfig + pusch_pdu->pusch_ptrs.ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_pdu->mcs_index, pusch_pdu->mcs_table); + pusch_pdu->pusch_ptrs.ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_pdu->rb_size); + pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t)); + pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; + + pusch_pdu->pdu_bit_map &= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS + } + else{ + // if(1<pusch_ptrs.ptrs_time_density >= pusch_pdu->nr_of_symbols) + pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS + } + + // -------------------------------------------------------------------------------------------------------------------------------------------- + + //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] + //Optional Data only included if indicated in pduBitmap + // TODO from harq function as in pdsch + pusch_pdu->pusch_data.rv_index = 0; + pusch_pdu->pusch_data.harq_process_id = 0; + pusch_pdu->pusch_data.new_data_indicator = 1; + + uint8_t num_dmrs_symb = 0; + + for(int dmrs_counter = pusch_pdu->start_symbol_index; dmrs_counter < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; dmrs_counter++) + num_dmrs_symb += ((pusch_pdu->ul_dmrs_symb_pos >> dmrs_counter) & 1); + + uint8_t N_PRB_DMRS; + if (pusch_pdu->dmrs_config_type == 0) { + N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*6; + } + else { + N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*4; + } + + pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order, + pusch_pdu->target_code_rate, + pusch_pdu->rb_size, + pusch_pdu->nr_of_symbols, + N_PRB_DMRS * num_dmrs_symb, + 0, //nb_rb_oh + 0, + pusch_pdu->nrOfLayers)>>3; + + + pusch_pdu->pusch_data.num_cb = 0; //CBG not supported + //pusch_pdu->pusch_data.cb_present_and_position; + //pusch_pdu->pusch_uci; + //pusch_pdu->pusch_ptrs; + //pusch_pdu->dfts_ofdm; + //beamforming + //pusch_pdu->beamforming; //not used for now + + + ul_dci_request_pdu = &UL_dci_req->ul_dci_pdu_list[UL_dci_req->numPdus]; + memset((void*)ul_dci_request_pdu,0,sizeof(nfapi_nr_ul_dci_request_pdus_t)); + ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; + UL_dci_req->numPdus+=1; + + int dci_formats[2]; + int rnti_types[2]; + + NR_SearchSpace_t *ss; + int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, + "searchPsacesToAddModList is empty\n"); + + int found=0; + + for (int i=0;ibwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) { + ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; + AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n"); + AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n"); + if (ss->searchSpaceType->present == target_ss) { + found=1; + break; + } + } + AssertFatal(found==1,"Couldn't find an adequate searchspace\n"); + + if (ss->searchSpaceType->choice.ue_Specific->dci_Formats) + dci_formats[0] = NR_UL_DCI_FORMAT_0_1; + else + dci_formats[0] = NR_UL_DCI_FORMAT_0_0; + + rnti_types[0] = NR_RNTI_C; + LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP); + + int ret = nr_configure_pdcch(nr_mac, + pdcch_pdu_rel15, + UE_list->rnti[UE_id], + 1, // ue-specific, + ss, + scc, + bwp); + + if (ret < 0) { + LOG_I(MAC,"CCE list not empty, couldn't schedule PUSCH\n"); + pusch_sched->active = false; + return; + } + else { + dci_pdu_rel15_t *dci_pdu_rel15 = calloc(MAX_DCI_CORESET,sizeof(dci_pdu_rel15_t)); + config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,n_ubwp,bwp_id); + fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pusch_pdu->bwp_size,bwp_id); + free(dci_pdu_rel15); + } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index fc2a2e18cf..809bf30c8a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -734,6 +734,19 @@ void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup, NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; switch(format) { + case NR_UL_DCI_FORMAT_0_1: + // format indicator + dci_pdu_rel15->format_indicator = 0; + // carrier indicator + if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL) + AssertFatal(1==0,"Cross Carrier Scheduling Config currently not supported\n"); + // supplementary uplink + if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->supplementaryUplink != NULL) + AssertFatal(1==0,"Supplementary Uplink currently not supported\n"); + // SRS request + dci_pdu_rel15->srs_request.val = 0; + dci_pdu_rel15->ulsch_indicator = 1; + break; case NR_DL_DCI_FORMAT_1_1: // format indicator dci_pdu_rel15->format_indicator = 1; @@ -782,16 +795,15 @@ void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup, // CBGTI and CBGFI if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) AssertFatal(1==0,"CBG transmission currently not supported\n"); - // dmrs sequence initialization - dci_pdu_rel15->dmrs_sequence_initialization = 0; // FIXME no information on what this bit should be in 38.212 break; default : - AssertFatal(1==0,"Prepare dci currently only implemented for 1_1 \n"); + AssertFatal(1==0,"Prepare dci currently only implemented for 1_1 and 0_1 \n"); } } -void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup, +void fill_dci_pdu_rel15(NR_ServingCellConfigCommon_t *scc, + NR_CellGroupConfig_t *secondaryCellGroup, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, @@ -804,11 +816,11 @@ void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup, for (int d=0;dnumDlDci;d++) { uint64_t *dci_pdu = (uint64_t *)pdcch_pdu_rel15->dci_pdu.Payload[d]; - int dci_size = nr_dci_size(secondaryCellGroup,&dci_pdu_rel15[d],dci_formats[d],rnti_types[d],N_RB,bwp_id); + int dci_size = nr_dci_size(scc,secondaryCellGroup,&dci_pdu_rel15[d],dci_formats[d],rnti_types[d],N_RB,bwp_id); pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d] = dci_size; AssertFatal(pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d]<=64, "DCI sizes above 64 bits not yet supported"); - if(dci_formats[d]==NR_DL_DCI_FORMAT_1_1) + if(dci_formats[d]==NR_DL_DCI_FORMAT_1_1 || dci_formats[d]==NR_UL_DCI_FORMAT_0_1) prepare_dci(secondaryCellGroup,&dci_pdu_rel15[d],dci_formats[d],bwp_id); /// Payload generation @@ -1118,6 +1130,110 @@ void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup, } break; + case NR_UL_DCI_FORMAT_0_1: + switch(rnti_types[d]) + { + case NR_RNTI_C: + // Indicating a DL DCI format 1bit + pos=1; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator&0x1)<<(dci_size-pos); + + // Carrier indicator + pos+=dci_pdu_rel15->carrier_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->carrier_indicator.val&((1<carrier_indicator.nbits)-1))<<(dci_size-pos); + + // UL/SUL Indicator + pos+=dci_pdu_rel15->ul_sul_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ul_sul_indicator.val&((1<ul_sul_indicator.nbits)-1))<<(dci_size-pos); + + // BWP indicator + pos+=dci_pdu_rel15->bwp_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->bwp_indicator.val&((1<bwp_indicator.nbits)-1))<<(dci_size-pos); + + // Frequency domain resource assignment + pos+=dci_pdu_rel15->frequency_domain_assignment.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val&((1<frequency_domain_assignment.nbits)-1)) << (dci_size-pos); + + // Time domain resource assignment + pos+=dci_pdu_rel15->time_domain_assignment.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->time_domain_assignment.val&((1<time_domain_assignment.nbits)-1)) << (dci_size-pos); + + // Frequency hopping + pos+=dci_pdu_rel15->frequency_hopping_flag.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val&((1<frequency_hopping_flag.nbits)-1)) << (dci_size-pos); + + // MCS 5bit + pos+=5; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs&0x1f)<<(dci_size-pos); + + // New data indicator 1bit + pos+=1; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi&0x1)<<(dci_size-pos); + + // Redundancy version 2bit + pos+=2; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->rv&0x3)<<(dci_size-pos); + + // HARQ process number 4bit + pos+=4; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->harq_pid&0xf)<<(dci_size-pos); + + // 1st Downlink assignment index + pos+=dci_pdu_rel15->dai[0].nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->dai[0].val&((1<dai[0].nbits)-1))<<(dci_size-pos); + + // 2nd Downlink assignment index + pos+=dci_pdu_rel15->dai[1].nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->dai[1].val&((1<dai[1].nbits)-1))<<(dci_size-pos); + + // TPC command for scheduled PUSCH 2bit + pos+=2; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->tpc&0x3)<<(dci_size-pos); + + // SRS resource indicator + pos+=dci_pdu_rel15->srs_resource_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->srs_resource_indicator.val&((1<srs_resource_indicator.nbits)-1))<<(dci_size-pos); + + // Precoding info and n. of layers + pos+=dci_pdu_rel15->precoding_information.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->precoding_information.val&((1<precoding_information.nbits)-1))<<(dci_size-pos); + + // Antenna ports + pos+=dci_pdu_rel15->antenna_ports.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->antenna_ports.val&((1<antenna_ports.nbits)-1))<<(dci_size-pos); + + // SRS request + pos+=dci_pdu_rel15->srs_request.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->srs_request.val&((1<srs_request.nbits)-1))<<(dci_size-pos); + + // CSI request + pos+=dci_pdu_rel15->csi_request.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->csi_request.val&((1<csi_request.nbits)-1))<<(dci_size-pos); + + // CBG transmission information + pos+=dci_pdu_rel15->cbgti.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->cbgti.val&((1<cbgti.nbits)-1))<<(dci_size-pos); + + // PTRS DMRS association + pos+=dci_pdu_rel15->ptrs_dmrs_association.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ptrs_dmrs_association.val&((1<ptrs_dmrs_association.nbits)-1))<<(dci_size-pos); + + // Beta offset indicator + pos+=dci_pdu_rel15->beta_offset_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->beta_offset_indicator.val&((1<beta_offset_indicator.nbits)-1))<<(dci_size-pos); + + // DMRS sequence initialization + pos+=dci_pdu_rel15->dmrs_sequence_initialization.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->dmrs_sequence_initialization.val&((1<dmrs_sequence_initialization.nbits)-1))<<(dci_size-pos); + + // UL-SCH indicator + pos+=1; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ulsch_indicator&0x1)<<(dci_size-pos); + + break; + } + break; + case NR_DL_DCI_FORMAT_1_1: // Indicating a DL DCI format 1bit pos=1; @@ -1223,7 +1339,7 @@ void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup, // DMRS sequence init pos+=1; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->dmrs_sequence_initialization&0x1)<<(dci_size-pos); + *dci_pdu |= ((uint64_t)dci_pdu_rel15->dmrs_sequence_initialization.val&0x1)<<(dci_size-pos); } } } @@ -1352,6 +1468,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ 0, sizeof(NR_UE_sched_ctrl_t)); UE_list->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch)); + UE_list->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(sizeof(NR_sched_pusch)); LOG_I(MAC, "gNB %d] Add NR UE_id %d : rnti %x\n", mod_idP, UE_id, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index ccbdd8c839..06f1b82f5d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -132,7 +132,13 @@ int configure_fapi_dl_pdu(int Mod_id, uint16_t *rbSize, uint16_t *rbStart); -void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types); +void config_uldci(NR_BWP_Uplink_t *ubwp, + nfapi_nr_pusch_pdu_t *pusch_pdu, + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, + dci_pdu_rel15_t *dci_pdu_rel15, + int *dci_formats, int *rnti_types, + int time_domain_assignment, + int n_ubwp, int bwp_id); void configure_fapi_dl_Tx(module_id_t Mod_idP, frame_t frameP, @@ -148,9 +154,10 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, int num_slots_per_tdd, nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_config); -void nr_schedule_uss_ulsch_phytest(int Mod_idP, - frame_t frameP, - sub_frame_t slotP); +void nr_schedule_pusch(int Mod_idP, + int UE_id, + frame_t frameP, + sub_frame_t slotP); void nr_update_pucch_scheduling(int Mod_idP, int UE_id, @@ -203,7 +210,8 @@ int nr_configure_pdcch(gNB_MAC_INST *nr_mac, NR_ServingCellConfigCommon_t *scc, NR_BWP_Downlink_t *bwp); -void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup, +void fill_dci_pdu_rel15(NR_ServingCellConfigCommon_t *scc, + NR_CellGroupConfig_t *secondaryCellGroup, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, @@ -281,6 +289,11 @@ void nr_generate_Msg2(module_id_t module_idP, void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP); +void schedule_fapi_ul_pdu(int Mod_idP, + frame_t frameP, + sub_frame_t slotP, + int num_slots_per_tdd, + int time_domain_assignment); void nr_process_mac_pdu( module_id_t module_idP, @@ -289,6 +302,10 @@ void nr_process_mac_pdu( uint8_t *pduP, uint16_t mac_pdu_len); +int binomial(int n, int k); + +bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot); + /* \brief Function to indicate a received SDU on ULSCH. @param Mod_id Instance ID of gNB diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index f84e7a900c..303a3545d8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -253,6 +253,13 @@ typedef struct NR_sched_pucch { uint8_t resource_indicator; } NR_sched_pucch; +typedef struct NR_sched_pusch { + int frame; + int slot; + bool active; + nfapi_nr_pusch_pdu_t pusch_pdu; +} NR_sched_pusch; + typedef struct NR_UE_harq { uint8_t is_waiting; uint8_t ndi; @@ -265,6 +272,7 @@ typedef struct { uint64_t dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch uint64_t ulsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains ulsch NR_sched_pucch *sched_pucch; + NR_sched_pusch *sched_pusch; uint16_t ta_timer; int16_t ta_update; uint8_t current_harq_pid; diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 583e10da94..7e3763fb4f 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -3198,6 +3198,42 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list, &rat); + /* request NR configuration */ + LTE_UECapabilityEnquiry_r8_IEs_t *r8 = &dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8; + LTE_UECapabilityEnquiry_v8a0_IEs_t r8_a0; + LTE_UECapabilityEnquiry_v1180_IEs_t r11_80; + LTE_UECapabilityEnquiry_v1310_IEs_t r13_10; + LTE_UECapabilityEnquiry_v1430_IEs_t r14_30; + LTE_UECapabilityEnquiry_v1510_IEs_t r15_10; + + memset(&r8_a0, 0, sizeof(r8_a0)); + memset(&r11_80, 0, sizeof(r11_80)); + memset(&r13_10, 0, sizeof(r13_10)); + memset(&r14_30, 0, sizeof(r14_30)); + memset(&r15_10, 0, sizeof(r15_10)); + + r8->nonCriticalExtension = &r8_a0; + r8_a0.nonCriticalExtension = &r11_80; + r11_80.nonCriticalExtension = &r13_10; + r13_10.nonCriticalExtension = &r14_30; + r14_30.nonCriticalExtension = &r15_10; + + /* TODO: no hardcoded values here */ + + OCTET_STRING_t req_freq; + unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 + //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x08, 0x18 }; // bands 7 & nr260 + + //unsigned char req_freq_buf[13] = { 0x00, 0xc0, 0x18, 0x01, 0x01, 0x30, 0x4b, 0x04, 0x0e, 0x08, 0x24, 0x04, 0xd0 }; +// unsigned char req_freq_buf[21] = { +//0x01, 0x60, 0x18, 0x05, 0x80, 0xc0, 0x04, 0x04, 0xc1, 0x2c, 0x10, 0x08, 0x20, 0x30, 0x40, 0xe0, 0x82, 0x40, 0x28, 0x80, 0x9a +// }; + + req_freq.buf = req_freq_buf; + req_freq.size = 5; +// req_freq.size = 21; + + r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void *)&dl_dcch_msg); } @@ -3276,17 +3312,17 @@ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, /* TODO: no hardcoded values here */ OCTET_STRING_t req_freq; - //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 + unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x08, 0x18 }; // bands 7 & nr260 //unsigned char req_freq_buf[13] = { 0x00, 0xc0, 0x18, 0x01, 0x01, 0x30, 0x4b, 0x04, 0x0e, 0x08, 0x24, 0x04, 0xd0 }; - unsigned char req_freq_buf[21] = { -0x01, 0x60, 0x18, 0x05, 0x80, 0xc0, 0x04, 0x04, 0xc1, 0x2c, 0x10, 0x08, 0x20, 0x30, 0x40, 0xe0, 0x82, 0x40, 0x28, 0x80, 0x9a - }; +// unsigned char req_freq_buf[21] = { +//0x01, 0x60, 0x18, 0x05, 0x80, 0xc0, 0x04, 0x04, 0xc1, 0x2c, 0x10, 0x08, 0x20, 0x30, 0x40, 0xe0, 0x82, 0x40, 0x28, 0x80, 0x9a +// }; req_freq.buf = req_freq_buf; req_freq.size = 5; - req_freq.size = 21; +// req_freq.size = 21; r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq; diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 42535db1e9..c163ef645b 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -837,7 +837,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup = calloc(1,sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup)); NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; NR_DMRS_UplinkConfig->dmrs_Type = NULL; - NR_DMRS_UplinkConfig->dmrs_AdditionalPosition =NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos0; + NR_DMRS_UplinkConfig->dmrs_AdditionalPosition = calloc(1,sizeof(*NR_DMRS_UplinkConfig->dmrs_AdditionalPosition)); + *NR_DMRS_UplinkConfig->dmrs_AdditionalPosition = NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos0; NR_DMRS_UplinkConfig->phaseTrackingRS=NULL; NR_DMRS_UplinkConfig->maxLength=NULL; NR_DMRS_UplinkConfig->transformPrecodingDisabled = calloc(1,sizeof(*NR_DMRS_UplinkConfig->transformPrecodingDisabled)); @@ -928,7 +929,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco srs_res0->resourceMapping.repetitionFactor=NR_SRS_Resource__resourceMapping__repetitionFactor_n1; srs_res0->freqDomainPosition=0; srs_res0->freqDomainShift=0; - srs_res0->freqHopping.c_SRS = 61; + srs_res0->freqHopping.c_SRS = 0; srs_res0->freqHopping.b_SRS=0; srs_res0->freqHopping.b_hop=0; srs_res0->groupOrSequenceHopping=NR_SRS_Resource__groupOrSequenceHopping_neither; @@ -1107,7 +1108,19 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id)); *secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = 1; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig = NULL; + + secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig)); + NR_PUSCH_ServingCellConfig_t *pusch_scc = calloc(1,sizeof(*pusch_scc)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->present = NR_SetupRelease_PUSCH_ServingCellConfig_PR_setup; + secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup = pusch_scc; + pusch_scc->codeBlockGroupTransmission = NULL; + pusch_scc->rateMatching = NULL; + pusch_scc->xOverhead = NULL; + pusch_scc->ext1=calloc(1,sizeof(*pusch_scc->ext1)); + pusch_scc->ext1->maxMIMO_Layers = calloc(1,sizeof(*pusch_scc->ext1->maxMIMO_Layers)); + *pusch_scc->ext1->maxMIMO_Layers = 1; + pusch_scc->ext1->processingType2Enabled = NULL; + secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->carrierSwitching = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->supplementaryUplink=NULL; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_enb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_enb.conf index ea105d86b6..4c0d346360 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_enb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_enb.conf @@ -235,7 +235,7 @@ MACRLCs = ( THREAD_STRUCT = ( { - parallel_config = "PARALLEL_RU_L1_TRX_SPLITaaaaaa"; + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; worker_config = "ENABLE"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf index b63939add2..c8062fab47 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf @@ -132,12 +132,12 @@ gNBs = # pusch-ConfigCommon (up to 16 elements) initialULBWPk2_0 = 2; initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 + # this is SS=0 L=12 initialULBWPstartSymbolAndLength_0 = 55; initialULBWPk2_1 = 2; initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 + # this is SS=0 L=11 initialULBWPstartSymbolAndLength_1 = 69; initialULBWPk2_2 = 7; @@ -266,8 +266,8 @@ RUs = ( THREAD_STRUCT = ( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - //parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; - parallel_config = "PARALLEL_SINGLE_THREAD"; + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + //parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_ENABLE"; }