diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index b361f6389ba3a60295e26ab35a6834b06727ba83..1f5109e49e5abb9d189c1331b7edebbd073ecaa9 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2534,8 +2534,13 @@ target_link_libraries(polartest SIMU PHY PHY_NR PHY_COMMON m ${ATLAS_LIBRARIES}) add_executable(ldpctest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c) target_link_libraries(ldpctest SIMU PHY PHY_NR m ${ATLAS_LIBRARIES}) -add_executable(nr_pbchsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c ) -target_link_libraries(nr_pbchsim -Wl,--start-group UTIL SIMU PHY PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB ${CONFIG_LIBRARIES} -Wl,--end-group m pthread dl ${ATLAS_LIBRARIES}) +add_executable(nr_pbchsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c + ${CONFIG_SOURCES}) +target_link_libraries(nr_pbchsim -Wl,--start-group UTIL SIMU PHY PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB ${CONFIG_LIBRARIES} -Wl,--end-group m pthread dl rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES}) + +add_executable(nr_dlschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c + ${CONFIG_SOURCES}) +target_link_libraries(nr_dlschsim -Wl,--start-group UTIL SIMU PHY PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB ${CONFIG_LIBRARIES} -Wl,--end-group m pthread dl rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES}) foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim) diff --git a/openair1/PHY/CODING/nr_compute_tbs.c b/openair1/PHY/CODING/nr_compute_tbs.c index ddb82fed048439af27e83df2466e6efa30f42d28..c9165e3867f1055c4084e7ba3e051510d8a1581f 100644 --- a/openair1/PHY/CODING/nr_compute_tbs.c +++ b/openair1/PHY/CODING/nr_compute_tbs.c @@ -28,35 +28,8 @@ #define INDEX_MAX_TBS_TABLE (93) //Table 5.1.3.1-1 -uint16_t Mcsindextable1[29][3] = {{2,120,0.2344}, - {2,157,0.3066}, - {2,193,0.3770}, - {2,251,0.4902}, - {2,308,0.6016}, - {2,379,0.7402}, - {2,449,0.8770}, - {2,526,1.0273}, - {2,602,1.1758}, - {2,679,1.3262}, - {4,340,1.3281}, - {4,378,1.4766}, - {4,434,1.6953}, - {4,490,1.9141}, - {4,553,2.1602}, - {4,616,2.4063}, - {4,658,2.5703}, - {6,438,2.5664}, - {6,466,2.7305}, - {6,517,3.0293}, - {6,567,3.3223}, - {6,616,3.6094}, - {6,666,3.9023}, - {6,719,4.2129}, - {6,772,4.5234}, - {6,822,4.8164}, - {6,873,5.1152}, - {6,910,5.3320}, - {6,948,5.5547}}; +uint16_t Mcsindextable1[29][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616}, + {4,658},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}}; //Table 5.1.2.2-2 uint16_t Tbstable_nr[INDEX_MAX_TBS_TABLE] = {24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,208,224,240,256,272,288,304,320,336,352,368,384,408,432,456,480,504,528,552,576,608,640,672,704,736,768,808,848,888,928,984,1032,1064,1128,1160,1192,1224,1256,1288,1320,1352,1416,1480,1544,1608,1672,1736,1800,1864,1928,2024,2088,2152,2216,2280,2408,2472,2536,2600,2664,2728,2792,2856,2976,3104,3240,3368,3496,3624,3752,3824}; @@ -67,8 +40,9 @@ uint32_t nr_compute_tbs(uint8_t mcs, uint16_t length_dmrs, uint8_t Nl) { - uint16_t nbp_re, nb_re, nb_dmrs_prb, nb_rb_oh, Ninfo,Np_info,n,Qm,R,C; - uint32_t nr_tbs; + uint16_t nbp_re, nb_re, nb_dmrs_prb, nb_rb_oh,Qm,R; + uint32_t nr_tbs=0; + double Ninfo,Np_info,n,C; nb_rb_oh = 0; //set to 0 if not configured by higher layer Qm = Mcsindextable1[mcs][0]; @@ -80,17 +54,17 @@ uint32_t nr_compute_tbs(uint8_t mcs, nb_re = min(156, nbp_re) * nb_rb; // Intermediate number of information bits - Ninfo = (nb_re * R * Qm * Nl)/1024; + Ninfo = (double)((nb_re * R * Qm * Nl)/1024); //printf("Ninfo %d nbp_re %d nb_re %d Qm %d, R %d\n", Ninfo, nbp_re, nb_re, Qm, R); if (Ninfo <=3824) { n = max(3, floor(log2(Ninfo)) - 6); - Np_info = max(24, pow(n,2) * floor(Ninfo/pow(n,2))); + Np_info = max(24, pow(2,n) * floor(Ninfo/pow(2,n))); for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) { - if (Tbstable_nr[i] >= Np_info){ + if ((double)Tbstable_nr[i] >= Np_info){ nr_tbs = Tbstable_nr[i]; break; } @@ -98,19 +72,21 @@ uint32_t nr_compute_tbs(uint8_t mcs, } else { n = floor(log2(Ninfo-24)) - 5; - Np_info = max(3840, pow(n,2) * round((Ninfo - 24)/pow(n,2))); + Np_info = max(3840, pow(2,n) * round((Ninfo - 24)/pow(2,n))); - if (R <= 1024/4) { + if (R <= 256) { //1/4 C = ceil( (Np_info + 24)/3816 ); - nr_tbs = 8 * C * ceil( (Np_info + 24)/(8*C) ) - 24; + nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24); } else { if (Np_info > 8424){ C = ceil( (Np_info + 24)/8424 ); - nr_tbs = 8 * C * ceil( (Np_info + 24)/(8*C) ) - 24; + nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24); + } + else { + nr_tbs = (uint32_t)(8 * ceil( (Np_info + 24)/8 ) - 24); + //printf("n %f Np_info %f pow %f ceil %f \n",n, Np_info,pow(2,6),ceil( (Np_info + 24)/8 )); } - else - nr_tbs = 8 * ceil( (Np_info + 24)/8 ) - 24; } diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c index 19df32c246bfce72d6680992edd0e305f9b837e1..245f3b9b751ffc5c430eab8595737d66ac5e2881 100644 --- a/openair1/PHY/CODING/nr_rate_matching.c +++ b/openair1/PHY/CODING/nr_rate_matching.c @@ -54,7 +54,6 @@ void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f) uint32_t EQm; EQm = E/Qm; - memset(e,0,E*sizeof(uint8_t)); for (int j = 0; j< EQm; j++){ for (int i = 0; i< Qm; i++){ @@ -108,7 +107,7 @@ uint32_t nr_rate_matching_ldpc(uint8_t Ilbrm, ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z; #ifdef RM_DEBUG - printf("nr_rate_matching: E %d, k0 %d \n",E,ind); + printf("nr_rate_matching: E %d, k0 %d Cprime %d modcprime %d\n",E,ind, Cprime,((G/(Nl*Qm))%Cprime)); #endif e2 = e; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index bba325ff08658bb028cc7b904a5d42e0fa609185..a19900a8ba807b9344af53031fbc87f24dc9545a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -53,5 +53,15 @@ uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx); /** \brief Computes available bits G. @param nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs */ -uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs,uint8_t Qm); +uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs,uint8_t Qm, uint8_t Nl); + +int nr_dlsch_encoding(PHY_VARS_gNB *gNB, + unsigned char *a, + uint16_t nb_symb_sch, + NR_gNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *i_stats); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index d9a424121d31a18b19eac6ccc548fa3eb5c4c899..c2f51388bd20144386fbade88598b31f4fcb3106 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -162,10 +162,10 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t if (dlsch->harq_processes[i]) { bzero(dlsch->harq_processes[i],sizeof(NR_DL_gNB_HARQ_t)); // dlsch->harq_processes[i]->first_tx=1; - dlsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + dlsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling); if (dlsch->harq_processes[i]->b) { - bzero(dlsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + bzero(dlsch->harq_processes[i]->b,MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling); } else { printf("Can't get b\n"); exit_flag=1; @@ -245,7 +245,7 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) int nr_dlsch_encoding(PHY_VARS_gNB *gNB, unsigned char *a, - uint8_t num_pdcch_symbols, + uint16_t nb_symb_sch, NR_gNB_DLSCH_t *dlsch, int frame, uint8_t subframe, @@ -272,9 +272,10 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, uint32_t E; uint8_t Ilbrm = 0; uint32_t Tbslbrm = 950984; //max tbs - uint16_t nb_symb_sch =2; + //uint16_t nb_symb_sch =12; uint8_t nb_re_dmrs = 6; uint16_t length_dmrs = 1; + uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); @@ -284,9 +285,10 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, A = dlsch->harq_processes[harq_pid]->TBS; //printf("Encoder: A: %d frame.subframe %d.%d \n",A, frame,subframe); - mod_order = get_nr_Qm(dlsch->harq_processes[harq_pid]->mcs); + mod_order = nr_get_Qm(dlsch->harq_processes[harq_pid]->mcs,1); - G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order); + G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,dlsch->harq_processes[harq_pid]->Nl); + printf("dlsch coding A %d G %d mod_order %d\n", A,G, mod_order); Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, dlsch->harq_processes[harq_pid]->Nl); @@ -303,12 +305,12 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, printf("\n"); */ // Add 24-bit crc (polynomial A) to payload - crc = crc24a(a, - A)>>8; + crc = crc24a(a,A)>>8; a[A>>3] = ((uint8_t*)&crc)[2]; a[1+(A>>3)] = ((uint8_t*)&crc)[1]; a[2+(A>>3)] = ((uint8_t*)&crc)[0]; //printf("CRC %x (A %d)\n",crc,A); + //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]); dlsch->harq_processes[harq_pid]->B = A+24; // dlsch->harq_processes[harq_pid]->b = a; @@ -330,37 +332,44 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, BG = 2; } - //printf("Encoder: B %d F %d \n",dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->F); - Kr = dlsch->harq_processes[harq_pid]->K; //Kr_bytes = Kr>>3; start_meas(te_stats); for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) { d_tmp[r] = &dlsch->harq_processes[harq_pid]->d[r][0]; + channel_input[r] = &dlsch->harq_processes[harq_pid]->d[r][0]; #ifdef DEBUG_DLSCH_CODING + printf("Encoder: B %d F %d \n",dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->F); printf("start ldpc encoder segment %d/%d\n",r,dlsch->harq_processes[harq_pid]->C); printf("input %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->c[r][0], dlsch->harq_processes[harq_pid]->c[r][1], dlsch->harq_processes[harq_pid]->c[r][2],dlsch->harq_processes[harq_pid]->c[r][3], dlsch->harq_processes[harq_pid]->c[r][4]); - /*for (int cnt =0 ; cnt < 22*(*pz); cnt ++){ + for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){ printf("%d ", dlsch->harq_processes[harq_pid]->c[r][cnt]); - }*/ + } + printf("\n"); #endif - //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],&dlsch->harq_processes[harq_pid]->d[r][96],Kr,1,3,0); - //ldpc_encoder((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],&dlsch->harq_processes[harq_pid]->d[r][96],Kr,1,3); - //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][96],Kr,1,3,NULL,NULL,NULL,NULL); + //&dlsch->harq_processes[harq_pid]->d[r][0] //channel_input[r] + //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],&dlsch->harq_processes[harq_pid]->d[r][0],Kr,1,3,0); + ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],Kr,BG,0); + //ldpc_encoder((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],&dlsch->harq_processes[harq_pid]->d[r][0],Kr,1,3); + //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],Kr,1,3,NULL,NULL,NULL,NULL); } - ldpc_encoder_optim_8seg(dlsch->harq_processes[harq_pid]->c,d_tmp,Kr,1,3,dlsch->harq_processes[harq_pid]->C,NULL,NULL,NULL,NULL); - stop_meas(te_stats); - /*printf("end ldpc encoder -- output\n"); + //for (int i=0;i<68*384;i++) + // printf("channel_input[%d]=%d\n",i,channel_input[i]); - printf("output %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->d[r][0], dlsch->harq_processes[harq_pid]->d[r][1], dlsch->harq_processes[harq_pid]->d[r][2],dlsch->harq_processes[harq_pid]->d[r][3], dlsch->harq_processes[harq_pid]->d[r][4]); - for (int cnt =0 ; cnt < 66*(*pz); cnt ++){ - printf("%d \n", dlsch->harq_processes[harq_pid]->d[r][cnt]); - } - printf("\n");*/ + + /*printf("output %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->d[0][0], dlsch->harq_processes[harq_pid]->d[0][1], dlsch->harq_processes[harq_pid]->d[r][2],dlsch->harq_processes[harq_pid]->d[0][3], dlsch->harq_processes[harq_pid]->d[0][4]); + for (int cnt =0 ; cnt < 66*(*pz); cnt ++){ + printf("%d \n", dlsch->harq_processes[harq_pid]->d[0][cnt]); + } + printf("\n");*/ + + //ldpc_encoder_optim_8seg(dlsch->harq_processes[harq_pid]->c,d_tmp,Kr,1,3,dlsch->harq_processes[harq_pid]->C,NULL,NULL,NULL,NULL); + stop_meas(te_stats); + //printf("end ldpc encoder -- output\n"); #ifdef DEBUG_DLSCH_CODING write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4); @@ -383,7 +392,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, printf("rvidx in encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx); #endif - r_offset += nr_rate_matching_ldpc(Ilbrm, + E = nr_rate_matching_ldpc(Ilbrm, Tbslbrm, BG, *pz, @@ -396,18 +405,25 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, dlsch->harq_processes[harq_pid]->Nl, r); - +#ifdef DEBUG_DLSCH_CODING + for (int i =0; i<16; i++) + printf("output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i], r_offset); +#endif stop_meas(rm_stats); - if (r==0) E=r_offset; - start_meas(i_stats); nr_interleaving_ldpc(E, - dlsch->harq_processes[harq_pid]->Qm, + mod_order, dlsch->harq_processes[harq_pid]->e+r_offset, dlsch->harq_processes[harq_pid]->f+r_offset); stop_meas(i_stats); + r_offset += E; +#ifdef DEBUG_DLSCH_CODING + for (int i =0; i<16; i++) + printf("output interleaving f[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->f[i+r*r_offset], r_offset); +#endif + #ifdef DEBUG_DLSCH_CODING if (r==dlsch->harq_processes[harq_pid]->C-1) diff --git a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c index 14b06d56ce413008c60139c038ef857be509e36f..dcb3fe1571629d7b7b48207950206c489b6373f7 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c @@ -80,8 +80,8 @@ uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) { } } -uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm) { +uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) { uint32_t G; - G = ((12*nb_symb_sch)-(nb_re_dmrs*length_dmrs))*nb_rb*Qm; + G = ((12*nb_symb_sch)-(nb_re_dmrs*length_dmrs))*nb_rb*Qm*Nl; return(G); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index e1906011a9133c5287a6e866d953986a82d9ec87..1bd7f6af95dedbfe4d728abb4b8df6c22ac8a107 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -173,6 +173,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, NR_UE_DLSCH_t *dlsch, NR_DL_UE_HARQ_t *harq_process, uint32_t frame, + uint16_t nb_symb_sch, uint8_t nr_tti_rx, uint8_t harq_pid, uint8_t is_crnti, @@ -189,7 +190,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint32_t ret,offset; int32_t no_iteration_ldpc; //short dummy_w[MAX_NUM_DLSCH_SEGMENTS][3*(8448+64)]; - uint32_t r,r_offset=0,Kr,Kr_bytes,K_bytes_F,err_flag=0; + uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0; uint8_t crc_type; t_nrLDPC_dec_params decParams; t_nrLDPC_dec_params* p_decParams = &decParams; @@ -203,8 +204,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint8_t kb, kc; uint8_t Ilbrm = 0; uint32_t Tbslbrm = 950984; - uint16_t nb_rb = 106; //to update - uint16_t nb_symb_sch = 2; + uint16_t nb_rb = 30; //to update + //uint16_t nb_symb_sch = 12; uint8_t nb_re_dmrs = 6; uint16_t length_dmrs = 1; @@ -214,6 +215,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, __m128i *pv = (__m128i*)&z; __m128i *pl = (__m128i*)&l; + //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0]; + if (!dlsch_llr) { printf("dlsch_decoding.c: NULL dlsch_llr pointer\n"); return(dlsch->max_ldpc_iterations); @@ -229,15 +232,15 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return(dlsch->max_ldpc_iterations); } - if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-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); - } + }*/ - if (harq_process->harq_ack.ack != 2) { + /*if (harq_process->harq_ack.ack != 2) { LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n", phy_vars_ue->Mod_id, nr_tti_rx, harq_process->harq_ack.ack); - } + }*/ // nb_rb = dlsch->nb_rb; @@ -254,6 +257,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } */ + nb_rb = harq_process->nb_rb; + harq_process->trials[harq_process->round]++; harq_process->TBS = nr_compute_tbs(harq_process->mcs,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl); @@ -261,11 +266,10 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, A = harq_process->TBS; ret = dlsch->max_ldpc_iterations; - harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm); + 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; - //get_G(frame_parms,nb_rb,dlsch->rb_alloc,mod_order,num_pdcch_symbols,phy_vars_ue->frame,subframe); - // printf("DLSCH Decoding, harq_pid %d Ndi %d\n",harq_pid,harq_process->Ndi); + //printf("DLSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d \n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch); if (harq_process->round == 0) { // This is a new packet, so compute quantities regarding segmentation @@ -278,10 +282,12 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, &harq_process->Z, &harq_process->F); p_decParams->Z = harq_process->Z; - //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z); - //if (!frame%100) - //printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl); +#ifdef DEBUG_DLSCH_DECODING + printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z); + if (!frame%100) + printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl); +#endif } kb = harq_process->K/harq_process->Z; @@ -322,7 +328,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return((1+dlsch->max_ldpc_iterations)); } #ifdef DEBUG_DLSCH_DECODING - printf("Segmentation: C %d, Cminus %d, Kminus %d, K %d\n",harq_process->C,harq_process->Cminus,harq_process->Kminus,harq_process->K); + printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); #endif opp_enabled=1; @@ -336,6 +342,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, for (r=0; r<harq_process->C; r++) { + printf("start rx segment %d\n",r); + #if UE_TIMING_TRACE start_meas(dlsch_rate_unmatching_stats); #endif @@ -380,11 +388,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } r_offset += E; - /* - printf("Subblock deinterleaving, d %p w %p\n", - harq_process->d[r], - harq_process->w); - */ + //for (int i =0; i<16; i++) + // printf("rx output ratematching w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); + #if UE_TIMING_TRACE start_meas(dlsch_deinterleaving_stats); #endif @@ -393,6 +399,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->d[r], harq_process->w[r]); + //for (int i =0; i<16; i++) + // printf("rx output interleaving d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); + #if UE_TIMING_TRACE stop_meas(dlsch_deinterleaving_stats); #endif @@ -433,23 +442,20 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, //LOG_E(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A); //printf("harq process dr iteration %d\n", p_decParams->numMaxIter); - //66*p_decParams->Z - //if (A < 1000){ for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){ - inv_d[cnt] = (-1)*harq_process->d[r][cnt]; + inv_d[cnt] = (1)*harq_process->d[r][cnt]; } - //} - /*for (int cnt =0; cnt < 8; cnt++){ - printf("dr %d inv_d %d \n", harq_process->d[r][96+cnt], inv_d[cnt]); + /*for (int cnt =0; cnt < 16; cnt++){ + printf("dr %d inv_d %d \n", harq_process->d[r][cnt], inv_d[cnt]); } - printf(" \n");*/ + printf(" \n"); - /*printf("end dr \n"); + printf("end dr \n"); for (int cnt =(50*p_decParams->Z-16) ; cnt < 50*p_decParams->Z; cnt++){ - printf("%d ", harq_process->d[r][96+cnt]); + printf("%d ", harq_process->d[r][cnt]); } printf(" \n");*/ @@ -457,12 +463,12 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, //memset(pl,0,2*p_decParams->Z*sizeof(int8_t)); memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t)); - for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++) + for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F+((2*p_decParams->Z)>>3); i++, j++) { pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); } - for (i=Kr_bytes, j = K_bytes_F; i < ((kc*p_decParams->Z)>>3); i++, j++) + for (i=Kr_bytes+((2*p_decParams->Z)>>3),j=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) { pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); } @@ -497,9 +503,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, else { ret=2; } - if (!nb_total_decod%10000){ + //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); - } + //} //else //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); @@ -512,7 +518,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, #ifdef DEBUG_DLSCH_DECODING printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]); printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret); - write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); + //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); #endif diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index b16e5a97de47c271c78dace48fbd863ad6256a7d..ec86a5c470fdca865c38e3b0d22c4d9e565baa9c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -999,6 +999,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, NR_UE_DLSCH_t *dlsch, NR_DL_UE_HARQ_t *harq_process, uint32_t frame, + uint16_t nb_symb_sch, uint8_t nr_tti_rx, uint8_t harq_pid, uint8_t is_crnti, diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index 969fe1b1e547300067446adda0b032f20c6cb49e..174eadf95bbdfb4854c05e4a0a35a06df8087e08 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -57,7 +57,7 @@ * *********************************************************************/ -#define DBG_PSS_NR +//#define DBG_PSS_NR void *get_idft(int ofdm_symbol_size) { diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 2a6911106d6741a39c4761df03f576d3887a7887..2f63b9843f325be755793f6fcd60dde3cf4bf734 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -5761,7 +5761,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); #endif - /*ue_dlsch_procedures(ue, + nr_ue_dlsch_procedures(ue, proc, eNB_id, PDSCH, @@ -5769,7 +5769,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][1], &ue->dlsch_errors[eNB_id], mode, - abstraction_flag);*/ + abstraction_flag); #if UE_TIMING_TRACE stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); #if DISABLE_LOG_X diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c new file mode 100644 index 0000000000000000000000000000000000000000..e435d87de79b5f7f95c2768b104625bc519bb5e8 --- /dev/null +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -0,0 +1,668 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include <string.h> +#include <math.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/mman.h> + +#include "SIMULATION/TOOLS/sim.h" +#include "SIMULATION/RF/rf.h" +#include "PHY/types.h" +#include "PHY/defs_nr_common.h" +#include "PHY/defs_nr_UE.h" +#include "PHY/defs_gNB.h" +#include "PHY/NR_TRANSPORT/nr_dlsch.h" + +#include "PHY/INIT/phy_init.h" +#include "SCHED_NR/sched_nr.h" + +#include "PHY/MODULATION/modulation_common.h" +#include "common/config/config_load_configmodule.h" +#include "common/utils/LOG/log.h" +#include "UTIL/LISTS/list.h" +#include "common/ran_context.h" + +PHY_VARS_gNB *gNB; +PHY_VARS_NR_UE *UE; +RAN_CONTEXT_t RC; + + +double cpuf; + +// dummy functions +int nfapi_mode=0; +int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);} +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } + +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } + +int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } + +int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) {return(0);} + +uint32_t from_earfcn(int eutra_bandP,uint32_t dl_earfcn) {return(0);} +int32_t get_uldl_offset(int eutra_bandP) {return(0);} + +NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);} + +void exit_fun(const char *s) { exit(-1); } +//extern void init_eNB_afterRU(void); + +// needed for some functions +PHY_VARS_NR_UE * PHY_vars_UE_g[1][1]={NULL}; +uint16_t n_rnti=0x1234; + +char quantize(double D,double x,unsigned char B) +{ + double qxd; + short maxlev; + qxd = floor(x/D); + + maxlev = 1<<(B-1);//(char)(pow(2,B-1)); + + //printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev); + + if (qxd <= -maxlev) + qxd = -maxlev; + else if (qxd >= maxlev) + qxd = maxlev-1; + + return((char)qxd); +} + +int main(int argc, char **argv) +{ + + char c; + + int i,j,l,aa; + double sigma2, sigma2_dB=10,SNR,SNR_lin,snr0=-2.0,snr1=2.0; + double snr_step = 0.1; + uint8_t snr1set=0; + int **txdata; + double **s_re,**s_im,**r_re,**r_im; + double iqim = 0.0; + unsigned char pbch_pdu[6]; + // int sync_pos, sync_pos_slot; + // FILE *rx_frame_file; + FILE *output_fd = NULL; + uint8_t write_output_file=0; + //int result; + int freq_offset; + // int subframe_offset; + // char fname[40], vname[40]; + int trial,n_trials=1,n_errors,n_errors2,n_alamouti; + uint8_t transmission_mode = 1,n_tx=1,n_rx=1; + uint16_t Nid_cell=0; + + channel_desc_t *gNB2UE; + uint32_t nsymb,tx_lev,tx_lev1 = 0,tx_lev2 = 0; + uint8_t extended_prefix_flag=0; + int8_t interf1=-21,interf2=-21; + + FILE *input_fd=NULL,*pbch_file_fd=NULL; + char input_val_str[50],input_val_str2[50]; + + uint8_t frame_mod4,num_pdcch_symbols = 0; + uint16_t NB_RB=25; + + SCM_t channel_model=AWGN;//Rayleigh1_anticorr; + + double pbch_sinr; + int pbch_tx_ant; + uint8_t N_RB_DL=106,mu=1; + + unsigned char frame_type = 0; + unsigned char pbch_phase = 0; + + int frame=0,subframe=0; + int frame_length_complex_samples; + int frame_length_complex_samples_no_prefix; + NR_DL_FRAME_PARMS *frame_parms; + nfapi_nr_config_request_t *gNB_config; + + uint8_t Kmimo; + uint32_t Nsoft; + double sigma; + unsigned char qbits=8; + + int ret; + + cpuf = get_cpu_freq_GHz(); + + if ( load_configmodule(argc,argv) == 0) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + + logInit(); + randominit(0); + + while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:N:F:GR:dP:")) != -1) { + switch (c) { + case 'f': + write_output_file=1; + output_fd = fopen(optarg,"w"); + + if (output_fd==NULL) { + printf("Error opening %s\n",optarg); + exit(-1); + } + + break; + + case 'd': + frame_type = 1; + break; + + case 'g': + switch((char)*optarg) { + case 'A': + channel_model=SCM_A; + break; + + case 'B': + channel_model=SCM_B; + break; + + case 'C': + channel_model=SCM_C; + break; + + case 'D': + channel_model=SCM_D; + break; + + case 'E': + channel_model=EPA; + break; + + case 'F': + channel_model=EVA; + break; + + case 'G': + channel_model=ETU; + break; + + default: + msg("Unsupported channel model!\n"); + exit(-1); + } + + break; + + case 'i': + interf1=atoi(optarg); + break; + + case 'j': + interf2=atoi(optarg); + break; + + case 'n': + n_trials = atoi(optarg); + break; + + case 's': + snr0 = atof(optarg); + msg("Setting SNR0 to %f\n",snr0); + break; + + case 'S': + snr1 = atof(optarg); + snr1set=1; + msg("Setting SNR1 to %f\n",snr1); + break; + + /* + case 't': + Td= atof(optarg); + break; + */ + case 'p': + extended_prefix_flag=1; + break; + + /* + case 'r': + ricean_factor = pow(10,-.1*atof(optarg)); + if (ricean_factor>1) { + printf("Ricean factor must be between 0 and 1\n"); + exit(-1); + } + break; + */ + case 'x': + transmission_mode=atoi(optarg); + + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=6)) { + msg("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } + + break; + + case 'y': + n_tx=atoi(optarg); + + if ((n_tx==0) || (n_tx>2)) { + msg("Unsupported number of tx antennas %d\n",n_tx); + exit(-1); + } + + break; + + case 'z': + n_rx=atoi(optarg); + + if ((n_rx==0) || (n_rx>2)) { + msg("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } + + break; + + case 'N': + Nid_cell = atoi(optarg); + break; + + case 'R': + N_RB_DL = atoi(optarg); + break; + + case 'F': + input_fd = fopen(optarg,"r"); + + if (input_fd==NULL) { + printf("Problem with filename %s\n",optarg); + exit(-1); + } + + break; + + case 'P': + pbch_phase = atoi(optarg); + + if (pbch_phase>3) + printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); + + break; + + default: + case 'h': + printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", + argv[0]); + printf("-h This message\n"); + printf("-p Use extended prefix mode\n"); + printf("-d Use TDD\n"); + printf("-n Number of frames to simulate\n"); + printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); + printf("-t Delay spread for multipath channel\n"); + printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); + printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); + printf("-N Nid_cell\n"); + printf("-R N_RB_DL\n"); + printf("-O oversampling factor (1,2,4,8,16)\n"); + printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); + // printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); + printf("-f Output filename (.txt format) for Pe/SNR results\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); + exit (-1); + break; + } + } + + if (snr1set==0) + snr1 = snr0+10; + + gNB2UE = new_channel_desc_scm(n_tx, + n_rx, + channel_model, + 61.44e6, //N_RB2sampling_rate(N_RB_DL), + 40e6, //N_RB2channel_bandwidth(N_RB_DL), + 0, + 0, + 0); + + if (gNB2UE==NULL) { + msg("Problem generating channel model. Exiting.\n"); + exit(-1); + } + + RC.gNB = (PHY_VARS_gNB***) malloc(sizeof(PHY_VARS_gNB **)); + RC.gNB[0] = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *)); + RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB)); + gNB = RC.gNB[0][0]; + gNB_config = &gNB->gNB_config; + frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) + frame_parms->nb_antennas_tx = n_tx; + frame_parms->nb_antennas_rx = n_rx; + frame_parms->N_RB_DL = N_RB_DL; + + crcTableInit(); + nr_phy_config_request_sim(gNB); + phy_init_nr_gNB(gNB,0,0); + //init_eNB_afterRU(); + + frame_length_complex_samples = frame_parms->samples_per_subframe; + frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; + + s_re = malloc(2*sizeof(double*)); + s_im = malloc(2*sizeof(double*)); + r_re = malloc(2*sizeof(double*)); + r_im = malloc(2*sizeof(double*)); + txdata = malloc(2*sizeof(int*)); + + for (i=0; i<2; i++) { + + s_re[i] = malloc(frame_length_complex_samples*sizeof(double)); + bzero(s_re[i],frame_length_complex_samples*sizeof(double)); + s_im[i] = malloc(frame_length_complex_samples*sizeof(double)); + bzero(s_im[i],frame_length_complex_samples*sizeof(double)); + + r_re[i] = malloc(frame_length_complex_samples*sizeof(double)); + bzero(r_re[i],frame_length_complex_samples*sizeof(double)); + r_im[i] = malloc(frame_length_complex_samples*sizeof(double)); + bzero(r_im[i],frame_length_complex_samples*sizeof(double)); + + txdata[i] = malloc(frame_length_complex_samples*sizeof(int)); + bzero(r_re[i],frame_length_complex_samples*sizeof(int)); + + } + + if (pbch_file_fd!=NULL) { + load_pbch_desc(pbch_file_fd); + } + + for (int k=0; k<2; k++) { + // Create transport channel structures for 2 transport blocks (MIMO) + for (i=0; i<2; i++) { + gNB->dlsch[k][i] = new_gNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&gNB->frame_parms); + + if (!gNB->dlsch[k][i]) { + printf("Can't get eNB dlsch structures\n"); + exit(-1); + } + + gNB->dlsch[k][i]->rnti = n_rnti+k; + } + } + + + //configure UE + UE = malloc(sizeof(PHY_VARS_NR_UE)); + memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); + //phy_init_nr_top(frame_parms); + if (init_nr_ue_signal(UE, 1, 0) != 0) + { + printf("Error at UE NR initialisation\n"); + exit(-1); + } + //nr_init_frame_parms_ue(&UE->frame_parms); + //init_nr_ue_transport(UE, 0); + for (int sf = 0; sf < 2; sf++) { + for (i=0; i<2; i++) { + UE->dlsch[sf][0][i] = new_nr_ue_dlsch(Kmimo,8,Nsoft,5,N_RB_DL,0); + + if (!UE->dlsch[sf][0][i]) { + printf("Can't get ue dlsch structures\n"); + exit(-1); + } + + UE->dlsch[sf][0][i]->rnti = n_rnti; + } + } + + UE->dlsch_SI[0] = new_nr_ue_dlsch(1,1,Nsoft,5,N_RB_DL,0); + UE->dlsch_ra[0] = new_nr_ue_dlsch(1,1,Nsoft,5,N_RB_DL,0); + + + NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0]; + time_stats_t *rm_stats; + time_stats_t *te_stats; + time_stats_t *i_stats; + uint8_t is_crnti; + uint8_t llr8_flag; + unsigned char harq_pid = 0; //dlsch->harq_ids[subframe]; + unsigned int TBS = 8424; + unsigned int available_bits; + uint16_t nb_symb_sch =10; + uint8_t nb_re_dmrs = 6; + uint16_t length_dmrs = 1; + unsigned char mod_order; + uint16_t nb_rb = 106; + uint8_t Imcs=22; + uint8_t Nl=1; + uint8_t rvidx = 0; + + dlsch->harq_ids[subframe]= 0; + dlsch->harq_processes[0]->nb_rb = nb_rb; + dlsch->harq_processes[0]->mcs = Imcs; + dlsch->harq_processes[0]->Nl = Nl; + dlsch->harq_processes[0]->rvidx = rvidx; + + printf("dlschsim harqid %d nb_rb %d, mscs %d\n",dlsch->harq_ids[subframe], + dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->mcs,dlsch->harq_processes[0]->Nl); + + mod_order = nr_get_Qm(dlsch->harq_processes[0]->mcs,1); + available_bits = nr_get_G(dlsch->harq_processes[0]->nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,Nl); + TBS= nr_compute_tbs(Imcs,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs,Nl); + printf("available bits %d TBS %d mod_order %d\n",available_bits, TBS, mod_order); + + double *modulated_input = malloc16(sizeof(double) * 16*68*384); + short *channel_output_fixed = malloc16(sizeof( short) *16* 68*384); + short *channel_output_uncoded = malloc16(sizeof(unsigned short) *16* 68*384); + double errors_bit_uncoded=0; + unsigned char *estimated_output; + unsigned char *estimated_output_bit; + unsigned char *test_input_bit; + unsigned int errors_bit =0; + + test_input_bit = (unsigned char*) malloc16(sizeof(unsigned char) * 16*68*384); + estimated_output = (unsigned char*) malloc16(sizeof(unsigned char) * 16*68*384); + estimated_output_bit = (unsigned char*) malloc16(sizeof(unsigned char) * 16*68*384); + + NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[UE->current_thread_id[subframe]][0][0]; + NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid]; + harq_process->mcs = Imcs; + harq_process->Nl = Nl; + harq_process->nb_rb = nb_rb; + harq_process->Qm = mod_order; + harq_process->rvidx = rvidx; + printf("harq process ue mcs = %d Qm = %d\n", harq_process->mcs, harq_process->Qm); + + unsigned char *test_input; + test_input=(unsigned char *)malloc16(sizeof(unsigned char) * TBS/8); + for (i=0; i<TBS/8; i++) { + test_input[i]=(unsigned char) rand();} + + estimated_output = harq_process->b; + + //for (int i=0; i<TBS/8; i++) + // printf("test input[%d]=%d \n",i,test_input[i]); + + printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32)); + + // generate signal + if (input_fd==NULL) { + nr_dlsch_encoding(gNB, + test_input, + nb_symb_sch, + dlsch, + frame, + subframe, + rm_stats, + te_stats, + i_stats); + + } + + for (SNR=snr0;SNR<snr1;SNR+=snr_step) + { + + for (i = 0; i < available_bits; i++) { + #ifdef DEBUG_CODER + if ((i&0xf)==0) + printf("\ne %d..%d: ",i,i+15); + #endif + + //if (i<16) + // printf("encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]); + if (dlsch->harq_processes[0]->f[i]==0) + modulated_input[i]=1.0;///sqrt(2); //QPSK + else + modulated_input[i]=-1.0;///sqrt(2); + + //if (i<16) printf("modulated_input[%d] = %d\n",i,modulated_input[i]); + + //SNR =10; + SNR_lin = pow(10,SNR/10.0); + sigma = 1.0/sqrt(2*SNR_lin); + channel_output_fixed[i] = (short)quantize(sigma/4.0/4.0,modulated_input[i] + sigma*gaussdouble(0.0,1.0),qbits); + //channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0)); + //printf("llr[%d]=%d\n",i,channel_output_fixed[i]); + //printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]); + + + //channel_output_fixed[i] = (char)quantize(1,channel_output_fixed[i],qbits); + + //if (i<16) printf("channel_output_fixed[%d] = %d\n",i,channel_output_fixed[i]); + + //Uncoded BER + if (channel_output_fixed[i]<0) + channel_output_uncoded[i]=1; //QPSK demod + else + channel_output_uncoded[i]=0; + + if (channel_output_uncoded[i] != dlsch->harq_processes[harq_pid]->f[i]) + errors_bit_uncoded = errors_bit_uncoded + 1; + + } + + printf("errors bits uncoded %f\n", errors_bit_uncoded); + + + #ifdef DEBUG_CODER + printf("\n"); + exit(-1); + #endif + + nr_dlsch_decoding(UE, + channel_output_fixed, + &UE->frame_parms, + dlsch0_ue, + dlsch0_ue->harq_processes[0], + frame, + nb_symb_sch, + harq_pid, + is_crnti, + llr8_flag); + + //count errors + for (i=0; i<TBS; i++) + { + estimated_output_bit[i] = (estimated_output[i/8]&(1<<(i&7)))>>(i&7); + test_input_bit[i] = (test_input[i/8]&(1<<(i&7)))>>(i&7); // Further correct for multiple segments + if (estimated_output_bit[i] != test_input_bit[i]) + { + errors_bit = (errors_bit) + 1; + //printf("estimated bits error occurs @%d ",i); + } + } + + printf("\n errors_bit %d \n", errors_bit); + + printf("SNR %f, BER %f \n",SNR,(float)errors_bit/(float)n_trials/(float)TBS); + } + /*LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); + if (gNB->frame_parms.nb_antennas_tx>1) + LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);*/ + + //TODO: loop over slots + /*for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) { + if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) { + PHY_ofdm_mod(gNB->common_vars.txdataF[aa], + txdata[aa], + frame_parms->ofdm_symbol_size, + 12, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); + } else { + nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], + txdata[aa], + 14, + frame_parms); + } + } + + LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1); + if (gNB->frame_parms.nb_antennas_tx>1) + LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1); + + + for (i=0; i<frame_length_complex_samples; i++) { + for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) { + r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); + r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); + } + }*/ + + + for (i=0; i<2; i++) { + printf("gNB %d\n",i); + free_gNB_dlsch(gNB->dlsch[0][i]); + printf("UE %d\n",i); + free_nr_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]); + } + + for (i=0; i<2; i++) { + free(s_re[i]); + free(s_im[i]); + free(r_re[i]); + free(r_im[i]); + free(txdata[i]); + } + + free(s_re); + free(s_im); + free(r_re); + free(r_im); + free(txdata); + + if (write_output_file) + fclose(output_fd); + + return(n_errors); + +} + + + diff --git a/targets/RT/USER/nr-gnb.c b/targets/RT/USER/nr-gnb.c index 154e2687b10d508ba187d95c7f55c7f52b594973..51f2f2c1772bb9b65a6882d51f72c82acf0a66f7 100644 --- a/targets/RT/USER/nr-gnb.c +++ b/targets/RT/USER/nr-gnb.c @@ -726,7 +726,7 @@ void print_opp_meas(void) { print_meas(&softmodem_stats_rx_sf,"[gNB][total_phy_proc_rx]",NULL,NULL); } } -/* + void free_transport(PHY_VARS_gNB *gNB) { int i; @@ -736,20 +736,20 @@ void free_transport(PHY_VARS_gNB *gNB) LOG_I(PHY, "Freeing Transport Channel Buffers for DLSCH, UE %d\n",i); for (j=0; j<2; j++) free_gNB_dlsch(gNB->dlsch[i][j]); - LOG_I(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i); - free_gNB_ulsch(gNB->ulsch[1+i]); + //LOG_I(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i); + //free_gNB_ulsch(gNB->ulsch[1+i]); } - free_gNB_ulsch(gNB->ulsch[0]); -}*/ + //free_gNB_ulsch(gNB->ulsch[0]); +} -/* -void init_transport(PHY_VARS_gNB *gNB) { + +void init_nr_transport(PHY_VARS_gNB *gNB) { int i; int j; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - LOG_I(PHY, "Initialise transport\n"); + LOG_I(PHY, "Initialise nr transport\n"); for (i=0; i<NUMBER_OF_UE_MAX; i++) { LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i); @@ -764,8 +764,8 @@ void init_transport(PHY_VARS_gNB *gNB) { } } - LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i); - gNB->ulsch[1+i] = new_gNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0); + //LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i); + //gNB->ulsch[1+i] = new_gNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0); if (!gNB->ulsch[1+i]) { LOG_E(PHY,"Can't get gNB ulsch structures\n"); @@ -774,10 +774,10 @@ void init_transport(PHY_VARS_gNB *gNB) { // this is the transmission mode for the signalling channels // this will be overwritten with the real transmission mode by the RRC once the UE is connected - gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2; + //gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2; } // ULSCH for RA - gNB->ulsch[0] = new_gNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0); + //gNB->ulsch[0] = new_gNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0); if (!gNB->ulsch[0]) { LOG_E(PHY,"Can't get gNB ulsch structures\n"); @@ -804,9 +804,9 @@ void init_transport(PHY_VARS_gNB *gNB) { gNB->check_for_SUMIMO_transmissions = 0; - fp->pucch_config_common.deltaPUCCH_Shift = 1; + //fp->pucch_config_common.deltaPUCCH_Shift = 1; -} */ +} /// eNB kept in function name for nffapi calls, TO FIX void init_eNB_afterRU(void) { @@ -883,7 +883,7 @@ void init_eNB_afterRU(void) { "inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,gNB->gNB_config.rf_config.tx_antenna_ports.value); LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,gNB->gNB_config.rf_config.tx_antenna_ports.value); /// Transport init necessary for NR synchro - //init_transport(gNB); + init_nr_transport(gNB); //init_precoding_weights(RC.gNB[inst][CC_id]); } init_gNB_proc(inst); diff --git a/targets/RT/USER/nr-ue.c b/targets/RT/USER/nr-ue.c index 23effe052c423150bd741652538530723396fa1d..2f1fd1037e5eb2bee27b4845aeecc63218df102b 100644 --- a/targets/RT/USER/nr-ue.c +++ b/targets/RT/USER/nr-ue.c @@ -219,7 +219,7 @@ PHY_VARS_NR_UE* init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, // initialize all signal buffers init_nr_ue_signal(ue,1,abstraction_flag); // intialize transport - //init_nr_ue_transport(ue,abstraction_flag); + init_nr_ue_transport(ue,abstraction_flag); return(ue); }