From 668de031ec1330c6f6a105949d4f454f983ff89c Mon Sep 17 00:00:00 2001
From: Francesco Mani <francesco.mani@eurecom.fr>
Date: Mon, 21 Oct 2019 16:39:02 +0200
Subject: [PATCH] a single function to compute tbs and an additional function
 to compute tbslbrm

---
 .../nfapi/public_inc/nfapi_nr_interface.h     |   1 +
 openair1/PHY/CODING/coding_defs.h             |  14 ++-
 openair1/PHY/CODING/nr_compute_tbs.c          | 107 ++++++++++++++----
 openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c   |   9 +-
 openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c      | 105 +++++++++--------
 .../NR_TRANSPORT/nr_transport_common_proto.h  |   6 +-
 openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c |   6 +-
 .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c   |  71 ++++++++----
 .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c   |   6 +-
 .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h     |   2 +
 .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c     |   9 +-
 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c    |  17 ++-
 openair1/SCHED_NR_UE/fapi_nr_ue_l1.c          |   1 +
 openair1/SCHED_NR_UE/phy_procedures_nr_ue.c   |   3 +-
 openair1/SIMULATION/NR_PHY/dlschsim.c         |   9 +-
 openair1/SIMULATION/NR_PHY/ulschsim.c         |   6 +-
 openair1/SIMULATION/NR_PHY/ulsim.c            |   6 +-
 .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c |   6 +-
 18 files changed, 249 insertions(+), 135 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 d316c0a9cfb..fcd550179e5 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
@@ -586,6 +586,7 @@ typedef struct {
   uint8_t start_symbol;
   uint8_t nb_symbols;
   uint8_t mcs_idx;
+  uint8_t mcs_table;
   uint8_t ndi;
   uint8_t nb_codewords;
   uint8_t nb_layers;
diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h
index 45f7116be1c..5ab4c022d94 100644
--- a/openair1/PHY/CODING/coding_defs.h
+++ b/openair1/PHY/CODING/coding_defs.h
@@ -458,12 +458,18 @@ int32_t nr_segmentation(unsigned char *input_buffer,
                      uint8_t BG);
 
 uint32_t nr_compute_tbs(uint16_t Qm,
-			uint16_t R,
+                        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 nb_dmrs_prb,
+                        uint16_t nb_rb_oh,
+			uint8_t Nl,
+                        uint8_t scale);
+
+uint32_t nr_compute_tbslbrm(uint16_t table,
+			    uint16_t nb_rb,
+		            uint8_t Nl,
+                            uint8_t C);
 
 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 f16fdaa0659..0a832081949 100644
--- a/openair1/PHY/CODING/nr_compute_tbs.c
+++ b/openair1/PHY/CODING/nr_compute_tbs.c
@@ -24,69 +24,128 @@
    author: Hongzhi WANG (TCL)
 */
 #include "PHY/defs_nr_UE.h"
-//#include "SCHED/extern.h"
 #define INDEX_MAX_TBS_TABLE (93)
 
 //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};
 
+uint16_t NPRB_LBRM[7] = {32,66,107,135,162,217,273};
+
 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 nb_dmrs_prb,
+                        uint16_t nb_rb_oh,
+			uint8_t Nl,
+                        uint8_t scale)
 {
 
-    uint16_t nbp_re, nb_re, nb_dmrs_prb, nb_rb_oh;
+    uint16_t nbp_re, nb_re;
     uint32_t nr_tbs=0;
-    double Ninfo,Np_info,n,C;
+    uint16_t Ninfo, Np_info, C;
+    uint8_t n;
 
-    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;
+    nbp_re = NR_NB_SC_PER_RB * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
 
     nb_re = min(156, nbp_re) * nb_rb;
 
     // Intermediate number of information bits
-    Ninfo = (double)((nb_re * R * Qm * Nl)/1024);
+    Ninfo = (nb_re * R * Qm * Nl)>>scale;
 
     //printf("Ninfo %lf nbp_re %d nb_re %d mcs %d Qm %d, R %d\n", Ninfo, nbp_re, nb_re,mcs, Qm, R);
 
     if (Ninfo <=3824) {
-
     	n = max(3, floor(log2(Ninfo)) - 6);
-        Np_info = max(24, pow(2,n) * floor(Ninfo/pow(2,n)));
-
+        Np_info = max(24, (Ninfo>>n)<<n);
         for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
-        	if ((double)Tbstable_nr[i] >= Np_info){
+        	if (Tbstable_nr[i] >= Np_info){
         		nr_tbs = Tbstable_nr[i];
         		break;
         	}
         }
     }
     else {
-    	n = floor(log2(Ninfo-24)) - 5;
-        Np_info = max(3840, pow(2,n) * round((Ninfo - 24)/pow(2,n)));
+    	n = log2(Ninfo-24)-5;
+        Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
 
-        if (R <= 256) { //1/4
-            C = ceil( (Np_info + 24)/3816 );
-            nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24);
+        if (R <= 256) { 
+            C = CEILIDIV((Np_info+24),3816);
+            nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
         }
         else {
             if (Np_info > 8424){
-                C = ceil( (Np_info + 24)/8424 );
-                nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24);
+                C = CEILIDIV((Np_info+24),8424);
+                nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
             }
             else {
-            	nr_tbs = (uint32_t)(8 * ceil( (Np_info + 24)/8 ) - 24);
-            	//printf("n %lf Np_info %f pow %f ceil %f \n",n, Np_info,pow(2,6),ceil( (Np_info + 24)/8 ));
+            	nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24;
             }
 
         }
 
     }
