diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h index 0c1dbfae35..3e6222c341 100644 --- a/openair1/PHY/CODING/coding_defs.h +++ b/openair1/PHY/CODING/coding_defs.h @@ -38,7 +38,7 @@ #define MAX_TURBO_ITERATIONS_MBSFN 8 #define MAX_TURBO_ITERATIONS max_turbo_iterations -#define MAX_LDPC_ITERATIONS 4 +#define MAX_LDPC_ITERATIONS 5 #define MAX_LDPC_ITERATIONS_MBSFN 4 #define LTE_NULL 2 diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 964bbf802a..8f6806141f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -128,6 +128,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint dlsch->Kmimo = Kmimo; dlsch->Mdlharq = Mdlharq; dlsch->Nsoft = Nsoft; + dlsch->Mlimit = 4; dlsch->max_ldpc_iterations = max_ldpc_iterations; for (i=0; inrUE_config; //uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value; uint8_t nb_re_dmrs = 6; //(dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4; @@ -254,22 +255,22 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if (!dlsch_llr) { printf("dlsch_decoding.c: NULL dlsch_llr pointer\n"); - return(dlsch->max_ldpc_iterations); + return(dlsch->max_ldpc_iterations + 1); } if (!harq_process) { printf("dlsch_decoding.c: NULL harq_process pointer\n"); - return(dlsch->max_ldpc_iterations); + return(dlsch->max_ldpc_iterations + 1); } if (!frame_parms) { printf("dlsch_decoding.c: NULL frame_parms pointer\n"); - return(dlsch->max_ldpc_iterations); + return(dlsch->max_ldpc_iterations + 1); } /*if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) { printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx); - return(dlsch->max_ldpc_iterations); + return(dlsch->max_ldpc_iterations + 1); }*/ /*if (harq_process->harq_ack.ack != 2) { @@ -282,13 +283,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, /* if (nb_rb > frame_parms->N_RB_DL) { printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb); - return(max_ldpc_iterations); + return(max_ldpc_iterations + 1); }*/ /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]]; if (harq_pid >= 8) { printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid); - return(max_ldpc_iterations); + return(max_ldpc_iterations + 1); } */ @@ -299,7 +300,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->TBS = nr_compute_tbs(harq_process->mcs,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl); A = harq_process->TBS; - ret = dlsch->max_ldpc_iterations; + ret = dlsch->max_ldpc_iterations + 1; harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl); G = harq_process->G; @@ -447,7 +448,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, stop_meas(dlsch_rate_unmatching_stats); #endif LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n"); - return(dlsch->max_ldpc_iterations); + return(dlsch->max_ldpc_iterations + 1); } else { #if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); @@ -522,12 +523,12 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - printf("Segment %d CRC OK\n",r); - ret = 2; + printf("\x1B[34m" "Segment %d CRC OK\n",r); + ret = no_iteration_ldpc; } else { - printf("CRC NOK\n"); - ret = 1+dlsch->max_ldpc_iterations; + printf("\x1B[33m" "CRC NOK\n"); + ret = 1 + dlsch->max_ldpc_iterations; } nb_total_decod++; @@ -535,8 +536,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, nb_error_decod++; } - ret=no_iteration_ldpc; - //if (!nb_total_decod%10000){ //printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); //} @@ -561,6 +560,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, stop_meas(dlsch_turbo_decoding_stats); #endif } + + /*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f dlsch_turbo_decoding_stats %5.3f \n", harq_process->C, @@ -593,21 +594,21 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->harq_ack.harq_id = harq_pid; harq_process->harq_ack.send_harq_status = 1; harq_process->errors[harq_process->round]++; - harq_process->round++; - + // harq_process->round++; // [hna] uncomment this line when HARQ is implemented // printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); - if (harq_process->round >= dlsch->Mdlharq) { + if (harq_process->round >= dlsch->Mlimit) { harq_process->status = SCH_IDLE; harq_process->round = 0; } + if(is_crnti) { LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS); } - return((1+dlsch->max_ldpc_iterations)); + return((1 + dlsch->max_ldpc_iterations)); } else { #if UE_DEBUG_TRACE LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", @@ -619,6 +620,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->harq_ack.ack = 1; harq_process->harq_ack.harq_id = harq_pid; harq_process->harq_ack.send_harq_status = 1; + //LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n", // phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs); @@ -1145,14 +1147,14 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, // printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); - if (harq_process->round >= dlsch->Mdlharq) { + if (harq_process->round >= dlsch->Mlimit) { harq_process->status = SCH_IDLE; harq_process->round = 0; } if(is_crnti) { LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", - phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS); + phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS); } return((1+dlsch->max_ldpc_iterations)); @@ -1634,7 +1636,6 @@ void *nr_dlsch_decoding_process(void *arg) proc->decoder_thread_available = 1; //proc->decoder_main_available = 0; - } void *dlsch_thread(void *arg) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 167d7cfbc5..53c6615dbd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -2397,7 +2397,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, //if ((frame_parms->N_RB_DL&1) == 0){ // even number of RBs - for (rb=start_rb;rb=frame_parms->ofdm_symbol_size) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index e479c7cc34..86b551435e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -372,6 +372,8 @@ typedef struct { uint8_t max_ldpc_iterations; /// number of iterations used in last turbo decoding uint8_t last_iteration_cnt; + /// Maximum number of HARQ rounds + uint8_t Mlimit; } NR_UE_DLSCH_t; typedef enum {format0_0, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 73b66c539f..29f7939103 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -3384,7 +3384,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1); - for (m=s0;m<=s1;m++) { + for (m = s0; m < (s1 + s0); m++) { if (m==s0) nr_pdsch_channel_estimation(ue, diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index b6edec1dc9..4f515946d6 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -93,7 +93,7 @@ int main(int argc, char **argv) //int freq_offset; // int subframe_offset; // char fname[40], vname[40]; - int trial,n_trials=1,n_errors=0; + int trial, n_trials = 1, n_errors = 0, n_false_positive = 0; //int n_errors2, n_alamouti; uint8_t transmission_mode = 1,n_tx=1,n_rx=1; uint16_t Nid_cell=0; @@ -113,7 +113,7 @@ int main(int argc, char **argv) //double pbch_sinr; //int pbch_tx_ant; - int N_RB_DL=273,mu=1; + int N_RB_DL=106,mu=1; uint16_t ssb_periodicity = 10; @@ -371,7 +371,6 @@ int main(int argc, char **argv) phy_init_nr_gNB(gNB,0,0); mac_top_init_gNB(); - double fs,bw; if (mu == 1 && N_RB_DL == 217) { @@ -484,7 +483,15 @@ int main(int argc, char **argv) UE_mac->if_module = nr_ue_if_module_init(0); + + unsigned int available_bits; + unsigned char *estimated_output_bit; + unsigned char *test_input_bit; + unsigned int errors_bit = 0; + uint32_t errors_scrambling = 0; + test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); + estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); // generate signal if (input_fd==NULL) { @@ -633,81 +640,171 @@ int main(int argc, char **argv) nr_ue_phy_config_request(&UE_mac->phy_config); - for (SNR=snr0; SNRnb_antennas_rx; aa++) { - ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } - if (n_trials==1) { - LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0],frame_length_complex_samples,1,1); - if (UE->frame_parms.nb_antennas_rx>1) - LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_length_complex_samples,1,1); + if (n_trials == 1) { + + LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1); + if (UE->frame_parms.nb_antennas_rx>1) + LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1); + } + if (UE->is_synchronized == 0) { - UE_nr_rxtx_proc_t proc={0}; - ret = nr_initial_sync(&proc, UE, normal_txrx,1); - printf("nr_initial_sync1 returns %d\n",ret); - if (ret<0) n_errors++; - } - else { - UE->rx_offset=0; - UE_proc.frame_rx = frame; - UE_proc.nr_tti_rx= slot; - UE_proc.subframe_rx = slot; + UE_nr_rxtx_proc_t proc = {0}; + ret = nr_initial_sync(&proc, UE, normal_txrx, 1); + printf("nr_initial_sync1 returns %d\n", ret); - nr_ue_scheduled_response(&UE_mac->scheduled_response); + if (ret < 0) + n_errors++; - printf("Running phy procedures UE RX %d.%d\n",frame,slot); + } else { // UE->is_synchronized != 0 - phy_procedures_nrUE_RX(UE, - &UE_proc, - 0, - do_pdcch_flag, - normal_txrx); + UE->rx_offset = 0; + UE_proc.frame_rx = frame; + UE_proc.nr_tti_rx = slot; + UE_proc.subframe_rx = slot; - if (n_trials==1) { - LOG_M("rxsigF0.m","rxsF0", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0],slot_length_complex_samples_no_prefix,1,1); - if (UE->frame_parms.nb_antennas_rx>1) - LOG_M("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[1],slot_length_complex_samples_no_prefix,1,1); - } + nr_ue_scheduled_response(&UE_mac->scheduled_response); - if (UE_mac->dl_config_request.number_pdus==0) n_errors++; //if (UE->dci_ind.number_of_dcis==0) n_errors++; - } - } //noise trials + printf("Running phy procedures UE RX %d.%d\n", frame, slot); - printf("SNR %f : n_errors (negative CRC) = %d/%d\n", SNR,n_errors,n_trials); + phy_procedures_nrUE_RX(UE, + &UE_proc, + 0, + do_pdcch_flag, + normal_txrx); + + if (n_trials == 1) { + + LOG_M("rxsigF0.m","rxsF0", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0], slot_length_complex_samples_no_prefix, 1, 1); + if (UE->frame_parms.nb_antennas_rx > 1) + LOG_M("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[1], slot_length_complex_samples_no_prefix, 1, 1); + + } + + if (UE_mac->dl_config_request.number_pdus == 0) + n_errors++; + + //---------------------------------------------------------- + //---------------------- count errors ---------------------- + //---------------------------------------------------------- + + NR_gNB_DLSCH_t *gNB_dlsch = gNB->dlsch[0][0]; + + NR_UE_DLSCH_t *dlsch0 = UE->dlsch[UE->current_thread_id[UE_proc.nr_tti_rx]][0][0]; + int harq_pid = dlsch0->current_harq_pid; + NR_DL_UE_HARQ_t *UE_harq_process = dlsch0->harq_processes[harq_pid]; + + NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE->current_thread_id[UE_proc.nr_tti_rx]]; + int16_t *UE_llr = pdsch_vars[0]->llr[0]; + + nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = gNB_dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; + uint32_t TBS = rel15.transport_block_size; + uint16_t length_dmrs = 1; + uint16_t nb_rb = rel15.n_prb; + uint8_t nb_re_dmrs = rel15.nb_re_dmrs; + uint8_t mod_order = rel15.modulation_order; + uint8_t nb_symb_sch = rel15.nb_symbols; + + available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15.nb_layers); + + printf("\n"); + printf("available_bits = %d\n",available_bits); + + for (i = 0; i < available_bits; i++) { + + if(((gNB_dlsch->harq_processes[harq_pid]->f[i] == 0) && (UE_llr[i] <= 0)) || + ((gNB_dlsch->harq_processes[harq_pid]->f[i] == 1) && (UE_llr[i] >= 0))) + { + if(errors_scrambling == 0) { + printf("\n"); + printf("First bit in error in unscrambling = %d\n",i); + } + errors_scrambling++; + } + + } + + for (i = 0; i < TBS; i++) { + + estimated_output_bit[i] = (UE_harq_process->b[i/8] & (1 << (i & 7))) >> (i & 7); + test_input_bit[i] = (gNB_dlsch->harq_processes[harq_pid]->b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments + + if (estimated_output_bit[i] != test_input_bit[i]) { + if(errors_bit == 0) + printf("First bit in error in decoding = %d\n",i); + errors_bit++; + } + + } + + //////////////////////////////////////////////////////////// + + if (errors_scrambling > 0) { + if (n_trials == 1) + printf("errors_scrambling = %d (trial %d)\n", errors_scrambling, trial); + } + + if (errors_bit > 0) { + n_false_positive++; + if (n_trials == 1) + printf("errors_bit = %d (trial %d)\n", errors_bit, trial); + } + + printf("\n"); + + } // if (UE->is_synchronized == 0) + + } // noise trials + + printf("*****************************************\n"); + printf("SNR %f, (false positive %f)\n", SNR, + (float) n_false_positive / (float) n_trials); + printf("*****************************************\n"); + printf("\n"); + + if (errors_bit == 0) { + printf("PDSCH test OK\n"); + printf("\n"); + } + + printf("SNR %f : n_errors (negative CRC) = %d/%d\n", SNR, n_errors, n_trials); + printf("\n"); if ((float)n_errors/(float)n_trials <= target_error_rate) { printf("PDCCH test OK\n"); break; } - if (n_trials==1) + if (n_trials == 1) break; } // NSR - for (i=0; i<2; i++) { + for (i = 0; i < 2; i++) { free(s_re[i]); free(s_im[i]); free(r_re[i]); @@ -720,7 +817,9 @@ int main(int argc, char **argv) free(r_re); free(r_im); free(txdata); - + free(test_input_bit); + free(estimated_output_bit); + if (output_fd) fclose(output_fd); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index b6b0a41924..b825b528ac 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -33,7 +33,6 @@ #include "mac_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_dci.h" - extern RAN_CONTEXT_t RC; /*Scheduling of DLSCH with associated DCI in common search space @@ -296,8 +295,15 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, TX_req->pdu_length = dlsch_pdu_rel15->transport_block_size; TX_req->pdu_index = nr_mac->pdu_index[CC_id]++; TX_req->num_segments = 1; - TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0]; + // HOT FIX for all zero pdu problem + // ------------------------------------------------------------------------------------------------ + for(int i = 0; i < dlsch_pdu_rel15->transport_block_size/8; i++) { + ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i] = (unsigned char) rand(); + } + // ------------------------------------------------------------------------------------------------ + + TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0]; TX_req->segments[0].segment_length = dlsch_pdu_rel15->transport_block_size+2; nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; nr_mac->TX_req[CC_id].sfn_sf = sfn_sf;