added pucch2 rx

This commit is contained in:
Ismael Gomez 2017-03-24 22:51:17 -04:00
parent 533dafb8db
commit 6855615635
8 changed files with 106 additions and 100 deletions

View File

@ -106,4 +106,14 @@ SRSLTE_API int srslte_predecoding_type(cf_t *y,
srslte_mimo_type_t type,
float noise_estimate);
SRSLTE_API int srslte_predecoding_type_multi(cf_t *y[SRSLTE_MAX_PORTS],
cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
cf_t *x[SRSLTE_MAX_LAYERS],
int nof_rxant,
int nof_ports,
int nof_layers,
int nof_symbols,
srslte_mimo_type_t type,
float noise_estimate);
#endif /* PRECODING_H_ */

View File

@ -41,6 +41,7 @@
#include "srslte/modem/mod.h"
#include "srslte/phch/cqi.h"
#include "srslte/phch/uci.h"
#include "srslte/modem/demod_hard.h"
#define SRSLTE_PUCCH_N_SEQ 12
#define SRSLTE_PUCCH_MAX_BITS SRSLTE_CQI_MAX_BITS
@ -84,6 +85,7 @@ typedef struct SRSLTE_API {
srslte_pucch_cfg_t pucch_cfg;
srslte_sequence_t seq_f2[SRSLTE_NSUBFRAMES_X_FRAME];
srslte_modem_table_t mod;
srslte_demod_hard_t demod;
uint8_t bits_scram[SRSLTE_PUCCH_MAX_BITS];
cf_t d[SRSLTE_PUCCH_MAX_BITS/2];

View File

@ -207,11 +207,9 @@ int srslte_layerdemap_type(cf_t *x[SRSLTE_MAX_LAYERS], cf_t *d[SRSLTE_MAX_CODEWO
}
break;
case SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX:
case SRSLTE_MIMO_TYPE_CDD:
return srslte_layerdemap_multiplex(x, d, nof_layers, nof_cw, nof_layer_symbols, nof_symbols);
break;
case SRSLTE_MIMO_TYPE_CDD:
fprintf(stderr, "CDD Not implemented\n");
return -1;
}
return 0;
}

View File