+    return nr_tbs;
+}
+
+
+//tbslbrm calculation according to 5.4.2.1 of 38.212
+uint32_t nr_compute_tbslbrm(uint16_t table,
+			    uint16_t nb_rb,
+		            uint8_t Nl,
+                            uint8_t C)
+{
+
+  uint16_t R, nb_re;
+  uint16_t nr_rb_lbrm=0;
+  uint8_t Qm;
+  int i;
+  uint32_t nr_tbs=0;
+  uint16_t Ninfo, Np_info;
+  uint8_t n;
+
+  for (i=0; i<7; i++) {
+      	if (NPRB_LBRM[i] >= nb_rb){
+     		nr_rb_lbrm = NPRB_LBRM[i];
+       		break;
+       	}
+  }
+
+  Qm = ((table == 1)? 8 : 6);
+  R = 948;
+  nb_re = 156 * nr_rb_lbrm;
+
+  // Intermediate number of information bits
+  Ninfo = (nb_re * R * Qm * Nl)>>10;
+
+  if (Ninfo <=3824) {
+    	n = max(3, floor(log2(Ninfo)) - 6);
+        Np_info = max(24, (Ninfo>>n)<<n);
+        for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
+        	if (Tbstable_nr[i] >= Np_info){
+        		nr_tbs = Tbstable_nr[i];
+        		break;
+        	}
+        }
+  }
+  else {
+    	n = log2(Ninfo-24)-5;
+        Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
+
+        if (R <= 256) { 
+            nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
+        }
+        else {
+            if (Np_info > 8424){
+                nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
+            }
+            else {
+            	nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24;
+            }
+
+        }
+
+  }
+  return nr_tbs;
 
-	return nr_tbs;
 }
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index 6f3e7a49a4e..2f4a9099043 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -297,6 +297,7 @@ int nr_dlsch_encoding(unsigned char *a,
   uint16_t Qm=rel15.modulation_order;
   uint16_t length_dmrs = 1;
   float Coderate = 0.0;
+  uint8_t Nl = 4;
 
   /*
   uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char
@@ -313,8 +314,6 @@ int nr_dlsch_encoding(unsigned char *a,
 
   LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order);
 
-  Tbslbrm = nr_compute_tbs(nr_get_Qm_dl(28,1),nr_get_code_rate_dl(28,1),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
 #ifdef DEBUG_DLSCH_CODING
@@ -452,6 +451,12 @@ int nr_dlsch_encoding(unsigned char *a,
 
     E = nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15.nb_layers, r);
 
+    // for tbslbrm calculation according to 5.4.2.1 of 38.212
+    if (rel15.nb_layers < Nl)
+      Nl = rel15.nb_layers;
+
+    Tbslbrm = nr_compute_tbslbrm(rel15.mcs_table,nb_rb,Nl,dlsch->harq_processes[harq_pid]->C);
+
     nr_rate_matching_ldpc(Ilbrm,
                           Tbslbrm,
                           BG,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
index 1ce38563bb6..cfc2a3fcbbc 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
@@ -31,6 +31,7 @@
 */
 
 #include "nr_transport_common_proto.h"
+#include "PHY/CODING/coding_defs.h"
 
 //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},
@@ -53,22 +54,18 @@ uint16_t Table_61411[28][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{
 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_dl(uint8_t Imcs, uint8_t table_idx) {
   switch(table_idx) {
-    case 1:
+    case 0:
       return (Table_51311[Imcs][0]);
     break;
 
-    case 2:
+    case 1:
       return (Table_51312[Imcs][0]);
     break;
 
-    case 3:
+    case 2:
       return (Table_51313[Imcs][0]);
     break;
 
@@ -79,15 +76,15 @@ 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) {
   switch(table_idx) {
-    case 1:
+    case 0:
       return (Table_51311[Imcs][1]);
     break;
 
-    case 2:
+    case 1:
       return (Table_51312[Imcs][1]);
     break;
 
-    case 3:
+    case 2:
       return (Table_51313[Imcs][1]);
     break;
 
@@ -98,11 +95,23 @@ uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) {
 
 uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
   switch(table_idx) {
+    case 0:
+      return (Table_51311[Imcs][0]);
+    break;
+
     case 1:
-      return (Table_61411[Imcs][0]);
+      return (Table_51312[Imcs][0]);
     break;
 
     case 2:
+      return (Table_51313[Imcs][0]);
+    break;
+
+    case 3:
+      return (Table_61411[Imcs][0]);
+    break;
+
+    case 4:
       return (Table_61412[Imcs][0]);
     break;
 
@@ -113,11 +122,23 @@ 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) {
   switch(table_idx) {
+    case 0:
+      return (Table_51311[Imcs][1]);
+    break;
+
     case 1:
-      return (Table_61411[Imcs][1]);
+      return (Table_51312[Imcs][1]);
     break;
 
     case 2:
+      return (Table_51313[Imcs][1]);
+    break;
+
+    case 3:
+      return (Table_61411[Imcs][1]);
+    break;
+
+    case 4:
       return (Table_61412[Imcs][1]);
     break;
 
@@ -146,16 +167,16 @@ static inline uint8_t get_table_idx(uint8_t mcs_table, uint8_t dci_format, uint8
     return 1;
 }
 
-void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
-                nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
-                nfapi_nr_config_request_t config) {
+void nr_get_tbs_dl(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
+                   nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
+                   nfapi_nr_config_request_t config) {
 
   LOG_D(MAC, "TBS calculation\n");
 
   nfapi_nr_dl_config_pdcch_parameters_rel15_t params_rel15 = dci_pdu.pdcch_params_rel15;
   nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_rel15 = &dlsch_pdu->dlsch_pdu_rel15;
   uint8_t rnti_type = params_rel15.rnti_type;
-  uint8_t N_PRB_oh = ((rnti_type==NFAPI_NR_RNTI_SI)||(rnti_type==NFAPI_NR_RNTI_RA)||(rnti_type==NFAPI_NR_RNTI_P))? 0 : \
+  uint16_t N_PRB_oh = ((rnti_type==NFAPI_NR_RNTI_SI)||(rnti_type==NFAPI_NR_RNTI_RA)||(rnti_type==NFAPI_NR_RNTI_P))? 0 : \
   (config.pdsch_config.x_overhead.value);
   uint8_t N_PRB_DMRS = (config.pdsch_config.dmrs_type.value == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000
   uint8_t N_sh_symb = dlsch_rel15->nb_symbols;
@@ -163,58 +184,36 @@ void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
   uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh;
   LOG_D(MAC, "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n", N_RE_prime, N_sh_symb, N_PRB_DMRS, N_PRB_oh);
 
-  uint16_t N_RE, Ninfo, Ninfo_prime, C, TBS=0, R;
-  uint8_t table_idx, Qm, n, scale;
+  uint16_t R, TBS=0;
+  uint8_t table_idx, Qm, scale;
 
   /*uint8_t mcs_table = config.pdsch_config.mcs_table.value;
   uint8_t ss_type = params_rel15.search_space_type;
   uint8_t dci_format = params_rel15.dci_format;
   get_table_idx(mcs_table, dci_format, rnti_type, ss_type);*/
-  table_idx = 1;
-  scale = ((table_idx==2)&&((Imcs==20)||(Imcs==26)))?11:10;
-  
-  N_RE = min(156, N_RE_prime)*dlsch_rel15->n_prb;
-
+  table_idx = 0;
   R = nr_get_code_rate_dl(Imcs, table_idx);
   Qm = nr_get_Qm_dl(Imcs, table_idx);
+  scale = ((table_idx==1)&&((Imcs==20)||(Imcs==26)))?11:10;
 
-  Ninfo = (N_RE*R*Qm*dlsch_rel15->nb_layers)>>scale;
-
-  if (Ninfo <= 3824) {
-    n = max(3, (log2(Ninfo)-6));
-    Ninfo_prime = max(24, (Ninfo>>n)<<n);
-    for (int i=0; i<93; i++)
-      if (nr_tbs_table[i] >= Ninfo_prime) {
-        TBS = nr_tbs_table[i];
-        break;
-      }
-  }
-  else {
-    n = log2(Ninfo-24)-5;
-    Ninfo_prime = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
-
-    if (R<256) {
-      C = CEILIDIV((Ninfo_prime+24),3816);
-      TBS = (C<<3)*CEILIDIV((Ninfo_prime+24),(C<<3)) - 24;
-    }
-    else {
-      if (Ninfo_prime>8424) {
-        C = CEILIDIV((Ninfo_prime+24),8424);
-        TBS = (C<<3)*CEILIDIV((Ninfo_prime+24),(C<<3)) - 24;
-      }
-      else
-        TBS = ((CEILIDIV((Ninfo_prime+24),8))<<3) - 24;
-    }    
-  }
+  TBS = nr_compute_tbs(Qm,
+                       R,
+		       dlsch_rel15->n_prb,
+		       N_sh_symb,
+		       N_PRB_DMRS,
+		       N_PRB_oh,
+		       dlsch_rel15->nb_layers,
+                       scale);
 
   dlsch_rel15->coding_rate = R;
   dlsch_rel15->modulation_order = Qm;
   dlsch_rel15->transport_block_size = TBS;
   dlsch_rel15->nb_re_dmrs = N_PRB_DMRS;
   dlsch_rel15->nb_mod_symbols = N_RE_prime*dlsch_rel15->n_prb*dlsch_rel15->nb_codewords;
+  dlsch_rel15->mcs_table = table_idx;
 
-  LOG_D(MAC, "TBS %d : N_RE %d  N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d Ninfo %d Ninfo_prime %d R %d Qm %d table %d scale %d nb_symbols %d\n",
-  TBS, N_RE, N_PRB_DMRS, N_sh_symb, N_PRB_oh, Ninfo, Ninfo_prime, R, Qm, table_idx, scale, dlsch_rel15->nb_mod_symbols);
+  LOG_D(MAC, "TBS %d : N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d R %d Qm %d table %d scale %d nb_symbols %d\n",
+  TBS, N_PRB_DMRS, N_sh_symb, N_PRB_oh, R, Qm, table_idx, scale, dlsch_rel15->nb_mod_symbols);
 }
 
 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) {
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
index 0b4337da2e1..6a88203f8c0 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
@@ -56,9 +56,9 @@ uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
 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,
-                nfapi_nr_config_request_t config);
+void nr_get_tbs_dl(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
+                   nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
+                   nfapi_nr_config_request_t config);
 
 /** \brief Computes available bits G. */
 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);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index 7b5dcabdad8..3729b7aa940 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -339,7 +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(Qm, R, 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, 0, n_layers, 10);
 
   A   = harq_process->TBS;
   ret = ulsch->max_ldpc_iterations + 1;
@@ -438,8 +438,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
 
   K_bytes_F = Kr_bytes-(harq_process->F>>3);
 
-  Tbslbrm = nr_compute_tbs(nr_get_Qm_ul(28,1),nr_get_code_rate_ul(28,1),nb_rb,frame_parms->symbols_per_slot,0,0,nfapi_ulsch_pdu_rel15->n_layers);
-
   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);
 
@@ -489,6 +487,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
 
     ///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
 
+    Tbslbrm = nr_compute_tbslbrm(0,nb_rb,nfapi_ulsch_pdu_rel15->n_layers,harq_process->C);
+
     if (nr_rate_matching_ldpc_rx(Ilbrm,
                                  Tbslbrm,
                                  p_decParams->BG,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index 81c8b5ce1d9..dd8f54ffbbf 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,
   int8_t l [68*384];
   //__m128i l;
   //int16_t inv_d [68*384];
-  uint8_t kc;
+  uint8_t kc,scale;
   uint8_t Ilbrm = 1;
   uint32_t Tbslbrm; //= 950984;
   uint16_t nb_rb; //= 30;
@@ -299,12 +299,15 @@ 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->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl);
+  scale = ((harq_process->mcs_table==1)&&((harq_process->mcs==20)||(harq_process->mcs==26)))?11:10;
+  uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
+
+  harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl, scale);
 
   A = harq_process->TBS;
   ret = dlsch->max_ldpc_iterations + 1;
   dlsch->last_iteration_cnt = ret;
-
+ 
   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;
 
@@ -312,7 +315,11 @@ 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);
 
-  Coderate = (float) A /(float) G;
+  if (scale == 10)
+    Coderate = (float) (harq_process->R) /(float) 1024;
+  else
+    Coderate = (float) (harq_process->R) /(float) 2048;
+
   if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
   {
     p_decParams->BG = 2;
@@ -409,8 +416,6 @@ 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(nr_get_Qm_dl(28,1),nr_get_code_rate_dl(28,1),nb_rb,frame_parms->symbols_per_slot,0,0,harq_process->Nl);
-
   for (r=0; r<harq_process->C; r++) {
 
     //printf("start rx segment %d\n",r);
@@ -454,6 +459,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 
     vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
 
+    if ((harq_process->Nl)<4)
+      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
+    else
+      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);
+
     if (nr_rate_matching_ldpc_rx(Ilbrm,
                                  Tbslbrm,
                                  p_decParams->BG,
@@ -750,7 +760,6 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
   int32_t no_iteration_ldpc,length_dec;
   /*uint8_t C;
   uint8_t Qm;
-  uint8_t Nl;
   uint8_t r_thread;
   uint32_t Er, Gp,GpmodC;*/
   t_nrLDPC_dec_params decParams;
@@ -759,13 +768,13 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
   t_nrLDPC_time_stats* p_procTime =&procTime ;
   int8_t llrProcBuf[OAI_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
   t_nrLDPC_procBuf* p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0];
-
+  uint8_t Nl=4;
   int16_t z [68*384];
   int8_t l [68*384];
   //__m128i l;
   int16_t inv_d [68*384];
   //int16_t *p_invd =&inv_d;
-  uint8_t kb, kc;
+  uint8_t kb, kc, scale;
   uint8_t Ilbrm = 1;
   uint32_t Tbslbrm = 950984;
   uint16_t nb_rb = 30;
@@ -824,7 +833,11 @@ 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->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl);
+  scale = ((harq_process->mcs_table==1)&&((harq_process->mcs==20)||(harq_process->mcs==26)))?11:10;
+  uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
+
+  harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl, scale);
+
 
   A = harq_process->TBS;
 
@@ -844,7 +857,11 @@ 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);
 
-  Coderate = (float) A /(float) G;
+  if (scale == 10)
+    Coderate = (float) (harq_process->R) /(float) 1024;
+  else
+    Coderate = (float) (harq_process->R) /(float) 2048;
+
   if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
   {
     p_decParams->BG = 2;
@@ -975,8 +992,6 @@ 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(nr_get_Qm_dl(28,1),nr_get_code_rate_dl(28,1),nb_rb,frame_parms->symbols_per_slot,0,0,harq_process->Nl);
-
     E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
 
     /*
@@ -1017,6 +1032,12 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
           harq_process->round);
 #endif
 
+    // for tbslbrm calculation according to 5.4.2.1 of 38.212
+    if (harq_process->Nl < Nl)
+      Nl = harq_process->Nl;
+
+    Tbslbrm = nr_compute_tbslbrm(rel15.mcs_table,nb_rb,Nl,dlsch->harq_processes[harq_pid]->C);
+
     if (nr_rate_matching_ldpc_rx(Ilbrm,
                                  Tbslbrm,
                                  p_decParams->BG,
@@ -1364,8 +1385,8 @@ void *nr_dlsch_decoding_process(void *arg)
   int harq_pid              = proc->harq_pid;
   llr8_flag1                = proc->llr8_flag;
   int frame                 = proc->frame_rx;
-  int slot              = proc->nr_tti_rx;
-  r               			= proc->num_seg;
+  int slot                  = proc->nr_tti_rx;
+  r               	    = proc->num_seg;
 
   NR_UE_DLSCH_t *dlsch      = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[slot]][eNB_id][0];
   NR_DL_UE_HARQ_t *harq_process  = dlsch->harq_processes[harq_pid];
@@ -1393,7 +1414,10 @@ void *nr_dlsch_decoding_process(void *arg)
 
   harq_process->trials[harq_process->round]++;
 
-  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);
+  scale = ((harq_process->mcs_table==1)&&((harq_process->mcs==20)||(harq_process->mcs==26)))?11:10;
+  uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
+
+  harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl, scale);
 
   A = harq_process->TBS; //2072 for QPSK 1/3
 
@@ -1405,7 +1429,11 @@ 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);
 
-  Coderate = (float) A /(float) G;
+  if (scale == 10)
+    Coderate = (float) (harq_process->R) /(float) 1024;
+  else
+    Coderate = (float) (harq_process->R) /(float) 2048;
+
   if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
   {
     p_decParams->BG = 2;
@@ -1518,9 +1546,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(nr_get_Qm_dl(28,1),nr_get_code_rate_dl(28,1),nb_rb,frame_parms->symbols_per_slot,0,0,harq_process->Nl);
-
-    E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
+  E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
 
 #if UE_TIMING_TRACE
     start_meas(dlsch_deinterleaving_stats);
@@ -1555,6 +1581,11 @@ void *nr_dlsch_decoding_process(void *arg)
           harq_process->round);
 #endif
 
+    if (Nl<4)
+      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl,harq_process->C);
+    else
+      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);
+
     if (nr_rate_matching_ldpc_rx(Ilbrm,
                                  Tbslbrm,
                                  p_decParams->BG,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 0500a4c78e3..8f810d36d31 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -176,8 +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_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);
+  dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
+  dlsch[0]->harq_processes[harq_pid]->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
   
   //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",
@@ -965,7 +965,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     break;
   }
   if (dlsch1_harq) {
-  switch (nr_get_Qm_dl(dlsch1_harq->mcs, 1)) {
+  switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) {
   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 ffda8ce4c0f..39b037a6005 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -265,6 +265,8 @@ typedef struct {
   uint8_t *c[MAX_NUM_NR_DLSCH_SEGMENTS];
   /// Index of current HARQ round for this DLSCH
   uint8_t round;
+  /// MCS table for this DLSCH
+  uint8_t mcs_table;
   /// MCS format for this DLSCH
   uint8_t mcs;
   /// Qm (modulation order) 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 aace9545395..21d0a4cc6f5 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -222,8 +222,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_ul(harq_process->mcs,1);
-  R = nr_get_code_rate_ul(harq_process->mcs,1);
+  mod_order = nr_get_Qm_ul(harq_process->mcs,0);
+  R = nr_get_code_rate_ul(harq_process->mcs,0);
   Kr=0;
   r_offset=0;
   BG = 1;
@@ -251,9 +251,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
 
   G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,harq_process->Nl);
   LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order);
-  
-
-  Tbslbrm = nr_compute_tbs(nr_get_Qm_ul(28,1),nr_get_code_rate_ul(28,1),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
@@ -394,6 +391,8 @@ opp_enabled=0;
 
     E = nr_get_E(G, harq_process->C, mod_order, harq_process->Nl, r);
 
+    Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->Nl,harq_process->C);
+
     nr_rate_matching_ldpc(Ilbrm,
                           Tbslbrm,
                           BG,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 778ceb6a1f0..9d3c1d78bfc 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -130,10 +130,17 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
     harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*harq_process_ul_ue->nb_rb*num_of_codewords;
 
-    mod_order      = nr_get_Qm_ul(harq_process_ul_ue->mcs, 1);
-    code_rate      = nr_get_code_rate_ul(harq_process_ul_ue->mcs, 1);
-
-    harq_process_ul_ue->TBS = nr_compute_tbs( mod_order, harq_process_ul_ue->nb_rb, code_rate, harq_process_ul_ue->number_of_symbols, ulsch_ue->nb_re_dmrs, ulsch_ue->length_dmrs, harq_process_ul_ue->Nl);
+    mod_order      = nr_get_Qm_ul(harq_process_ul_ue->mcs, 0);
+    code_rate      = nr_get_code_rate_ul(harq_process_ul_ue->mcs, 0);
+
+    harq_process_ul_ue->TBS = nr_compute_tbs(mod_order, 
+                                             code_rate,
+                                             harq_process_ul_ue->nb_rb,
+                                             harq_process_ul_ue->number_of_symbols,
+                                             ulsch_ue->nb_re_dmrs*ulsch_ue->length_dmrs,
+                                             0,
+                                             harq_process_ul_ue->Nl,
+                                             10);
 
     //-----------------------------------------------------//
     // to be removed later when MAC is ready
@@ -159,7 +166,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
     /////////////////////////ULSCH scrambling/////////////////////////
     ///////////
 
-    mod_order      = nr_get_Qm_ul(harq_process_ul_ue->mcs, 1);
+    mod_order      = nr_get_Qm_ul(harq_process_ul_ue->mcs, 0);
 
     available_bits = nr_get_G(harq_process_ul_ue->nb_rb,
                               harq_process_ul_ue->number_of_symbols,
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 6802b77d8c6..ced40c491ae 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -123,6 +123,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
 	  dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id;
 	  dlsch0_harq->harq_ack.slot_for_feedback_ack = dlsch_config_pdu->pdsch_to_harq_feedback_time_ind;
 	  dlsch0_harq->Nl=1;
+	  dlsch0_harq->mcs_table=0;
 	  dlsch0_harq->status = ACTIVE;
 	  LOG_D(MAC,">>>> \tdlsch0->g_pucch=%d\tdlsch0_harq.mcs=%d\n",dlsch0->g_pucch,dlsch0_harq->mcs);
 
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 1540cb33cfa..a7d407504d9 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -3307,7 +3307,7 @@ void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t
 
   harq_processes_dest->B             = current_harq_processes->B             ;
   harq_processes_dest->C             = current_harq_processes->C             ;
-  harq_processes_dest->DCINdi         = current_harq_processes->DCINdi             ;
+  harq_processes_dest->DCINdi         = current_harq_processes->DCINdi       ;
   harq_processes_dest->F             = current_harq_processes->F             ;
   harq_processes_dest->G             = current_harq_processes->G             ;
   harq_processes_dest->K             = current_harq_processes->K             ;
@@ -3320,6 +3320,7 @@ void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t
   harq_processes_dest->dl_power_off   = current_harq_processes->dl_power_off   ;
   harq_processes_dest->first_tx       = current_harq_processes->first_tx       ;
   harq_processes_dest->mcs            = current_harq_processes->mcs            ;
+  harq_processes_dest->mcs_table      = current_harq_processes->mcs_table      ;
   harq_processes_dest->mimo_mode      = current_harq_processes->mimo_mode      ;
   harq_processes_dest->nb_rb          = current_harq_processes->nb_rb          ;
   harq_processes_dest->pmi_alloc      = current_harq_processes->pmi_alloc      ;
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index 7577a14897f..39df082f60f 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -110,6 +110,7 @@ int main(int argc, char **argv)
 	uint16_t nb_symb_sch = 12;
 	uint16_t nb_rb = 50;
 	uint8_t Imcs = 9;
+        uint8_t mcs_table = 1;
 
 	cpuf = get_cpu_freq_GHz();
 
@@ -438,10 +439,11 @@ 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_dl(Imcs, 1);
-        rate = nr_get_code_rate_dl(Imcs, 1);
+	mod_order = nr_get_Qm_dl(Imcs, mcs_table);
+        rate = nr_get_code_rate_dl(Imcs, mcs_table);
 	available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
-	TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl);
+        scale = ((mcs_table==2)&&((Imcs==20)||(Imcs==26)))?11:10;
+	TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl);
 	printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
 	//dlsch->harq_ids[subframe]= 0;
 	rel15->n_prb = nb_rb;
@@ -464,6 +466,7 @@ int main(int argc, char **argv)
 	NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[0][0][0];
 	NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid];
 	harq_process->mcs = Imcs;
+	harq_process->mcs = mcs_table;
 	harq_process->Nl = Nl;
 	harq_process->nb_rb = nb_rb;
 	harq_process->Qm = mod_order;
diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c
index e897ff87a56..4c848afc72b 100644
--- a/openair1/SIMULATION/NR_PHY/ulschsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c
@@ -386,10 +386,10 @@ int main(int argc, char **argv)
 
   NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0];
 
-  mod_order = nr_get_Qm_ul(Imcs, 1);
-  code_rate = nr_get_code_rate_ul(Imcs, 1);
+  mod_order = nr_get_Qm_ul(Imcs, 0);
+  code_rate = nr_get_code_rate_ul(Imcs, 0);
   available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
-  TBS = nr_compute_tbs(mod_order,code_rate, 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, 0, Nl, 10);
 
   printf("\nAvailable bits %u TBS %u 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 48af9ef29ee..06095b0db43 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -412,10 +412,10 @@ int main(int argc, char **argv)
   unsigned char mod_order;
   uint16_t code_rate;
 
-  mod_order      = nr_get_Qm_ul(Imcs, 1);
-  code_rate      = nr_get_code_rate_ul(Imcs, 1);
+  mod_order      = nr_get_Qm_ul(Imcs, 0);
+  code_rate      = nr_get_code_rate_ul(Imcs, 0);
   available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
-  TBS            = nr_compute_tbs(mod_order, code_rate, 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, 0, precod_nbr_layers, 10);
 
   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;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 41de40488fb..81c05d7dcff 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -145,7 +145,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
                 params_rel15->nb_slots,
                 params_rel15->sfn_mod2,
                 params_rel15->first_slot);
-  nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg);
+  nr_get_tbs_dl(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg);
   LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d\n",
   dlsch_pdu_rel15->start_prb,
   dlsch_pdu_rel15->n_prb,
@@ -270,7 +270,7 @@ int configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req,
 	                      params_rel15->rb_offset,
 	                      params_rel15->first_symbol,
 	                      params_rel15->search_space_type);
-	        nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg);
+	        nr_get_tbs_dl(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg);
 		    // Hardcode it for now
 		    TBS = dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15.transport_block_size;
 		    LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n",
@@ -360,7 +360,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t   module_idP,
 
       // Hardcode it for now
       TBS = 6784/8; //TBS in bytes
-      //nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg);
+      //nr_get_tbs_dl(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg);
       //TBS = dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15.transport_block_size;
 
     	for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
-- 
GitLab