diff --git a/common/openairinterface5g_limits.h b/common/openairinterface5g_limits.h
index 2349941cf232324aaf7cdc951038d1dca167261a..8f3a2b40fd7e545bf58a31f0ba2f50934c7d13cf 100644
--- a/common/openairinterface5g_limits.h
+++ b/common/openairinterface5g_limits.h
@@ -18,7 +18,6 @@
 
 #        define NUMBER_OF_NR_SCH_STATS_MAX 16
 
-#        define NUMBER_OF_NR_PUCCH_MAX 16
 #        define NUMBER_OF_NR_PDCCH_MAX 16
 
 #define MAX_MANAGED_ENB_PER_MOBILE  2
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index 852e805e6dd9497d7194c4f2210d07b84e52f0d1..9660f89f5c9a3513b5eddc6bfdfe41577dc7f1fe 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -198,7 +198,8 @@ void rx_func(void *param) {
         }
         up_removed++;
       }
-    for (j = 0; j < NUMBER_OF_NR_PUCCH_MAX; j++)
+
+    for (j = 0; j < gNB->max_nb_pucch; j++)
       if (gNB->pucch[j]->active > 0 &&
           gNB->pucch[j]->pucch_pdu.rnti == rnti_to_remove[i]) {
         gNB->pucch[j]->active = 0;
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 6f983f613c4b83550e452ef211c19dc3265f4f2b..515950c15e09834d5bac6072d14cc5be00908ab4 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -134,7 +134,7 @@ int init_codebook_gNB(PHY_VARS_gNB *gNB) {
 
       int max_mimo_layers = (CSI_RS_antenna_ports<NR_MAX_NB_LAYERS) ? CSI_RS_antenna_ports : NR_MAX_NB_LAYERS;
 
-      gNB->nr_mimo_precoding_matrix = (int32_t ***)malloc16(max_mimo_layers* sizeof(int32_t **));
+      gNB->nr_mimo_precoding_matrix = (int32_t ***)malloc16(max_mimo_layers * sizeof(int32_t **));
       int32_t ***mat = gNB->nr_mimo_precoding_matrix;
       double complex res_code;
 
@@ -1002,14 +1002,43 @@ void reset_DLSCH_struct(const PHY_VARS_gNB *gNB, processingData_L1tx_t *msg)
       free_gNB_dlsch(&msg->dlsch[i][j], grid_size, fp);
 }
 
-void init_nr_transport(PHY_VARS_gNB *gNB) {
+void init_nr_transport(PHY_VARS_gNB *gNB)
+{
+
   NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
+  const nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
   LOG_I(PHY, "Initialise nr transport\n");
 
-  for (int i=0; i<NUMBER_OF_NR_PUCCH_MAX; i++) {
-    LOG_I(PHY,"Allocating Transport Channel Buffers for PUCCH %d/%d\n",i,NUMBER_OF_NR_PUCCH_MAX);
+  int nb_slots_per_period = cfg->cell_config.frame_duplex_type.value ?
+                            fp->slots_per_frame / get_nb_periods_per_frame(cfg->tdd_table.tdd_period.value) :
+                            fp->slots_per_frame;
+  int nb_ul_slots_period = 0;
+  if (cfg->cell_config.frame_duplex_type.value) {
+    for(int i=0; i<nb_slots_per_period; i++) {
+      for(int j=0; j<NR_NUMBER_OF_SYMBOLS_PER_SLOT; j++) {
+        if(cfg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[j].slot_config.value == 1) { // UL symbol
+          nb_ul_slots_period++;
+          break;
+        }  
+      }
+    }
+  }
+  else
+    nb_ul_slots_period = fp->slots_per_frame;
+
+  int pucch_slots;
+  if (gNB->if_inst->sl_ahead > nb_slots_per_period)
+    pucch_slots = nb_ul_slots_period + (gNB->if_inst->sl_ahead - nb_slots_per_period);
+  else
+    pucch_slots = (nb_ul_slots_period < gNB->if_inst->sl_ahead) ? nb_ul_slots_period : gNB->if_inst->sl_ahead;
+
+  gNB->max_nb_pucch = MAX_MOBILES_PER_GNB * pucch_slots;
+
+  gNB->pucch = (NR_gNB_PUCCH_t **) malloc16(gNB->max_nb_pucch * sizeof(NR_gNB_PUCCH_t*));
+  for (int i = 0; i < gNB->max_nb_pucch; i++) {
+    LOG_I(PHY,"Allocating Transport Channel Buffers for PUCCH %d/%d\n", i, gNB->max_nb_pucch);
     gNB->pucch[i] = new_gNB_pucch();
-    AssertFatal(gNB->pucch[i]!=NULL,"Can't initialize pucch %d \n", i);
+    AssertFatal(gNB->pucch[i] != NULL,"Can't initialize pucch %d \n", i);
   }
 
   for (int i=0; i<NUMBER_OF_NR_SRS_MAX; i++) {
@@ -1039,7 +1068,7 @@ void reset_nr_transport(PHY_VARS_gNB *gNB)
 {
   const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
 
-  for (int i = 0; i < NUMBER_OF_NR_PUCCH_MAX; i++)
+  for (int i = 0; i < gNB->max_nb_pucch; i++)
     free_gNB_pucch(gNB->pucch[i]);
 
   for (int i = 0; i < NUMBER_OF_NR_SRS_MAX; i++)
diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
index 905e03801cf5e8aba23b56e1c2b969a0ffdb9617..03ed927c37015df3804ff2df3897282672983cc7 100644
--- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c
+++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
@@ -70,20 +70,21 @@ void free_gNB_pucch(NR_gNB_PUCCH_t *pucch)
 int nr_find_pucch(uint16_t rnti,
                   int frame,
                   int slot,
-                  PHY_VARS_gNB *gNB) {
+                  PHY_VARS_gNB *gNB)
+{
 
   AssertFatal(gNB!=NULL,"gNB is null\n");
   int index = -1;
 
-  for (int i = 0; i < NUMBER_OF_NR_PUCCH_MAX; i++) {
+  for (int i = 0; i < gNB->max_nb_pucch; i++) {
     AssertFatal(gNB->pucch[i] != NULL,"gNB->pucch[%d] is null\n",i);
     if ((gNB->pucch[i]->active > 0) &&
         (gNB->pucch[i]->pucch_pdu.rnti == rnti) &&
         (gNB->pucch[i]->frame == frame) &&
         (gNB->pucch[i]->slot == slot))
-      return(i);
+      return i;
     else if ((gNB->pucch[i]->active == 0) && (index == -1))
-      index=i;
+      index = i;
   }
 
   if (index==-1)
@@ -95,11 +96,13 @@ int nr_find_pucch(uint16_t rnti,
 void nr_fill_pucch(PHY_VARS_gNB *gNB,
                    int frame,
                    int slot,
-                   nfapi_nr_pucch_pdu_t *pucch_pdu) {
+                   nfapi_nr_pucch_pdu_t *pucch_pdu)
+{
+
   if (NFAPI_MODE == NFAPI_MODE_PNF)
     gNB->pucch[0]->active = 0; //check if ture in monolithic mode 
   int id = nr_find_pucch(pucch_pdu->rnti,frame,slot,gNB);
-  AssertFatal((id >= 0) && (id < NUMBER_OF_NR_PUCCH_MAX),
+  AssertFatal((id >= 0) && (id < gNB->max_nb_pucch),
               "invalid id found for pucch !!! rnti %04x id %d\n",pucch_pdu->rnti,id);
 
   NR_gNB_PUCCH_t  *pucch = gNB->pucch[id];
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 0f2f41c47041926516aa808411660a8217ab6bc0..73cad1fc87f5ca36f76ab0ef7c035ab04382956f 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -617,12 +617,13 @@ typedef struct PHY_VARS_gNB_s {
   nfapi_nr_ul_tti_request_t     UL_tti_req;
   nfapi_nr_uci_indication_t uci_indication;
   
+  int max_nb_pucch;
   NR_gNB_PBCH        pbch;
   NR_gNB_COMMON      common_vars;
   NR_gNB_PRACH       prach_vars;
   NR_gNB_PRS         prs_vars;
   NR_gNB_PUSCH       *pusch_vars[NUMBER_OF_NR_ULSCH_MAX];
-  NR_gNB_PUCCH_t     *pucch[NUMBER_OF_NR_PUCCH_MAX];
+  NR_gNB_PUCCH_t     **pucch;
   NR_gNB_SRS_t       *srs[NUMBER_OF_NR_SRS_MAX];
   NR_gNB_PDCCH_t     pdcch_pdu[NUMBER_OF_NR_PDCCH_MAX];
   NR_gNB_UL_PDCCH_t  ul_pdcch_pdu[NUMBER_OF_NR_PDCCH_MAX];
diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c
index 25c39846fe0e57ef492b362fe089906c0eb43ecf..9ed7255a84a7d9a962d51beab89f7fb7bfc38d31 100644
--- a/openair1/SCHED_NR/phy_frame_config_nr.c
+++ b/openair1/SCHED_NR/phy_frame_config_nr.c
@@ -33,6 +33,7 @@
 #include "PHY/defs_gNB.h"
 #include "PHY/defs_nr_UE.h"
 #include "SCHED_NR/phy_frame_config_nr.h"
+#include "common/utils/nr/nr_common.h"
 
 /*******************************************************************
 *
@@ -53,48 +54,13 @@
 int set_tdd_config_nr( nfapi_nr_config_request_scf_t *cfg,
                        int mu,
                        int nrofDownlinkSlots, int nrofDownlinkSymbols,
-                       int nrofUplinkSlots,   int nrofUplinkSymbols) {
+                       int nrofUplinkSlots,   int nrofUplinkSymbols)
+{
+
   int slot_number = 0;
-  int nb_periods_per_frame;
+  int nb_periods_per_frame = get_nb_periods_per_frame(cfg->tdd_table.tdd_period.value);
   int nb_slots_to_set = TDD_CONFIG_NB_FRAMES*(1<<mu)*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
 
-  switch(cfg->tdd_table.tdd_period.value) {
-    case 0:
-      nb_periods_per_frame = 20; // 10ms/0p5ms
-      break;
-
-    case 1:
-      nb_periods_per_frame = 16; // 10ms/0p625ms
-      break;
-
-    case 2:
-      nb_periods_per_frame = 10; // 10ms/1ms
-      break;
-
-    case 3:
-      nb_periods_per_frame = 8; // 10ms/1p25ms
-      break;
-
-    case 4:
-      nb_periods_per_frame = 5; // 10ms/2ms
-      break;
-
-    case 5:
-      nb_periods_per_frame = 4; // 10ms/2p5ms
-      break;
-
-    case 6:
-      nb_periods_per_frame = 2; // 10ms/5ms
-      break;
-
-    case 7:
-      nb_periods_per_frame = 1; // 10ms/10ms
-      break;
-
-    default:
-      AssertFatal(1==0,"Undefined tdd period %d\n", cfg->tdd_table.tdd_period.value);
-  }
-
   int nb_slots_per_period = ((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME)/nb_periods_per_frame;
 
   if ( (nrofDownlinkSymbols + nrofUplinkSymbols) == 0 )
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 38e1cfd3b4d977d57659a94cccf23aaa38195cf6..d53eed2c1ef7cf61dd917390e6836eae6c978d13 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -529,7 +529,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
     }
   }
 
-  for (int i=0;i<NUMBER_OF_NR_PUCCH_MAX;i++){
+  for (int i = 0; i < gNB->max_nb_pucch; i++){
     NR_gNB_PUCCH_t *pucch = gNB->pucch[i];
     if (pucch) {
       if ((pucch->active == 1) &&
@@ -713,7 +713,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
 
   start_meas(&gNB->phy_proc_rx);
 
-  for (int i=0;i<NUMBER_OF_NR_PUCCH_MAX;i++){
+  for (int i = 0; i < gNB->max_nb_pucch; i++){
     NR_gNB_PUCCH_t *pucch = gNB->pucch[i];
     if (pucch) {
       if (NFAPI_MODE == NFAPI_MODE_PNF)