Commit 87f21854 authored by Cedric Roux's avatar Cedric Roux

Merge remote-tracking branch 'origin/mmse_receiver' into develop_integration_2018_w29

Conflicts:
	cmake_targets/CMakeLists.txt
parents c836ef28 759c1342
......@@ -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
......@@ -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
......@@ -2005,7 +2033,7 @@ 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
${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)
......@@ -2045,7 +2073,7 @@ 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
${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 )
......
......@@ -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 \
......
......@@ -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)
{
......
......@@ -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
......
......@@ -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;
......@@ -447,6 +458,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
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],
......@@ -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,
......@@ -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++) {
......@@ -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));
......@@ -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,48 +2647,37 @@ 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) {
}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) {
}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) {
}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 {
}else {
LOG_E(PHY,"Unknown MIMO mode\n");
return;
}
}
if (mod_order0>2) {
......@@ -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++) {
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) {
}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) {
}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 {
}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,127 +3357,6 @@ 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)
{
#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;
}
// printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i);
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", 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,
......@@ -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];
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]);
} }
// 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 (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 (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];
__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;
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,
......@@ -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,19 +3723,21 @@ 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
//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]);
//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));
......@@ -3552,20 +3752,19 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
//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) {
/*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] +
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;
// printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
}
_mm_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,56 +3812,114 @@ 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] +
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;
int16_t x = factor2(length);
int16_t y = (length)>>x;
for (aatx=0; aatx<n_tx; aatx++)
for (aarx=0; aarx<n_rx; aarx++) {
avg128D = _mm_setzero_si128();
dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*n_rx + aarx][start_point];
length_mod8=length&7;
if (length_mod8 == 0){
length2 = length>>3;
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));
dl_ch128+=2;
}
}else {
printf ("Channel level: Received number of subcarriers is not multiple of 4, \n"
"need to adapt the code!\n");
}
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]);
}
_mm_empty();
_m_empty();
/* FIXME This part needs to be adapted like the one above */
#elif defined(__arm__)
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;
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;
for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
//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;
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*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))
......@@ -3670,130 +3927,630 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext,
else
nre=12;
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];
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);
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]);
//printf("Channel level : %d\n",avg[aatx*(frame_parms->nb_antennas_rx-1) + aarx]);
}
#endif
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);
avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));
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){
avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp));
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;
dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[1]);
dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[1]);
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
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);
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;
// 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));
length = nre*nb_rb;
start_point = symbol*nb_rb*12;
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;
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);
}
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);
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){
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));
int aatx, aarx, re;
float imag;
float real;
dl_ch0_128+=3;
dl_ch1_128+=3;
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);
}
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]);
chan_est_to_float(dl_ch_estimates_ext,
dl_ch_estimates_ext_flcpx,
n_tx,
n_rx,
length,
start_point);
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]);
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];
}
}
}
//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];
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 (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 (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 (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,
......
......@@ -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;
llr32 = (int32_t*)dlsch_llr;
} else {
llr32 = (uint32_t*)*llr32p;
llr32 = (int32_t*)*llr32p;
}
#elif defined(__arm__)
if (first_symbol_flag==1) {
llr16 = (int16_t*)dlsch_llr;
} else {
llr16 = (int16_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;
}
......
/*
* 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;
}
}
/* 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
#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);
......@@ -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);
......
......@@ -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 {
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment