diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index 27d578efea8628c6860039fb6c395b32aaa07edc..c7f6bba473cf702b3672c1f093541f6c8e49a352 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -343,8 +343,13 @@ void nr_decode_pucch1(int32_t **rxdataF,
                       uint8_t timeDomainOCC,
                       uint8_t nr_bit);
 
+void nr_decode_pucch2(PHY_VARS_gNB *gNB,
+                      int slot,
+                      nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu,
+                      nfapi_nr_pucch_pdu_t* pucch_pdu);
+
 void nr_decode_pucch0(PHY_VARS_gNB *gNB,
-              int slot,
+                      int slot,
                       nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu,
                       nfapi_nr_pucch_pdu_t* pucch_pdu);
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
index 7ff52ae69252ff5d799cfff36f2a836386786592..f4f977ff7481a150bc5bf4d3d47cabec3dc4dab5 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
@@ -75,6 +75,12 @@ void nr_ulsch_unscrambling(int16_t* llr,
                          uint32_t n_RNTI);
 
 
+void nr_ulsch_unscrambling_optim(int16_t* llr,
+				 uint32_t size,
+				 uint8_t q,
+				 uint32_t Nid,
+				 uint32_t n_RNTI);
+
 void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
                          int frame_rx,
                          int slot_rx,
diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
index e61b3c48c0e307e07a44b4215cb8682a840e7560..ff969323f4c0b880166c7d83bf119f270eac2554 100644
--- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c
+++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
@@ -373,6 +373,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
 
   index=maxpos;
 #endif
+
   // first bit of bitmap for sr presence and second bit for acknack presence
   uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
   uci_pdu->pucch_format = 0; // format 0
diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h
index b393e9566e7a744dfbe609f952653f8c79ac07c1..59ac1496e779a9bb1ff9420f26dbc8cf092bc2c0 100644
--- a/openair1/SCHED_NR/sched_nr.h
+++ b/openair1/SCHED_NR/sched_nr.h
@@ -34,7 +34,7 @@
 #include "PHY/NR_TRANSPORT/nr_dci.h"
 #include "phy_frame_config_nr.h"
 
-
+void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
 void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp);
 void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas);
 void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c
index 424c763a5a9dba2d732d1e3f9c13c23b629eb78c..1004b96443db0eb76099535679112a18c40dbfc3 100644
--- a/openair1/SIMULATION/NR_PHY/pucchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pucchsim.c
@@ -36,6 +36,7 @@
 #include "PHY/NR_REFSIG/nr_mod_table.h"
 #include "PHY/MODULATION/modulation_eNB.h"
 #include "PHY/MODULATION/modulation_UE.h"
+#include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
 #include "PHY/INIT/phy_init.h"
 #include "PHY/NR_TRANSPORT/nr_transport_proto.h"
 #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
@@ -521,6 +522,15 @@ int main(int argc, char **argv)
       }
       int rxlev = signal_energy(&rxdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size],
 				frame_parms->ofdm_symbol_size);
+
+      // noise measurement
+      gNB->ulmask_symb = startingSymbolIndex;
+      for (int rb=0; rb<nrofPRB; rb++) {
+        int rb2 = rb+startingPRB;
+        gNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
+      }
+      gNB_I0_measurements(gNB);
+
       if (n_trials==1) printf("rxlev %d (%d dB), sigma2 %f dB, SNR %f, TX %f\n",rxlev,dB_fixed(rxlev),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12));
       if(format==0){
 	nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu;