From 57c01460c6388e78a074ad50bfc9e966732efd72 Mon Sep 17 00:00:00 2001
From: Francesco Mani <francesco.mani@eurecom.fr>
Date: Fri, 27 Sep 2019 17:07:16 +0200
Subject: [PATCH] adding mcs tables and using good mcs for tbs computation

---
 .../nfapi/public_inc/nfapi_nr_interface.h     |   1 +
 openair1/PHY/CODING/coding_defs.h             |  13 +-
 openair1/PHY/CODING/nr_compute_tbs.c          |  34 ++---
 openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c   |  27 ++--
 openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c      |  81 ++++++++---
 .../NR_TRANSPORT/nr_transport_common_proto.h  |   9 +-
 openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c |   6 +-
 .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c   | 132 +++++++++---------
 .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c   |   5 +-
 .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h     |   2 +
 .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c     |  27 ++--
 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c    |  12 +-
 openair1/SCHED_NR_UE/phy_procedures_nr_ue.c   |  13 +-
 openair1/SIMULATION/NR_PHY/dlschsim.c         |   6 +-
 openair1/SIMULATION/NR_PHY/ulschsim.c         |   7 +-
 openair1/SIMULATION/NR_PHY/ulsim.c            |   6 +-
 16 files changed, 229 insertions(+), 152 deletions(-)

diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
index aad688c9d42..d316c0a9cfb 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
@@ -694,6 +694,7 @@ typedef struct {
     nr_pusch_freq_hopping_t pusch_freq_hopping;
     uint8_t mcs;
     uint8_t Qm;
+    uint16_t R;
     uint8_t ndi;
     uint8_t rv;
     int8_t accumulated_delta_PUSCH;
diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h
index 066697a8d4d..45f7116be1c 100644
--- a/openair1/PHY/CODING/coding_defs.h
+++ b/openair1/PHY/CODING/coding_defs.h
@@ -457,12 +457,13 @@ int32_t nr_segmentation(unsigned char *input_buffer,
                      unsigned int *F,
                      uint8_t BG);
 
-uint32_t nr_compute_tbs(uint8_t mcs,
-						uint16_t nb_rb,
-						uint16_t nb_symb_sch,
-						uint8_t nb_re_dmrs,
-						uint16_t length_dmrs,
-						uint8_t Nl);
+uint32_t nr_compute_tbs(uint16_t Qm,
+			uint16_t R,
+			uint16_t nb_rb,
+			uint16_t nb_symb_sch,
+			uint8_t nb_re_dmrs,
+			uint16_t length_dmrs,
+			uint8_t Nl);
 
 void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f);
 
diff --git a/openair1/PHY/CODING/nr_compute_tbs.c b/openair1/PHY/CODING/nr_compute_tbs.c
index e1c15d4a86d..f16fdaa0659 100644
--- a/openair1/PHY/CODING/nr_compute_tbs.c
+++ b/openair1/PHY/CODING/nr_compute_tbs.c
@@ -25,33 +25,29 @@
 */
 #include "PHY/defs_nr_UE.h"
 //#include "SCHED/extern.h"
-
 #define INDEX_MAX_TBS_TABLE (93)
-//Table 5.1.3.1-1
-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};
 
-uint32_t nr_compute_tbs(uint8_t mcs,
-						uint16_t nb_rb,
-						uint16_t nb_symb_sch,
-						uint8_t nb_re_dmrs,
-						uint16_t length_dmrs,
-						uint8_t Nl)
+uint32_t nr_compute_tbs(uint16_t Qm,
+                        uint16_t R,
+			uint16_t nb_rb,
+			uint16_t nb_symb_sch,
+			uint8_t nb_re_dmrs,
+			uint16_t length_dmrs,
+			uint8_t Nl)
 {
-	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];
-	R  = Mcsindextable1[mcs][1];
-	nb_dmrs_prb = nb_re_dmrs*length_dmrs;
+    uint16_t nbp_re, nb_re, nb_dmrs_prb, nb_rb_oh;
+    uint32_t nr_tbs=0;
+    double Ninfo,Np_info,n,C;
 
-	nbp_re = 12 * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
+    nb_rb_oh = 0; //set to 0 if not configured by higher layer
+    nb_dmrs_prb = nb_re_dmrs*length_dmrs;
+    nbp_re = 12 * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
 
