From b0b5cb21e53fade58af575ac2cd0794af191803e Mon Sep 17 00:00:00 2001
From: Florian Kaltenberger <florian.kaltenberger@eurecom.fr>
Date: Wed, 18 Jan 2017 15:31:04 +0100
Subject: [PATCH] Beamforming is now only done when necessary. This patch is
 based on one from enhancement-10-harmony.

---
 openair1/PHY/INIT/lte_init.c        |  1 +
 openair1/PHY/MODULATION/defs.h      |  2 +-
 openair1/PHY/MODULATION/ofdm_mod.c  | 22 +++++++++++-----------
 openair1/PHY/defs.h                 |  2 ++
 openair1/SIMULATION/LTE_PHY/dlsim.c |  6 ++++--
 targets/RT/USER/lte-enb.c           | 20 ++++++++++++++------
 6 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index accc54af547..4d927dc5d3d 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -684,6 +684,7 @@ void phy_config_dedicated_eNB(uint8_t Mod_id,
 	break;
       case AntennaInfoDedicated__transmissionMode_tm7:
         lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti);
+	eNB->do_precoding = 1;
 	eNB->transmission_mode[UE_id] = 7;
 	break;
       default:
diff --git a/openair1/PHY/MODULATION/defs.h b/openair1/PHY/MODULATION/defs.h
index 6937db6d9bb..da599114a91 100644
--- a/openair1/PHY/MODULATION/defs.h
+++ b/openair1/PHY/MODULATION/defs.h
@@ -82,7 +82,7 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA
 
 void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
 
-void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
+void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms,int do_precoding);
 
 void remove_7_5_kHz(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe);
 
diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c
index 74037b4a6e0..8e09cea1ec7 100644
--- a/openair1/PHY/MODULATION/ofdm_mod.c
+++ b/openair1/PHY/MODULATION/ofdm_mod.c
@@ -285,16 +285,16 @@ void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t ne
 }
 
 // OFDM modulation for each symbol
-void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms)
+void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms,int do_precoding)
 {
 
-  int aa, l, slot_offset;
-  int32_t **txdataF = eNB_common_vars->txdataF[eNB_id];
+  int aa, l, slot_offset, slot_offsetF;
+  int32_t **txdataF    = eNB_common_vars->txdataF[eNB_id];
   int32_t **txdataF_BF = eNB_common_vars->txdataF_BF[eNB_id];
-  int32_t **txdata = eNB_common_vars->txdata[eNB_id];
-
-  slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1);
+  int32_t **txdata     = eNB_common_vars->txdata[eNB_id];
 
+  slot_offset  = (next_slot)*(frame_parms->samples_per_tti>>1);
+  slot_offsetF = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==EXTENDED) ? 6 : 7);
   //printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc());
   for (l=0; l<frame_parms->symbols_per_tti>>1; l++) {
   
@@ -302,13 +302,13 @@ void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t ne
 
       //printf("do_OFDM_mod_l, slot=%d, l=%d, NUMBER_OF_OFDM_CARRIERS=%d,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES=%d\n",next_slot, l,NUMBER_OF_OFDM_CARRIERS,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,1);
-      beam_precoding(txdataF,txdataF_BF,frame_parms,eNB_common_vars->beam_weights[eNB_id],next_slot,l,aa);
+      if (do_precoding==1) beam_precoding(txdataF,txdataF_BF,frame_parms,eNB_common_vars->beam_weights[eNB_id],next_slot,l,aa);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,0);
 
       //PMCH case not implemented... 
 
