diff --git a/matlab/tests/diversity_decode_test.m b/matlab/tests/diversity_decode_test.m index 75c29c2e3..24ad28ca7 100644 --- a/matlab/tests/diversity_decode_test.m +++ b/matlab/tests/diversity_decode_test.m @@ -1,6 +1,6 @@ clear -addpath('../../debug/srslte/lib/mimo/test') +addpath('../../build/srslte/lib/mimo/test') %enb = lteRMCDL('R.10'); % 2-ports enb = lteRMCDL('R.0'); % 1-ports @@ -11,7 +11,7 @@ cec.InterpWinSize = 1; cec.InterpWindow = 'Causal'; cfg.Seed = 1; % Random channel seed -cfg.NRxAnts = 1; % 1 receive antenna +cfg.NRxAnts = 2; % 1 receive antenna cfg.DelayProfile = 'ETU'; % EVA delay spread cfg.DopplerFreq = 100; % 120Hz Doppler frequency cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation @@ -47,13 +47,8 @@ else Nt=1; end -if (Nr > 1) - rx=reshape(rxGrid,p,n,Nr); - hp=reshape(h,p,n,Nr,Nt); -else - rx=rxGrid; - hp=h; -end +rx=reshape(rxGrid,p*n,Nr); +hp=reshape(h,p*n,Nr,Nt); if (Nt > 1) output_mat = lteTransmitDiversityDecode(rx, hp); @@ -65,6 +60,6 @@ output_srs = srslte_diversitydecode(rx, hp, n0); plot(abs(output_mat(:)-output_srs(:))) mean(abs(output_mat(:)-output_srs(:)).^2) -t=1:10; +t=1:100; plot(t,real(output_mat(t)),t,real(output_srs(t))) diff --git a/srslte/include/srslte/mimo/precoding.h b/srslte/include/srslte/mimo/precoding.h index 667e1d02b..b71a38603 100644 --- a/srslte/include/srslte/mimo/precoding.h +++ b/srslte/include/srslte/mimo/precoding.h @@ -83,6 +83,13 @@ SRSLTE_API int srslte_predecoding_diversity(cf_t *y, int nof_ports, int nof_symbols); +SRSLTE_API int srslte_predecoding_diversity_multi(cf_t *y[SRSLTE_MAX_RXANT], + cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], + cf_t *x[SRSLTE_MAX_LAYERS], + int nof_rxant, + int nof_ports, + int nof_symbols); + SRSLTE_API int srslte_predecoding_type(cf_t *y, cf_t *h[SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], diff --git a/srslte/lib/mimo/precoding.c b/srslte/lib/mimo/precoding.c index 22e2bdc5f..1b9183485 100644 --- a/srslte/lib/mimo/precoding.c +++ b/srslte/lib/mimo/precoding.c @@ -38,7 +38,7 @@ #include #include int srslte_predecoding_single_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate); -int srslte_predecoding_diversity2_sse(cf_t *y, cf_t *h[SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], int nof_symbols); +int srslte_predecoding_diversity2_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], cf_t *x[SRSLTE_MAX_LAYERS], int nof_rxant, int nof_symbols); #endif #ifdef LV_HAVE_AVX @@ -160,8 +160,6 @@ int srslte_predecoding_single_avx(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_ __m256 h1Val1, h2Val1, y1Val1, y2Val1, h12square, h1square, h2square, h1_p, h2_p, h1conj1, h2conj1, x1Val, x2Val; __m256 h1Val2, h2Val2, y1Val2, y2Val2, h1conj2, h2conj2; - printf("using avx\n"); - for (int i=0;i 32) { + if (nof_symbols > 32 && nof_rxant <= 2) { return srslte_predecoding_single_avx(y, h, x, nof_rxant, nof_symbols, noise_estimate); } else { return srslte_predecoding_single_gen(y, h, x, nof_rxant, nof_symbols, noise_estimate); } #else #ifdef LV_HAVE_SSE - if (nof_symbols > 32) { + if (nof_symbols > 32 && nof_rxant <= 2) { return srslte_predecoding_single_sse(y, h, x, nof_rxant, nof_symbols, noise_estimate); } else { return srslte_predecoding_single_gen(y, h, x, nof_rxant, nof_symbols, noise_estimate); @@ -295,54 +293,67 @@ int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MA } /* C implementatino of the SFBC equalizer */ -int srslte_predecoding_diversity_gen_(cf_t *y, cf_t *h[SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], - int nof_ports, int nof_symbols, int symbol_start) +int srslte_predecoding_diversity_gen_(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], + cf_t *x[SRSLTE_MAX_LAYERS], + int nof_rxant, int nof_ports, int nof_symbols, int symbol_start) { int i; if (nof_ports == 2) { cf_t h00, h01, h10, h11, r0, r1; - float hh; for (i = symbol_start/2; i < nof_symbols / 2; i++) { - h00 = h[0][2 * i]; - h01 = h[0][2 * i+1]; - h10 = h[1][2 * i]; - h11 = h[1][2 * i+1]; - hh = crealf(h00) * crealf(h00) + cimagf(h00) * cimagf(h00) - + crealf(h11) * crealf(h11) + cimagf(h11) * cimagf(h11); - r0 = y[2 * i]; - r1 = y[2 * i + 1]; - if (hh == 0) { - hh = 1e-4; + float hh = 0; + cf_t x0 = 0; + cf_t x1 = 0; + for (int p=0;p 32 && nof_ports == 2) { + return srslte_predecoding_diversity2_sse(y, h, x, nof_rxant, nof_symbols); + } else { + return srslte_predecoding_diversity_gen(y, h, x, nof_rxant, nof_ports, nof_symbols); + } +#else + return srslte_predecoding_diversity_gen(y, h, x, nof_rxant, nof_ports, nof_symbols); +#endif +} + +int srslte_predecoding_diversity_multi(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], cf_t *x[SRSLTE_MAX_LAYERS], + int nof_rxant, int nof_ports, int nof_symbols) { #ifdef LV_HAVE_SSE if (nof_symbols > 32 && nof_ports == 2) { - return srslte_predecoding_diversity2_sse(y, h, x, nof_symbols); + return srslte_predecoding_diversity2_sse(y, h, x, nof_rxant, nof_symbols); } else { - return srslte_predecoding_diversity_gen(y, h, x, nof_ports, nof_symbols); + return srslte_predecoding_diversity_gen(y, h, x, nof_rxant, nof_ports, nof_symbols); } #else - return srslte_predecoding_diversity_gen(y, h, x, nof_ports, nof_symbols); + return srslte_predecoding_diversity_gen(y, h, x, nof_rxant, nof_ports, nof_symbols); #endif } + /* 36.211 v10.3.0 Section 6.3.4 */ int srslte_predecoding_type(cf_t *y, cf_t *h[SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], int nof_ports, int nof_layers, int nof_symbols, srslte_mimo_type_t type, float noise_estimate) { diff --git a/srslte/lib/mimo/test/diversitydecode_mex.c b/srslte/lib/mimo/test/diversitydecode_mex.c index 7c020c6b8..4e2859acc 100644 --- a/srslte/lib/mimo/test/diversitydecode_mex.c +++ b/srslte/lib/mimo/test/diversitydecode_mex.c @@ -65,13 +65,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) uint32_t nof_rx_ants = 1; const mwSize *dims = mxGetDimensions(INPUT); mwSize ndims = mxGetNumberOfDimensions(INPUT); - nof_symbols = dims[0]*dims[1]; + nof_symbols = dims[0]; - if (ndims >= 3) { - nof_rx_ants = dims[2]; - } - if (ndims >= 4) { - nof_tx_ports = dims[3]; + if (ndims >= 2) { + nof_rx_ants = dims[1]; } // Read channel estimates @@ -79,7 +76,15 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Error reading hest\n"); return; } + dims = mxGetDimensions(HEST); + ndims = mxGetNumberOfDimensions(HEST); + + if (ndims == 3) { + nof_tx_ports = dims[2]; + } + mexPrintf("nof_tx_ports=%d, nof_rx_ants=%d, nof_symbols=%d\n", nof_tx_ports, nof_rx_ants, nof_symbols); + // Read noise estimate float noise_estimate = 0; if (nrhs >= NOF_INPUTS) { @@ -111,12 +116,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) for (int j=0;j 1) { - //srslte_predecoding_diversity(input, h, x, nof_tx_ports, nof_symbols); - //srslte_layerdemap_diversity(x, output, nof_tx_ports, nof_symbols / nof_tx_ports); + srslte_predecoding_diversity_multi(y, h, x, nof_rx_ants, nof_tx_ports, nof_symbols); + srslte_layerdemap_diversity(x, output, nof_tx_ports, nof_symbols / nof_tx_ports); } else { srslte_predecoding_single_multi(y, h[0], output, nof_rx_ants, nof_symbols, noise_estimate); }