-	nb_re = min(156, nbp_re) * nb_rb;
+    nb_re = min(156, nbp_re) * nb_rb;
 
     // Intermediate number of information bits
     Ninfo = (double)((nb_re * R * Qm * Nl)/1024);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index ff4f277cc5f..87da76b8daa 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -289,9 +289,11 @@ int nr_dlsch_encoding(unsigned char *a,int frame,
   //uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS];
   uint8_t BG=1;
   uint32_t E;
-  uint8_t Ilbrm = 0;
+  uint8_t Ilbrm = 1;
   uint32_t Tbslbrm = 950984; //max tbs
   uint8_t nb_re_dmrs = rel15.nb_re_dmrs;
+  uint16_t R=rel15.coding_rate;
+  uint16_t Qm=rel15.modulation_order;
   uint16_t length_dmrs = 1;
   float Coderate = 0.0;
 
@@ -309,9 +311,8 @@ int nr_dlsch_encoding(unsigned char *a,int frame,
   G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15.nb_layers);
 
   LOG_D(PHY,"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, rel15.nb_layers);
+  Tbslbrm = nr_compute_tbs(Qm,R,nb_rb,frame_parms->symbols_per_slot,0,0, rel15.nb_layers);
 
   //  if (dlsch->harq_processes[harq_pid]->Ndi == 1) {  // this is a new packet
   if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
@@ -340,7 +341,10 @@ int nr_dlsch_encoding(unsigned char *a,int frame,
 
     memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
 
-    Coderate = (float) A /(float) G;
+    if (R<1000)
+      Coderate = (float) R /(float) 1024;
+    else  // to scale for mcs 20 and 26 in table 5.1.3.1-2 which are decimal and input 2* in nr_tbs_tools
+      Coderate = (float) R /(float) 2048;
 
     if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
 		BG = 2;
@@ -410,13 +414,14 @@ int nr_dlsch_encoding(unsigned char *a,int frame,
 
   for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
 
-	  	  if (dlsch->harq_processes[harq_pid]->F>0) {
-	          for (int k=(Kr-F-2*(*pz)); k<Kr-2*(*pz); k++) {
-	        	  dlsch->harq_processes[harq_pid]->d[r][k] = NR_NULL;
-	        	  //if (k<(Kr-F+8))
-	            //printf("r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]);
-	          }
-	  }
+    if (dlsch->harq_processes[harq_pid]->F>0) {
+      for (int k=(Kr-F-2*(*pz)); k<Kr-2*(*pz); k++) {
+        dlsch->harq_processes[harq_pid]->d[r][k] = NR_NULL;
+	//if (k<(Kr-F+8))
+	//printf("r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]);
+      }
+    }
+
 #ifdef DEBUG_DLSCH_CODING
     printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
         r,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
index 07ca17cd6d8..1ce38563bb6 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
@@ -32,31 +32,44 @@
 
 #include "nr_transport_common_proto.h"
 
-/// Target code rate tables indexed by Imcs
-uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \
-                                            616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948};
-  // Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
-uint16_t nr_target_code_rate_table2[28] = {120, 193, 308, 449, 602, 378, 434, 490, 553, 616, 658, 466, 517, 567, \
-                                            616, 666, 719, 772, 822, 873, 1365, 711, 754, 797, 841, 885, 1833, 948};
-uint16_t nr_target_code_rate_table3[29] = {30, 40, 50, 64, 78, 99, 120, 157, 193, 251, 308, 379, 449, 526, 602, 340, \
-                                            378, 434, 490, 553, 616, 438, 466, 517, 567, 616, 666, 719, 772};
+//Table 5.1.3.1-1 of 38.214
+uint16_t Table_51311[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.3.1-2 of 38.214
+// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
+uint16_t Table_51312[28][2] = {{2,120},{2,193},{2,308},{2,449},{2,602},{4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{6,466},{6,517},{6,567},{6,616},{6,666},
+		{6,719},{6,772},{6,822},{6,873},{8,1365},{8,711},{8,754},{8,797},{8,841},{8,885},{8,1833},{8,948}};
+
+//Table 5.1.3.1-3 of 38.214
+uint16_t Table_51313[29][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{4,340},
+		{4,378},{4,434},{4,490},{4,553},{4,616},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666}, {6,719}, {6,772}};
+
+//Table 6.1.4.1-1 of 38.214 TODO fix for tp-pi2BPSK
+uint16_t Table_61411[28][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,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}};
+
+//Table 6.1.4.1-2 of 38.214 TODO fix for tp-pi2BPSK
+uint16_t Table_61412[28][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},
+		{4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{4,699},{4,772},{6,567},{6,616},{6,666}, {6,772}};
+
 uint16_t nr_tbs_table[93] = {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};
 
-uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx) {
+uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) {
   switch(table_idx) {
     case 1:
-      return (((Imcs<10)||(Imcs==29))?2:((Imcs<17)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
+      return (Table_51311[Imcs][0]);
     break;
 
     case 2:
-      return (((Imcs<5)||(Imcs==28))?2:((Imcs<11)||(Imcs==29))?4:((Imcs<20)||(Imcs==30))?6:((Imcs<28)||(Imcs==31))?8:-1);
+      return (Table_51312[Imcs][0]);
     break;
 
     case 3:
-      return (((Imcs<15)||(Imcs==29))?2:((Imcs<21)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
+      return (Table_51313[Imcs][0]);
     break;
 
     default:
@@ -64,18 +77,18 @@ uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx) {
   }
 }
 
-uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) {
+uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) {
   switch(table_idx) {
     case 1:
-      return (nr_target_code_rate_table1[Imcs]);
+      return (Table_51311[Imcs][1]);
     break;
 
     case 2:
-      return (nr_target_code_rate_table2[Imcs]);
+      return (Table_51312[Imcs][1]);
     break;
 
     case 3:
-      return (nr_target_code_rate_table3[Imcs]);
+      return (Table_51313[Imcs][1]);
     break;
 
     default:
@@ -83,6 +96,36 @@ uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) {
   }
 }
 
+uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
+  switch(table_idx) {
+    case 1:
+      return (Table_61411[Imcs][0]);
+    break;
+
+    case 2:
+      return (Table_61412[Imcs][0]);
+    break;
+
+    default:
+      AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx);
+  }
+}
+
+uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
+  switch(table_idx) {
+    case 1:
+      return (Table_61411[Imcs][1]);
+    break;
+
+    case 2:
+      return (Table_61412[Imcs][1]);
+    break;
+
+    default:
+      AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx);
+  }
+}
+
 static inline uint8_t is_codeword_disabled(uint8_t format, uint8_t Imcs, uint8_t rv) {
   return ((format==NFAPI_NR_DL_DCI_FORMAT_1_1)&&(Imcs==26)&&(rv==1));
 }
@@ -131,8 +174,10 @@ void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
   scale = ((table_idx==2)&&((Imcs==20)||(Imcs==26)))?11:10;
   
   N_RE = min(156, N_RE_prime)*dlsch_rel15->n_prb;
-  R = nr_get_code_rate(Imcs, table_idx);
-  Qm = nr_get_Qm(Imcs, table_idx);
+
+  R = nr_get_code_rate_dl(Imcs, table_idx);
+  Qm = nr_get_Qm_dl(Imcs, table_idx);
+
   Ninfo = (N_RE*R*Qm*dlsch_rel15->nb_layers)>>scale;
 
   if (Ninfo <= 3824) {
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
index 36f3fb5c2c6..0b4337da2e1 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
@@ -48,10 +48,13 @@
 #define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1
 #define NR_PUSCH_y 3 // UCI placeholder bit 
 
-/** \brief Computes Q based on I_MCS PDSCH and table_idx. Implements Table 5.1.3.1-2 from 38.214. */
-uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx);
+/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */
+uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
+uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
 
-uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx);
+/** \brief Computes Q based on I_MCS PDSCH and table_idx for uplink. Implements MCS Tables from 38.214. */
+uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx);
+uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx);
 
 void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
                 nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index 6825c423c33..24ab5a76bc3 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -310,6 +310,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
   uint16_t nb_rb          = nfapi_ulsch_pdu_rel15->number_rbs;
   uint16_t number_symbols = nfapi_ulsch_pdu_rel15->number_symbols;
   uint8_t Qm              = nfapi_ulsch_pdu_rel15->Qm;
+  uint8_t R               = nfapi_ulsch_pdu_rel15->R;
   uint8_t mcs             = nfapi_ulsch_pdu_rel15->mcs;
   uint8_t n_layers        = nfapi_ulsch_pdu_rel15->n_layers;
   uint8_t nb_re_dmrs      = nfapi_ulsch_pdu_rel15->nb_re_dmrs;
@@ -338,8 +339,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
   }
 
   // harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
-  
-  harq_process->TBS = nr_compute_tbs(mcs, nb_rb, number_symbols, nb_re_dmrs, length_dmrs, n_layers);
+  harq_process->TBS = nr_compute_tbs(Qm, R, nb_rb, number_symbols, nb_re_dmrs, length_dmrs, n_layers);
 
   A   = harq_process->TBS;
   ret = ulsch->max_ldpc_iterations;
@@ -440,7 +440,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
 
   K_bytes_F = Kr_bytes-(harq_process->F>>3);
 
-  Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, nfapi_ulsch_pdu_rel15->n_layers);
+  Tbslbrm = harq_process->TBS;
 
   for (r=0; r<harq_process->C; r++) {
     E = nr_get_E(G, harq_process->C, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers, r);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index e9a147dce11..ff85d3fd75d 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -238,7 +238,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
   //__m128i l;
   //int16_t inv_d [68*384];
   uint8_t kc;
-  uint8_t Ilbrm = 0;
+  uint8_t Ilbrm = 1;
   uint32_t Tbslbrm; //= 950984;
   uint16_t nb_rb; //= 30;
   double Coderate; //= 0.0;
@@ -298,7 +298,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 
   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);
