From 8765bd9ab10296fc2aedbab3e1a80722ea9ae8ec Mon Sep 17 00:00:00 2001
From: Hongzhi Wang <hongzhi.wang@tcl.com>
Date: Mon, 22 Oct 2018 16:39:59 +0200
Subject: [PATCH] adding nr_dlschsim for dlsch coding/decoding

---
 cmake_targets/CMakeLists.txt                  |   9 +-
 openair1/PHY/CODING/nr_compute_tbs.c          |  56 +-
 openair1/PHY/CODING/nr_rate_matching.c        |   3 +-
 openair1/PHY/NR_TRANSPORT/nr_dlsch.h          |  12 +-
 openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c   |  72 +-
 openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c      |   4 +-
 .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c   |  72 +-
 .../NR_UE_TRANSPORT/nr_transport_proto_ue.h   |   1 +
 openair1/PHY/NR_UE_TRANSPORT/pss_nr.c         |   2 +-
 openair1/SCHED_NR_UE/phy_procedures_nr_ue.c   |   4 +-
 openair1/SIMULATION/NR_PHY/dlschsim.c         | 668 ++++++++++++++++++
 targets/RT/USER/nr-gnb.c                      |  30 +-
 targets/RT/USER/nr-ue.c                       |   2 +-
 13 files changed, 808 insertions(+), 127 deletions(-)
 create mode 100644 openair1/SIMULATION/NR_PHY/dlschsim.c

diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index b361f6389b..1f5109e49e 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 ddb82fed04..c9165e3867 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 19df32c246..245f3b9b75 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 bba325ff08..a19900a8ba 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 d9a424121d..c2f51388bd 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 14b06d56ce..dcb3fe1571 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 e1906011a9..1bd7f6af95 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 b16e5a97de..ec86a5c470 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 969fe1b1e5..174eadf95b 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 2a6911106d..2f63b9843f 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 0000000000..e435d87de7
--- /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 154e2687b1..51f2f2c177 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 23effe052c..2f1fd1037e 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);
 }
-- 
2.26.2