@ -516,9 +516,23 @@ int srslte_predecoding_diversity_multi(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE
}
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)
{
cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
cf_t *y[SRSLTE_MAX_PORTS];
uint32_t nof_rxant = 1;
for (int i=0;i<nof_ports;i++) {
h[i][0] = h_[i];
}
y[0] = y_;
return srslte_predecoding_type_multi(y, h, x, nof_rxant, nof_ports, nof_layers, nof_symbols, type, noise_estimate);
}
/* 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) {
int srslte_predecoding_type_multi(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS],
int nof_rxant, int nof_ports, int nof_layers, int nof_symbols, srslte_mimo_type_t type, float noise_estimate) {
if (nof_ports > SRSLTE_MAX_PORTS) {
fprintf(stderr, "Maximum number of ports is %d (nof_ports=%d)\n", SRSLTE_MAX_PORTS,

View File

@ -1,56 +0,0 @@
#
# Copyright 2013-2015 Software Radio Systems Limited
#
# This file is part of the srsLTE library.
#
# srsLTE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# srsLTE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# A copy of the GNU Affero General Public License can be found in
# the LICENSE file in the top-level directory of this distribution
# and at http://www.gnu.org/licenses/.
#
########################################################################
# LAYER MAPPING TEST
########################################################################
add_executable(layermap_test layermap_test.c)
target_link_libraries(layermap_test srslte)
add_test(layermap_single layermap_test -n 1000 -m single -c 1 -l 1)
add_test(layermap_diversity_2 layermap_test -n 1000 -m diversity -c 1 -l 2)
add_test(layermap_diversity_4 layermap_test -n 1000 -m diversity -c 1 -l 4)
add_test(layermap_multiplex_11 layermap_test -n 1000 -m multiplex -c 1 -l 1)
add_test(layermap_multiplex_12 layermap_test -n 1000 -m multiplex -c 1 -l 2)
add_test(layermap_multiplex_13 layermap_test -n 1002 -m multiplex -c 1 -l 3)
add_test(layermap_multiplex_14 layermap_test -n 1000 -m multiplex -c 1 -l 4)
add_test(layermap_multiplex_22 layermap_test -n 1000 -m multiplex -c 2 -l 2)
add_test(layermap_multiplex_23 layermap_test -n 1002 -m multiplex -c 2 -l 3)
add_test(layermap_multiplex_24 layermap_test -n 1000 -m multiplex -c 2 -l 4)
########################################################################
# LAYER MAPPING TEST
########################################################################
add_executable(precoding_test precoder_test.c)
target_link_libraries(precoding_test srslte)
add_test(precoding_single precoding_test -n 1000 -m single)
add_test(precoding_diversity2 precoding_test -n 1000 -m diversity -l 2 -p 2)
add_test(precoding_diversity4 precoding_test -n 1024 -m diversity -l 4 -p 4)

View File

@ -31,16 +31,18 @@
/** MEX function to be called from MATLAB to test the predecoder
*/
#define INPUT prhs[0]
#define HEST prhs[1]
#define NEST prhs[2]
#define NOF_INPUTS 2
#define INPUT prhs[0]
#define HEST prhs[1]
#define NEST prhs[2]
#define NLAYERS prhs[3]
#define TXSCHEME prhs[4]
#define NOF_INPUTS 5
void help()
{
mexErrMsgTxt
("[output] = srslte_predecoder(input, hest, nest)\n\n");
("[output] = srslte_predecoder(input, hest, nest, Nl, TxScheme)\n\n");
}
/* the gateway function */
@ -61,7 +63,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
mexErrMsgTxt("Error reading input\n");
return;
}
uint32_t nof_layers = mxGetScalar(NLAYERS);
uint32_t nof_tx_ports = 1;
uint32_t nof_codewords = 1;
uint32_t nof_rx_ants = 1;
const mwSize *dims = mxGetDimensions(INPUT);
mwSize ndims = mxGetNumberOfDimensions(INPUT);
@ -83,7 +88,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
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);
mexPrintf("nof_tx_ports=%d, nof_rx_ants=%d, nof_layers=%d, nof_symbols=%d\n", nof_tx_ports, nof_rx_ants, nof_layers, nof_symbols);
// Read noise estimate
float noise_estimate = 0;
@ -117,12 +122,31 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
y[j] = &input[j*nof_symbols];
}
if (nof_tx_ports > 1) {
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);
char *txscheme = "Port0";
if (nrhs >= NOF_INPUTS) {
txscheme = mxArrayToString(TXSCHEME);
}
srslte_mimo_type_t type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
if (!strcmp(txscheme, "Port0")) {
type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
} else if (!strcmp(txscheme, "TxDiversity")) {
type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
} else if (!strcmp(txscheme, "CDD")) {
type = SRSLTE_MIMO_TYPE_CDD;
} else if (!strcmp(txscheme, "SpatialMux")) {
type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
} else {
srslte_predecoding_single_multi(y, h[0], output, nof_rx_ants, nof_symbols, noise_estimate);
mexPrintf("Unsupported TxScheme=%s\n", txscheme);
return;
}
int symbols_layers[SRSLTE_MAX_LAYERS];
for (int i=0;i<nof_layers;i++) {
symbols_layers[i] = nof_symbols;
}
cf_t *d[SRSLTE_MAX_LAYERS];
d[0] = output;
srslte_predecoding_type_multi(y, h, x, nof_rx_ants, nof_tx_ports, nof_layers, nof_symbols/nof_layers, type, noise_estimate);
srslte_layerdemap_type(x, d, nof_layers, nof_codewords, nof_symbols, symbols_layers, type);
if (nlhs >= 1) {

View File

@ -429,6 +429,9 @@ int srslte_pucch_init(srslte_pucch_t *q, srslte_cell_t cell) {
if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK)) {
return SRSLTE_ERROR;
}
srslte_demod_hard_init(&q->demod);
srslte_demod_hard_table_set(&q->demod, SRSLTE_MOD_QPSK);
// Precompute group hopping values u.
if (srslte_group_hopping_f_gh(q->f_gh, q->cell.id)) {
@ -582,13 +585,19 @@ static int uci_mod_bits(srslte_pucch_t *q, srslte_pucch_format_t format, uint8_t
// Declare this here, since we can not include refsignal_ul.h
void srslte_refsignal_r_uv_arg_1prb(float *arg, uint32_t u);
static int pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format,
uint32_t n_pucch, uint32_t sf_idx,
uint8_t bits[SRSLTE_PUCCH_MAX_BITS], cf_t z[SRSLTE_PUCCH_MAX_SYMBOLS])
static int pucch_encode_(srslte_pucch_t* q, srslte_pucch_format_t format,
uint32_t n_pucch, uint32_t sf_idx,
uint8_t bits[SRSLTE_PUCCH_MAX_BITS], cf_t z[SRSLTE_PUCCH_MAX_SYMBOLS], bool signal_only)
{
if (uci_mod_bits(q, format, bits, sf_idx)) {
fprintf(stderr, "Error encoding PUCCH bits\n");
return SRSLTE_ERROR;
if (!signal_only) {
if (uci_mod_bits(q, format, bits, sf_idx)) {
fprintf(stderr, "Error encoding PUCCH bits\n");
return SRSLTE_ERROR;
}
} else {
for (int i=0;i<SRSLTE_PUCCH_MAX_BITS/2;i++) {
q->d[i] = 1.0;
}
}
uint32_t N_sf_0 = get_N_sf(format, 0, q->shortened);
for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) {
@ -631,6 +640,14 @@ static int pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format,
return SRSLTE_SUCCESS;
}
static int pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format,
uint32_t n_pucch, uint32_t sf_idx,
uint8_t bits[SRSLTE_PUCCH_MAX_BITS], cf_t z[SRSLTE_PUCCH_MAX_SYMBOLS])
{
return pucch_encode_(q, format, n_pucch, sf_idx, bits, z, false);
}
/* Encode, modulate and resource mapping of PUCCH bits according to Section 5.4.1 of 36.211 */
int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format,
uint32_t n_pucch, uint32_t sf_idx, uint8_t bits[SRSLTE_PUCCH_MAX_BITS],
@ -689,6 +706,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format,
sf_symbols != NULL)
{
ret = SRSLTE_ERROR;
cf_t ref[SRSLTE_PUCCH_MAX_SYMBOLS];
// Shortened PUCCH happen in every cell-specific SRS subframes for Format 1/1a/1b
if (q->pucch_cfg.srs_configured && format < SRSLTE_PUCCH_FORMAT_2) {
@ -705,7 +723,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format,
q->last_n_pucch = n_pucch;
if (format >= SRSLTE_PUCCH_FORMAT_2 && !q->rnti_is_set) {
fprintf(stderr, "Error decoding PUCCH: C-RNTI must be set before encoding PUCCH Format 2/2a/2b\n");
fprintf(stderr, "Error decoding PUCCH: C-RNTI must be set before decoding PUCCH Format 2/2a/2b\n");
return SRSLTE_ERROR;
}
int nof_re = pucch_get(q, format, n_pucch, sf_symbols, q->z_tmp);
@ -755,28 +773,24 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format,
DEBUG("format1a b=%d, corr=%f, nof_re=%d, th=%f\n", b, corr, nof_re, q->threshold_format1a);
}
q->last_corr = corr_max;
/*
if (corr_max < 0.01) {
srslte_vec_save_file("sf_symbols", sf_symbols, sizeof(cf_t)*SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp));
srslte_vec_save_file("sf_ce", ce, sizeof(cf_t)*SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp));
srslte_vec_save_file("ce", q->ce, sizeof(cf_t)*nof_re);
srslte_vec_save_file("z_before", zz, sizeof(cf_t)*nof_re);
srslte_vec_save_file("z_eq", q->z, sizeof(cf_t)*nof_re);
srslte_vec_save_file("z_1", q->z_tmp, sizeof(cf_t)*nof_re);
bits[0] = 0;
pucch_encode(q, format, n_pucch, sf_idx, bits, q->z_tmp);
srslte_vec_save_file("z_0", q->z_tmp, sizeof(cf_t)*nof_re);
printf("corr_max=%f, b_max=%d, n_pucch=%d, n_prb=%d, sf_idx=%d, nof_re=%d, noise_estimate=%f\n", corr_max, b_max, n_pucch, q->last_n_prb, sf_idx, nof_re, noise_estimate);
exit(-1);
}
*/
bits[0] = b_max;
break;
default:
fprintf(stderr, "Error decoding PUCCH: Format %d not supported\n", format);
ret = SRSLTE_ERROR;
case SRSLTE_PUCCH_FORMAT_2:
pucch_encode_(q, format, n_pucch, sf_idx, NULL, ref, true);
srslte_vec_prod_conj_ccc(q->z, ref, q->z_tmp, SRSLTE_PUCCH_MAX_SYMBOLS);
for (int i=0;i<SRSLTE_PUCCH_MAX_BITS/2;i++) {
q->z[i] = 0;
for (int j=0;j<SRSLTE_NRE;j++) {
q->z[i] += q->z_tmp[i*SRSLTE_NRE+j]/SRSLTE_NRE;
}
}
srslte_demod_hard_demodulate(&q->demod, q->z, bits, SRSLTE_PUCCH_MAX_BITS/2);
srslte_scrambling_b(&q->seq_f2[sf_idx], bits);
ret = 1;
break;
default:
fprintf(stderr, "PUCCH format %d not implemented\n", format);
return SRSLTE_ERROR;
}
}

View File

@ -192,7 +192,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return;
}
if (srslte_pucch_decode(&pucch, format, n_pucch, sf_idx, sf_symbols, ce, 0, bits)) {
if (srslte_pucch_decode(&pucch, format, n_pucch, sf_idx, sf_symbols, ce, 0, bits)<0) {
mexErrMsgTxt("Error decoding PUCCH\n");
return;
}
@ -210,11 +210,11 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
}
if (nlhs >= 2) {
mexutils_write_cf(pucch.z, &plhs[1], 2*srslte_refsignal_dmrs_N_rs(format, cell.cp)*SRSLTE_NRE*2, 1);
mexutils_write_cf(pucch.z, &plhs[1], 10, 1);
}
if (nlhs >= 3) {
mexutils_write_cf(ce, &plhs[2], nof_re, 1);
mexutils_write_cf(pucch.z_tmp, &plhs[2], 120, 1);
}
srslte_pucch_free(&pucch);