-      if (frame_parms->Ncp == 1)
-        PHY_ofdm_mod(txdataF_BF[aa],         // input
+      if (frame_parms->Ncp == EXTENDED)
+        PHY_ofdm_mod((do_precoding == 1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size],         // input
                      &txdata[aa][slot_offset+l*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],            // output
                      frame_parms->ofdm_symbol_size,       
                      1,                                   // number of symbols
@@ -316,7 +316,7 @@ void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t ne
                      CYCLIC_PREFIX);
       else {
         if (l==0) {
-          PHY_ofdm_mod(txdataF_BF[aa],        // input
+          PHY_ofdm_mod((do_precoding==1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size],        // input
                        &txdata[aa][slot_offset],           // output
                        frame_parms->ofdm_symbol_size,      
                        1,                                  // number of symbols
@@ -324,7 +324,7 @@ void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t ne
                        CYCLIC_PREFIX);
            
         } else {
-          PHY_ofdm_mod(txdataF_BF[aa],        // input
+	  PHY_ofdm_mod((do_precoding==1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size],        // input
                        &txdata[aa][slot_offset+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(l-1)*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],           // output
                        frame_parms->ofdm_symbol_size,      
                        1,                                  // number of symbols
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index d462fe58cb3..0bc7c6e1c1a 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -415,6 +415,8 @@ typedef struct PHY_VARS_eNB_s {
   int                  single_thread_flag;
   openair0_rf_map      rf_map;
   int                  abstraction_flag;
+  // indicator for precoding function (eNB,3GPP_eNB_BBU)
+  int                  do_precoding;
   void                 (*do_prach)(struct PHY_VARS_eNB_s *eNB);
   void                 (*fep)(struct PHY_VARS_eNB_s *eNB);
   int                  (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag);
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index f9a8acfa85c..0682308ab73 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -2409,12 +2409,14 @@ int main(int argc, char **argv)
             do_OFDM_mod_symbol(&eNB->common_vars,
                                eNB_id,
                                (subframe*2),
-                               &eNB->frame_parms);
+                               &eNB->frame_parms,
+			       eNB->do_precoding);
 
             do_OFDM_mod_symbol(&eNB->common_vars,
                                eNB_id,
                                (subframe*2)+1,
-                               &eNB->frame_parms);
+                               &eNB->frame_parms,
+			       eNB->do_precoding);
 
 
 	    stop_meas(&eNB->ofdm_mod_stats);
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index a3d6d96e03c..331a2b5fe10 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -296,16 +296,18 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,1);
 
     do_OFDM_mod_symbol(&phy_vars_eNB->common_vars,
-                  0,
-                  subframe<<1,
-                  &phy_vars_eNB->frame_parms);
+		       0,
+		       subframe<<1,
+		       &phy_vars_eNB->frame_parms,
+		       &phy_vars_eNB->do_precoding);
  
     // if S-subframe generate first slot only 
     if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL) {
       do_OFDM_mod_symbol(&phy_vars_eNB->common_vars,
-                    0,
-                    1+(subframe<<1),
-                    &phy_vars_eNB->frame_parms);
+			 0,
+			 1+(subframe<<1),
+			 &phy_vars_eNB->frame_parms,
+			 &phy_vars_eNB->do_precoding);
     }
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,0);
@@ -1637,6 +1639,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
       case NGFI_RRU_IF5:
 	eNB->do_prach             = NULL;
 	eNB->fep                  = eNB_fep_rru_if5;
+	eNB->do_precoding         = 0;
 	eNB->td                   = NULL;
 	eNB->te                   = NULL;
 	eNB->proc_uespec_rx       = NULL;
@@ -1661,6 +1664,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
         }
 	break;
       case NGFI_RRU_IF4p5:
+	eNB->do_precoding         = 0;
 	eNB->do_prach             = do_prach;
 	eNB->fep                  = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full;
 	eNB->td                   = NULL;
@@ -1690,6 +1694,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
 
 	break;
       case eNodeB_3GPP:
+	eNB->do_precoding         = eNB->frame_parms.nb_antennas_tx==eNB->frame_parms.nb_antenna_ports_eNB;
 	eNB->do_prach             = do_prach;
 	eNB->fep                  = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full;
 	eNB->td                   = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data;
@@ -1710,6 +1715,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
 	eNB->ifdevice.host_type   = BBU_HOST;
 	break;
       case eNodeB_3GPP_BBU:
+	eNB->do_precoding   = eNB->frame_parms.nb_antennas_tx==eNB->frame_parms.nb_antenna_ports_eNB;
 	eNB->do_prach       = do_prach;
 	eNB->fep            = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full;
 	eNB->td             = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data;
@@ -1742,6 +1748,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
         }
 	break;
       case NGFI_RCC_IF4p5:
+	eNB->do_precoding         = 0;
 	eNB->do_prach             = do_prach;
 	eNB->fep                  = NULL;
 	eNB->td                   = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data;
@@ -1765,6 +1772,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
 
 	break;
       case NGFI_RAU_IF4p5:
+	eNB->do_precoding   = 0;
 	eNB->do_prach       = do_prach;
 	eNB->fep            = NULL;
 
-- 
GitLab