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 e1bd4191b35744f7fd8041b154c8d7c693337ccd..b227acd5e479a7301a8851ad01d28c39d258be59 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
@@ -375,8 +375,8 @@ typedef struct{
 
 typedef struct {
   nfapi_tl_t tl;
-  nfapi_nr_search_space_t search_space;
-  
+  nfapi_nr_coreset_t coreset;
+  nfapi_nr_search_space_t search_space;  
 } nfapi_nr_dl_config_pdcch_parameters_rel15_t;
 
 typedef struct {
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index ac745d05bbe4dfd29ee10b286417011f65f03ca7..f99a201d183534c8d354fad5d2d31d7f90a48470 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -165,25 +165,69 @@ uint8_t nr_generate_dci_top(NR_gNB_DCI_ALLOC_t dci_alloc,
 
   uint16_t mod_dmrs[NR_MAX_PDCCH_DMRS_LENGTH<<1];
   uint8_t idx=0;
+  uint16_t a;
+  int k,l;
+  nr_cce_t cce;
 
   /// DMRS QPSK modulation
-  for (int m=0; m<NR_MAX_PDCCH_DMRS_LENGTH>>1; m++) {
-    idx = ((((gold_pdcch_dmrs[(m<<1)>>5])>>((m<<1)&0x1f))&1)<<1) ^ (((gold_pdcch_dmrs[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1);
-    mod_dmrs[m<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
-    mod_dmrs[(m<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
+  for (int i=0; i<NR_MAX_PDCCH_DMRS_LENGTH>>1; i++) {
+    idx = ((((gold_pdcch_dmrs[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((gold_pdcch_dmrs[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
+    mod_dmrs[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
+    mod_dmrs[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
 #ifdef DEBUG_PDCCH_DMRS
-  printf("m %d idx %d gold seq %d b0-b1 %d-%d mod_dmrs %d %d\n", m, idx, gold_pdcch_dmrs[(m<<1)>>5], (((gold_pdcch_dmrs[(m<<1)>>5])>>((m<<1)&0x1f))&1),
-  (((gold_pdcch_dmrs[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1), mod_dmrs[(m<<1)], mod_dmrs[(m<<1)+1]);
+  printf("i %d idx %d gold seq %d b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, gold_pdcch_dmrs[(i<<1)>>5], (((gold_pdcch_dmrs[(i<<1)>>5])>>((i<<1)&0x1f))&1),
+  (((gold_pdcch_dmrs[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), mod_dmrs[(i<<1)], mod_dmrs[(i<<1)+1]);
 #endif
   }
 
   /// DCI payload processing
+    //channel coding
+  
     // scrambling
   uint32_t scrambled_payload[4]; 
   nr_pdcch_scrambling(dci_alloc, pdcch_vars, config, scrambled_payload);
 
     // QPSK modulation
-  
+  uint32_t mod_dci[NR_MAX_DCI_SIZE>>1];
+  for (int i=0; i<dci_alloc.size>>1; i++) {
+    idx = (((scrambled_payload[i<<1]>>(i<<1))&1)<<1) ^ ((scrambled_payload[(i<<1)+1]>>((i<<1)+1))&1);
+    mod_dci[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
+    mod_dci[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
+  }
+
+  /// Resource mapping
+  a = (config.rf_config.tx_antenna_ports.value == 1) ? amp : (amp*ONE_OVER_SQRT2_Q15)>>15;
+  uint8_t n_rb = pdcch_vars.coreset_params.n_rb;
+  uint8_t rb_offset = pdcch_vars.coreset_params.n_symb;
+  uint8_t n_symb = pdcch_vars.coreset_params.rb_offset;
+  uint8_t first_slot = pdcch_vars.first_slot;
+  uint8_t first_symb = pdcch_vars.ss_params.first_symbol_idx;
+
+   /*The coreset is initialised
+    * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset
+    * in time: by its first slot and its first symbol*/
+  uint8_t cset_start_sc = frame_parms.first_carrier_offset + ((int)floor(frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB)+rb_offset)*NR_NB_SC_PER_RB;
+  uint8_t cset_start_symb = first_slot*frame_parms.symbols_per_slot + first_symb;
+
+  for (int aa = 0; aa < config.rf_config.tx_antenna_ports.value; aa++)
+  {
+    if (cset_start_sc >= frame_parms.ofdm_symbol_size)
+      cset_start_sc -= frame_parms.ofdm_symbol_size;
+
+    for (int cce_idx=0; cce_idx<dci_alloc.L; cce_idx++){
+      cce = pdcch_vars.cce_list[cce_idx];
+      k = cset_start_sc + cce.start_sc_idx;
+      l = cset_start_symb + cce.symb_idx;
+      for (int m=0; m<NR_NB_SC_PER_RB; m++) {
+        ((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (a * mod_dci[m<<1]) >> 15;
+        ((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (a * mod_dci[(m<<1) + 1]) >> 15;
+        k++;
+        if (k >= frame_parms.ofdm_symbol_size)
+          k -= frame_parms.ofdm_symbol_size;
+      }
+    }
+
+  }
 
   return 0;
 }
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h
index 6ada2948b2ecb4de6e59d621fb28fecd8f1d5881..ab7cb5023a58f0e2467b375772c07c59df364743 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h
@@ -78,15 +78,21 @@ typedef struct {
   uint8_t n_rb;
   uint8_t n_symb;
   uint8_t rb_offset;
+  nr_cce_reg_mapping_type_e cr_mapping_type;
   nr_ssb_and_cset_mux_pattern_type_e mux_pattern;
 } nr_pdcch_coreset_params_t;
 
+typedef struct {
+  uint8_t start_sc_idx;
+  uint8_t symb_idx;
+} nr_cce_t;
+
 typedef struct {
   uint8_t first_slot;
   uint8_t nb_slots;
   uint8_t sfn_mod2;
   uint32_t dmrs_scrambling_id;
-  nr_cce_reg_mapping_type_e cr_mapping_type;
+  nr_cce_t cce_list[NR_MAX_PDCCH_AGG_LEVEL];
   nr_pdcch_ss_params_t ss_params;
   nr_pdcch_coreset_params_t coreset_params;
 } nr_pdcch_vars_t;
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index f760fe344ada268d12e651e4686a9c85b0b56163..b30ed9e4a31dfdedd2d8591c28fb946d83ae2381 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -42,6 +42,8 @@
 
 #define MAX_NUM_SUBCARRIER_SPACING 5
 
+#define NR_NB_SC_PER_RB 12
+
 #define NR_SYMBOLS_PER_SLOT 14
 
 #define ONE_OVER_SQRT2_Q15 23170
@@ -60,8 +62,13 @@
 #define NR_MAX_PDCCH_DMRS_LENGTH 100
 #define NR_MAX_PDCCH_DMRS_LENGTH_DWORD 5
 
+#define NR_MAX_DCI_PAYLOAD_SIZE 64
+#define NR_MAX_DCI_SIZE 200 //random values
+
 #define NR_MAX_NUM_BWP 4
 
+#define NR_MAX_PDCCH_AGG_LEVEL 16
+
 typedef enum {
   NR_MU_0=0,
   NR_MU_1,
diff --git a/openair1/SCHED_NR/phy_procedures_nr_common.c b/openair1/SCHED_NR/phy_procedures_nr_common.c
index 8b2263781444d9e421ecb910b5b09c810b1fe41e..8d88770acfcb0b91ed23b066e299a633d8654152 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_common.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_common.c
@@ -39,7 +39,7 @@ uint8_t nr_coreset_nsymb_pdcch_type_0_a40Mhz[10] = {2,2,3,3,1,1,2,2,3,3}; // abo
 /// LUT for the number of RBs in the coreset indexed by coreset index
 uint8_t nr_coreset_rb_offset_pdcch_type_0_b40Mhz[16] = {0,1,2,3,4,0,1,2,3,4,12,14,16,12,14,16};
 uint8_t nr_coreset_rb_offset_pdcch_type_0_a40Mhz[10] = {0,4,0,4,0,28,0,28,0,28};
-/// LUT for monitoring occasions param O indexed by ss index (4 MSB rmsi_pdcch_config)
+/// LUT for monitoring occasions param O indexed by ss index (4 LSB rmsi_pdcch_config)
 uint8_t nr_ss_param_O_type_0_mux1_FR1[16] = {0,0,2,2,5,5,7,7,0,5,0,0,2,2,5,5};
 uint8_t nr_ss_param_O_type_0_mux1_FR2[14] = {0,0,2.5,2.5,5,5,0,2.5,5,7.5,7.5,7.5,0,5};
 /// LUT for number of SS sets per slot indexed by ss index