+  harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl);
 
   A = harq_process->TBS;
   ret = dlsch->max_ldpc_iterations + 1;
@@ -310,28 +310,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 
   vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
 
-  if (harq_process->round == 0) {
-    // This is a new packet, so compute quantities regarding segmentation
-    harq_process->B = A+24;
-    nr_segmentation(NULL,
-                    NULL,
-                    harq_process->B,
-                    &harq_process->C,
-                    &harq_process->K,
-                    &harq_process->Z, // [hna] Z is Zc
-                    &harq_process->F);
-
-#ifdef DEBUG_DLSCH_DECODING
-    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
-  }
-
-  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
-
-  p_decParams->Z = harq_process->Z;
-  //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z);
-
   Coderate = (float) A /(float) G;
   if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
   {
@@ -365,6 +343,30 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
     }
   }
 
+
+  if (harq_process->round == 0) {
+    // This is a new packet, so compute quantities regarding segmentation
+    harq_process->B = A+24;
+    nr_segmentation(NULL,
+                    NULL,
+                    harq_process->B,
+                    &harq_process->C,
+                    &harq_process->K,
+                    &harq_process->Z, // [hna] Z is Zc
+                    &harq_process->F,
+                    p_decParams->BG);
+
+#ifdef DEBUG_DLSCH_DECODING
+    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
+  }
+
+  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
+
+  p_decParams->Z = harq_process->Z;
+  //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z);
+
   //printf("coderate %f kc %d \n", Coderate, kc);
 
   p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
@@ -401,7 +403,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 
   K_bytes_F = Kr_bytes-(harq_process->F>>3);
 
-  Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl);
+  Tbslbrm = harq_process->TBS;
 
   for (r=0; r<harq_process->C; r++) {
 
@@ -737,7 +739,7 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
   int16_t inv_d [68*384];
   //int16_t *p_invd =&inv_d;
   uint8_t kb, kc;
-  uint8_t Ilbrm = 0;
+  uint8_t Ilbrm = 1;
   uint32_t Tbslbrm = 950984;
   uint16_t nb_rb = 30;
   double Coderate = 0.0;
@@ -795,7 +797,7 @@ uint32_t  nr_dlsch_decoding_mthread(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);
+  harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl);
 
   A = harq_process->TBS;
 
@@ -815,21 +817,6 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
 
   //  printf("DLSCH Decoding, harq_pid %d Ndi %d\n",harq_pid,harq_process->Ndi);
 
-  if (harq_process->round == 0) {
-      // This is a new packet, so compute quantities regarding segmentation
-      harq_process->B = A+24;
-      nr_segmentation(NULL,
-                      NULL,
-                      harq_process->B,
-                      &harq_process->C,
-                      &harq_process->K,
-                      &harq_process->Z,
-                      &harq_process->F);
-
-      p_decParams->Z = harq_process->Z;
-
-    }
-
   Coderate = (float) A /(float) G;
   if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
   {
@@ -863,6 +850,22 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
     }
   }
 
+  if (harq_process->round == 0) {
+      // This is a new packet, so compute quantities regarding segmentation
+      harq_process->B = A+24;
+      nr_segmentation(NULL,
+                      NULL,
+                      harq_process->B,
+                      &harq_process->C,
+                      &harq_process->K,
+                      &harq_process->Z,
+                      &harq_process->F,
+                      p_decParams->BG);
+
+      p_decParams->Z = harq_process->Z;
+
+    }
+
   //printf("coderate %f kc %d \n", Coderate, kc);
   p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
   p_decParams->outMode= 0;
@@ -941,7 +944,7 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
     Kr_bytes = Kr>>3;
     K_bytes_F = Kr_bytes-(harq_process->F>>3);
 
-    Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl);
+    Tbslbrm = harq_process->TBS;
 
     E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
 
@@ -1286,7 +1289,7 @@ void *nr_dlsch_decoding_process(void *arg)
     int16_t inv_d [68*384];
     int16_t *p_invd =&inv_d;
     uint8_t kb, kc;
-    uint8_t Ilbrm = 0;
+    uint8_t Ilbrm = 1;
     uint32_t Tbslbrm = 950984;
     uint16_t nb_rb = 30; //to update
     double Coderate = 0.0;
@@ -1355,7 +1358,7 @@ void *nr_dlsch_decoding_process(void *arg)
 
   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);
+  harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl);
 
   A = harq_process->TBS; //2072 for QPSK 1/3
 
@@ -1367,22 +1370,6 @@ void *nr_dlsch_decoding_process(void *arg)
 
   LOG_I(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
 
-    
-  if (harq_process->round == 0) {
-    // This is a new packet, so compute quantities regarding segmentation
-    harq_process->B = A+24;
-
-    nr_segmentation(NULL,
-                          NULL,
-                          harq_process->B,
-                          &harq_process->C,
-                          &harq_process->K,
-            &harq_process->Z,
-                          &harq_process->F);
-      p_decParams->Z = harq_process->Z;
-
-    }
-
   Coderate = (float) A /(float) G;
   if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
   {
@@ -1414,7 +1401,26 @@ void *nr_dlsch_decoding_process(void *arg)
       p_decParams->R = 89;
       kc = 27;
     }
-  }
+  }    
+
+  if (harq_process->round == 0) {
+    // This is a new packet, so compute quantities regarding segmentation
+    harq_process->B = A+24;
+
+    nr_segmentation(NULL,
+                    NULL,
+                    harq_process->B,
+                    &harq_process->C,
+                    &harq_process->K,
+                    &harq_process->Z,
+                    &harq_process->F,
+                    p_decParams->BG);
+
+    p_decParams->Z = harq_process->Z;
+
+    }
+
+  
 
   p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
   p_decParams->outMode= 0;
@@ -1474,7 +1480,7 @@ void *nr_dlsch_decoding_process(void *arg)
   Kr_bytes = Kr>>3;
   K_bytes_F = Kr_bytes-(harq_process->F>>3);
 
-  Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl);
+  Tbslbrm = harq_process->TBS;
 
     E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 53c6615dbd3..91417d73eeb 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -176,7 +176,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id];
 
 
-  dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm(dlsch[0]->harq_processes[harq_pid]->mcs, 1);;
+  dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, 1);
+  dlsch[0]->harq_processes[harq_pid]->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, 1);
   
   //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
     LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d,  harq status %d.%d \n",
@@ -964,7 +965,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     break;
   }
   if (dlsch1_harq) {
-  switch (nr_get_Qm(dlsch1_harq->mcs, 1)) {
+  switch (nr_get_Qm_dl(dlsch1_harq->mcs, 1)) {
   case 2 :
     if (rx_type==rx_standard) {
         nr_dlsch_qpsk_llr(frame_parms,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index 86b551435e8..1766c6ae569 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -273,6 +273,8 @@ typedef struct {
   uint8_t mcs;
   /// Qm (modulation order) for this DLSCH
   uint8_t Qm;
+  /// target code rate R x 1024
+  uint16_t R;
   /// Redundancy-version of the current sub-frame
   uint8_t rvidx;
   /// MIMO mode for this DLSCH
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index 5c8493c3709..39896f3888b 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -203,7 +203,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
   uint32_t A, Z, F;
   uint32_t *pz; 
   uint8_t mod_order; 
-  uint16_t Kr,r,r_offset;
+  uint16_t Kr,r,r_offset,R;
   uint8_t BG;
   uint32_t E;
   uint8_t Ilbrm; 
@@ -225,7 +225,8 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
   nb_symb_sch = harq_process->number_of_symbols;
   A = harq_process->TBS;
   pz = &Z;
-  mod_order = nr_get_Qm(harq_process->mcs,1);
+  mod_order = nr_get_Qm_ul(harq_process->mcs,1);
+  R = nr_get_code_rate_ul(harq_process->mcs,1);
   Kr=0;
   r_offset=0;
   BG = 1;
@@ -255,7 +256,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
   LOG_D(PHY,"ulsch 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, harq_process->Nl);
+  Tbslbrm = nr_compute_tbs(mod_order,R,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl);
 
   //  if (harq_process->Ndi == 1) {  // this is a new packet
   if (harq_process->round == 0) {  // this is a new packet
@@ -290,15 +291,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
 ///////////////////////// b---->| block segmentation |---->c /////////////////////////
 ///////////
 
-    nr_segmentation(harq_process->b,
-        harq_process->c,
-        harq_process->B,
-        &harq_process->C,
-        &harq_process->K,
-        pz,
-        &harq_process->F);
-
-    F = harq_process->F;
     Coderate = (float) A /(float) G;
 
     if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
@@ -308,6 +300,17 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
       BG = 1;
     }
 
+    nr_segmentation(harq_process->b,
+        harq_process->c,
+        harq_process->B,
+        &harq_process->C,
+        &harq_process->K,
+        pz,
+        &harq_process->F,
+        BG);
+
+    F = harq_process->F;
+
     Kr = harq_process->K;
 #ifdef DEBUG_DLSCH_CODING
     uint16_t Kr_bytes;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 2b59f93160c..9886960429f 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -53,6 +53,8 @@ int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE,
   int N_PRB_oh, N_RE_prime, cwd_idx, length_dmrs, Nid_cell;
   int nb_rb, Nsymb_pusch, first_rb, nb_codewords,mcs,rvidx;
   uint16_t n_rnti;
+  unsigned char mod_order;
+  uint16_t code_rate;
 
   NR_UE_ULSCH_t *ulsch_ue;
   NR_UL_UE_HARQ_t *harq_process_ul_ue;
@@ -89,6 +91,9 @@ int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE,
 
     if (harq_process_ul_ue) {
 
+      mod_order      = nr_get_Qm_ul(mcs, 1);
+      code_rate      = nr_get_code_rate_ul(mcs, 1);
+
       harq_process_ul_ue->mcs                = mcs;
       harq_process_ul_ue->Nl                 = nb_codewords;
       harq_process_ul_ue->nb_rb              = nb_rb;
@@ -96,7 +101,8 @@ int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE,
       harq_process_ul_ue->number_of_symbols  = Nsymb_pusch;
       harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*nb_codewords;
       harq_process_ul_ue->rvidx              = rvidx;
-      harq_process_ul_ue->TBS                = nr_compute_tbs(harq_process_ul_ue->mcs,
+      harq_process_ul_ue->TBS                = nr_compute_tbs(mod_order,
+                                                              code_rate,
                                                               nb_rb,
                                                               Nsymb_pusch,
                                                               ulsch_ue->nb_re_dmrs,
@@ -166,7 +172,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   int32_t **txdataF;
   uint16_t start_sc, start_rb;
   int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
-  uint16_t n_dmrs;
+  uint16_t n_dmrs,code_rate;
   uint8_t dmrs_type;
   uint8_t mapping_type;
   int ap, start_symbol, i;
@@ -195,7 +201,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
     /////////////////////////ULSCH scrambling/////////////////////////
     ///////////
 
-    mod_order      = nr_get_Qm(harq_process_ul_ue->mcs, 1);
+    mod_order      = nr_get_Qm_ul(harq_process_ul_ue->mcs, 1);
 
     available_bits = nr_get_G(harq_process_ul_ue->nb_rb,
                               ulsch_ue->Nsymb_pusch,
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 9a0e82fa60d..1ace1281ca7 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -2464,9 +2464,9 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_
 
 
 void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
-		                    UE_nr_rxtx_proc_t *proc,
-							uint8_t gNB_id,
-							uint8_t thread_id)
+		            UE_nr_rxtx_proc_t *proc,
+			    uint8_t gNB_id,
+			    uint8_t thread_id)
 {
   //NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
   NR_UE_ULSCH_t *ulsch_ue;
@@ -2497,11 +2497,14 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
   ulsch_ue = ue->ulsch[thread_id][gNB_id][0]; // cwd_index = 0
   harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
 
-  TBS = nr_compute_tbs( harq_process_ul_ue->mcs, harq_process_ul_ue->nb_rb, ulsch_ue->Nsymb_pusch, ulsch_ue->nb_re_dmrs, ulsch_ue->length_dmrs, harq_process_ul_ue->Nl);
-
 //-----------------------------------------------------//
   // to be removed later when MAC is ready
 
+  uint8_t Qm = nr_get_Qm_ul(harq_process_ul_ue->mcs, 1);
+  uint16_t R = nr_get_code_rate_ul(harq_process_ul_ue->mcs, 1);
+  TBS = nr_compute_tbs( Qm, R, harq_process_ul_ue->nb_rb, ulsch_ue->Nsymb_pusch, ulsch_ue->nb_re_dmrs, ulsch_ue->length_dmrs, harq_process_ul_ue->Nl);
+
+
   for (i = 0; i < TBS / 8; i++)
     harq_process_ul_ue->a[i] = (unsigned char) rand();
 
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index 2a6d6d04ad0..8d27b7d4f66 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -427,6 +427,7 @@ int main(int argc, char **argv)
 	uint8_t nb_re_dmrs = 6;
 	uint16_t length_dmrs = 1;
 	unsigned char mod_order;
+        uint16_t rate;
 	uint8_t Nl = 1;
 	uint8_t rvidx = 0;
 	dlsch->rnti = 1;
@@ -434,9 +435,10 @@ int main(int argc, char **argv)
 	 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(Imcs, 1);
+	mod_order = nr_get_Qm_dl(Imcs, 1);
+        rate = nr_get_code_rate_dl(Imcs, 1);
 	available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
-	TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl);
+	TBS = nr_compute_tbs(mod_order,rate, 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);
 	//dlsch->harq_ids[subframe]= 0;
 	rel15->n_prb = nb_rb;
diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c
index b3f769fef09..e0ac686ebbf 100644
--- a/openair1/SIMULATION/NR_PHY/ulschsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c
@@ -372,7 +372,7 @@ int main(int argc, char **argv)
   uint8_t nb_re_dmrs = 6;
   uint8_t length_dmrs = 1;
   uint8_t N_PRB_oh;
-  uint16_t N_RE_prime;
+  uint16_t N_RE_prime,code_rate;
   unsigned char mod_order;
   uint8_t Nl = 1;
   uint8_t rvidx = 0;
@@ -383,9 +383,10 @@ int main(int argc, char **argv)
 
   NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0];
 
-  mod_order = nr_get_Qm(Imcs, 1);
+  mod_order = nr_get_Qm_ul(Imcs, 1);
+  code_rate = nr_get_code_rate_ul(Imcs, 1);
   available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
-  TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl);
+  TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl);
   printf("\n");
   printf("available bits %d TBS %d mod_order %d\n", available_bits, TBS, mod_order);
 
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index d71bea59f0a..33c59c66932 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -387,10 +387,12 @@ int main(int argc, char **argv)
   uint8_t nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4;
   uint8_t length_dmrs = 1;
   unsigned char mod_order;
+  uint16_t code_rate;
 
-  mod_order      = nr_get_Qm(Imcs, 1);
+  mod_order      = nr_get_Qm_ul(Imcs, 1);
+  code_rate      = nr_get_code_rate_ul(Imcs, 1);
   available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
-  TBS            = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, precod_nbr_layers);
+  TBS            = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, precod_nbr_layers);
 
   NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id+1][0];
   nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu;
-- 
GitLab