diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index ff4a452866e0ecba89e2a0e6a74a10fe303344c6..c7836e7a7f96c47e854a516ecefaac665daf1599 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -515,12 +515,12 @@ set (CONFIG_SOURCES ${CONFIG_ROOTDIR}/config_load_configmodule.c ${CONFIG_ROOTDIR}/config_userapi.c ${CONFIG_ROOTDIR}/config_cmdline.c - ) + ) set (CONFIG_LIBCONFIG_SOURCES ${CONFIG_ROOTDIR}/libconfig/config_libconfig.c - ) + ) add_library(params_libconfig MODULE ${CONFIG_LIBCONFIG_SOURCES} ) -target_link_libraries(params_libconfig config) +target_link_libraries(params_libconfig config) # shared library loader set (SHLIB_LOADER_SOURCES ${OPENAIR_DIR}/common/utils/load_module_shlib.c @@ -665,6 +665,7 @@ add_boolean_option(SMBV False "Rohde&Schwarz SMBV100A vector add_boolean_option(DEBUG_PHY False "Enable PHY layer debugging options") add_boolean_option(DEBUG_PHY_PROC False "Enable debugging of PHY layer procedures") add_boolean_option(DEBUG_DLSCH False "Enable debugging of DLSCH physical layer channel") +add_boolean_option(MEX False "Enabling compilation with mex") ########################## # NAS LAYER OPTIONS @@ -984,7 +985,7 @@ set(SECU_CN_SRC ) add_library(SECU_CN ${SECU_CN_SRC}) -# Physical Channel Procedures Scheduling +# Physical Channel Procedures Scheduling ################################" set(SCHED_SRC ${OPENAIR1_DIR}/SCHED/fapi_l1.c @@ -1084,6 +1085,7 @@ set(PHY_SRC_COMMON # ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/slss.c # ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sldch.c # ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/slsch.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/get_pmi.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/group_hopping.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/phich_common.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pcfich_common.c @@ -1172,6 +1174,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/sss_ue.c ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/uci_tools_ue.c @@ -1219,6 +1222,27 @@ add_library(PHY ${PHY_SRC}) add_library(PHY_UE ${PHY_SRC_UE}) add_library(PHY_RU ${PHY_SRC_RU}) +#Library for mex functions +#########################3 +set(PHY_MEX_UE + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c + ${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/get_pmi.c + ${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pmch_common.c + ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c + ${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c + ${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c + ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ue_measurements.c + ${OPENAIR2_DIR}/UTIL/LOG/log.c + ) +add_library(PHY_MEX ${PHY_MEX_UE}) + #Layer 2 library ##################### set(MAC_DIR ${OPENAIR2_DIR}/LAYER2/MAC) @@ -1814,11 +1838,13 @@ endif() # So, here are some hacks here. Hope this gets fixed in future! if(EXISTS "/usr/include/atlas/cblas.h" OR EXISTS "/usr/include/cblas.h") include_directories("/usr/include/atlas") + LINK_DIRECTORIES("/usr/lib/lapack") LINK_DIRECTORIES("/usr/lib64") LINK_DIRECTORIES("/usr/lib64/atlas") #Added because atlas libraries in CentOS 7 are here! - + if(EXISTS "/usr/lib64/libblas.so" OR EXISTS "/usr/lib/libblas.so") #Case for CentOS7 list(APPEND ATLAS_LIBRARIES blas) + else() # Case for Ubuntu list(APPEND ATLAS_LIBRARIES cblas) endif() @@ -1844,6 +1870,8 @@ else() message("No Blas/Atlas libs found, some targets will fail") endif() +list(APPEND ATLAS_LIBRARIES lapack lapacke) + if (${XFORMS}) include_directories ("/usr/include/X11") set(XFORMS_SOURCE @@ -1926,7 +1954,7 @@ add_executable(lte-softmodem target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 + RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) @@ -1964,7 +1992,7 @@ add_executable(lte-softmodem-nos1 ) target_link_libraries (lte-softmodem-nos1 -Wl,--start-group - RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} + RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl ) @@ -2004,8 +2032,8 @@ add_executable(lte-uesoftmodem target_link_libraries (lte-uesoftmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU - ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 + RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) @@ -2044,8 +2072,8 @@ add_executable(lte-uesoftmodem-nos1 target_link_libraries (lte-uesoftmodem-nos1 -Wl,--start-group - RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} - ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 + RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} + ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl ) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index d5a2d9412c05e5b22c5415281271d1a67a315c9c..f51d3656a1f53bff18c6f9cd7c207741d78f41a0 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -56,7 +56,7 @@ white='\E[37m' reset_color='\E[00m' COLORIZE=1 -cecho() { +cecho() { # Color-echo # arg1 = message # arg2 = color @@ -147,10 +147,10 @@ clean_kernel() { clean_all_files() { set_openair_env dir=$OPENAIR_DIR/cmake_targets - rm -rf $dir/log $OPENAIR_DIR/targets/bin/* + rm -rf $dir/log $OPENAIR_DIR/targets/bin/* rm -rf $dir/lte_build_oai $dir/lte-simulators/build rm -rf $dir/oaisim_build_oai/build $dir/oaisim_build_oai/CMakeLists.txt - rm -rf $dir/autotests/bin $dir/autotests/log $dir/autotests/*/build + rm -rf $dir/autotests/bin $dir/autotests/log $dir/autotests/*/build } ################################### @@ -272,7 +272,7 @@ check_install_usrp_uhd_driver(){ v=$(lsb_release -cs) $SUDO apt-add-repository --remove "deb http://files.ettus.com/binaries/uhd/repo/uhd/ubuntu/$v $v main" # The new USRP repository - # Raphael Defosseux: Adding a loop on adding PPA because in CI the gpg key retrieve may + # Raphael Defosseux: Adding a loop on adding PPA because in CI the gpg key retrieve may # timeout due to proxy / network latencies in Eurecom on VM echo_info "\nAdding PPA repository ettusresearch/uhd\n" x=0 @@ -352,7 +352,7 @@ check_install_bladerf_driver(){ fi $SUDO apt-get install -y --allow-unauthenticated bladerf libbladerf-dev $SUDO apt-get install -y --allow-unauthenticated bladerf-firmware-fx3 - $SUDO apt-get install -y --allow-unauthenticated bladerf-fpga-hostedx40 + $SUDO apt-get install -y --allow-unauthenticated bladerf-fpga-hostedx40 elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then install_bladerf_driver_from_source else @@ -373,7 +373,7 @@ check_install_lmssdr_driver(){ echo_error "lmssdr support implies installing lmssdr drivers and tools" \ " from sources. check:" echo_info "https://open-cells.com/index.php/2017/05/10/limesdr-installation/" - echo_fatal "Cannot compile lmssdr device" + echo_fatal "Cannot compile lmssdr device" fi @@ -470,7 +470,7 @@ check_install_additional_tools (){ python2-matplotlib" fi $SUDO $INSTALLER install -y $PACKAGE_LIST - + $SUDO rm -fr /opt/ssh $SUDO GIT_SSL_NO_VERIFY=true git clone https://gitlab.eurecom.fr/oai/ssh.git /opt/ssh @@ -549,6 +549,8 @@ check_install_oai_software() { iptables-dev \ libatlas-base-dev \ libblas-dev \ + liblapack-dev\ + liblapacke-dev\ libffi-dev \ libforms-bin \ libforms-dev \ @@ -602,7 +604,7 @@ check_install_oai_software() { # Fedora repos already contain gccxml's successor castxml. $SUDO $INSTALLER install -y castxml fi - + $SUDO $INSTALLER install -y \ autoconf \ automake \ @@ -689,7 +691,7 @@ install_asn1c_from_source(){ } ################################################# -# 2. compile +# 2. compile ################################################ install_nas_tools() { @@ -718,7 +720,7 @@ set_openair_env(){ [ -f "/.$fullpath" ] || fullpath=`readlink -f $PWD/$fullpath` openair_path=${fullpath%/cmake_targets/*} openair_path=${openair_path%/targets/*} - openair_path=${openair_path%/openair[123]/*} + openair_path=${openair_path%/openair[123]/*} export OPENAIR_DIR=$openair_path export OPENAIR1_DIR=$openair_path/openair1 export OPENAIR2_DIR=$openair_path/openair2 @@ -735,7 +737,7 @@ ppid=$$ arraycounter=1 echo_info "** Trapped CTRL-C. Killing all subprocesses now..." echo_info "** Calling sync now..." -sync +sync while true do FORLOOP=FALSE @@ -753,7 +755,7 @@ do arraycounter=`expr $arraycounter - 1` ## We want to kill child process id first and then parent id's while [ $arraycounter -ne 0 ] - do + do echo "first we send ctrl-c to program" $SUDO kill -INT "${procid[$arraycounter]}" sleep 5 diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c index 842fb376a05c60349ef2674a6e2e3569f7ac87f2..6cb2ae47386c88e4234e6d157c5cc805223ad8f9 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c @@ -165,49 +165,6 @@ int8_t delta_PUSCH_acc[4] = {-1,0,1,3}; int8_t *delta_PUCCH_lut = delta_PUSCH_acc; -uint8_t get_pmi(uint8_t N_RB_DL, MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb) -{ - /* - MIMO_mode_t mode = dlsch_harq->mimo_mode; - uint32_t pmi_alloc = dlsch_harq->pmi_alloc; - */ - - switch (N_RB_DL) { - case 6: // 1 PRB per subband - if (mode <= PUSCH_PRECODING1) - return((pmi_alloc>>(rb<<1))&3); - else - return((pmi_alloc>>rb)&1); - - break; - - default: - case 25: // 4 PRBs per subband - if (mode <= PUSCH_PRECODING1) - return((pmi_alloc>>((rb>>2)<<1))&3); - else - return((pmi_alloc>>(rb>>2))&1); - - break; - - case 50: // 6 PRBs per subband - if (mode <= PUSCH_PRECODING1) - return((pmi_alloc>>((rb/6)<<1))&3); - else - return((pmi_alloc>>(rb/6))&1); - - break; - - case 100: // 8 PRBs per subband - if (mode <= PUSCH_PRECODING1) - return((pmi_alloc>>((rb>>3)<<1))&3); - else - return((pmi_alloc>>(rb>>3))&1); - - break; - } -} - uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t lprime,uint8_t mi) { @@ -330,7 +287,7 @@ void conv_eMTC_rballoc(uint16_t resource_block_coding, uint32_t N_RB_DL, uint32_t *rb_alloc) { - + int narrowband = resource_block_coding>>5; int RIV = resource_block_coding&31; int N_NB_DL = N_RB_DL/6; @@ -346,7 +303,7 @@ void conv_eMTC_rballoc(uint16_t resource_block_coding, rb_alloc[2] = 0; rb_alloc[3] = 0; rb_alloc[ind] = alloc<<ind_mod; - if (ind_mod > 26) rb_alloc[ind+1] = alloc>>(6-(ind_mod-26)); + if (ind_mod > 26) rb_alloc[ind+1] = alloc>>(6-(ind_mod-26)); } void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t *rb_alloc2) @@ -410,7 +367,7 @@ void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t // bit mask across if ((rb_alloc2[0]>>31)==1) rb_alloc2[1] |= 1; - + if ((rb_alloc&1) != 0) rb_alloc2[1] |= (3<<16); break; @@ -420,7 +377,7 @@ void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t for (i=0; i<25; i++) { if ((rb_alloc&(1<<(24-i))) != 0) rb_alloc2[(4*i)>>5] |= (0xf<<((4*i)%32)); - + // printf("rb_alloc2[%d] (type 0) %x (%d)\n",(4*i)>>5,rb_alloc2[(4*i)>>5],rb_alloc&(1<<i)); } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index ce30aff04238767b8d800f8ccedcc1925c52a89b..5bf6f073d86180cc41a5acdf6d025aa194c16c79 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -37,7 +37,7 @@ #include "PHY/LTE_TRANSPORT/transport_eNB.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" - +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" //#define DEBUG_DLSCH_MODULATION #define NEW_ALLOC_RE @@ -714,8 +714,8 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, int first_layer0 = -1; //= dlsch0_harq->first_layer; int Nlayers0 = -1; // = dlsch0_harq->Nlayers; - uint8_t mod_order0=0; - uint8_t mod_order1=0; + uint8_t mod_order0=0; + uint8_t mod_order1=0; uint8_t precoder_index0,precoder_index1; uint8_t *x1=NULL; diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c index 81347085539ef01ace695a7eb85e891fee79f0a9..9750656a4fe736590b56add4a60625c6e54e0dcc 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -36,8 +36,18 @@ #include "transport_proto_ue.h" #include "PHY/sse_intrin.h" #include "T.h" +#include<stdio.h> +#include<math.h> +#include <stdlib.h> +#include <string.h> +#include <lapacke_utils.h> +#include <lapacke.h> +#include <cblas.h> +#include "linear_preprocessing_rec.h" #define NOCYGWIN_STATIC +//#define DEBUG_MMSE + /* dynamic shift for LLR computation for TM3/4 * set as command line argument, see lte-softmodem.c @@ -103,6 +113,7 @@ int rx_pdsch(PHY_VARS_UE *ue, int avg[4]; int avg_0[2]; int avg_1[2]; + unsigned short mmse_flag=0; #if UE_TIMING_TRACE uint8_t slot = 0; @@ -440,14 +451,15 @@ int rx_pdsch(PHY_VARS_UE *ue, ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))) { - dlsch_channel_level_TM34(pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - pdsch_vars[eNB_id]->pmi_ext, - avg_0, - avg_1, - symbol, - nb_rb, - dlsch0_harq->mimo_mode); + dlsch_channel_level_TM34(pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + pdsch_vars[eNB_id]->pmi_ext, + avg_0, + avg_1, + symbol, + nb_rb, + mmse_flag, + dlsch0_harq->mimo_mode); LOG_D(PHY,"Channel Level TM34 avg_0 %d, avg_1 %d, rx_type %d, rx_standard %d, dlsch_demod_shift %d \n", avg_0[0], avg_1[0], rx_type, rx_standard, dlsch_demod_shift); @@ -546,6 +558,27 @@ int rx_pdsch(PHY_VARS_UE *ue, #if UE_TIMING_TRACE start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #endif + + if (rx_type==rx_IC_dual_stream && mmse_flag==1){ + + precode_channel_est(pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + pdsch_vars[eNB_id], + symbol, + nb_rb, + dlsch0_harq->mimo_mode); + + mmse_processing_oai(pdsch_vars[eNB_id], + frame_parms, + measurements, + first_symbol_flag, + dlsch0_harq->mimo_mode, + mmse_flag, + 0.0, + symbol, + nb_rb); + } + // Now channel compensation if (dlsch0_harq->mimo_mode<LARGE_CDD) { dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext, @@ -564,7 +597,7 @@ int rx_pdsch(PHY_VARS_UE *ue, if (symbol == 5) { LOG_M("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); } - + if ((rx_type==rx_IC_single_stream) && (eNB_id_i<ue->n_connected_eNB)) { dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext, @@ -606,6 +639,7 @@ int rx_pdsch(PHY_VARS_UE *ue, dlsch0_harq->round, dlsch0_harq->mimo_mode, nb_rb, + mmse_flag, pdsch_vars[eNB_id]->log2_maxh0, pdsch_vars[eNB_id]->log2_maxh1); if (symbol == 5) { @@ -1279,15 +1313,14 @@ void dlsch_channel_compensation(int **rxdataF_ext, QAM_amp128b = _mm_set1_epi16(QAM64_n2); } - // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128 = (__m128i *)&dl_ch_mag[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128b = (__m128i *)&dl_ch_magb[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; + //print_shorts("dl_ch128[0]=",&dl_ch128[0]);*/ + dl_ch_mag128 = (__m128i *)&dl_ch_mag[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128b = (__m128i *)&dl_ch_magb[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128 = (__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0; rb<nb_rb; rb++) { @@ -1308,9 +1341,9 @@ void dlsch_channel_compensation(int **rxdataF_ext, dl_ch_mag128b[0] = dl_ch_mag128[0]; dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); - //print_ints("Re(ch):",(int16_t*)&mmtmpD0); - //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); - //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); + //print_ints("Re(ch):",(int16_t*)&mmtmpD0); + //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); + //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); dl_ch_mag128b[1] = dl_ch_mag128[1]; dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); @@ -1343,7 +1376,6 @@ void dlsch_channel_compensation(int **rxdataF_ext, // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); @@ -1400,7 +1432,7 @@ void dlsch_channel_compensation(int **rxdataF_ext, rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); // print_shorts("rx:",rxdataF128+2); // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); + // print_shorts("pack:",rxdataF_comp128+2); dl_ch128+=3; dl_ch_mag128+=3; @@ -1541,11 +1573,11 @@ void dlsch_channel_compensation(int **rxdataF_ext, // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - dl_ch128 = (int16x4_t*)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128 = (int16x8_t*)&dl_ch_mag[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128b = (int16x8_t*)&dl_ch_magb[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch128 = (int16x4_t*)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128 = (int16x8_t*)&dl_ch_mag[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128b = (int16x8_t*)&dl_ch_magb[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128 = (int16x4x2_t*)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128 = (int16x4x2_t*)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0; rb<nb_rb; rb++) { if (mod_order>2) { @@ -1706,6 +1738,204 @@ void dlsch_channel_compensation(int **rxdataF_ext, #endif } +void dlsch_channel_compensation_core(int **rxdataF_ext, + int **dl_ch_estimates_ext, + int **dl_ch_mag, + int **dl_ch_magb, + int **rxdataF_comp, + int **rho, + unsigned char n_tx, + unsigned char n_rx, + unsigned char mod_order, + unsigned char output_shift, + int length, + int start_point) + +{ + + unsigned short ii; + int length_mod8 = 0; + int length2; + __m128i *dl_ch128,*dl_ch_mag128,*dl_ch_mag128b, *dl_ch128_2, *rxdataF128,*rxdataF_comp128,*rho128; + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b; + int aatx = 0, aarx = 0; + + for (aatx=0; aatx<n_tx; aatx++) { + + if (mod_order == 4) { + QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) + QAM_amp128b = _mm_setzero_si128(); + } else if (mod_order == 6) { + QAM_amp128 = _mm_set1_epi16(QAM64_n1); // + QAM_amp128b = _mm_set1_epi16(QAM64_n2); + } + + for (aarx=0; aarx<n_rx; aarx++) { + + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aatx*n_rx + aarx][start_point]; + dl_ch_mag128 = (__m128i *)&dl_ch_mag[aatx*n_rx + aarx][start_point]; + dl_ch_mag128b = (__m128i *)&dl_ch_magb[aatx*n_rx + aarx][start_point]; + rxdataF128 = (__m128i *)&rxdataF_ext[aarx][start_point]; + rxdataF_comp128 = (__m128i *)&rxdataF_comp[aatx*n_rx + aarx][start_point]; + + length_mod8 = length&7; + if (length_mod8 == 0){ + length2 = length>>3; + + for (ii=0; ii<length2; ++ii) { + if (mod_order>2) { + // get channel amplitude if not QPSK + + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + + mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + + // store channel magnitude here in a new field of dlsch + + dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[0] = dl_ch_mag128[0]; + dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); + dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); + //print_ints("Re(ch):",(int16_t*)&mmtmpD0); + //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); + //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); + dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[1] = dl_ch_mag128[1]; + dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); + dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); + + dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); + dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); + + dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); + dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); + + } + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); + + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + // print_ints("im",&mmtmpD1); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + // print_ints("re(shift)",&mmtmpD0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + // print_ints("im(shift)",&mmtmpD1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); + rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch128); + // print_shorts("pack:",rxdataF_comp128); + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch128+1); + //print_shorts("pack:",rxdataF_comp128+1); + + dl_ch128+=2; + dl_ch_mag128+=2; + dl_ch_mag128b+=2; + rxdataF128+=2; + rxdataF_comp128+=2; + } + }else { + printf ("Channel Compensation: Received number of subcarriers is not multiple of 8, \n" + "need to adapt the code!\n"); + } + } + } + +/*This part of code makes sense only for processing in 2x2 blocks*/ + if (rho) { + + + for (aarx=0; aarx<n_rx; aarx++) { + rho128 = (__m128i *)&rho[aarx][start_point]; + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][start_point]; + dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][start_point]; + + if (length_mod8 == 0){ + length2 = length>>3; + + for (ii=0; ii<length2; ++ii) { + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]); + // print_ints("re",&mmtmpD0); + + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + // print_ints("im",&mmtmpD1); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[0]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + // print_ints("re(shift)",&mmtmpD0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + // print_ints("im(shift)",&mmtmpD1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); + rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + + //print_shorts("rx:",dl_ch128_2); + //print_shorts("ch:",dl_ch128); + //print_shorts("pack:",rho128); + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[1]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3); + dl_ch128+=2; + dl_ch128_2+=2; + rho128+=2; + } + }else { + printf ("Channel Compensation: Received number of subcarriers is not multiple of 8, \n" + "need to adapt the code!\n"); + } + } + } + _mm_empty(); + _m_empty(); +} + #if defined(__x86_64__) || defined(__i386__) void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) @@ -2282,6 +2512,69 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, _m_empty(); } +void precode_channel_est(int32_t **dl_ch_estimates_ext, + LTE_DL_FRAME_PARMS *frame_parms, + LTE_UE_PDSCH *pdsch_vars, + unsigned char symbol, + unsigned short nb_rb, + MIMO_mode_t mimo_mode){ + + unsigned short rb; + __m128i *dl_ch0_128,*dl_ch1_128; + unsigned char aarx=0,symbol_mod,pilots=0; + unsigned char *pmi_ext = pdsch_vars->pmi_ext; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) + pilots=1; + + for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) { + + dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 + dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h12 + + for (rb=0; rb<nb_rb; rb++) { + if (mimo_mode==LARGE_CDD) { + prec2A_TM3_128(&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM3_128(&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { + prec2A_TM3_128(&dl_ch0_128[2],&dl_ch1_128[2]); + } + }else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) { + prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { + prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]); + } + }else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) { + prec2A_TM4_128(1,&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(1,&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { + prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]); + } + }else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); + } + }else { + LOG_E(PHY,"Unknown MIMO mode\n"); + return; + } + if (pilots==0){ + dl_ch0_128+=3; + dl_ch1_128+=3; + }else { + dl_ch0_128+=2; + dl_ch1_128+=2; + } + } + + } +} + void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, LTE_UE_PDSCH *pdsch_vars, PHY_MEASUREMENTS *measurements, @@ -2293,6 +2586,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int round, MIMO_mode_t mimo_mode, unsigned short nb_rb, + unsigned short mmse_flag, unsigned char output_shift0, unsigned char output_shift1) { @@ -2342,20 +2636,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) { - /* if (aarx==0) { - output_shift=output_shift0; - } - else { - output_shift=output_shift1; - } */ - - // printf("antenna %d\n", aarx); - // printf("symbol %d, rx antenna %d\n", symbol, aarx); - dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h12 - - dl_ch_mag0_128 = (__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1 dl_ch_mag0_128b = (__m128i *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12];//responsible for x1 dl_ch_mag1_128 = (__m128i *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 @@ -2365,50 +2647,39 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, rxdataF_comp1_128 = (__m128i *)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; //result of multipl with MF x2 on antenna of interest for (rb=0; rb<nb_rb; rb++) { - + if (mmse_flag == 0) { // combine TX channels using precoder from pmi - if (mimo_mode==LARGE_CDD) { - prec2A_TM3_128(&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM3_128(&dl_ch0_128[1],&dl_ch1_128[1]); - - - if (pilots==0) { - prec2A_TM3_128(&dl_ch0_128[2],&dl_ch1_128[2]); - } - } - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) { - prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]); - - if (pilots==0) { - prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]); - } - } - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) { - prec2A_TM4_128(1,&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM4_128(1,&dl_ch0_128[1],&dl_ch1_128[1]); - - if (pilots==0) { - prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]); - } - } - - else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { - prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); - - if (pilots==0) { - prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); + if (mimo_mode==LARGE_CDD) { + prec2A_TM3_128(&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM3_128(&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { + prec2A_TM3_128(&dl_ch0_128[2],&dl_ch1_128[2]); + } + }else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) { + prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { + prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]); + } + }else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) { + prec2A_TM4_128(1,&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(1,&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { + prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]); + } + }else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); + } + }else { + LOG_E(PHY,"Unknown MIMO mode\n"); + return; } } - else { - LOG_E(PHY,"Unknown MIMO mode\n"); - return; - } - - if (mod_order0>2) { // get channel amplitude if not QPSK @@ -2535,7 +2806,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // print_shorts("rx:",rxdataF128); // print_shorts("ch:",dl_ch0_128); - // print_shorts("pack:",rxdataF_comp0_128); + //print_shorts("pack:",rxdataF_comp0_128); // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]); @@ -2754,36 +3025,31 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, rxdataF_comp1_128 = (int16x8_t*)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0; rb<nb_rb; rb++) { - // combine TX channels using precoder from pmi - if (mimo_mode==LARGE_CDD) { - prec2A_TM3_128(&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM3_128(&dl_ch0_128[1],&dl_ch1_128[1]); - - - if (pilots==0) { - prec2A_TM3_128(&dl_ch0_128[2],&dl_ch1_128[2]); - } - } - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) { - prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]); - - if (pilots==0) { - prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]); - } - } - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) { - prec2A_TM4_128(1,&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM4_128(1,&dl_ch0_128[1],&dl_ch1_128[1]); - - if (pilots==0) { - prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]); + if (mmse_flag == 0) { + // combine TX channels using precoder from pmi + if (mimo_mode==LARGE_CDD) { + prec2A_TM3_128(&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM3_128(&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { + prec2A_TM3_128(&dl_ch0_128[2],&dl_ch1_128[2]); + } + }else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) { + prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { + prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]); + } + }else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) { + prec2A_TM4_128(1,&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(1,&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { + prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]); + } + }else { + LOG_E(PHY,"Unknown MIMO mode\n"); + return; } } - else { - LOG_E(PHY,"Unknown MIMO mode\n"); - return; - } if (mod_order0>2) { @@ -3008,19 +3274,15 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - - - //printf ("antenna %d", aarx); dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; if (dl_ch_estimates_ext_i == NULL) // TM3/4 - dl_ch128i = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch128i = (__m128i *)&dl_ch_estimates_ext[aarx + frame_parms->nb_antennas_rx][symbol*frame_parms->N_RB_DL*12]; else dl_ch128i = (__m128i *)&dl_ch_estimates_ext_i[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch_rho128 = (__m128i *)&dl_ch_rho_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - for (rb=0; rb<nb_rb; rb++) { // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128i[0]); @@ -3095,158 +3357,37 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, } -/*void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms, - unsigned char symbol, - unsigned short nb_rb, - int **dl_ch_estimates_ext, - int **dl_ch_estimates_ext_i, - int **dl_ch_rho_ext, - unsigned char output_shift0, - unsigned char output_shift1) +void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + int **rxdataF_comp_i, + int **rho, + int **rho_i, + int **dl_ch_mag, + int **dl_ch_magb, + int **dl_ch_mag_i, + int **dl_ch_magb_i, + unsigned char symbol, + unsigned short nb_rb, + unsigned char dual_stream_UE) { #if defined(__x86_64__)||defined(__i386__) - unsigned short rb; - __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; - unsigned char aarx,symbol_mod,pilots=0; - int output_shift; - - // printf("dlsch_dual_stream_correlation: symbol %d\n",symbol); - - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - - if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { - pilots=1; - } + unsigned char aatx; + int i; + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1, + *dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; - // printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i); + if (frame_parms->nb_antennas_rx>1) { - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { - if (aarx==0) { - output_shift=output_shift0; - } - else { - output_shift=output_shift1; - } - - //printf ("antenna %d", aarx); - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - - if (dl_ch_estimates_ext_i == NULL) // TM3/4 - dl_ch128i = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - else - dl_ch128i = (__m128i *)&dl_ch_estimates_ext_i[aarx][symbol*frame_parms->N_RB_DL*12]; - - dl_ch_rho128 = (__m128i *)&dl_ch_rho_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - - - for (rb=0; rb<nb_rb; rb++) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128i[0]); - // print_ints("re",&mmtmpD0); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[0]); - // print_ints("im",&mmtmpD1); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - dl_ch_rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rho 0:",dl_ch_rho128); - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - dl_ch_rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3); - - - if (pilots==0) { - - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - dl_ch_rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - - dl_ch128+=3; - dl_ch128i+=3; - dl_ch_rho128+=3; - } else { - - dl_ch128+=2; - dl_ch128i+=2; - dl_ch_rho128+=2; - } - } - - } - - _mm_empty(); - _m_empty(); - -#elif defined(__arm__) - -#endif -} -*/ - -void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, - int **rxdataF_comp, - int **rxdataF_comp_i, - int **rho, - int **rho_i, - int **dl_ch_mag, - int **dl_ch_magb, - int **dl_ch_mag_i, - int **dl_ch_magb_i, - unsigned char symbol, - unsigned short nb_rb, - unsigned char dual_stream_UE) -{ - -#if defined(__x86_64__)||defined(__i386__) - - unsigned char aatx; - int i; - __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1, - *dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; - - if (frame_parms->nb_antennas_rx>1) { - - for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { - - rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_0b = (__m128i *)&dl_ch_magb[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_1b = (__m128i *)&dl_ch_magb[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0b = (__m128i *)&dl_ch_magb[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1b = (__m128i *)&dl_ch_magb[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) for (i=0;i<nb_rb*3;i++) { @@ -3356,7 +3497,6 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, #endif } - void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, LTE_UE_PDSCH *pdsch_vars, int harq_pid, @@ -3366,7 +3506,11 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, unsigned char dual_stream_UE) { int i; - __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1,*dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1; + __m128i *dl_ch_mag128_0,*dl_ch_mag128_1; + __m128i *dl_ch_mag128_0b,*dl_ch_mag128_1b; + __m128i *rho128_0, *rho128_1; + int **rxdataF_comp0 = pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 = pdsch_vars->rxdataF_comp1[harq_pid][round]; @@ -3377,66 +3521,120 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_magb0 = pdsch_vars->dl_ch_magb0; int **dl_ch_magb1 = pdsch_vars->dl_ch_magb1[harq_pid][round]; - if (frame_parms->nb_antennas_rx>1) { - - rxdataF_comp128_0 = (__m128i *)&rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_1 = (__m128i *)&rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_0 = (__m128i *)&dl_ch_mag0[0][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_1 = (__m128i *)&dl_ch_mag0[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_0b = (__m128i *)&dl_ch_magb0[0][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_1b = (__m128i *)&dl_ch_magb0[1][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0 = (__m128i *)&dl_ch_mag0[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1 = (__m128i *)&dl_ch_mag0[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0b = (__m128i *)&dl_ch_magb0[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1b = (__m128i *)&dl_ch_magb0[1][symbol*frame_parms->N_RB_DL*12]; + rho128_0 = (__m128i *) &dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12]; + rho128_1 = (__m128i *) &dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12]; // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) - for (i=0;i<nb_rb*3;i++) { - rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); - dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1)); - dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1)); - - // print_shorts("mrc compens0:",&rxdataF_comp128_0[i]); - // print_shorts("mrc mag128_0:",&dl_ch_mag128_0[i]); - // print_shorts("mrc mag128_0b:",&dl_ch_mag128_0b[i]); - } } + for (i=0;i<nb_rb*3;i++) { + rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); + dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1)); + dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1)); + rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1)); + + if (frame_parms->nb_antennas_rx>2) { + + __m128i *rxdataF_comp128_2 = NULL; + __m128i *rxdataF_comp128_3 = NULL; + __m128i *dl_ch_mag128_2 = NULL; + __m128i *dl_ch_mag128_3 = NULL; + __m128i *dl_ch_mag128_2b = NULL; + __m128i *dl_ch_mag128_3b = NULL; + __m128i *rho128_2 = NULL; + __m128i *rho128_3 = NULL; + + rxdataF_comp128_2 = (__m128i *)&rxdataF_comp0[2][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_3 = (__m128i *)&rxdataF_comp0[3][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_2 = (__m128i *)&dl_ch_mag0[2][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_3 = (__m128i *)&dl_ch_mag0[3][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_2b = (__m128i *)&dl_ch_magb0[2][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_3b = (__m128i *)&dl_ch_magb0[3][symbol*frame_parms->N_RB_DL*12]; + rho128_2 = (__m128i *) &dl_ch_rho2_ext[2][symbol*frame_parms->N_RB_DL*12]; + rho128_3 = (__m128i *) &dl_ch_rho2_ext[3][symbol*frame_parms->N_RB_DL*12]; + /*rxdataF_comp*/ + rxdataF_comp128_2[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_2[i],1),_mm_srai_epi16(rxdataF_comp128_3[i],1)); + rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_2[i],1)); + /*dl_ch_mag*/ + dl_ch_mag128_2[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_2[i],1),_mm_srai_epi16(dl_ch_mag128_3[i],1)); + dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_2[i],1)); + /*dl_ch_mag*/ + dl_ch_mag128_2b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_2b[i],1),_mm_srai_epi16(dl_ch_mag128_3b[i],1)); + dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_2b[i],1)); + /*rho*/ + rho128_2[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_2[i],1),_mm_srai_epi16(rho128_3[i],1)); + rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_2[i],1)); + } + } - // if (rho) { - rho128_0 = (__m128i *) &dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12]; - rho128_1 = (__m128i *) &dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12]; - for (i=0;i<nb_rb*3;i++) { - // print_shorts("mrc rho0:",&rho128_0[i]); - // print_shorts("mrc rho1:",&rho128_1[i]); - rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1)); - } - //} + if (dual_stream_UE == 1) { + __m128i *dl_ch_mag128_i0, *dl_ch_mag128_i1; + __m128i *dl_ch_mag128_i0b, *dl_ch_mag128_i1b; + __m128i *rho128_i0, *rho128_i1; + __m128i *rxdataF_comp128_i0, *rxdataF_comp128_i1; - if (dual_stream_UE == 1) { - rho128_i0 = (__m128i *) &dl_ch_rho_ext[0][symbol*frame_parms->N_RB_DL*12]; - rho128_i1 = (__m128i *) &dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp1[0][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp1[1][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128_i0 = (__m128i *)&dl_ch_mag1[0][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128_i1 = (__m128i *)&dl_ch_mag1[1][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128_i0b = (__m128i *)&dl_ch_magb1[0][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128_i1b = (__m128i *)&dl_ch_magb1[1][symbol*frame_parms->N_RB_DL*12]; + rho128_i0 = (__m128i *) &dl_ch_rho_ext[0][symbol*frame_parms->N_RB_DL*12]; + rho128_i1 = (__m128i *) &dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12]; + + for (i=0;i<nb_rb*3;i++) { rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1)); - rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1)); - dl_ch_mag128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0[i],1),_mm_srai_epi16(dl_ch_mag128_i1[i],1)); dl_ch_mag128_i0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0b[i],1),_mm_srai_epi16(dl_ch_mag128_i1b[i],1)); + rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1)); - //print_shorts("mrc compens1:",&rxdataF_comp128_i0[i]); - //print_shorts("mrc mag128_i0:",&dl_ch_mag128_i0[i]); - //print_shorts("mrc mag128_i0b:",&dl_ch_mag128_i0b[i]); + if (frame_parms->nb_antennas_rx>2) { + + __m128i *rxdataF_comp128_i2 = NULL; + __m128i *rxdataF_comp128_i3 = NULL; + __m128i *dl_ch_mag128_i2 = NULL; + __m128i *dl_ch_mag128_i3 = NULL; + __m128i *dl_ch_mag128_i2b = NULL; + __m128i *dl_ch_mag128_i3b = NULL; + __m128i *rho128_i2 = NULL; + __m128i *rho128_i3 = NULL; + + rxdataF_comp128_i2 = (__m128i *)&rxdataF_comp1[2][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_i3 = (__m128i *)&rxdataF_comp1[3][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i2 = (__m128i *)&dl_ch_mag1[2][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i3 = (__m128i *)&dl_ch_mag1[3][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i2b = (__m128i *)&dl_ch_magb1[2][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i3b = (__m128i *)&dl_ch_magb1[3][symbol*frame_parms->N_RB_DL*12]; + rho128_i2 = (__m128i *) &dl_ch_rho_ext[2][symbol*frame_parms->N_RB_DL*12]; + rho128_i3 = (__m128i *) &dl_ch_rho_ext[3][symbol*frame_parms->N_RB_DL*12]; + + + /*rxdataF_comp*/ + rxdataF_comp128_i2[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i2[i],1),_mm_srai_epi16(rxdataF_comp128_i3[i],1)); + rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i2[i],1)); + /*dl_ch_mag*/ + dl_ch_mag128_i2[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i2[i],1),_mm_srai_epi16(dl_ch_mag128_i3[i],1)); + dl_ch_mag128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0[i],1),_mm_srai_epi16(dl_ch_mag128_i2[i],1)); + /*dl_ch_mag*/ + dl_ch_mag128_i2b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i2b[i],1),_mm_srai_epi16(dl_ch_mag128_i3b[i],1)); + dl_ch_mag128_i0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0b[i],1),_mm_srai_epi16(dl_ch_mag128_i2b[i],1)); + /*rho*/ + rho128_i2[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i2[i],1),_mm_srai_epi16(rho128_i3[i],1)); + rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i2[i],1)); + } } } - _mm_empty(); _m_empty(); } - - void dlsch_scale_channel(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, LTE_UE_DLSCH_t **dlsch_ue, @@ -3462,7 +3660,7 @@ void dlsch_scale_channel(int **dl_ch_estimates_ext, // Determine scaling amplitude based the symbol ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); - + LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol_mod,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol); // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); @@ -3498,7 +3696,6 @@ void dlsch_scale_channel(int **dl_ch_estimates_ext, #endif } - //compute average channel_level on each (TX,RX) antenna pair void dlsch_channel_level(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, @@ -3508,6 +3705,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, { #if defined(__x86_64__)||defined(__i386__) + //printf("symbol = %d\n", symbol); short rb; unsigned char aatx,aarx,nre=12,symbol_mod; @@ -3525,21 +3723,23 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, //nb_rb*nre = y * 2^x int16_t x = factor2(nb_rb*nre); int16_t y = (nb_rb*nre)>>x; - //printf("nb_rb*nre = %d = %d * 2^(%d)\n",nb_rb*nre,y,x); for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - //clear average level + //clear average level + //printf("aatx = %d, aarx = %d, aatx*frame_parms->nb_antennas_rx + aarx] = %d \n", aatx, aarx, aatx*frame_parms->nb_antennas_rx + aarx); + avg128D = _mm_setzero_si128(); // 5 is always a symbol with no pilots for both normal and extended prefix - dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; + + dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0;rb<nb_rb;rb++) { - // printf("rb %d : ",rb); - // print_shorts("ch",&dl_ch128[0]); - avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x)); - avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x)); + + //printf("rb %d : ",rb); + avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x)); + avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x)); //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[0],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[0], coeff128),15))); //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[1],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[1], coeff128),15))); @@ -3548,25 +3748,24 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, dl_ch128+=2; } else { - avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x)); + avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x)); //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[2], coeff128),15))); dl_ch128+=3; } - /* - if (rb==0) { - print_shorts("dl_ch128",&dl_ch128[0]); - print_shorts("dl_ch128",&dl_ch128[1]); - print_shorts("dl_ch128",&dl_ch128[2]); - } - */ + + /*if(rb==0){ + print_shorts("dl_ch128",&dl_ch128[0]); + print_shorts("dl_ch128",&dl_ch128[1]); + print_shorts("dl_ch128",&dl_ch128[2]); + }*/ + } - avg[(aatx<<1)+aarx] =(((int32_t*)&avg128D)[0] + - ((int32_t*)&avg128D)[1] + - ((int32_t*)&avg128D)[2] + - ((int32_t*)&avg128D)[3])/y; - // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); - } + avg[aatx*frame_parms->nb_antennas_rx + aarx] =(((int32_t*)&avg128D)[0] + + ((int32_t*)&avg128D)[1] + + ((int32_t*)&avg128D)[2] + + ((int32_t*)&avg128D)[3])/y; + } _mm_empty(); _m_empty(); @@ -3586,7 +3785,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, avg128D = vdupq_n_s32(0); // 5 is always a symbol with no pilots for both normal and extended prefix - dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0; rb<nb_rb; rb++) { // printf("rb %d : ",rb); @@ -3596,7 +3795,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[2],dl_ch128[2])); avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[3],dl_ch128[3])); - if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) { dl_ch128+=4; } else { avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[4],dl_ch128[4])); @@ -3613,187 +3812,745 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, */ } - - if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) nre=8; - else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB==1)) + else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1)) nre=10; else nre=12; - avg[(aatx<<1)+aarx] = (((int32_t*)&avg128D)[0] + - ((int32_t*)&avg128D)[1] + - ((int32_t*)&avg128D)[2] + - ((int32_t*)&avg128D)[3])/(nb_rb*nre); + avg[aatx*frame_parms->nb_antennas_rx + aarx] = (((int32_t*)&avg128D)[0] + + ((int32_t*)&avg128D)[1] + + ((int32_t*)&avg128D)[2] + + ((int32_t*)&avg128D)[3])/(nb_rb*nre); - // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); + //printf("Channel level : %d\n",avg[aatx*(frame_parms->nb_antennas_rx-1) + aarx]); } - - #endif -} -//compute average channel_level of effective (precoded) channel +} -//compute average channel_level of effective (precoded) channel -void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, - LTE_DL_FRAME_PARMS *frame_parms, - unsigned char *pmi_ext, - int *avg_0, - int *avg_1, - uint8_t symbol, - unsigned short nb_rb, - MIMO_mode_t mimo_mode){ +void dlsch_channel_level_core(int **dl_ch_estimates_ext, + int32_t *avg, + int n_tx, + int n_rx, + int length, + int start_point) +{ #if defined(__x86_64__)||defined(__i386__) + short ii; + int aatx,aarx; + int length_mod8; + int length2; + __m128i *dl_ch128, avg128D; - short rb; - unsigned char aarx,nre=12,symbol_mod; - __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp, avg_0_128D, avg_1_128D; - - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - - //clear average level - // avg_0_128D = _mm_setzero_si128(); - // avg_1_128D = _mm_setzero_si128(); - avg_0[0] = 0; - avg_0[1] = 0; - avg_1[0] = 0; - avg_1[1] = 0; - // 5 is always a symbol with no pilots for both normal and extended prefix - - if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) - nre=8; - else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB==1)) - nre=10; - else - nre=12; + int16_t x = factor2(length); + int16_t y = (length)>>x; - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + for (aatx=0; aatx<n_tx; aatx++) + for (aarx=0; aarx<n_rx; aarx++) { - avg_0_128D = _mm_setzero_si128(); - avg_1_128D = _mm_setzero_si128(); - for (rb=0; rb<nb_rb; rb++) { - // printf("rb %d : \n",rb); - // print_shorts("ch0\n",&dl_ch0_128[0]); - //print_shorts("ch1\n",&dl_ch1_128[0]); - dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[0]); - dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[0]); + avg128D = _mm_setzero_si128(); - if (mimo_mode==LARGE_CDD) - prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) - prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) - prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) - prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); + dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*n_rx + aarx][start_point]; - // mmtmpD0 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); - avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + length_mod8=length&7; - avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp)); + if (length_mod8 == 0){ - dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[1]); - dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[1]); + length2 = length>>3; - if (mimo_mode==LARGE_CDD) - prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) - prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) - prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) - prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); + for (ii=0;ii<length2;ii++) { + avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x)); + avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x)); - // mmtmpD1 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); - avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + dl_ch128+=2; + } + }else { + printf ("Channel level: Received number of subcarriers is not multiple of 4, \n" + "need to adapt the code!\n"); + } - avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp)); - if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { - dl_ch0_128+=2; - dl_ch1_128+=2; + avg[aatx*n_rx + aarx] =(((int32_t*)&avg128D)[0] + + ((int32_t*)&avg128D)[1] + + ((int32_t*)&avg128D)[2] + + ((int32_t*)&avg128D)[3])/y; + //printf("Channel level [%d]: %d\n",aatx*n_rx + aarx, avg[aatx*n_rx + aarx]); } - else { - dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); - dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); - if (mimo_mode==LARGE_CDD) - prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) - prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) - prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) - prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); - // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); + _mm_empty(); + _m_empty(); - avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp)); - avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + /* FIXME This part needs to be adapted like the one above */ +#elif defined(__arm__) - dl_ch0_128+=3; - dl_ch1_128+=3; - } - } + short rb; + unsigned char aatx,aarx,nre=12,symbol_mod; + int32x4_t avg128D; + int16x4_t *dl_ch128; + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - avg_0[aarx] = (((int*)&avg_0_128D)[0])/(nb_rb*nre) + - (((int*)&avg_0_128D)[1])/(nb_rb*nre) + - (((int*)&avg_0_128D)[2])/(nb_rb*nre) + - (((int*)&avg_0_128D)[3])/(nb_rb*nre); - // printf("From Chan_level aver stream 0 %d =%d\n", aarx, avg_0[aarx]); + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + //clear average level + avg128D = vdupq_n_s32(0); + // 5 is always a symbol with no pilots for both normal and extended prefix - avg_1[aarx] = (((int*)&avg_1_128D)[0])/(nb_rb*nre) + - (((int*)&avg_1_128D)[1])/(nb_rb*nre) + - (((int*)&avg_1_128D)[2])/(nb_rb*nre) + - (((int*)&avg_1_128D)[3])/(nb_rb*nre); - // printf("From Chan_level aver stream 1 %d =%d\n", aarx, avg_1[aarx]); + dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; + + for (rb=0; rb<nb_rb; rb++) { + // printf("rb %d : ",rb); + // print_shorts("ch",&dl_ch128[0]); + avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[0],dl_ch128[0])); + avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[1],dl_ch128[1])); + avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[2],dl_ch128[2])); + avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[3],dl_ch128[3])); + + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { + dl_ch128+=4; + } else { + avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[4],dl_ch128[4])); + avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[5],dl_ch128[5])); + dl_ch128+=6; + } + } + + + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) + nre=8; + else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB==1)) + nre=10; + else + nre=12; + + avg[aatx*frame_parms->nb_antennas_rx + aarx] = (((int32_t*)&avg128D)[0] + + ((int32_t*)&avg128D)[1] + + ((int32_t*)&avg128D)[2] + + ((int32_t*)&avg128D)[3])/(nb_rb*nre); + + //printf("Channel level : %d\n",avg[aatx*(frame_parms->nb_antennas_rx-1) + aarx]); + } +#endif + +} + +void mmse_processing_oai(LTE_UE_PDSCH *pdsch_vars, + LTE_DL_FRAME_PARMS *frame_parms, + PHY_MEASUREMENTS *measurements, + unsigned char first_symbol_flag, + MIMO_mode_t mimo_mode, + unsigned short mmse_flag, + int noise_power, + unsigned char symbol, + unsigned short nb_rb){ + + int **rxdataF_ext = pdsch_vars->rxdataF_ext; + int **dl_ch_estimates_ext = pdsch_vars->dl_ch_estimates_ext; + unsigned char *pmi_ext = pdsch_vars->pmi_ext; + int avg_00[frame_parms->nb_antenna_ports_eNB*frame_parms->nb_antennas_rx]; + int avg_01[frame_parms->nb_antenna_ports_eNB*frame_parms->nb_antennas_rx]; + int symbol_mod, length, start_point, nre; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) + nre=8; + else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB==1)) + nre=10; + else + nre=12; + + length = nre*nb_rb; + start_point = symbol*nb_rb*12; + + + mmse_processing_core(rxdataF_ext, + dl_ch_estimates_ext, + noise_power, + frame_parms->nb_antenna_ports_eNB, + frame_parms->nb_antennas_rx, + length, + start_point); + + + /*dlsch_channel_aver_band(dl_ch_estimates_ext, + frame_parms, + chan_avg, + symbol, + nb_rb); + + + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + H[aatx*frame_parms->nb_antennas_rx + aarx] = (float)(chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].r/(32768.0)) + I*(float)(chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].i/(32768.0)); + // printf("H [%d] = (%f, %f) \n", aatx*frame_parms->nb_antennas_rx + aarx, creal(H[aatx*frame_parms->nb_antennas_rx + aarx]), cimag(H[aatx*frame_parms->nb_antennas_rx + aarx])); + }*/ + + if (first_symbol_flag == 1){ + dlsch_channel_level_TM34(dl_ch_estimates_ext, + frame_parms, + pmi_ext, + avg_00, + avg_01, + symbol, + nb_rb, + mmse_flag, + mimo_mode); + + avg_00[0] = (log2_approx(avg_00[0])/2) + dlsch_demod_shift+4;// + 2 ;//+ 4; + avg_01[0] = (log2_approx(avg_01[0])/2) + dlsch_demod_shift+4;// + 2 ;//+ 4; + pdsch_vars->log2_maxh0 = cmax(avg_00[0],0); + pdsch_vars->log2_maxh1 = cmax(avg_01[0],0); } -//avg_0[0] = max(avg_0[0],avg_0[1]); -//avg_1[0] = max(avg_1[0],avg_1[1]); -//avg_0[0]= max(avg_0[0], avg_1[0]); +} - avg_0[0] = avg_0[0] + avg_0[1]; - // printf("From Chan_level aver stream 0 final =%d\n", avg_0[0]); - avg_1[0] = avg_1[0] + avg_1[1]; - // printf("From Chan_level aver stream 1 final =%d\n", avg_1[0]); - avg_0[0] = min (avg_0[0], avg_1[0]); - avg_1[0] = avg_0[0]; +void mmse_processing_core(int32_t **rxdataF_ext, + int32_t **dl_ch_estimates_ext, + int noise_power, + int n_tx, + int n_rx, + int length, + int start_point){ - _mm_empty(); - _m_empty(); + int aatx, aarx, re; + float imag; + float real; + + + float complex **W_MMSE= malloc(n_tx*n_rx*sizeof(float complex*)); + for (int j=0; j<n_tx*n_rx; j++) { + W_MMSE[j] = malloc(sizeof(float complex)*length); + } + + float complex *H= malloc(n_tx*n_rx*sizeof(float complex)); + float complex *W_MMSE_re= malloc(n_tx*n_rx*sizeof(float complex)); + + float complex** dl_ch_estimates_ext_flcpx = malloc(n_tx*n_rx*sizeof(float complex*)); + for (int j=0; j<n_tx*n_rx; j++) { + dl_ch_estimates_ext_flcpx[j] = malloc(sizeof(float complex)*length); + } + + float complex** rxdataF_ext_flcpx = malloc(n_rx*sizeof(float complex*)); + for (int j=0; j<n_rx; j++) { + rxdataF_ext_flcpx[j] = malloc(sizeof(float complex)*length); + } + + chan_est_to_float(dl_ch_estimates_ext, + dl_ch_estimates_ext_flcpx, + n_tx, + n_rx, + length, + start_point); + + for (re=0; re<length; re++){ + for (aatx=0; aatx<n_tx; aatx++){ + for (aarx=0; aarx<n_rx; aarx++) { + imag = cimag(dl_ch_estimates_ext_flcpx[aatx*n_rx + aarx][re]); + real = creal(dl_ch_estimates_ext_flcpx[aatx*n_rx + aarx][re]); + H[aatx*n_rx + aarx] = real+ I*imag; + } + } + compute_MMSE(H, n_tx, noise_power, W_MMSE_re); + for (aatx=0; aatx<n_tx; aatx++){ + for (aarx=0; aarx<n_rx; aarx++) { + W_MMSE[aatx*n_rx + aarx][re] = W_MMSE_re[aatx*n_rx + aarx]; + } + } + } + + rxdataF_to_float(rxdataF_ext, + rxdataF_ext_flcpx, + n_rx, + length, + start_point); + + mult_mmse_rxdataF(W_MMSE, + rxdataF_ext_flcpx, + n_tx, + n_rx, + length, + start_point); + + + mult_mmse_chan_est(W_MMSE, + dl_ch_estimates_ext_flcpx, + n_tx, + n_rx, + length, + start_point); + + + float_to_rxdataF(rxdataF_ext, + rxdataF_ext_flcpx, + n_tx, + n_rx, + length, + start_point); + + + float_to_chan_est(dl_ch_estimates_ext, + dl_ch_estimates_ext_flcpx, + n_tx, + n_rx, + length, + start_point); + +free(W_MMSE); +free(H); +free(W_MMSE_re); +free(dl_ch_estimates_ext_flcpx); +free(rxdataF_ext_flcpx); + +} + + +/*THIS FUNCTION TAKES FLOAT_POINT INPUT. SHOULD NOT BE USED WITH OAI*/ +void mmse_processing_core_flp(float complex** rxdataF_ext_flcpx, + float complex **H, + int32_t **rxdataF_ext, + int32_t **dl_ch_estimates_ext, + float noise_power, + int n_tx, + int n_rx, + int length, + int start_point){ + + int aatx, aarx, re; + float max = 0; + float one_over_max = 0; + + float complex **W_MMSE= malloc(n_tx*n_rx*sizeof(float complex*)); + for (int j=0; j<n_tx*n_rx; j++) { + W_MMSE[j] = malloc(sizeof(float complex)*length); + } + + float complex *H_re= malloc(n_tx*n_rx*sizeof(float complex)); + float complex *W_MMSE_re= malloc(n_tx*n_rx*sizeof(float complex)); + + for (re=0; re<length; re++){ + for (aatx=0; aatx<n_tx; aatx++){ + for (aarx=0; aarx<n_rx; aarx++) { + H_re[aatx*n_rx + aarx] = H[aatx*n_rx + aarx][re]; +#ifdef DEBUG_MMSE + if (re == 0) + printf(" H_re[%d]= (%f + i%f)\n", aatx*n_rx + aarx, creal(H_re[aatx*n_rx + aarx]), cimag(H_re[aatx*n_rx + aarx])); +#endif + } + } + compute_MMSE(H_re, n_tx, noise_power, W_MMSE_re); + for (aatx=0; aatx<n_tx; aatx++){ + for (aarx=0; aarx<n_rx; aarx++) { + W_MMSE[aatx*n_rx + aarx][re] = W_MMSE_re[aatx*n_rx + aarx]; + if (fabs(creal(W_MMSE_re[aatx*n_rx + aarx])) > max) + max = fabs(creal(W_MMSE_re[aatx*n_rx + aarx])); + if (fabs(cimag(W_MMSE_re[aatx*n_rx + aarx])) > max) + max = fabs(cimag(W_MMSE_re[aatx*n_rx + aarx])); + } + } + } + one_over_max = 1.0/max; + + for (re=0; re<length; re++) + for (aatx=0; aatx<n_tx; aatx++) + for (aarx=0; aarx<n_rx; aarx++){ +#ifdef DEBUG_MMSE + if (re == 0) + printf(" W_MMSE[%d] = (%f + i%f)\n", aatx*n_rx + aarx, creal(W_MMSE[aatx*n_rx + aarx][re]), cimag(W_MMSE[aatx*n_rx + aarx][re])); +#endif + W_MMSE[aatx*n_rx + aarx][re] = one_over_max*W_MMSE[aatx*n_rx + aarx][re]; +#ifdef DEBUG_MMSE + if (re == 0) + printf(" AFTER NORM W_MMSE[%d] = (%f + i%f), max = %f \n", aatx*n_rx + aarx, creal(W_MMSE[aatx*n_rx + aarx][re]), cimag(W_MMSE[aatx*n_rx + aarx][re]), max); +#endif + } + + + mult_mmse_rxdataF(W_MMSE, + rxdataF_ext_flcpx, + n_tx, + n_rx, + length, + start_point); + + mult_mmse_chan_est(W_MMSE, + H, + n_tx, + n_rx, + length, + start_point); + + float_to_rxdataF(rxdataF_ext, + rxdataF_ext_flcpx, + n_tx, + n_rx, + length, + start_point); + + float_to_chan_est(dl_ch_estimates_ext, + H, + n_tx, + n_rx, + length, + start_point); + free(H_re); + free(W_MMSE); + free(W_MMSE_re); + +} + + +void dlsch_channel_aver_band(int **dl_ch_estimates_ext, + LTE_DL_FRAME_PARMS *frame_parms, + struct complex32 *chan_avg, + unsigned char symbol, + unsigned short nb_rb) +{ + +#if defined(__x86_64__)||defined(__i386__) + + short rb; + unsigned char aatx,aarx,nre=12,symbol_mod; + __m128i *dl_ch128, avg128D; + int32_t chan_est_avg[4]; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) + nre=8; + else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB==1)) + nre=10; + else + nre=12; + + for (aatx=0; aatx<frame_parms->nb_antennas_tx; aatx++){ + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; + avg128D = _mm_setzero_si128(); + // print_shorts("avg128D 1",&avg128D); + + for (rb=0;rb<nb_rb;rb++) { + /* printf("symbol %d, ant %d, nre*nrb %d, rb %d \n", symbol, aatx*frame_parms->nb_antennas_rx + aarx, nb_rb*nre, rb); + print_shorts("aver dl_ch128",&dl_ch128[0]); + print_shorts("aver dl_ch128",&dl_ch128[1]); + print_shorts("aver dl_ch128",&dl_ch128[2]); + avg128D = _mm_add_epi16(avg128D, dl_ch128[0]);*/ + //print_shorts("avg128D 2",&avg128D); + + avg128D = _mm_add_epi16(avg128D, dl_ch128[1]); + // print_shorts("avg128D 3",&avg128D); + + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { + dl_ch128+=2; + }else { + avg128D = _mm_add_epi16(avg128D,dl_ch128[2]); + // print_shorts("avg128D 4",&avg128D); + dl_ch128+=3; + } + } + + chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].r =(((int16_t*)&avg128D)[0] + + ((int16_t*)&avg128D)[2] + + ((int16_t*)&avg128D)[4] + + ((int16_t*)&avg128D)[6])/(nb_rb*nre); + // printf("symb %d chan_avg re [%d] = %d\n", symbol, aatx*frame_parms->nb_antennas_rx + aarx, chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].r); + + + + chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].i =(((int16_t*)&avg128D)[1] + + ((int16_t*)&avg128D)[3] + + ((int16_t*)&avg128D)[5] + + ((int16_t*)&avg128D)[7])/(nb_rb*nre); + // printf("symb %d chan_avg im [%d] = %d\n", symbol, aatx*frame_parms->nb_antennas_rx + aarx, chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].i); + + //printf("symb %d chan_avg im [%d] = %d\n", symbol, aatx*frame_parms->nb_antennas_rx + aarx, chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].i); + + + chan_est_avg[aatx*frame_parms->nb_antennas_rx + aarx] = (((int32_t)chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].i)<<16)|(((int32_t)chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].r) & 0xffff); + + //printf("symb %d chan_est_avg [%d] = %d\n", symbol, aatx*frame_parms->nb_antennas_rx + aarx, chan_est_avg[aatx*frame_parms->nb_antennas_rx + aarx]); + + dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; + + for (rb=0;rb<nb_rb;rb++) { + dl_ch128[0] = _mm_set1_epi32(chan_est_avg[aatx*frame_parms->nb_antennas_rx + aarx]); + dl_ch128[1] = _mm_set1_epi32(chan_est_avg[aatx*frame_parms->nb_antennas_rx + aarx]); + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { + dl_ch128+=2; + }else { + dl_ch128[2] = _mm_set1_epi32(chan_est_avg[aatx*frame_parms->nb_antennas_rx + aarx]); + dl_ch128+=3; + } + } + } + } + + _mm_empty(); + _m_empty(); #elif defined(__arm__) +#endif + } + +void rxdataF_to_float(int32_t **rxdataF_ext, + float complex **rxdataF_f, + int n_rx, + int length, + int start_point) +{ + short re; + int aarx; + int16_t imag; + int16_t real; + + for (aarx=0; aarx<n_rx; aarx++) { + for (re=0; re<length; re++){ + imag = (int16_t) (rxdataF_ext[aarx][start_point + re] >> 16); + real = (int16_t) (rxdataF_ext[aarx][start_point + re] & 0xffff); + rxdataF_f[aarx][re] = (float)(real/(32768.0)) + I*(float)(imag/(32768.0)); +#ifdef DEBUG_MMSE + if (re==0){ + printf("rxdataF_to_float: aarx = %d, real= %d, imag = %d\n", aarx, real, imag); + //printf("rxdataF_to_float: rxdataF_ext[%d][%d] = %d\n", aarx, start_point + re, rxdataF_ext[aarx][start_point + re]); + //printf("rxdataF_to_float: ant %d, re = %d, rxdataF_f real = %f, rxdataF_f imag = %f \n", aarx, re, creal(rxdataF_f[aarx][re]), cimag(rxdataF_f[aarx][re])); + } +#endif + } + } +} + + + +void chan_est_to_float(int32_t **dl_ch_estimates_ext, + float complex **dl_ch_estimates_ext_f, + int n_tx, + int n_rx, + int length, + int start_point) +{ + short re; + int aatx,aarx; + int16_t imag; + int16_t real; + + for (aatx=0; aatx<n_tx; aatx++){ + for (aarx=0; aarx<n_rx; aarx++) { + for (re=0; re<length; re++){ + imag = (int16_t) (dl_ch_estimates_ext[aatx*n_rx + aarx][start_point + re] >> 16); + real = (int16_t) (dl_ch_estimates_ext[aatx*n_rx + aarx][start_point+ re] & 0xffff); + dl_ch_estimates_ext_f[aatx*n_rx + aarx][re] = (float)(real/(32768.0)) + I*(float)(imag/(32768.0)); +#ifdef DEBUG_MMSE + if (re==0){ + printf("ant %d, re = %d, real = %d, imag = %d \n", aatx*n_rx + aarx, re, real, imag); + printf("ant %d, re = %d, real = %f, imag = %f \n", aatx*n_rx + aarx, re, creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]), cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])); + } +#endif + } + } + } +} + +void float_to_chan_est(int32_t **dl_ch_estimates_ext, + float complex **dl_ch_estimates_ext_f, + int n_tx, + int n_rx, + int length, + int start_point) +{ + + short re; + int aarx, aatx; + int16_t imag; + int16_t real; + + for (aatx=0; aatx<n_tx; aatx++){ + for (aarx=0; aarx<n_rx; aarx++) { + for (re=0; re<length; re++){ + if (cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])<-1) + imag = 0x8000; + else if (cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])>=1) + imag = 0x7FFF; + else + imag = cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])*32768; + if (creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])<-1) + real = 0x8000; + else if (creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])>=1) + real = 0x7FFF; + else + real = creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])*32768; + + dl_ch_estimates_ext[aatx*n_rx + aarx][start_point + re] = (((int32_t)imag)<<16)|((int32_t)real & 0xffff); +#ifdef DEBUG_MMSE + if (re==0){ + printf(" float_to_chan_est: chan est real = %f, chan est imag = %f\n",creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]), cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])); + printf("float_to_chan_est: real fixed = %d, imag fixed = %d\n", real, imag); + printf("float_to_chan_est: ant %d, re = %d, dl_ch_estimates_ext = %d \n", aatx*n_rx + aarx, re, dl_ch_estimates_ext[aatx*n_rx + aarx][start_point + re]); + } +#endif + } + } + } +} + + +void float_to_rxdataF(int32_t **rxdataF_ext, + float complex **rxdataF_f, + int n_tx, + int n_rx, + int length, + int start_point) +{ + + short re; + int aarx; + int16_t imag; + int16_t real; + + for (aarx=0; aarx<n_rx; aarx++) { + for (re=0; re<length; re++){ + if (cimag(rxdataF_f[aarx][re])<-1) + imag = 0x8000; + else if (cimag(rxdataF_f[aarx][re])>=1) + imag = 0x7FFF; + else + imag = cimag(rxdataF_f[aarx][re])*32768; + if (creal(rxdataF_f[aarx][re])<-1) + real = 0x8000; + else if (creal(rxdataF_f[aarx][re])>=1) + real = 0x7FFF; + else + real = creal(rxdataF_f[aarx][re])*32768; + rxdataF_ext[aarx][start_point + re] = (((int32_t)imag)<<16)|(((int32_t)real) & 0xffff); +#ifdef DEBUG_MMSE + if (re==0){ + printf(" float_to_rxdataF: real = %f, imag = %f\n",creal(rxdataF_f[aarx][re]), cimag(rxdataF_f[aarx][re])); + printf("float_to_rxdataF: real fixed = %d, imag fixed = %d\n", real, imag); + printf("float_to_rxdataF: ant %d, re = %d, rxdataF_ext = %d \n", aarx, re, rxdataF_ext[aarx][start_point + re]); + } +#endif + } + } +} + + +void mult_mmse_rxdataF(float complex** Wmmse, + float complex** rxdataF_ext_f, + int n_tx, + int n_rx, + int length, + int start_point) +{ + short re; + int aarx, aatx; + + + float complex* rxdata_re = malloc(n_rx*sizeof(float complex)); + float complex* rxdata_mmse_re = malloc(n_rx*sizeof(float complex)); + float complex* Wmmse_re = malloc(n_tx*n_rx*sizeof(float complex)); + + for (re=0;re<length; re++){ + for (aarx=0; aarx<n_rx; aarx++){ + rxdata_re[aarx] = rxdataF_ext_f[aarx][re]; +#ifdef DEBUG_MMSE + if (re==0) + printf("mult_mmse_rxdataF before: rxdata_re[%d] = (%f, %f)\n", aarx, creal(rxdata_re[aarx]), cimag(rxdata_re[aarx])); +#endif + } + for (aatx=0; aatx<n_tx; aatx++){ + for (aarx=0; aarx<n_rx; aarx++){ + Wmmse_re[aatx*n_rx + aarx] = Wmmse[aatx*n_rx + aarx][re]; + } + } + mutl_matrix_matrix_col_based(Wmmse_re, rxdata_re, n_rx, n_tx, n_rx, 1, rxdata_mmse_re); + + for (aarx=0; aarx<n_rx; aarx++){ + rxdataF_ext_f[aarx][re] = rxdata_mmse_re[aarx]; +#ifdef DEBUG_MMSE + if (re==0) + printf("mult_mmse_rxdataF after: rxdataF_ext_f[%d] = (%f, %f)\n", aarx, creal(rxdataF_ext_f[aarx][re]), cimag(rxdataF_ext_f[aarx][re])); +#endif + } + } + free(rxdata_re); + free(rxdata_mmse_re); + free(Wmmse_re); +} + +void mult_mmse_chan_est(float complex** Wmmse, + float complex** dl_ch_estimates_ext_f, + int n_tx, + int n_rx, + int length, + int start_point) +{ + short re; + int aarx, aatx; + + float complex* chan_est_re = malloc(n_tx*n_rx*sizeof(float complex)); + float complex* chan_est_mmse_re = malloc(n_tx*n_rx*sizeof(float complex)); + float complex* Wmmse_re = malloc(n_tx*n_rx*sizeof(float complex)); + + for (re=0;re<length; re++){ + for (aatx=0; aatx<n_tx; aatx++){ + for (aarx=0; aarx<n_rx; aarx++){ + chan_est_re[aatx*n_rx + aarx] = dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]; + Wmmse_re[aatx*n_rx + aarx] = Wmmse[aatx*n_rx + aarx][re]; +#ifdef DEBUG_MMSE + if (re==0) + printf("mult_mmse_chan_est: chan_est_re[%d] = (%f, %f)\n", aatx*n_rx + aarx, creal(chan_est_re[aatx*n_rx + aarx]), cimag(chan_est_re[aatx*n_rx + aarx])); +#endif + } + } + mutl_matrix_matrix_col_based(Wmmse_re, chan_est_re, n_rx, n_tx, n_rx, n_tx, chan_est_mmse_re); + for (aatx=0; aatx<n_tx; aatx++){ + for (aarx=0; aarx<n_rx; aarx++){ + dl_ch_estimates_ext_f[aatx*n_rx + aarx][re] = chan_est_mmse_re[aatx*n_rx + aarx]; +#ifdef DEBUG_MMSE + if (re==0) + printf("mult_mmse_chan_est: dl_ch_estimates_ext_f[%d][%d] = (%f, %f)\n", aatx*n_rx + aarx, re, creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]), cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])); #endif + } + } + } + free(Wmmse_re); + free(chan_est_re); + free(chan_est_mmse_re); } -/*void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, + + +//compute average channel_level of effective (precoded) channel +void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, - int *avg, + unsigned char *pmi_ext, + int *avg_0, + int *avg_1, uint8_t symbol, unsigned short nb_rb, + unsigned int mmse_flag, MIMO_mode_t mimo_mode){ #if defined(__x86_64__)||defined(__i386__) - short rb; unsigned char aarx,nre=12,symbol_mod; - __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp,avg128D; + __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp, avg_0_128D, avg_1_128D; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; //clear average level - avg128D = _mm_setzero_si128(); - avg[0] = 0; - avg[1] = 0; + // avg_0_128D = _mm_setzero_si128(); + // avg_1_128D = _mm_setzero_si128(); + avg_0[0] = 0; + avg_0[1] = 0; + avg_1[0] = 0; + avg_1[1] = 0; // 5 is always a symbol with no pilots for both normal and extended prefix if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) @@ -3807,33 +4564,49 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + avg_0_128D = _mm_setzero_si128(); + avg_1_128D = _mm_setzero_si128(); for (rb=0; rb<nb_rb; rb++) { - + // printf("rb %d : \n",rb); + //print_shorts("ch0\n",&dl_ch0_128[0]); + //print_shorts("ch1\n",&dl_ch1_128[0]); dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[0]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[0]); - if (mimo_mode==LARGE_CDD) - prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) - prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) - prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + if (mmse_flag == 0){ + if (mimo_mode==LARGE_CDD) + prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) + prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) + prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); + } // mmtmpD0 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); - avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + + avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp)); dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[1]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[1]); - if (mimo_mode==LARGE_CDD) - prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) - prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) - prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + if (mmse_flag == 0){ + if (mimo_mode==LARGE_CDD) + prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) + prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) + prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); + } // mmtmpD1 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); - avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + + avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp)); if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { dl_ch0_128+=2; @@ -3843,29 +4616,49 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); - if (mimo_mode==LARGE_CDD) - prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) - prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) - prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - + if (mmse_flag == 0){ + if (mimo_mode==LARGE_CDD) + prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) + prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) + prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); + } // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); - avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + + avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp)); + avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); dl_ch0_128+=3; dl_ch1_128+=3; } } - avg[aarx] = (((int*)&avg128D)[0])/(nb_rb*nre) + - (((int*)&avg128D)[1])/(nb_rb*nre) + - (((int*)&avg128D)[2])/(nb_rb*nre) + - (((int*)&avg128D)[3])/(nb_rb*nre); + + avg_0[aarx] = (((int*)&avg_0_128D)[0])/(nb_rb*nre) + + (((int*)&avg_0_128D)[1])/(nb_rb*nre) + + (((int*)&avg_0_128D)[2])/(nb_rb*nre) + + (((int*)&avg_0_128D)[3])/(nb_rb*nre); + // printf("From Chan_level aver stream 0 %d =%d\n", aarx, avg_0[aarx]); + + avg_1[aarx] = (((int*)&avg_1_128D)[0])/(nb_rb*nre) + + (((int*)&avg_1_128D)[1])/(nb_rb*nre) + + (((int*)&avg_1_128D)[2])/(nb_rb*nre) + + (((int*)&avg_1_128D)[3])/(nb_rb*nre); + // printf("From Chan_level aver stream 1 %d =%d\n", aarx, avg_1[aarx]); } +//avg_0[0] = max(avg_0[0],avg_0[1]); +//avg_1[0] = max(avg_1[0],avg_1[1]); +//avg_0[0]= max(avg_0[0], avg_1[0]); - // choose maximum of the 2 effective channels - avg[0] = cmax(avg[0],avg[1]); + avg_0[0] = avg_0[0] + avg_0[1]; + // printf("From Chan_level aver stream 0 final =%d\n", avg_0[0]); + avg_1[0] = avg_1[0] + avg_1[1]; + // printf("From Chan_level aver stream 1 final =%d\n", avg_1[0]); + avg_0[0] = min (avg_0[0], avg_1[0]); + avg_1[0] = avg_0[0]; _mm_empty(); _m_empty(); @@ -3873,7 +4666,7 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, #elif defined(__arm__) #endif -}*/ +} //compute average channel_level of effective (precoded) channel void dlsch_channel_level_TM56(int **dl_ch_estimates_ext, diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c index a3ad9b05ca008d30df368022b90d00e75b299265..ea3f100504e8b263b16e8e230e3bc7ba310f3910 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c @@ -642,7 +642,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][((int32_t)symbol*frame_parms->N_RB_DL*12)]; uint32_t *llr32; - int i,len; + int len; uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; /* @@ -681,19 +681,28 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, dlsch_llr, llr32); */ - //printf("ll32p=%p , dlsch_llr=%p, symbol=%d, flag=%d \n", llr32, dlsch_llr, symbol, first_symbol_flag); - for (i=0; i<len; i++) { - *llr32 = *rxF; - //printf("llr %d : (%d,%d)\n",i,((int16_t*)llr32)[0],((int16_t*)llr32)[1]); - rxF++; - llr32++; - } - //*llr32p = (int16_t *)llr32; + qpsk_llr((short *)rxF, + (short *)llr32, + len); return(0); } +void qpsk_llr(int16_t *stream0_in, + int16_t *stream0_out, + int length) +{ + int i; + for (i=0; i<2*length; i++) { + *stream0_out = *stream0_in; + //printf("llr %d : (%d,%d)\n",i,((int16_t*)stream0_out)[0],((int16_t*)stream0_out)[1]); + stream0_in++; + stream0_out++; + } + +} + int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, int32_t **sic_buffer, //Q15 @@ -817,45 +826,21 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, int16_t **llr32p, uint8_t beamforming_mode) { + int32_t *rxF = (int32_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + int32_t *ch_mag = (int32_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; + int32_t *llr32; -#if defined(__x86_64__) || defined(__i386__) - __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - __m128i *ch_mag; - __m128i llr128[2]; - uint32_t *llr32; -#elif defined(__arm__) - int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16x8_t *ch_mag; - int16x8_t xmm0; - int16_t *llr16; -#endif - - - int i,len; + int len; unsigned char symbol_mod,len_mod4=0; - -#if defined(__x86_64__) || defined(__i386__) if (first_symbol_flag==1) { - llr32 = (uint32_t*)dlsch_llr; - } else { - llr32 = (uint32_t*)*llr32p; - } -#elif defined(__arm__) - if (first_symbol_flag==1) { - llr16 = (int16_t*)dlsch_llr; + llr32 = (int32_t*)dlsch_llr; } else { - llr16 = (int16_t*)*llr32p; + llr32 = (int32_t*)*llr32p; } -#endif symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; -#if defined(__x86_64__) || defined(__i386__) - ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; -#elif defined(__arm__) - ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; -#endif if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { if (frame_parms->nb_antenna_ports_eNB!=1) len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3); @@ -881,18 +866,45 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, len>>=2; // length in quad words (4 REs) // printf("len>>=2=%d\n", len); len+=(len_mod4==0 ? 0 : 1); - // printf("len+=%d\n", len); - for (i=0; i<len; i++) { + qam16_llr((short *)rxF, + (short *)ch_mag, + (short *)llr32, + len); + // printf ("This line in qam16_llr is %d.\n", __LINE__); + +} + +void qam16_llr(int16_t *stream0_in, + int16_t *chan_magn, + int16_t *llr, + int length) +{ + int i; + #if defined(__x86_64__) || defined(__i386__) + __m128i *rxF_128 = (__m128i*)stream0_in; + __m128i *ch_mag_128 = (__m128i*)chan_magn; + __m128i llr128[2]; + int32_t *llr32 = (int32_t*) llr; +#elif defined(__arm__) + int16x8_t *rxF_128 = (int16x8_t*)stream0_in; + int16x8_t *ch_mag_128 = (int16x8_t*)chan_magn; + int16x8_t xmm0; + int16_t *llr16 = (int16_t*)llr; +#endif + + // printf ("This line in qam16_llr is %d.\n", __LINE__); + + for (i=0; i<length; i++) { #if defined(__x86_64__) || defined(__i386) - xmm0 = _mm_abs_epi16(rxF[i]); - xmm0 = _mm_subs_epi16(ch_mag[i],xmm0); + xmm0 = _mm_abs_epi16(rxF_128[i]); + xmm0 = _mm_subs_epi16(ch_mag_128[i],xmm0); // lambda_1=y_R, lambda_2=|y_R|-|h|^2, lamda_3=y_I, lambda_4=|y_I|-|h|^2 - llr128[0] = _mm_unpacklo_epi32(rxF[i],xmm0); - llr128[1] = _mm_unpackhi_epi32(rxF[i],xmm0); + llr128[0] = _mm_unpacklo_epi32(rxF_128[i],xmm0); + llr128[1] = _mm_unpackhi_epi32(rxF_128[i],xmm0); llr32[0] = _mm_extract_epi32(llr128[0],0); //((uint32_t *)&llr128[0])[0]; - llr32[1] = _mm_extract_epi32(llr128[0],1); //((uint32_t *)&llr128[0])[1]; + llr32[1] = _mm_extract_epi32(llr128[0],1); //((uint32_t *)&llr128[0])[0]; llr32[2] = _mm_extract_epi32(llr128[0],2); //((uint32_t *)&llr128[0])[2]; llr32[3] = _mm_extract_epi32(llr128[0],3); //((uint32_t *)&llr128[0])[3]; llr32[4] = _mm_extract_epi32(llr128[1],0); //((uint32_t *)&llr128[1])[0]; @@ -922,14 +934,17 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, llr16[14] = vgetq_lane_s16(xmm0,7); llr16[15] = vgetq_lane_s16(xmm0,7); llr16+=16; + #endif } -#if defined(__x86_64__) || defined(__i386__) +#if defined(__x86_64__) || defined(__i386) _mm_empty(); _m_empty(); #endif + + } void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, @@ -1036,6 +1051,7 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, } } + //---------------------------------------------------------------------------------------------- // 64-QAM //---------------------------------------------------------------------------------------------- @@ -1053,14 +1069,10 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, uint32_t llr_offset, uint8_t beamforming_mode) { -#if defined(__x86_64__) || defined(__i386__) - __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - __m128i *ch_mag,*ch_magb; -#elif defined(__arm__) - int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16x8_t *ch_mag,*ch_magb,xmm1,xmm2; -#endif - int i,len,len2; + int32_t *rxF = (int32_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + int32_t *ch_mag = (int32_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; + int32_t *ch_magb = (int32_t*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; + int len,len2; unsigned char symbol_mod,len_mod4; short *llr; int16_t *llr2; @@ -1079,13 +1091,6 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; -#if defined(__x86_64__) || defined(__i386__) - ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; -#elif defined(__arm__) - ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - ch_magb = (int16x8_t*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; -#endif if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { if (frame_parms->nb_antenna_ports_eNB!=1) len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3); @@ -1115,18 +1120,49 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, len2=len>>2; // length in quad words (4 REs) len2+=((len_mod4==0)?0:1); - for (i=0; i<len2; i++) { + qam64_llr((short *)rxF, + (short *)ch_mag, + (short *)ch_magb, + llr2, + len2); +} + + +void qam64_llr(int16_t *stream0_in, + int16_t *chan_magn, + int16_t *chan_magn_b, + int16_t *llr, + int length) +{ #if defined(__x86_64__) || defined(__i386__) - xmm1 = _mm_abs_epi16(rxF[i]); - xmm1 = _mm_subs_epi16(ch_mag[i],xmm1); + __m128i *rxF_128 = (__m128i*)stream0_in; + __m128i *ch_mag_128 = (__m128i*)chan_magn; + __m128i *ch_magb_128 = (__m128i*)chan_magn_b; +#elif defined(__arm__) + int16x8_t *rxF_128 = (int16x8_t*)stream0_in; + int16x8_t *ch_mag_128 = (int16x8_t*)chan_magn; + int16x8_t *ch_magb_128 = (int16x8_t*)chan_magn_b; + int16x8_t xmm1,xmm2; +#endif + + + int i; + //int16_t *llr2; + //llr2 = llr; + + for (i=0; i<length; i++) { + +#if defined(__x86_64__) || defined(__i386__) + xmm1 = _mm_abs_epi16(rxF_128[i]); + xmm1 = _mm_subs_epi16(ch_mag_128[i],xmm1); xmm2 = _mm_abs_epi16(xmm1); - xmm2 = _mm_subs_epi16(ch_magb[i],xmm2); + xmm2 = _mm_subs_epi16(ch_magb_128[i],xmm2); #elif defined(__arm__) - xmm1 = vabsq_s16(rxF[i]); - xmm1 = vsubq_s16(ch_mag[i],xmm1); + xmm1 = vabsq_s16(rxF_128[i]); + xmm1 = vsubq_s16(ch_mag_128[i],xmm1); xmm2 = vabsq_s16(xmm1); - xmm2 = vsubq_s16(ch_magb[i],xmm2); + xmm2 = vsubq_s16(ch_magb_128[i],xmm2); #endif // loop over all LLRs in quad word (24 coded bits) /* @@ -1141,64 +1177,64 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, llr2+=6; } */ - llr2[0] = ((short *)&rxF[i])[0]; - llr2[1] = ((short *)&rxF[i])[1]; + llr[0] = ((short *)&rxF_128[i])[0]; + llr[1] = ((short *)&rxF_128[i])[1]; #if defined(__x86_64__) || defined(__i386__) - llr2[2] = _mm_extract_epi16(xmm1,0); - llr2[3] = _mm_extract_epi16(xmm1,1);//((short *)&xmm1)[j+1]; - llr2[4] = _mm_extract_epi16(xmm2,0);//((short *)&xmm2)[j]; - llr2[5] = _mm_extract_epi16(xmm2,1);//((short *)&xmm2)[j+1]; + llr[2] = _mm_extract_epi16(xmm1,0); + llr[3] = _mm_extract_epi16(xmm1,1);//((short *)&xmm1)[j+1]; + llr[4] = _mm_extract_epi16(xmm2,0);//((short *)&xmm2)[j]; + llr[5] = _mm_extract_epi16(xmm2,1);//((short *)&xmm2)[j+1]; #elif defined(__arm__) - llr2[2] = vgetq_lane_s16(xmm1,0); - llr2[3] = vgetq_lane_s16(xmm1,1);//((short *)&xmm1)[j+1]; - llr2[4] = vgetq_lane_s16(xmm2,0);//((short *)&xmm2)[j]; - llr2[5] = vgetq_lane_s16(xmm2,1);//((short *)&xmm2)[j+1]; + llr[2] = vgetq_lane_s16(xmm1,0); + llr[3] = vgetq_lane_s16(xmm1,1);//((short *)&xmm1)[j+1]; + llr[4] = vgetq_lane_s16(xmm2,0);//((short *)&xmm2)[j]; + llr[5] = vgetq_lane_s16(xmm2,1);//((short *)&xmm2)[j+1]; #endif - llr2+=6; - llr2[0] = ((short *)&rxF[i])[2]; - llr2[1] = ((short *)&rxF[i])[3]; + llr+=6; + llr[0] = ((short *)&rxF_128[i])[2]; + llr[1] = ((short *)&rxF_128[i])[3]; #if defined(__x86_64__) || defined(__i386__) - llr2[2] = _mm_extract_epi16(xmm1,2); - llr2[3] = _mm_extract_epi16(xmm1,3);//((short *)&xmm1)[j+1]; - llr2[4] = _mm_extract_epi16(xmm2,2);//((short *)&xmm2)[j]; - llr2[5] = _mm_extract_epi16(xmm2,3);//((short *)&xmm2)[j+1]; + llr[2] = _mm_extract_epi16(xmm1,2); + llr[3] = _mm_extract_epi16(xmm1,3);//((short *)&xmm1)[j+1]; + llr[4] = _mm_extract_epi16(xmm2,2);//((short *)&xmm2)[j]; + llr[5] = _mm_extract_epi16(xmm2,3);//((short *)&xmm2)[j+1]; #elif defined(__arm__) - llr2[2] = vgetq_lane_s16(xmm1,2); - llr2[3] = vgetq_lane_s16(xmm1,3);//((short *)&xmm1)[j+1]; - llr2[4] = vgetq_lane_s16(xmm2,2);//((short *)&xmm2)[j]; - llr2[5] = vgetq_lane_s16(xmm2,3);//((short *)&xmm2)[j+1]; + llr[2] = vgetq_lane_s16(xmm1,2); + llr[3] = vgetq_lane_s16(xmm1,3);//((short *)&xmm1)[j+1]; + llr[4] = vgetq_lane_s16(xmm2,2);//((short *)&xmm2)[j]; + llr[5] = vgetq_lane_s16(xmm2,3);//((short *)&xmm2)[j+1]; #endif - llr2+=6; - llr2[0] = ((short *)&rxF[i])[4]; - llr2[1] = ((short *)&rxF[i])[5]; + llr+=6; + llr[0] = ((short *)&rxF_128[i])[4]; + llr[1] = ((short *)&rxF_128[i])[5]; #if defined(__x86_64__) || defined(__i386__) - llr2[2] = _mm_extract_epi16(xmm1,4); - llr2[3] = _mm_extract_epi16(xmm1,5);//((short *)&xmm1)[j+1]; - llr2[4] = _mm_extract_epi16(xmm2,4);//((short *)&xmm2)[j]; - llr2[5] = _mm_extract_epi16(xmm2,5);//((short *)&xmm2)[j+1]; + llr[2] = _mm_extract_epi16(xmm1,4); + llr[3] = _mm_extract_epi16(xmm1,5);//((short *)&xmm1)[j+1]; + llr[4] = _mm_extract_epi16(xmm2,4);//((short *)&xmm2)[j]; + llr[5] = _mm_extract_epi16(xmm2,5);//((short *)&xmm2)[j+1]; #elif defined(__arm__) - llr2[2] = vgetq_lane_s16(xmm1,4); - llr2[3] = vgetq_lane_s16(xmm1,5);//((short *)&xmm1)[j+1]; - llr2[4] = vgetq_lane_s16(xmm2,4);//((short *)&xmm2)[j]; - llr2[5] = vgetq_lane_s16(xmm2,5);//((short *)&xmm2)[j+1]; + llr[2] = vgetq_lane_s16(xmm1,4); + llr[3] = vgetq_lane_s16(xmm1,5);//((short *)&xmm1)[j+1]; + llr[4] = vgetq_lane_s16(xmm2,4);//((short *)&xmm2)[j]; + llr[5] = vgetq_lane_s16(xmm2,5);//((short *)&xmm2)[j+1]; #endif - llr2+=6; - llr2[0] = ((short *)&rxF[i])[6]; - llr2[1] = ((short *)&rxF[i])[7]; + llr+=6; + llr[0] = ((short *)&rxF_128[i])[6]; + llr[1] = ((short *)&rxF_128[i])[7]; #if defined(__x86_64__) || defined(__i386__) - llr2[2] = _mm_extract_epi16(xmm1,6); - llr2[3] = _mm_extract_epi16(xmm1,7);//((short *)&xmm1)[j+1]; - llr2[4] = _mm_extract_epi16(xmm2,6);//((short *)&xmm2)[j]; - llr2[5] = _mm_extract_epi16(xmm2,7);//((short *)&xmm2)[j+1]; + llr[2] = _mm_extract_epi16(xmm1,6); + llr[3] = _mm_extract_epi16(xmm1,7);//((short *)&xmm1)[j+1]; + llr[4] = _mm_extract_epi16(xmm2,6);//((short *)&xmm2)[j]; + llr[5] = _mm_extract_epi16(xmm2,7);//((short *)&xmm2)[j+1]; #elif defined(__arm__) - llr2[2] = vgetq_lane_s16(xmm1,6); - llr2[3] = vgetq_lane_s16(xmm1,7);//((short *)&xmm1)[j+1]; - llr2[4] = vgetq_lane_s16(xmm2,6);//((short *)&xmm2)[j]; - llr2[5] = vgetq_lane_s16(xmm2,7);//((short *)&xmm2)[j+1]; + llr[2] = vgetq_lane_s16(xmm1,6); + llr[3] = vgetq_lane_s16(xmm1,7);//((short *)&xmm1)[j+1]; + llr[4] = vgetq_lane_s16(xmm2,6);//((short *)&xmm2)[j]; + llr[5] = vgetq_lane_s16(xmm2,7);//((short *)&xmm2)[j+1]; #endif - llr2+=6; + llr+=6; } @@ -8865,7 +8901,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, (int16_t *)llr16, (int32_t *) rho_256i, len); - + free16(rxF_256i, sizeof(rxF_256i)); free16(rxF_i_256i, sizeof(rxF_i_256i)); free16(ch_mag_256i, sizeof(ch_mag_256i)); diff --git a/openair1/PHY/LTE_UE_TRANSPORT/get_pmi.c b/openair1/PHY/LTE_UE_TRANSPORT/get_pmi.c new file mode 100644 index 0000000000000000000000000000000000000000..7bbe8e894257d772ae1edc96795df9e84119a0d7 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/get_pmi.c @@ -0,0 +1,65 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" + +uint8_t get_pmi(uint8_t N_RB_DL, MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb) +{ + /* + MIMO_mode_t mode = dlsch_harq->mimo_mode; + uint32_t pmi_alloc = dlsch_harq->pmi_alloc; + */ + + switch (N_RB_DL) { + case 6: // 1 PRB per subband + if (mode <= PUSCH_PRECODING1) + return((pmi_alloc>>(rb<<1))&3); + else + return((pmi_alloc>>rb)&1); + + break; + + default: + case 25: // 4 PRBs per subband + if (mode <= PUSCH_PRECODING1) + return((pmi_alloc>>((rb>>2)<<1))&3); + else + return((pmi_alloc>>(rb>>2))&1); + + break; + + case 50: // 6 PRBs per subband + if (mode <= PUSCH_PRECODING1) + return((pmi_alloc>>((rb/6)<<1))&3); + else + return((pmi_alloc>>(rb/6))&1); + + break; + + case 100: // 8 PRBs per subband + if (mode <= PUSCH_PRECODING1) + return((pmi_alloc>>((rb>>3)<<1))&3); + else + return((pmi_alloc>>(rb>>3))&1); + + break; + } +} diff --git a/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c b/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c new file mode 100644 index 0000000000000000000000000000000000000000..d85d440193757044eedadaf820ef4d46b47eddb6 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c @@ -0,0 +1,369 @@ +/* These functions compute linear preprocessing for +the UE using LAPACKE and CBLAS modules of +LAPACK libraries. +MMSE and MMSE whitening filters are available. +Functions are using RowMajor storage of the +matrices, like in conventional C. Traditional +Fortran functions of LAPACK employ ColumnMajor +data storage. */ + +#include<stdio.h> +#include<math.h> +#include<complex.h> +#include <stdlib.h> +#include <cblas.h> +#include <string.h> +#include <lapacke_utils.h> +#include <lapacke.h> + +//#define DEBUG_PREPROC + + +void transpose (int N, float complex *A, float complex *Result) +{ + // COnputes C := alpha*op(A)*op(B) + beta*C, + enum CBLAS_TRANSPOSE transa = CblasTrans; + enum CBLAS_TRANSPOSE transb = CblasNoTrans; + int rows_opA = N; // number of rows in op(A) and in C + int col_opB = N; //number of columns of op(B) and in C + int col_opA = N; //number of columns in op(A) and rows in op(B) + int col_B; //number of columns in B + float complex alpha = 1.0+I*0; + int lda = rows_opA; + float complex beta = 0.0+I*0; + int ldc = rows_opA; + int i; + float complex* B; + + int ldb = col_opB; + + if (transb == CblasNoTrans) { + B = (float complex*)calloc(ldb*col_opB,sizeof(float complex)); + col_B= col_opB; + } + else { + B = (float complex*)calloc(ldb*col_opA, sizeof(float complex)); + col_B = col_opA; + } + float complex* C = (float complex*)malloc(ldc*col_opB*sizeof(float complex)); + + for (i=0; i<lda*col_B; i+=N+1) + B[i]=1.0+I*0; + + cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, A, lda, B, ldb, &beta, C, ldc); + + memcpy(Result, C, N*N*sizeof(float complex)); + + free(B); + free(C); + } + + +void conjugate_transpose (int N, float complex *A, float complex *Result) +{ + // Computes C := alpha*op(A)*op(B) + beta*C, + enum CBLAS_TRANSPOSE transa = CblasConjTrans; + enum CBLAS_TRANSPOSE transb = CblasNoTrans; + int rows_opA = N; // number of rows in op(A) and in C + int col_opB = N; //number of columns of op(B) and in C + int col_opA = N; //number of columns in op(A) and rows in op(B) + int col_B; //number of columns in B + float complex alpha = 1.0+I*0; + int lda = rows_opA; + float complex beta = 0.0+I*0; + int ldc = rows_opA; + int i; + float complex* B; + int ldb = col_opB; + + if (transb == CblasNoTrans) { + B = (float complex*)calloc(ldb*col_opB,sizeof(float complex)); + col_B= col_opB; + } + else { + B = (float complex*)calloc(ldb*col_opA, sizeof(float complex)); + col_B = col_opA; + } + float complex* C = (float complex*)malloc(ldc*col_opB*sizeof(float complex)); + + for (i=0; i<lda*col_B; i+=N+1) + B[i]=1.0+I*0; + + cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, A, lda, B, ldb, &beta, C, ldc); + + memcpy(Result, C, N*N*sizeof(float complex)); + + free(B); + free(C); + } + +void H_hermH_plus_sigma2I (int N, int M, float complex *A, float sigma2, float complex *Result) +{ + //C := alpha*op(A)*op(B) + beta*C, + enum CBLAS_TRANSPOSE transa = CblasConjTrans; + enum CBLAS_TRANSPOSE transb = CblasNoTrans; + int rows_opA = N; // number of rows in op(A) and in C + int col_opB = N; //number of columns of op(B) and in C + int col_opA = N; //number of columns in op(A) and rows in op(B) + int col_C = N; //number of columns in B + float complex alpha = 1.0+I*0; + int lda = col_opA; + float complex beta = 1.0 + I*0; + int ldc = col_opA; + int i; + + float complex* C = (float complex*)calloc(ldc*col_opB, sizeof(float complex)); + + for (i=0; i<lda*col_C; i+=N+1) + C[i]=sigma2*(1.0+I*0); + + cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, A, lda, A, lda, &beta, C, ldc); + + memcpy(Result, C, N*M*sizeof(float complex)); + free(C); + + } + + void HH_herm_plus_sigma2I (int M, int N, float complex *A, float sigma2, float complex *Result) +{ + //C := alpha*op(A)*op(B) + beta*C, + enum CBLAS_TRANSPOSE transa = CblasNoTrans; + enum CBLAS_TRANSPOSE transb = CblasConjTrans; + int k = N; //number of columns in op(A) and rows in op(B),k + float complex alpha = 1.0+I*0; + int lda = N; + int ldb = N; + int ldc = M; + int i; + + float complex* C = (float complex*)calloc(M*M, sizeof(float complex)); + + for (i=0; i<M*M; i+=M+1) + C[i]=1.0+I*0; + + cblas_cgemm(CblasRowMajor, transa, transb, M, M, k, &alpha, A, lda, A, ldb, &sigma2, C, ldc); + + memcpy(Result, C, M*M*sizeof(float complex)); + free(C); + +} + +void eigen_vectors_values (int N, float complex *A, float complex *Vectors, float *Values_Matrix) +{ + // This function computes ORTHONORMAL eigenvectors and eigenvalues of matrix A, + // where Values_Matrix is a diagonal matrix of eigenvalues. + // A=Vectors*Values_Matrix*Vectors' + char jobz = 'V'; + char uplo = 'U'; + int order_A = N; + int lda = N; + int i; + float* Values = (float*)malloc(sizeof(float)*1*N); + + LAPACKE_cheev(LAPACK_ROW_MAJOR, jobz, uplo, order_A, A, lda, Values); + + memcpy(Vectors, A, N*N*sizeof(float complex)); + + for (i=0; i<lda; i+=1) + Values_Matrix[i*(lda+1)]=Values[i]; + + free(Values); +} + + void lin_eq_solver (int N, float complex* A, float complex* B, float complex* Result) +{ + int n = N; + int lda = N; + int ldb = N; + int nrhs = N; + + char transa = 'N'; + int* IPIV = malloc(N*N*sizeof(int)); + + // Compute LU-factorization + LAPACKE_cgetrf(LAPACK_ROW_MAJOR, n, nrhs, A, lda, IPIV); + + // Solve AX=B + LAPACKE_cgetrs(LAPACK_ROW_MAJOR, transa, n, nrhs, A, lda, IPIV, B, ldb); + + // cgetrs( "N", N, 4, A, lda, IPIV, B, ldb, INFO ) + + memcpy(Result, B, N*N*sizeof(float complex)); + + free(IPIV); + +} + +void mutl_matrix_matrix_row_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result ){ + enum CBLAS_TRANSPOSE transa = CblasNoTrans; + enum CBLAS_TRANSPOSE transb = CblasNoTrans; + int rows_opA = rows_M0; // number of rows in op(A) and in C + int col_opB = col_M1; //number of columns of op(B) and in C + int col_opA = col_M0; //number of columns in op(A) and rows in op(B) + float complex alpha =1.0; + int lda = col_M0; + float complex beta = 0.0; + int ldc = col_M1; + int ldb = col_M1; + +#ifdef DEBUG_PREPROC + int i=0; + printf("rows_M0 %d, col_M0 %d, rows_M1 %d, col_M1 %d\n", rows_M0, col_M0, rows_M1, col_M1); + + for(i=0; i<rows_M0*col_M0; ++i) + printf(" rows_opA = %d, col_opB = %d, W_MMSE[%d] = (%f + i%f)\n", rows_opA, col_opB, i , creal(M0[i]), cimag(M0[i])); + + for(i=0; i<rows_M1*col_M1; ++i) + printf(" M1[%d] = (%f + i%f)\n", i , creal(M1[i]), cimag(M1[i])); +#endif + + cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, M0, lda, M1, ldb, &beta, Result, ldc); + +#ifdef DEBUG_PREPROC + for(i=0; i<rows_opA*col_opB; ++i) + printf(" result[%d] = (%f + i%f)\n", i , creal(Result[i]), cimag(Result[i])); +#endif + +} +void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result ){ + enum CBLAS_TRANSPOSE transa = CblasNoTrans; + enum CBLAS_TRANSPOSE transb = CblasNoTrans; + int rows_opA = rows_M0; // number of rows in op(A) and in C + int col_opB = col_M1; //number of columns of op(B) and in C + int col_opA = col_M0; //number of columns in op(A) and rows in op(B) + float complex alpha =1.0; + int lda = col_M0; + float complex beta = 0.0; + int ldc = rows_M1; + int ldb = rows_M1; + +#ifdef DEBUG_PREPROC + int i = 0; + printf("rows_M0 %d, col_M0 %d, rows_M1 %d, col_M1 %d\n", rows_M0, col_M0, rows_M1, col_M1); + + for(i=0; i<rows_M0*col_M0; ++i) + printf(" rows_opA = %d, col_opB = %d, W_MMSE[%d] = (%f + i%f)\n", rows_opA, col_opB, i , creal(M0[i]), cimag(M0[i])); + + + for(i=0; i<rows_M1*col_M1; ++i) + printf(" M1[%d] = (%f + i%f)\n", i , creal(M1[i]), cimag(M1[i])); +#endif + + cblas_cgemm(CblasColMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, M0, lda, M1, ldb, &beta, Result, ldc); + +#ifdef DEBUG_PREPROC + for(i=0; i<rows_opA*col_opB; ++i) + printf(" result[%d] = (%f + i%f)\n", i , creal(Result[i]), cimag(Result[i])); +#endif +} + + +/*FILTERS */ +void compute_MMSE(float complex* H, int order_H, float sigma2, float complex* W_MMSE) +{ + int N = order_H; + float complex* H_hermH_sigmaI = malloc(N*N*sizeof(float complex)); + float complex* H_herm = malloc(N*N*sizeof(float complex)); + + H_hermH_plus_sigma2I(N, N, H, sigma2, H_hermH_sigmaI); + +#ifdef DEBUG_PREPROC + int i =0; + for(i=0;i<N*N;i++) + printf(" H_hermH_sigmaI[%d] = (%f + i%f)\n", i , creal(H_hermH_sigmaI[i]), cimag(H_hermH_sigmaI[i])); +#endif + + conjugate_transpose (N, H, H_herm); //equals H_herm + +#ifdef DEBUG_PREPROC + for(i=0;i<N*N;i++) + printf(" H_herm[%d] = (%f + i%f)\n", i , creal(H_herm[i]), cimag(H_herm[i])); +#endif + + lin_eq_solver(N, H_hermH_sigmaI, H_herm, W_MMSE); + +#ifdef DEBUG_PREPROC + for(i=0;i<N*N;i++) + printf(" W_MMSE[%d] = (%f + i%f)\n", i , creal(W_MMSE[i]), cimag(W_MMSE[i])); +#endif + + free(H_hermH_sigmaI); + free(H_herm); +} + +#if 0 +void compute_white_filter(float complex* H_re, + int order_H, + float sigma2, + float complex* W_Wh_0_re, + float complex* W_Wh_1_re){ + + int aatx, aarx, re; + int i,j; + int M =n_rx; + int N = n_tx; + int sigma2=noise_power; + + float complex *H0_re = malloc(n_rx*(n_tx>>2)*sizeof(float complex)); + float complex *H1_re = malloc(n_rx*(n_tx>>2)*sizeof(float complex)); + float complex *R_corr_col_n_0_re = malloc(n_rx*n_tx*sizeof(float complex)); + float complex *R_corr_col_n_1_re = malloc(n_rx*n_tx*sizeof(float complex)); + float complex *U_0_re = malloc(n_rx*n_tx*sizeof(float complex)); + float complex *U_1_re = malloc(n_rx*n_tx*sizeof(float complex)); + float complex *U_0_herm_re = malloc(n_rx*n_tx*sizeof(float complex)); + float complex *U_1_herm_re = malloc(n_rx*n_tx*sizeof(float complex)); + float complex *D_0_re = malloc(n_rx*n_tx*sizeof(float complex)); + float complex *D_1_re = malloc(n_rx*n_tx*sizeof(float complex)); + float complex *W_Wh_0_re = malloc(n_rx*n_tx*sizeof(float complex)); + float complex *W_Wh_1_re = malloc(n_rx*n_tx*sizeof(float complex)); + + for (aatx=0; aatx<n_tx/2; aatx++){ + for (aarx=0; aarx<n_rx; aarx++) { + H0_re[aatx*n_rx + aarx] = H_re[aatx*n_rx + aarx][re]; // H0 gets [0 1 2 3; 4,5,6,7].' coefficients of H + H1_re[aatx*n_rx + aarx] = H_re[aatx*n_rx + aarx + 8][re]; // H1 gets [8 9 10 11; 12, 13, 14, 15].' coefficients of H + if (re == 0) + printf("ant %d, H_re = (%f + i%f) \n", aatx*n_rx + aarx, creal(H[aatx*n_rx + aarx][re]), cimag(H[aatx*n_rx + aarx][re])); + } + } + + + //HH_herm_plus_sigma2I(n_rx, (n_tx>>2), H1_re, sigma2, R_corr_col_n_0_re); + HH_herm_plus_sigma2I(n_rx, (n_tx>>2), H0_re, sigma2, R_corr_col_n_1_re); + + eigen_vectors_values(n_rx, R_corr_col_n_0_re, U_0_re, D_0_re); + eigen_vectors_values(n_rx, R_corr_col_n_1_re, U_1_re, D_1_re); + + transpose (n_rx, U_0_re, U_0_herm_re); + transpose (n_rx, U_1_re, U_1_herm_re); + + sigma = (float)(sqrt((double)(sigma2))); + + /*The inverse of a diagonal matrix is obtained by replacing each element in the diagonal with its reciprocal. + A square root of a diagonal matrix is given by the diagonal matrix, whose diagonal entries are just the square + roots of the original matrix.*/ + + + D_0_re_inv_sqrt[0] = sqrt_float(1/D_0_re_inv[0]); + D_0_re_inv_sqrt[5] = sqrt_float(1/D_0_re_inv[5]); + D_0_re_inv_sqrt[10] = sqrt_float(1/D_0_re_inv[10]); + D_0_re_inv_sqrt[15] = sqrt_float(1/D_0_re_inv[15]); + + D_1_re_inv[0] = sqrt_float(1/D_1_re_inv[0]); + D_1_re_inv[5] = sqrt_float(1/D_1_re_inv[5]); + D_1_re_inv[10] = sqrt_float(1/D_1_re_inv[10]); + D_1_re_inv[15] = sqrt_float(1/D_1_re_inv[15]); + + now only to multiply + + free(H0); + free(H1); + free(R_corr_col_n_0); + free(R_corr_col_n_1); +} +#endif + +float sqrt_float(float x, float sqrt_x) +{ + sqrt_x = (float)(sqrt((double)(x))); + return sqrt_x; +} \ No newline at end of file diff --git a/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.h b/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.h new file mode 100755 index 0000000000000000000000000000000000000000..f38bc475567633a97fd55e3ad4cccc4c3c964ace --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.h @@ -0,0 +1,121 @@ + +#include<stdio.h> +#include<math.h> +#include<complex.h> +#include <stdlib.h> +#include "PHY/defs_UE.h" + + +/* FUNCTIONS FOR LINEAR PREPROCESSING: MMSE, WHITENNING, etc*/ +void transpose(int N, float complex *A, float complex *Result); + +void conjugate_transpose(int N, float complex *A, float complex *Result); + +void H_hermH_plus_sigma2I(int N, int M, float complex *A, float sigma2, float complex *Result); + +void HH_herm_plus_sigma2I(int M, int N, float complex *A, float sigma2, float complex *Result); + +void eigen_vectors_values(int N, float complex *A, float complex *Vectors, float *Values_Matrix); + +void lin_eq_solver(int N, float complex *A, float complex* B); +//float complex* lin_eq_solver (int N, float complex* A, float complex* B); + +/* mutl_matrix_matrix_row_based performs multiplications when matrix is row-oriented H[0], H[1]; H[2], H[3]*/ +void mutl_matrix_matrix_row_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result ); + +/* mutl_matrix_matrix_col_based performs multiplications matrix is column-oriented H[0], H[2]; H[1], H[3]*/ +void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result ); + +void compute_MMSE(float complex* H, int order_H, float sigma2, float complex* W_MMSE); + +void compute_white_filter(float complex* H, int order_H, float sigma2, float complex* U_1, float complex* D_1); + +void mmse_processing_oai(LTE_UE_PDSCH *pdsch_vars, + LTE_DL_FRAME_PARMS *frame_parms, + PHY_MEASUREMENTS *measurements, + unsigned char first_symbol_flag, + MIMO_mode_t mimo_mode, + unsigned short mmse_flag, + int noise_power, + unsigned char symbol, + unsigned short nb_rb); + + +void precode_channel_est(int32_t **dl_ch_estimates_ext, + LTE_DL_FRAME_PARMS *frame_parms, + LTE_UE_PDSCH *pdsch_vars, + unsigned char symbol, + unsigned short nb_rb, + MIMO_mode_t mimo_mode); + + +void rxdataF_to_float(int32_t **rxdataF_ext, + float complex **rxdataF_f, + int n_rx, + int length, + int start_point); + +void chan_est_to_float(int32_t **dl_ch_estimates_ext, + float complex **dl_ch_estimates_ext_f, + int n_tx, + int n_rx, + int length, + int start_point); + +void float_to_chan_est(int32_t **dl_ch_estimates_ext, + float complex **dl_ch_estimates_ext_f, + int n_tx, + int n_rx, + int length, + int start_point); + +void float_to_rxdataF(int32_t **rxdataF_ext, + float complex **rxdataF_f, + int n_tx, + int n_rx, + int length, + int start_point); + +void mult_mmse_rxdataF(float complex** Wmmse, + float complex** rxdataF_ext_f, + int n_tx, + int n_rx, + int length, + int start_point); + +void mult_mmse_chan_est(float complex** Wmmse, + float complex** dl_ch_estimates_ext_f, + int n_tx, + int n_rx, + int length, + int start_point); + +void mmse_processing_core(int32_t **rxdataF_ext, + int32_t **dl_ch_estimates_ext, + int sigma2, + int n_tx, + int n_rx, + int length, + int start_point); + +void mmse_processing_core_flp(float complex** rxdataF_ext_flcpx, + float complex **H, + int32_t **rxdataF_ext, + int32_t **dl_ch_estimates_ext, + float sigma2, + int n_tx, + int n_rx, + int length, + int start_point); + +void whitening_processing_core_flp(float complex** rxdataF_ext_flcpx, + float complex **H, + int32_t **rxdataF_ext, + int32_t **dl_ch_estimates_ext, + float sigma2, + int n_tx, + int n_rx, + int length, + int start_point); + +float sqrt_float(float x, float sqrt_x); diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h index ade621faa2a3fb3b386e4df3e8a1782549f56219..814816a8852797713b44f89a6193f32fbf863d7a 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h +++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h @@ -106,6 +106,22 @@ void qpsk_qpsk(int16_t *stream0_in, @param nb_rb number of RBs for this allocation @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS @param llr128p pointer to pointer to symbol in dlsch_llr*/ + +void qpsk_llr(int16_t *stream0_in, + int16_t *stream0_out, + int length); + +void qam16_llr(int16_t *stream0_in, + int16_t *chan_magn, + int16_t *llr, + int length); + +void qam64_llr(int16_t *stream0_in, + int16_t *chan_magn, + int16_t *chan_magn_b, + int16_t *llr, + int length); + int32_t dlsch_qpsk_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, int32_t **rxdataF_comp_i, @@ -816,6 +832,19 @@ void dlsch_channel_compensation(int32_t **rxdataF_ext, uint8_t output_shift, PHY_MEASUREMENTS *phy_measurements); +void dlsch_channel_compensation_core(int **rxdataF_ext, + int **dl_ch_estimates_ext, + int **dl_ch_mag, + int **dl_ch_magb, + int **rxdataF_comp, + int **rho, + unsigned char n_tx, + unsigned char n_rx, + unsigned char mod_order, + unsigned char output_shift, + int length, + int start_point); + void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, unsigned char symbol, unsigned short nb_rb, @@ -912,6 +941,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int round, MIMO_mode_t mimo_mode, unsigned short nb_rb, + unsigned short mmse_flag, unsigned char output_shift0, unsigned char output_shift1); @@ -929,6 +959,13 @@ void dlsch_channel_level(int32_t **dl_ch_estimates_ext, uint8_t pilots_flag, uint16_t nb_rb); +void dlsch_channel_level_core(int32_t **dl_ch_estimates_ext, + int32_t *avg, + int n_tx, + int n_rx, + int length, + int start_point); + void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, @@ -937,6 +974,7 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, int *avg_1, uint8_t symbol, unsigned short nb_rb, + unsigned int mmse_flag, MIMO_mode_t mimo_mode); @@ -1672,8 +1710,8 @@ double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, LTE_UE_DLSCH_t *dlsch_ue); */ -uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t prach_ConfigIndex, +uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t prach_ConfigIndex, uint8_t n_ra_prboffset, uint8_t tdd_mapindex, uint16_t Nf); diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index de17bbee0b9856833664acf3375a07a1f612cc4f..f079794a34afa069d83032b6f0e20a00353d50e4 100644 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -69,6 +69,38 @@ #include <pthread.h> #include "assertions.h" +#ifdef MEX +#include "mex.h" +# define msg mexPrintf +# undef LOG_D +# undef LOG_E +# undef LOG_I +# undef LOG_N +# undef LOG_T +# undef LOG_W +# undef LOG_M +# define LOG_D(x, ...) mexPrintf(__VA_ARGS__) +# define LOG_E(x, ...) mexPrintf(__VA_ARGS__) +# define LOG_I(x, ...) mexPrintf(__VA_ARGS__) +# define LOG_N(x, ...) mexPrintf(__VA_ARGS__) +# define LOG_T(x, ...) mexPrintf(__VA_ARGS__) +# define LOG_W(x, ...) mexPrintf(__VA_ARGS__) +# define LOG_M(x, ...) mexPrintf(__VA_ARGS__) +#else +# ifdef OPENAIR2 +# if ENABLE_RAL +# include "collection/hashtable/hashtable.h" +# include "COMMON/ral_messages_types.h" +# include "UTIL/queue.h" +# endif +# include "log.h" +# define msg(aRGS...) LOG_D(PHY, ##aRGS) +# else +# define msg printf +# endif +#endif + + /// Context data structure for RX/TX portion of subframe processing typedef struct { @@ -273,13 +305,13 @@ typedef struct { /// - first index: rx antenna [0..nb_antennas_rx[ /// - second index: symbol [0..28*ofdm_symbol_size[ int32_t **rxdataF; - + /// \brief Hold the channel estimates in frequency domain. /// - first index: eNB id [0..6] (hard coded) /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - third index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ int32_t **dl_ch_estimates[7]; - + /// \brief Hold the channel estimates in time domain (used for tracking). /// - first index: eNB id [0..6] (hard coded) /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx @@ -848,7 +880,7 @@ typedef struct { /// RF and Interface devices per CC - openair0_device rfdevice; + openair0_device rfdevice; } PHY_VARS_UE; /* this structure is used to pass both UE phy vars and diff --git a/targets/build_helper.bash b/targets/build_helper.bash index a3c57b8dce53bbce85d15422aae272874ec22f4d..9c98ef85b0173ce4f9bac95a529d0363f727f8c1 100755 --- a/targets/build_helper.bash +++ b/targets/build_helper.bash @@ -23,7 +23,7 @@ # brief # author Lionel Gauthier and Navid Nikaein # company Eurecom -# email: lionel.gauthier@eurecom.fr and navid.nikaein@eurecom.fr +# email: lionel.gauthier@eurecom.fr and navid.nikaein@eurecom.fr # ####################################### # Helper Func @@ -42,30 +42,30 @@ declare UBUNTU_REL=`lsb_release -r | cut -f2` declare UBUNTU_REL_NAME=`lsb_release -cs` set_build_from_makefile(){ - BUILD_FROM_MAKEFILE=$1 + BUILD_FROM_MAKEFILE=$1 } check_for_root_rights() { - + # if [[ $EUID -ne $ROOT_EUID ]]; then if [ $USER != "root" ]; then SUDO="sudo -E " - echo "Run as a sudoers" + echo "Run as a sudoers" return 1 - else - echo "Run as a root" + else + echo "Run as a root" return 0 fi } test_install_package() { # usage: test_install_package package_name - + if [ $# -eq 1 ]; then dpkg -s "$1" > /dev/null 2>&1 && { - echo "$1 is installed." + echo "$1 is installed." } || { - echo "$1 is not installed." + echo "$1 is not installed." OAI_INSTALLED=0 $SUDO apt-get install -y $@ } @@ -73,13 +73,13 @@ test_install_package() { } test_uninstall_package() { - + if [ $# -eq 1 ]; then dpkg -s "$1" > /dev/null 2>&1 && { - $SUDO apt-get remove --assume-yes $1 - echo "$1 is uninstalled." + $SUDO apt-get remove --assume-yes $1 + echo "$1 is uninstalled." } || { - echo "$1 is not installed." + echo "$1 is not installed." } fi } @@ -97,8 +97,8 @@ check_for_machine_type(){ else if [ ${MACHINE_TYPE} = "i686" ]; then return 32 # 32-bit stuff here - else - return -1 + else + return -1 fi fi } @@ -108,7 +108,7 @@ check_for_machine_type(){ ##################################################### #################################################### -# 1. install the required packages +# 1. install the required packages #################################################### make_certs(){ @@ -118,32 +118,32 @@ make_certs(){ mkdir -m 777 -p demoCA echo 01 > demoCA/serial touch demoCA/index.txt - + echo "creating the certificate" - + user=$(whoami) HOSTNAME=$(hostname -f) echo "Creating certificate for user '$HOSTNAME'" - + # CA self certificate openssl req -new -batch -x509 -days 3650 -nodes -newkey rsa:1024 -out cacert.pem -keyout cakey.pem -subj /CN=eur/C=FR/ST=PACA/L=Aix/O=Eurecom/OU=CM - + # openssl genrsa -out user.key.pem 1024 openssl genrsa -out hss.key.pem 1024 #openssl req -new -batch -out user.csr.pem -key user.key.pem -subj /CN=$HOSTNAME.eur/C=FR/ST=PACA/L=Aix/O=Eurecom/OU=CM openssl req -new -batch -out hss.csr.pem -key hss.key.pem -subj /CN=hss.eur/C=FR/ST=PACA/L=Aix/O=Eurecom/OU=CM openssl ca -cert cacert.pem -keyfile cakey.pem -in hss.csr.pem -out hss.cert.pem -outdir . -batch - + if [ ! -d /usr/local/etc/freeDiameter ]; then echo "Creating non existing directory: /usr/local/etc/freeDiameter/" $SUDO mkdir /usr/local/etc/freeDiameter/ fi - + echo "Copying *.pem to /usr/local/etc/freeDiameter/" $SUDO cp *.pem /usr/local/etc/freeDiameter/ mv *.pem bin/ - + # openssl genrsa -out ubuntu.key.pem 1024 # openssl req -new -batch -x509 -out ubuntu.csr.pem -key ubuntu.key.pem -subj /CN=ubuntu.localdomain/C=FR/ST=BdR/L=Aix/O=fD/OU=Tests # openssl ca -cert cacert.pem -keyfile cakey.pem -in ubuntu.csr.pem -out ubuntu.cert.pem -outdir . -batch @@ -151,25 +151,25 @@ make_certs(){ } check_install_nettle(){ - if [ ! -f ./.lock_oaibuild ]; then - if [ $UBUNTU_REL = "12.04" ]; then + if [ ! -f ./.lock_oaibuild ]; then + if [ $UBUNTU_REL = "12.04" ]; then test_uninstall_package nettle-dev test_uninstall_package nettle-bin - + if [ ! -d /usr/local/src/ ]; then echo "/usr/local/src/ doesn't exist please create one" exit -1 fi - + if [ ! -w /usr/local/src/ ]; then echo "You don't have permissions to write to /usr/local/src/, installing as a sudoer" # exit -1 fi - + cd /usr/local/src/ - + echo "Downloading nettle archive" - + if [ -f nettle-2.5.tar.gz ]; then $SUDO rm -f nettle-2.5.tar.gz fi @@ -179,44 +179,44 @@ check_install_nettle(){ if [ -d nettle-2.5 ]; then $SUDO rm -rf nettle-2.5/ fi - - - $SUDO wget ftp://ftp.lysator.liu.se/pub/security/lsh/nettle-2.5.tar.gz - $SUDO gunzip nettle-2.5.tar.gz + + + $SUDO wget ftp://ftp.lysator.liu.se/pub/security/lsh/nettle-2.5.tar.gz + $SUDO gunzip nettle-2.5.tar.gz $SUDO echo "Uncompressing nettle archive" $SUDO tar -xf nettle-2.5.tar cd nettle-2.5/ - $SUDO ./configure --disable-openssl --enable-shared --prefix=/usr + $SUDO ./configure --disable-openssl --enable-shared --prefix=/usr if [ $? -ne 0 ]; then exit -1 fi echo "Compiling nettle" - $SUDO make -j $NUM_CPU - $SUDO make check - $SUDO make install + $SUDO make -j $NUM_CPU + $SUDO make check + $SUDO make install cd ../ fi fi } check_install_freediamter(){ - - if [ $UBUNTU_REL = "12.04" ]; then + + if [ $UBUNTU_REL = "12.04" ]; then if [ ! -d /usr/local/src/ ]; then echo "/usr/local/src/ doesn't exist please create one" exit -1 fi - + if [ ! -w /usr/local/src/ ]; then echo "You don't have permissions to write to /usr/local/src/, installing as a sudoer" # exit -1 fi - + cd /usr/local/src/ - + echo "Downloading nettle archive" - + if [ -f nettle-2.5.tar.gz ]; then $SUDO rm -f nettle-2.5.tar.gz fi @@ -226,36 +226,36 @@ check_install_freediamter(){ if [ -d nettle-2.5 ]; then $SUDO rm -rf nettle-2.5/ fi - - - $SUDO wget ftp://ftp.lysator.liu.se/pub/security/lsh/nettle-2.5.tar.gz - $SUDO gunzip nettle-2.5.tar.gz + + + $SUDO wget ftp://ftp.lysator.liu.se/pub/security/lsh/nettle-2.5.tar.gz + $SUDO gunzip nettle-2.5.tar.gz $SUDO echo "Uncompressing nettle archive" $SUDO tar -xf nettle-2.5.tar cd nettle-2.5/ - $SUDO ./configure --disable-openssl --enable-shared --prefix=/usr + $SUDO ./configure --disable-openssl --enable-shared --prefix=/usr if [ $? -ne 0 ]; then exit -1 fi echo "Compiling nettle" - $SUDO make -j $NUM_CPU - $SUDO make check - $SUDO make install + $SUDO make -j $NUM_CPU + $SUDO make check + $SUDO make install cd ../ fi - + echo "Downloading gnutls archive" - + if [ -f gnutls-3.1.23.tar.xz ]; then $SUDO rm -f gnutls-3.1.23.tar.xz fi if [ -d gnutls-3.1.23/ ]; then $SUDO rm -rf gnutls-3.1.23/ fi - + test_uninstall_package libgnutls-dev - - $SUDO wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.1/gnutls-3.1.23.tar.xz + + $SUDO wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.1/gnutls-3.1.23.tar.xz $SUDO tar -xf gnutls-3.1.23.tar.xz echo "Uncompressing gnutls archive ($PWD)" cd gnutls-3.1.23/ @@ -264,38 +264,38 @@ check_install_freediamter(){ exit -1 fi echo "Compiling gnutls" - $SUDO make -j $NUM_CPU - $SUDO make install + $SUDO make -j $NUM_CPU + $SUDO make install cd ../ - + echo "Downloading freeDiameter archive" - + if [ -f 1.1.5.tar.gz ]; then $SUDO rm -f 1.1.5.tar.gz fi if [ -d freeDiameter-1.1.5/ ]; then $SUDO rm -rf freeDiameter-1.1.5/ fi - - $SUDO wget http://www.freediameter.net/hg/freeDiameter/archive/1.1.5.tar.gz - $SUDO tar -xzf 1.1.5.tar.gz + + $SUDO wget http://www.freediameter.net/hg/freeDiameter/archive/1.1.5.tar.gz + $SUDO tar -xzf 1.1.5.tar.gz echo "Uncompressing freeDiameter archive" cd freeDiameter-1.1.5 - $SUDO patch -p1 < $OPENAIR3_DIR/S6A/freediameter/freediameter-1.1.5.patch + $SUDO patch -p1 < $OPENAIR3_DIR/S6A/freediameter/freediameter-1.1.5.patch $SUDO mkdir build cd build - $SUDO cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr ../ + $SUDO cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr ../ if [ $? -ne 0 ]; then exit -1 fi echo "Compiling freeDiameter" - $SUDO make -j $NUM_CPU + $SUDO make -j $NUM_CPU #make help - $SUDO make test - $SUDO sudo make install - + $SUDO make test + $SUDO sudo make install + # make_certs - + } @@ -339,7 +339,7 @@ check_hss_s6a_certificate() { then echo_success "HSS S6A: Found valid certificate in /usr/local/etc/freeDiameter" return 0 - else + else echo_error "Bad hss hostname found in cert file: "$full_hostname " hostname is "`hostname` fi fi @@ -357,43 +357,43 @@ check_hss_s6a_certificate() { } check_install_usrp_uhd_driver(){ - if [ ! -f /etc/apt/sources.list.d/ettus.list ] ; then + if [ ! -f /etc/apt/sources.list.d/ettus.list ] ; then $SUDO bash -c 'echo "deb http://files.ettus.com/binaries/uhd/repo/uhd/ubuntu/`lsb_release -cs` `lsb_release -cs` main" >> /etc/apt/sources.list.d/ettus.list' $SUDO apt-get update - fi + fi $SUDO apt-get install -t $UBUNTU_REL_NAME uhd - test_install_package python - test_install_package libboost-all-dev + test_install_package python + test_install_package libboost-all-dev test_install_package libusb-1.0-0-dev #test_install_package uhd } check_install_oai_software() { - - if [ ! -f ./.lock_oaibuild ]; then + + if [ ! -f ./.lock_oaibuild ]; then $SUDO apt-get update - if [ $UBUNTU_REL = "12.04" ]; then + if [ $UBUNTU_REL = "12.04" ]; then test_uninstall_package nettle-dev test_uninstall_package nettle-bin - else + else test_install_package nettle-dev test_install_package nettle-bin - fi - test_install_package autoconf - test_install_package automake - test_install_package bison + fi + test_install_package autoconf + test_install_package automake + test_install_package bison test_install_package build-essential test_install_package dialog - test_install_package flex + test_install_package flex test_install_package gawk test_install_package gcc - test_install_package gdb + test_install_package gdb test_install_package make test_install_package cmake test_install_package openssh-client test_install_package openssh-server sudo service ssh start - test_install_package unzip + test_install_package unzip test_install_package autoconf test_install_package automake test_install_package bison @@ -405,7 +405,7 @@ check_install_oai_software() { test_install_package gawk test_install_package gcc test_install_package gccxml - test_install_package gdb + test_install_package gdb test_install_package guile-2.0-dev test_install_package iperf test_install_package iproute @@ -414,6 +414,8 @@ check_install_oai_software() { test_install_package libatlas-dev test_install_package libblas3gf test_install_package libblas-dev + test_install_package liblapack-dev + test_install_package liblapack-dev # if [ $MACHINE_ARCH = 64 ]; then test_install_package libconfig8-dev # else @@ -436,7 +438,7 @@ check_install_oai_software() { test_install_package libxml2-dev # test_install_package linux-headers-`uname -r` test_install_package openssl - test_install_package libssl-dev + test_install_package libssl-dev test_install_package pkg-config test_install_package python-dev test_install_package python-pexpect @@ -445,90 +447,90 @@ check_install_oai_software() { test_install_package valgrind test_install_package doxygen test_install_package graphviz - + # test_install_package libboost-all-dev - - if [ $OAI_INSTALLED = 1 ]; then + + if [ $OAI_INSTALLED = 1 ]; then touch ./.lock_oaibuild - fi - + fi + else echo_info "All the required packages installed: skip" - fi - + fi + } check_install_hss_software() { - if [ ! -f ./.lock_oaibuild ]; then + if [ ! -f ./.lock_oaibuild ]; then $SUDO apt-get update - if [ $UBUNTU_REL = "12.04" ]; then + if [ $UBUNTU_REL = "12.04" ]; then test_uninstall_package nettle-dev test_uninstall_package nettle-bin - else + else test_install_package nettle-dev test_install_package nettle-bin - fi - test_install_package autoconf - test_install_package automake - test_install_package bison + fi + test_install_package autoconf + test_install_package automake + test_install_package bison test_install_package build-essential test_install_package cmake - test_install_package cmake-curses-gui + test_install_package cmake-curses-gui test_install_package dialog test_install_package dkms - test_install_package flex + test_install_package flex test_install_package gawk test_install_package gcc - test_install_package gdb - test_install_package guile-2.0-dev + test_install_package gdb + test_install_package guile-2.0-dev test_install_package g++ - test_install_package libgmp-dev - test_install_package libgcrypt11-dev - test_install_package libidn11-dev - test_install_package libidn2-0-dev - test_install_package libmysqlclient-dev - test_install_package libtasn1-3-dev - test_install_package libsctp1 - test_install_package libsctp-dev - test_install_package libxml2-dev -# test_install_package linux-headers-`uname -r` + test_install_package libgmp-dev + test_install_package libgcrypt11-dev + test_install_package libidn11-dev + test_install_package libidn2-0-dev + test_install_package libmysqlclient-dev + test_install_package libtasn1-3-dev + test_install_package libsctp1 + test_install_package libsctp-dev + test_install_package libxml2-dev +# test_install_package linux-headers-`uname -r` test_install_package make - test_install_package mysql-client - test_install_package mysql-server-core-5.5 + test_install_package mysql-client + test_install_package mysql-server-core-5.5 test_install_package mysql-server test_install_package openssh-client test_install_package openssh-server sudo service ssh start test_install_package phpmyadmin - test_install_package python-dev + test_install_package python-dev test_install_package sshfs - test_install_package swig - test_install_package unzip + test_install_package swig + test_install_package unzip # test_install_package nettle-bin # test_install_package nettle-dev - test_install_package valgrind + test_install_package valgrind - if [ $OAI_INSTALLED = 1 ]; then + if [ $OAI_INSTALLED = 1 ]; then touch ./.lock_oaibuild - fi - + fi + else echo_info "All the required packages installed: skip" - fi + fi } check_install_epc_software() { - if [ ! -f ./.lock_oaibuild ]; then + if [ ! -f ./.lock_oaibuild ]; then $SUDO apt-get update - if [ $UBUNTU_REL = "12.04" ]; then + if [ $UBUNTU_REL = "12.04" ]; then test_uninstall_package nettle-dev test_uninstall_package nettle-bin - else + else test_install_package nettle-dev test_install_package nettle-bin - fi + fi test_install_package autoconf test_install_package automake test_install_package bison @@ -543,7 +545,7 @@ check_install_epc_software() { test_install_package gawk test_install_package gcc test_install_package gccxml - test_install_package gdb + test_install_package gdb test_install_package guile-2.0-dev test_install_package gtkwave test_install_package iperf @@ -573,7 +575,7 @@ check_install_epc_software() { test_install_package libsctp-dev test_install_package libssl-dev test_install_package libtasn1-3-dev - test_install_package libtool + test_install_package libtool test_install_package libxml2 test_install_package libxml2-dev # test_install_package linux-headers-`uname -r` @@ -593,21 +595,21 @@ check_install_epc_software() { test_install_package unzip test_install_package valgrind test_install_package vlan - - if [ $OAI_INSTALLED = 1 ]; then + + if [ $OAI_INSTALLED = 1 ]; then touch ./.lock_oaibuild - fi - + fi + else echo_info "All the required packages installed: skip" - fi + fi } check_install_asn1c(){ - + test_command_install_script "asn1c" "$OPENAIR_TARGETS/SCRIPTS/install_asn1c_0.9.24.modified.bash $SUDO" - + # One mor check about version of asn1c ASN1C_COMPILER_REQUIRED_VERSION_MESSAGE="ASN.1 Compiler, v0.9.24" ASN1C_COMPILER_VERSION_MESSAGE=`asn1c -h 2>&1 | grep -i ASN\.1\ Compiler` @@ -624,15 +626,15 @@ check_install_asn1c(){ fi done fi - + } ################################################# -# 2. compile +# 2. compile ################################################ compile_hss() { cd $OPENAIR3_DIR/OPENAIRHSS - + if [ "$1" -eq 1 ]; then echo_info "build a clean HSS" rm -rfv obj* @@ -642,14 +644,14 @@ compile_hss() { fi OBJ_DIR=`find . -maxdepth 1 -type d -iname obj*` - + if [ ! -n "$OBJ_DIR" ]; then OBJ_DIR="objs" mkdir --verbose -m 777 ./$OBJ_DIR else OBJ_DIR=`basename $OBJ_DIR` fi - + if [ ! -f "$OBJ_DIR"/Makefile ]; then if [ ! -d m4 ]; then mkdir --verbose -m 777 m4 @@ -661,7 +663,7 @@ compile_hss() { fi cd $OBJ_DIR echo_success "Invoking configure" - ../configure + ../configure if [ $? -ne 0 ]; then return 1 fi @@ -675,7 +677,7 @@ compile_hss() { if [ $? -ne 0 ]; then echo_error "Build failed, exiting" return 1 - else + else return 0 fi else @@ -705,11 +707,11 @@ compile_epc() { fi bash_exec "autoreconf -i -f" echo_success "Invoking autogen" - bash_exec "libtoolize" + bash_exec "libtoolize" bash_exec "./autogen.sh" cd ./$OBJ_DIR echo_success "Invoking configure" - if [ $DEBUG -ne 0 ]; then + if [ $DEBUG -ne 0 ]; then ../configure --enable-debug --enable-standalone-epc --enable-gtp1u-in-kernel LDFLAGS=-L/usr/local/lib else ../configure --enable-standalone-epc --enable-gtp1u-in-kernel LDFLAGS=-L/usr/local/lib @@ -727,30 +729,30 @@ compile_epc() { if [ $? -ne 0 ]; then echo_error "Build failed, exiting" return 1 - else + else cp -pf ./OAI_EPC/oai_epc $OPENAIR_TARGETS/bin fi else echo_error "Configure failed, exiting" return 1 fi - + cd $OPENAIR3_DIR/GTPV1-U/GTPUAH; make if [ $? -ne 0 ]; then echo_error "Build GTPUAH module failed, exiting" return 1 - else + else $SUDO cp -pfv ./Bin/libxt_*.so /lib/xtables $SUDO cp -pfv ./Bin/*.ko $OPENAIR_TARGETS/bin fi - + cd $OPENAIR3_DIR/GTPV1-U/GTPURH; make if [ $? -ne 0 ]; then echo_error "Build GTPURH module failed, exiting" return 1 - else + else $SUDO cp -pfv ./Bin/libxt_*.so /lib/xtables $SUDO cp -pfv ./Bin/*.ko $OPENAIR_TARGETS/bin fi @@ -777,15 +779,15 @@ compile_ltesoftmodem() { if [ $? -ne 0 ]; then # to locate easily compilation error in log file make $SOFTMODEM_DIRECTIVES - fi + fi if [ $? -ne 0 ]; then - if [ ! -f ./lte-softmodem ]; then + if [ ! -f ./lte-softmodem ]; then echo_error "Build lte-softmodem failed, returning" return 1 - else + else cp -pf ./lte-softmodem $OPENAIR_TARGETS/bin return 0 - fi + fi else cp -pf ./lte-softmodem $OPENAIR_TARGETS/bin return 0 @@ -801,11 +803,11 @@ compile_oaisim() { if [ -f Makefile ]; then echo "Compiling for oaisim target ($OAISIM_DIRECTIVES)" make cleanall > /dev/null - make -j $NUM_CPU $OAISIM_DIRECTIVES + make -j $NUM_CPU $OAISIM_DIRECTIVES if [ $? -ne 0 ]; then echo_error "Build oaisim failed, returning" return 1 - else + else cp -pf ./oaisim $OPENAIR_TARGETS/bin return 0 fi @@ -820,11 +822,11 @@ compile_unisim() { if [ -f Makefile ]; then echo "Compiling for UNISIM target ..." make cleanall - make -j $NUM_CPU all + make -j $NUM_CPU all if [ $? -ne 0 ]; then echo_error "Build unisim failed, returning" return 1 - else + else cp -pf ./dlsim $OPENAIR_TARGETS/bin cp -pf ./ulsim $OPENAIR_TARGETS/bin cp -pf ./pucchsim $OPENAIR_TARGETS/bin @@ -843,9 +845,9 @@ compile_unisim() { compile_nas_tools() { export NVRAM_DIR=$OPENAIR_TARGETS/bin - + cd $NVRAM_DIR - + if [ ! -f /tmp/nas_cleaned ]; then echo_success "make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS/tools veryveryclean" make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS/tools veryveryclean @@ -963,11 +965,11 @@ check_for_nas_ue_executable() { ############################################### # arg1 is RT -# arg2 is HW +# arg2 is HW # arg3 is ENB_S1 install_ltesoftmodem() { # RT - if [ $1 = "RTAI" ]; then + if [ $1 = "RTAI" ]; then if [ ! -f /tmp/init_rt_done.tmp ]; then echo_info " 8.1 Insert RTAI modules" $SUDO insmod /usr/realtime/modules/rtai_hal.ko > /dev/null 2>&1 @@ -982,46 +984,46 @@ install_ltesoftmodem() { fi fi #HW - if [ $2 = "EXMIMO" ]; then + if [ $2 = "EXMIMO" ]; then echo_info " 8.2 [EXMIMO] creating RTAI fifos" - for i in `seq 0 64`; do + for i in `seq 0 64`; do have_rtfX=`ls /dev/ |grep -c rtf$i`; - if [ "$have_rtfX" -eq 0 ] ; then - $SUDO mknod -m 666 /dev/rtf$i c 150 $i; + if [ "$have_rtfX" -eq 0 ] ; then + $SUDO mknod -m 666 /dev/rtf$i c 150 $i; fi; done echo_info " 8.3 [EXMIMO] Build lte-softmodemdrivers" cd $OPENAIR_TARGETS/ARCH/EXMIMO/DRIVER/eurecom && make clean && make # || exit 1 cd $OPENAIR_TARGETS/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT && make clean && make # || exit 1 - + echo_info " 8.4 [EXMIMO] Setup RF card" cd $OPENAIR_TARGETS/RT/USER . ./init_exmimo2.sh - else + else if [ $2 = "USRP" ]; then echo_info " 8.2 [USRP] " fi fi - + # ENB_S1 - if [ $3 = 0 ]; then + if [ $3 = 0 ]; then cd $OPENAIR2_DIR && make clean && make nasmesh_netlink.ko #|| exit 1 cd $OPENAIR2_DIR/NAS/DRIVER/MESH/RB_TOOL && make clean && make # || exit 1 fi - + } # arg1 is ENB_S1 'boolean' install_oaisim() { - if [ $1 = 0 ]; then + if [ $1 = 0 ]; then cd $OPENAIR2_DIR && make clean && make nasmesh_netlink.ko #|| exit 1 cd $OPENAIR2_DIR/NAS/DRIVER/MESH/RB_TOOL && make clean && make # || exit 1 else compile_ue_ip_nw_driver install_nas_tools - fi - + fi + } @@ -1041,7 +1043,7 @@ install_nas_tools() { } install_nasmesh(){ - echo_success "LOAD NASMESH IP DRIVER FOR UE AND eNB" + echo_success "LOAD NASMESH IP DRIVER FOR UE AND eNB" (cd $OPENAIR2_DIR/NAS/DRIVER/MESH/RB_TOOL && make clean && make) (cd $OPENAIR2_DIR && make clean && make nasmesh_netlink_address_fix.ko) $SUDO rmmod nasmesh @@ -1069,7 +1071,7 @@ create_hss_database(){ fi set_openair_env - + # removed % #Q1="GRANT ALL PRIVILEGES ON *.* TO '$3'@'%' IDENTIFIED BY '$4' WITH GRANT OPTION;" Q1="GRANT ALL PRIVILEGES ON *.* TO '$3'@'localhost' IDENTIFIED BY '$4' WITH GRANT OPTION;" @@ -1082,8 +1084,8 @@ create_hss_database(){ else echo_success "$3 permissions succeeded" fi - - + + Q1="CREATE DATABASE IF NOT EXISTS ${BTICK}$5${BTICK};" SQL="${Q1}" $MYSQL -u $3 --password=$4 -e "$SQL" @@ -1093,12 +1095,12 @@ create_hss_database(){ else echo_success "$5 creation succeeded" fi - - + + # test if tables have been created mysql -u $3 --password=$4 -e "desc $5.users" > /dev/null 2>&1 - - if [ $? -eq 1 ]; then + + if [ $? -eq 1 ]; then $MYSQL -u $3 --password=$4 $5 < $OPENAIR3_DIR/OPENAIRHSS/db/oai_db.sql if [ $? -ne 0 ]; then echo_error "$5 tables creation failed" @@ -1107,7 +1109,7 @@ create_hss_database(){ echo_success "$5 tables creation succeeded" fi fi - + return 0 } @@ -1176,7 +1178,7 @@ print_help_perf(){ } ############################### -## echo and family +## echo and family ############################### black='\E[30m' red='\E[31m' @@ -1196,10 +1198,10 @@ cecho() # Color-echo local default_msg="No Message." message=${1:-$default_msg} color=${2:-$green} - if [ $BUILD_FROM_MAKEFILE = 0 ]; then + if [ $BUILD_FROM_MAKEFILE = 0 ]; then echo -e -n "$color$message$reset_color" echo - else + else echo "$message" fi return @@ -1304,7 +1306,7 @@ assert() { if [ -z "$2" ] ; then # Not enought parameters passed. return $E_PARAM_ERR fi - + lineno=$2 if [ ! $1 ]; then echo_error "Assertion failed: \"$1\""