diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index a4157d872..35f7d3e9f 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -318,7 +318,7 @@ void base_init() { } bzero(&pdsch, sizeof(srslte_pdsch_t)); - if (srslte_pdsch_init_tx_multi(&pdsch, cell)) { + if (srslte_pdsch_init_tx(&pdsch, cell)) { fprintf(stderr, "Error creating PDSCH object\n"); exit(-1); } @@ -820,14 +820,13 @@ int main(int argc, char **argv) { /* Configure pdsch_cfg parameters */ srslte_ra_dl_grant_t grant; srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, UE_CRNTI, &grant); - if (srslte_pdsch_cfg_multi(&pdsch_cfg, cell, &grant, cfi, sf_idx, rvidx, pdsch_cfg.mimo_type, multiplex_pmi)) { + if (srslte_pdsch_cfg_mimo(&pdsch_cfg, cell, &grant, cfi, sf_idx, rvidx, pdsch_cfg.mimo_type, multiplex_pmi)) { fprintf(stderr, "Error configuring PDSCH\n"); exit(-1); } /* Encode PDSCH */ - if (srslte_pdsch_encode_multi(&pdsch, &pdsch_cfg, softbuffers, data, UE_CRNTI, - sf_symbols)) { + if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, softbuffers, data, UE_CRNTI, sf_symbols)) { fprintf(stderr, "Error encoding PDSCH\n"); exit(-1); } diff --git a/lib/include/srslte/phy/enb/enb_dl.h b/lib/include/srslte/phy/enb/enb_dl.h index 08cb5da4f..d39eed1e1 100644 --- a/lib/include/srslte/phy/enb/enb_dl.h +++ b/lib/include/srslte/phy/enb/enb_dl.h @@ -152,11 +152,11 @@ SRSLTE_API void srslte_enb_dl_rem_rnti(srslte_enb_dl_t *q, SRSLTE_API int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant, - srslte_softbuffer_tx_t *softbuffer, + srslte_softbuffer_tx_t *softbuffer[SRSLTE_MAX_CODEWORDS], uint16_t rnti, uint32_t rv_idx, uint32_t sf_idx, - uint8_t *data); + uint8_t *data[SRSLTE_MAX_CODEWORDS]); SRSLTE_API int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q, srslte_ra_dl_dci_t *grant, diff --git a/lib/include/srslte/phy/phch/pdsch.h b/lib/include/srslte/phy/phch/pdsch.h index a30851648..44ed161e8 100644 --- a/lib/include/srslte/phy/phch/pdsch.h +++ b/lib/include/srslte/phy/phch/pdsch.h @@ -78,15 +78,12 @@ typedef struct SRSLTE_API { } srslte_pdsch_t; -SRSLTE_API int srslte_pdsch_init(srslte_pdsch_t *q, - srslte_cell_t cell); +SRSLTE_API int srslte_pdsch_init_tx(srslte_pdsch_t *q, + srslte_cell_t cell); -SRSLTE_API int srslte_pdsch_init_tx_multi(srslte_pdsch_t *q, - srslte_cell_t cell); - -SRSLTE_API int srslte_pdsch_init_rx_multi(srslte_pdsch_t *q, - srslte_cell_t cell, - uint32_t nof_antennas); +SRSLTE_API int srslte_pdsch_init_rx(srslte_pdsch_t *q, + srslte_cell_t cell, + uint32_t nof_antennas); SRSLTE_API void srslte_pdsch_free(srslte_pdsch_t *q); @@ -103,23 +100,16 @@ SRSLTE_API int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, uint32_t sf_idx, int rvidx); -SRSLTE_API int srslte_pdsch_cfg_multi(srslte_pdsch_cfg_t *cfg, - srslte_cell_t cell, - srslte_ra_dl_grant_t *grant, - uint32_t cfi, - uint32_t sf_idx, - int rvidx[SRSLTE_MAX_CODEWORDS], - srslte_mimo_type_t mimo_type, - uint32_t pmi); +SRSLTE_API int srslte_pdsch_cfg_mimo(srslte_pdsch_cfg_t *cfg, + srslte_cell_t cell, + srslte_ra_dl_grant_t *grant, + uint32_t cfi, + uint32_t sf_idx, + int rvidx[SRSLTE_MAX_CODEWORDS], + srslte_mimo_type_t mimo_type, + uint32_t pmi); SRSLTE_API int srslte_pdsch_encode(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, - srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, - uint16_t rnti, - cf_t *sf_symbols[SRSLTE_MAX_PORTS]); - -SRSLTE_API int srslte_pdsch_encode_multi(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffers[SRSLTE_MAX_CODEWORDS], uint8_t *data[SRSLTE_MAX_CODEWORDS], @@ -127,23 +117,14 @@ SRSLTE_API int srslte_pdsch_encode_multi(srslte_pdsch_t *q, cf_t *sf_symbols[SRSLTE_MAX_PORTS]); SRSLTE_API int srslte_pdsch_decode(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, - srslte_softbuffer_rx_t *softbuffer, - cf_t *sf_symbols, - cf_t *ce[SRSLTE_MAX_PORTS], - float noise_estimate, + srslte_pdsch_cfg_t *cfg, + srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS], + cf_t *sf_symbols[SRSLTE_MAX_PORTS], + cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], + float noise_estimate, uint16_t rnti, - uint8_t *data); - -SRSLTE_API int srslte_pdsch_decode_multi(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, - srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS], - cf_t *sf_symbols[SRSLTE_MAX_PORTS], - cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], - float noise_estimate, - uint16_t rnti, - uint8_t *data[SRSLTE_MAX_CODEWORDS], - bool acks[SRSLTE_MAX_CODEWORDS]); + uint8_t *data[SRSLTE_MAX_CODEWORDS], + bool acks[SRSLTE_MAX_CODEWORDS]); SRSLTE_API int srslte_pdsch_pmi_select(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg, diff --git a/lib/src/phy/enb/enb_dl.c b/lib/src/phy/enb/enb_dl.c index 4cc33d3b8..39606ff7f 100644 --- a/lib/src/phy/enb/enb_dl.c +++ b/lib/src/phy/enb/enb_dl.c @@ -83,7 +83,7 @@ int srslte_enb_dl_init(srslte_enb_dl_t *q, srslte_cell_t cell) goto clean_exit; } - if (srslte_pdsch_init(&q->pdsch, q->cell)) { + if (srslte_pdsch_init_tx(&q->pdsch, q->cell)) { fprintf(stderr, "Error creating PDSCH object\n"); goto clean_exit; } @@ -262,9 +262,9 @@ int srslte_enb_dl_put_pdcch_ul(srslte_enb_dl_t *q, srslte_ra_ul_dci_t *grant, return SRSLTE_SUCCESS; } -int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant, srslte_softbuffer_tx_t *softbuffer, +int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q, srslte_ra_dl_grant_t *grant, srslte_softbuffer_tx_t *softbuffer[SRSLTE_MAX_CODEWORDS], uint16_t rnti, uint32_t rv_idx, uint32_t sf_idx, - uint8_t *data) + uint8_t *data[SRSLTE_MAX_CODEWORDS]) { /* Configure pdsch_cfg parameters */ if (srslte_pdsch_cfg(&q->pdsch_cfg, q->cell, grant, q->cfi, sf_idx, rv_idx)) { diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index 9f0e4ed12..bc62df7fd 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -198,7 +198,7 @@ int srslte_pdsch_get(srslte_pdsch_t *q, cf_t *sf_symbols, cf_t *symbols, } /** Initializes the PDCCH transmitter or receiver */ -int srslte_pdsch_init_multi(srslte_pdsch_t *q, srslte_cell_t cell, uint32_t nof_antennas, bool is_receiver) +int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell, uint32_t nof_antennas, bool is_receiver) { int ret = SRSLTE_ERROR_INVALID_INPUTS; int i; @@ -243,7 +243,6 @@ int srslte_pdsch_init_multi(srslte_pdsch_t *q, srslte_cell_t cell, uint32_t nof_ if (!q->d[i]) { goto clean; } - } /* Layer mapped symbols memory allocation */ @@ -289,16 +288,12 @@ int srslte_pdsch_init_multi(srslte_pdsch_t *q, srslte_cell_t cell, uint32_t nof_ return ret; } -int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell) { - return srslte_pdsch_init_multi(q, cell, 1, true); +int srslte_pdsch_init_tx(srslte_pdsch_t *q, srslte_cell_t cell) { + return srslte_pdsch_init(q, cell, 0, false); } -int srslte_pdsch_init_tx_multi(srslte_pdsch_t *q, srslte_cell_t cell) { - return srslte_pdsch_init_multi(q, cell, 0, false); -} - -int srslte_pdsch_init_rx_multi(srslte_pdsch_t *q, srslte_cell_t cell, uint32_t nof_antennas) { - return srslte_pdsch_init_multi(q, cell, nof_antennas, true); +int srslte_pdsch_init_rx(srslte_pdsch_t *q, srslte_cell_t cell, uint32_t nof_antennas) { + return srslte_pdsch_init(q, cell, nof_antennas, true); } void srslte_pdsch_free(srslte_pdsch_t *q) { @@ -346,9 +341,75 @@ void srslte_pdsch_free(srslte_pdsch_t *q) { } bzero(q, sizeof(srslte_pdsch_t)); - } +/* Precalculate the PDSCH scramble sequences for a given RNTI. This function takes a while + * to execute, so shall be called once the final C-RNTI has been allocated for the session. + */ +int srslte_pdsch_set_rnti(srslte_pdsch_t *q, uint16_t rnti) { + uint32_t i, j; + if (!q->users[rnti]) { + q->users[rnti] = calloc(1, sizeof(srslte_pdsch_user_t)); + if (q->users[rnti]) { + for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { + for (j = 0; j < SRSLTE_MAX_CODEWORDS; j++) { + if (srslte_sequence_pdsch(&q->users[rnti]->seq[j][i], rnti, j, 2 * i, q->cell.id, + q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { + ERROR("Generating scrambling sequence"); + return SRSLTE_ERROR; + } + } + } + q->users[rnti]->sequence_generated = true; + } + } + return SRSLTE_SUCCESS; +} + +void srslte_pdsch_free_rnti(srslte_pdsch_t* q, uint16_t rnti) +{ + if (q->users[rnti]) { + for (int i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { + for (int j = 0; j < SRSLTE_MAX_CODEWORDS; j++) { + srslte_sequence_free(&q->users[rnti]->seq[j][i]); + } + } + free(q->users[rnti]); + q->users[rnti] = NULL; + } +} + +static void pdsch_decode_debug(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg, + cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]) +{ + if (SRSLTE_VERBOSE_ISDEBUG()) { + char filename[FILENAME_MAX]; + for (int j = 0; j < q->nof_rx_antennas; j++) { + if (snprintf(filename, FILENAME_MAX, "subframe_p%d.dat", j) < 0) { + ERROR("Generating file name"); + break; + } + DEBUG("SAVED FILE %s: received subframe symbols\n", filename); + srslte_vec_save_file(filename, sf_symbols, SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); + + for (int i = 0; i < q->cell.nof_ports; i++) { + if (snprintf(filename, FILENAME_MAX, "hest_%d%d.dat", i, j) < 0) { + ERROR("Generating file name"); + break; + } + DEBUG("SAVED FILE %s: channel estimates for Tx %d and Rx %d\n", filename, j, i); + srslte_vec_save_file(filename, ce[i][j], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); + } + } + DEBUG("SAVED FILE pdsch_symbols.dat: symbols after equalization\n",0); + srslte_vec_save_file("pdsch_symbols.dat", q->d, cfg->nbits[0].nof_re*sizeof(cf_t)); + + DEBUG("SAVED FILE llr.dat: LLR estimates after demodulation and descrambling\n",0); + srslte_vec_save_file("llr.dat", q->e, cfg->nbits[0].nof_bits*sizeof(int16_t)); + } +} + + /* Configures the structure srslte_pdsch_cfg_t from the DL DCI allocation dci_msg. * If dci_msg is NULL, the grant is assumed to be already stored in cfg->grant */ @@ -357,13 +418,13 @@ int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_g int _rvids[SRSLTE_MAX_CODEWORDS] = {1}; _rvids[0] = rvidx; - return srslte_pdsch_cfg_multi(cfg, cell, grant, cfi, sf_idx, _rvids, SRSLTE_MIMO_TYPE_SINGLE_ANTENNA, 0); + return srslte_pdsch_cfg_mimo(cfg, cell, grant, cfi, sf_idx, _rvids, SRSLTE_MIMO_TYPE_SINGLE_ANTENNA, 0); } /* Configures the structure srslte_pdsch_cfg_t from the DL DCI allocation dci_msg. * If dci_msg is NULL, the grant is assumed to be already stored in cfg->grant */ -int srslte_pdsch_cfg_multi(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_grant_t *grant, uint32_t cfi, +int srslte_pdsch_cfg_mimo(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, int rvidx[SRSLTE_MAX_CODEWORDS], srslte_mimo_type_t mimo_type, uint32_t pmi) { if (cfg) { @@ -425,29 +486,6 @@ int srslte_pdsch_cfg_multi(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_r } } -/* Precalculate the PDSCH scramble sequences for a given RNTI. This function takes a while - * to execute, so shall be called once the final C-RNTI has been allocated for the session. - */ -int srslte_pdsch_set_rnti(srslte_pdsch_t *q, uint16_t rnti) { - uint32_t i, j; - if (!q->users[rnti]) { - q->users[rnti] = calloc(1, sizeof(srslte_pdsch_user_t)); - if (q->users[rnti]) { - for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - for (j = 0; j < SRSLTE_MAX_CODEWORDS; j++) { - if (srslte_sequence_pdsch(&q->users[rnti]->seq[j][i], rnti, j, 2 * i, q->cell.id, - q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { - ERROR("Generating scrambling sequence"); - return SRSLTE_ERROR; - } - } - } - q->users[rnti]->sequence_generated = true; - } - } - return SRSLTE_SUCCESS; -} - static int srslte_pdsch_codeword_encode(srslte_pdsch_t *pdsch, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, uint16_t rnti, uint8_t *data, uint32_t codeword_idx) { @@ -529,45 +567,14 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *pdsch, srslte_pdsch_cfg_ return SRSLTE_SUCCESS; } -void srslte_pdsch_free_rnti(srslte_pdsch_t* q, uint16_t rnti) -{ - if (q->users[rnti]) { - for (int i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - for (int j = 0; j < SRSLTE_MAX_CODEWORDS; j++) { - srslte_sequence_free(&q->users[rnti]->seq[j][i]); - } - } - free(q->users[rnti]); - q->users[rnti] = NULL; - } -} - -int srslte_pdsch_decode(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, - cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, - uint16_t rnti, uint8_t *data) { - cf_t *_sf_symbols[SRSLTE_MAX_PORTS]; - cf_t *_ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; - bool acks[SRSLTE_MAX_CODEWORDS]; - srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_TB] = {NULL}; - - _sf_symbols[0] = sf_symbols; - for (int i = 0; i < q->cell.nof_ports; i++) { - _ce[i][0] = ce[i]; - } - - softbuffers[0] = softbuffer; - - return srslte_pdsch_decode_multi(q, cfg, softbuffers, _sf_symbols, _ce, noise_estimate, rnti, &data, acks); -} - /** Decodes the PDSCH from the received symbols */ -int srslte_pdsch_decode_multi(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS], - cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], - float noise_estimate, uint16_t rnti, uint8_t *data[SRSLTE_MAX_CODEWORDS], - bool acks[SRSLTE_MAX_CODEWORDS]) { +int srslte_pdsch_decode(srslte_pdsch_t *q, + srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS], + cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], + float noise_estimate, uint16_t rnti, uint8_t *data[SRSLTE_MAX_CODEWORDS], + bool acks[SRSLTE_MAX_CODEWORDS]) +{ /* Set pointers for layermapping & precoding */ uint32_t i; @@ -579,18 +586,17 @@ int srslte_pdsch_decode_multi(srslte_pdsch_t *q, cfg != NULL) { - INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, NofSymbols: %d, C_prb=%d\n", - cfg->sf_idx, rnti, cfg->nbits[0].nof_re, cfg->grant.nof_prb); + INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, NofSymbols: %d, C_prb=%d, mimo_type=%d, nof_layers=%d, nof_tb=%d\n", + cfg->sf_idx, rnti, cfg->nbits[0].nof_re, cfg->grant.nof_prb, cfg->nof_layers, cfg->grant.nof_tb); + // Extract Symbols and Channel Estimates for (int j=0;jnof_rx_antennas;j++) { - /* extract symbols */ int n = srslte_pdsch_get(q, sf_symbols[j], q->symbols[j], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx); if (n != cfg->nbits[0].nof_re) { fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits[0].nof_re, n); return SRSLTE_ERROR; } - /* extract channel estimates */ for (i = 0; i < q->cell.nof_ports; i++) { n = srslte_pdsch_get(q, ce[i][j], q->ce[i][j], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx); if (n != cfg->nbits[0].nof_re) { @@ -600,8 +606,7 @@ int srslte_pdsch_decode_multi(srslte_pdsch_t *q, } } - INFO("PDSCH Layer demapper and predecode: mimo_type=%d, nof_layers=%d, nof_tb=%d\n", cfg->mimo_type, - cfg->nof_layers, cfg->grant.nof_tb); + // Prepare layers int nof_symbols [SRSLTE_MAX_CODEWORDS]; nof_symbols[0] = cfg->nbits[0].nof_re * cfg->grant.nof_tb / cfg->nof_layers; nof_symbols[1] = cfg->nbits[1].nof_re * cfg->grant.nof_tb / cfg->nof_layers; @@ -612,53 +617,30 @@ int srslte_pdsch_decode_multi(srslte_pdsch_t *q, x[i] = q->d[i]; } } else { - /* number of layers equals number of ports */ - for (i = 0; i < cfg->nof_layers; i++) { - x[i] = q->x[i]; - } - memset(&x[cfg->nof_layers], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - cfg->nof_layers)); + /* number of layers equals number of ports */ + for (i = 0; i < cfg->nof_layers; i++) { + x[i] = q->x[i]; + } + memset(&x[cfg->nof_layers], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - cfg->nof_layers)); } - srslte_predecoding_type_multi(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, cfg->nof_layers, + // Pre-decoder + srslte_predecoding_type_multi(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, cfg->nof_layers, cfg->codebook_idx, cfg->nbits[0].nof_re, cfg->mimo_type, noise_estimate); + // Layer demapping only if necessary if (cfg->nof_layers != cfg->grant.nof_tb) { srslte_layerdemap_type(x, q->d, cfg->nof_layers, cfg->grant.nof_tb, nof_symbols[0], nof_symbols, cfg->mimo_type); } - if (SRSLTE_VERBOSE_ISDEBUG()) { - char filename[FILENAME_MAX]; - for (int j = 0; j < q->nof_rx_antennas; j++) { - if (snprintf(filename, FILENAME_MAX, "subframe_p%d.dat", j) < 0) { - ERROR("Generating file name"); - break; - } - DEBUG("SAVED FILE %s: received subframe symbols\n", filename); - srslte_vec_save_file(filename, sf_symbols, SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); - - for (i = 0; i < q->cell.nof_ports; i++) { - if (snprintf(filename, FILENAME_MAX, "hest_%d%d.dat", i, j) < 0) { - ERROR("Generating file name"); - break; - } - DEBUG("SAVED FILE %s: channel estimates for Tx %d and Rx %d\n", filename, j, i); - srslte_vec_save_file(filename, ce[i][j], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); - } - } - DEBUG("SAVED FILE pdsch_symbols.dat: symbols after equalization\n",0); - srslte_vec_save_file("pdsch_symbols.dat", q->d, cfg->nbits[0].nof_re*sizeof(cf_t)); - } - + // Codeword decoding for (uint32_t tb = 0; tb < cfg->grant.nof_tb; tb ++) { int ret = srslte_pdsch_codeword_decode(q, cfg, softbuffers[tb], rnti, data[tb], tb); acks[tb] = (ret == SRSLTE_SUCCESS); } - if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE llr.dat: LLR estimates after demodulation and descrambling\n",0); - srslte_vec_save_file("llr.dat", q->e, cfg->nbits[0].nof_bits*sizeof(int16_t)); - } + pdsch_decode_debug(q, cfg, sf_symbols, ce); return SRSLTE_SUCCESS; @@ -696,88 +678,10 @@ int srslte_pdsch_cn_compute(srslte_pdsch_t *q, } int srslte_pdsch_encode(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, - uint8_t *data, uint16_t rnti, cf_t *sf_symbols[SRSLTE_MAX_PORTS]) + srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffers[SRSLTE_MAX_CODEWORDS], + uint8_t *data[SRSLTE_MAX_CODEWORDS], uint16_t rnti, cf_t *sf_symbols[SRSLTE_MAX_PORTS]) { - int i; - /* Set pointers for layermapping & precoding */ - cf_t *x[SRSLTE_MAX_LAYERS]; - int ret = SRSLTE_ERROR_INVALID_INPUTS; - - if (q != NULL && - cfg != NULL) - { - - for (i=0;icell.nof_ports;i++) { - if (sf_symbols[i] == NULL) { - return SRSLTE_ERROR_INVALID_INPUTS; - } - } - - if (cfg->grant.mcs[0].tbs == 0) { - return SRSLTE_ERROR_INVALID_INPUTS; - } - - if (cfg->nbits[0].nof_re > q->max_re) { - fprintf(stderr, - "Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n", - cfg->nbits[0].nof_re, q->max_re, q->cell.nof_prb); - return SRSLTE_ERROR_INVALID_INPUTS; - } - - INFO("Encoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", - cfg->sf_idx, srslte_mod_string(cfg->grant.mcs[0].mod), cfg->grant.mcs[0].tbs, - cfg->nbits[0].nof_re, cfg->nbits[0].nof_bits, cfg->rv[0]); - - /* number of layers equals number of ports */ - for (i = 0; i < q->cell.nof_ports; i++) { - x[i] = q->x[i]; - } - memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports)); - - if (srslte_dlsch_encode(&q->dl_sch, cfg, softbuffer, data, q->e[0])) { - fprintf(stderr, "Error encoding TB\n"); - return SRSLTE_ERROR; - } - - /* scramble */ - if (q->users[rnti] && q->users[rnti]->sequence_generated) { - srslte_scrambling_bytes(&q->users[rnti]->seq[0][cfg->sf_idx], (uint8_t*) q->e[0], cfg->nbits[0].nof_bits); - } else { - srslte_sequence_t seq; - if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits[0].nof_bits)) { - return SRSLTE_ERROR; - } - srslte_scrambling_bytes(&seq, (uint8_t*) q->e[0], cfg->nbits[0].nof_bits); - srslte_sequence_free(&seq); - } - - srslte_mod_modulate_bytes(&q->mod[cfg->grant.mcs[0].mod], (uint8_t*) q->e[0], q->d[0], cfg->nbits[0].nof_bits); - - /* TODO: only diversity supported */ - if (q->cell.nof_ports > 1) { - srslte_layermap_diversity(q->d[0], x, q->cell.nof_ports, cfg->nbits[0].nof_re); - srslte_precoding_diversity(x, q->symbols, q->cell.nof_ports, - cfg->nbits[0].nof_re / q->cell.nof_ports); - } else { - memcpy(q->symbols[0], q->d, cfg->nbits[0].nof_re * sizeof(cf_t)); - } - - /* mapping to resource elements */ - for (i = 0; i < q->cell.nof_ports; i++) { - srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx); - } - - ret = SRSLTE_SUCCESS; - } - return ret; -} - -int srslte_pdsch_encode_multi(srslte_pdsch_t *q, - srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffers[SRSLTE_MAX_CODEWORDS], - uint8_t *data[SRSLTE_MAX_CODEWORDS], uint16_t rnti, cf_t *sf_symbols[SRSLTE_MAX_PORTS]) { - int i; /* Set pointers for layermapping & precoding */ cf_t *x[SRSLTE_MAX_LAYERS]; @@ -808,6 +712,7 @@ int srslte_pdsch_encode_multi(srslte_pdsch_t *q, ret |= srslte_pdsch_codeword_encode(q, cfg, softbuffers[tb], rnti, data[tb], tb); } + // Layer mapping & precode if necessary if (q->cell.nof_ports > 1) { int nof_symbols; /* If number of layers is equal to transport blocks (codewords) skip layer mapping */ @@ -836,7 +741,6 @@ int srslte_pdsch_encode_multi(srslte_pdsch_t *q, } /* mapping to resource elements */ - for (i = 0; i < q->cell.nof_ports; i++) { srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx); } diff --git a/lib/src/phy/phch/test/pdsch_test.c b/lib/src/phy/phch/test/pdsch_test.c index ea40ce824..b98d75c22 100644 --- a/lib/src/phy/phch/test/pdsch_test.c +++ b/lib/src/phy/phch/test/pdsch_test.c @@ -232,7 +232,7 @@ int main(int argc, char **argv) { #endif /* DO_OFDM */ /* Configure PDSCH */ - if (srslte_pdsch_cfg_multi(&pdsch_cfg, cell, &grant, cfi, subframe, rv_idx, mimo_type, pmi)) { + if (srslte_pdsch_cfg_mimo(&pdsch_cfg, cell, &grant, cfi, subframe, rv_idx, mimo_type, pmi)) { fprintf(stderr, "Error configuring PDSCH\n"); goto quit; } @@ -276,7 +276,7 @@ int main(int argc, char **argv) { } } - if (srslte_pdsch_init_rx_multi(&pdsch_rx, cell, nof_rx_antennas)) { + if (srslte_pdsch_init_rx(&pdsch_rx, cell, nof_rx_antennas)) { fprintf(stderr, "Error creating PDSCH object\n"); goto quit; } @@ -345,7 +345,7 @@ int main(int argc, char **argv) { srslte_filesource_free(&fsrc); } else { - if (srslte_pdsch_init_tx_multi(&pdsch_tx, cell)) { + if (srslte_pdsch_init_tx(&pdsch_tx, cell)) { fprintf(stderr, "Error creating PDSCH object\n"); goto quit; } @@ -385,7 +385,7 @@ int main(int argc, char **argv) { if (rv_idx[0] != 0 || rv_idx[1] != 0) { /* Do 1st transmission for rv_idx!=0 */ bzero(pdsch_cfg.rv, sizeof(uint32_t)*SRSLTE_MAX_CODEWORDS); - if (srslte_pdsch_encode_multi(&pdsch_tx, &pdsch_cfg, softbuffers_tx, data_tx, rnti, tx_slot_symbols)) { + if (srslte_pdsch_encode(&pdsch_tx, &pdsch_cfg, softbuffers_tx, data_tx, rnti, tx_slot_symbols)) { fprintf(stderr, "Error encoding PDSCH\n"); goto quit; } @@ -393,7 +393,7 @@ int main(int argc, char **argv) { memcpy(pdsch_cfg.rv, rv_idx, sizeof(uint32_t)*SRSLTE_MAX_CODEWORDS); gettimeofday(&t[1], NULL); for (k = 0; k < M; k++) { - if (srslte_pdsch_encode_multi(&pdsch_tx, &pdsch_cfg, softbuffers_tx, data_tx, rnti, tx_slot_symbols)) { + if (srslte_pdsch_encode(&pdsch_tx, &pdsch_cfg, softbuffers_tx, data_tx, rnti, tx_slot_symbols)) { ERROR("Error encoding PDSCH"); goto quit; } @@ -449,7 +449,7 @@ int main(int argc, char **argv) { srslte_softbuffer_rx_reset_tbs(softbuffers_rx[i], (uint32_t) grant.mcs[i].tbs); } } - r = srslte_pdsch_decode_multi(&pdsch_rx, &pdsch_cfg, softbuffers_rx, rx_slot_symbols, ce, 0, rnti, data_rx, acks); + r = srslte_pdsch_decode(&pdsch_rx, &pdsch_cfg, softbuffers_rx, rx_slot_symbols, ce, 0, rnti, data_rx, acks); } gettimeofday(&t[2], NULL); get_time_interval(t); diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 55f65ad3d..dfe9a18a7 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -97,7 +97,7 @@ int srslte_ue_dl_init_multi(srslte_ue_dl_t *q, goto clean_exit; } - if (srslte_pdsch_init_rx_multi(&q->pdsch, q->cell, nof_rx_antennas)) { + if (srslte_pdsch_init_rx(&q->pdsch, q->cell, nof_rx_antennas)) { fprintf(stderr, "Error creating PDSCH object\n"); goto clean_exit; } @@ -315,7 +315,7 @@ int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint3 } } } - return srslte_pdsch_cfg_multi(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx, mimo_type, pmi); + return srslte_pdsch_cfg_mimo(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx, mimo_type, pmi); } int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t tti, uint16_t rnti) { @@ -434,10 +434,10 @@ int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_POR if (q->pdsch_cfg.grant.mcs[0].mod > 0 && q->pdsch_cfg.grant.mcs[0].tbs >= 0) { - ret = srslte_pdsch_decode_multi(&q->pdsch, &q->pdsch_cfg, q->softbuffers, - q->sf_symbols_m, q->ce_m, - noise_estimate, - rnti, data, acks); + ret = srslte_pdsch_decode(&q->pdsch, &q->pdsch_cfg, q->softbuffers, + q->sf_symbols_m, q->ce_m, + noise_estimate, + rnti, data, acks); for (int tb = 0; tb < q->pdsch_cfg.grant.nof_tb; tb++) { if (!acks[tb]) { diff --git a/srsenb/src/phy/phch_worker.cc b/srsenb/src/phy/phch_worker.cc index 5c5537c61..d86bce9c9 100644 --- a/srsenb/src/phy/phch_worker.cc +++ b/srsenb/src/phy/phch_worker.cc @@ -647,8 +647,9 @@ int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants rnti, phy_grant.nof_prb, grant_str, grants[i].grant.harq_process, phy_grant.mcs[0].tbs/8, phy_grant.mcs[0].idx, grants[i].grant.rv_idx, tti_tx); } - if (srslte_enb_dl_put_pdsch(&enb_dl, &phy_grant, grants[i].softbuffer, rnti, grants[i].grant.rv_idx, sf_idx, - grants[i].data)) + srslte_softbuffer_tx_t *sb[SRSLTE_MAX_CODEWORDS] = {grants[i].softbuffer, NULL}; + uint8_t *d[SRSLTE_MAX_CODEWORDS] = {grants[i].data, NULL}; + if (srslte_enb_dl_put_pdsch(&enb_dl, &phy_grant, sb, rnti, grants[i].grant.rv_idx, sf_idx, d)) { fprintf(stderr, "Error putting PDSCH %d\n",i); return SRSLTE_ERROR; diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index a47008629..7b196f948 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -79,19 +79,12 @@ private: bool decode_phich(bool *ack); int decode_pdsch(srslte_ra_dl_grant_t *grant, - uint8_t *payload, srslte_softbuffer_rx_t *softbuffer, - int rv, - uint16_t rnti, - uint32_t pid, - bool acks[SRSLTE_MAX_CODEWORDS]); - - int decode_pdsch_multi(srslte_ra_dl_grant_t *grant, - uint8_t *payload[SRSLTE_MAX_CODEWORDS], - srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS], - int rv[SRSLTE_MAX_CODEWORDS], - uint16_t rnti, - uint32_t pid, - bool acks[SRSLTE_MAX_CODEWORDS]); + uint8_t *payload[SRSLTE_MAX_CODEWORDS], + srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS], + int rv[SRSLTE_MAX_CODEWORDS], + uint16_t rnti, + uint32_t pid, + bool acks[SRSLTE_MAX_CODEWORDS]); /* ... for UL */ void encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, uint32_t current_tx_nb, srslte_softbuffer_tx_t *softbuffer, diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 265d3e005..1959ba479 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -41,6 +41,7 @@ #include "srsgui/srsgui.h" #include #include +#include void init_plots(srsue::phch_worker *worker); pthread_t plot_thread; @@ -210,12 +211,14 @@ void phch_worker::work_imp() /* Decode PDSCH if instructed to do so */ if (dl_action.decode_enabled) { - decode_pdsch_multi(&dl_action.phy_grant.dl, dl_action.payload_ptr, - dl_action.softbuffers, dl_action.rv, dl_action.rnti, - dl_mac_grant.pid, dl_ack); + decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr, + dl_action.softbuffers, dl_action.rv, dl_action.rnti, + dl_mac_grant.pid, dl_ack); } if (dl_action.generate_ack_callback && dl_action.decode_enabled) { - for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { + + // NOTE: Currently hard-coded to 1st TB only + for (uint32_t tb = 0; tb < 1; tb++) { phy->mac->tb_decoded(dl_ack[tb], tb, dl_mac_grant.rnti_type, dl_mac_grant.pid); dl_ack[tb] = dl_action.generate_ack_callback(dl_action.generate_ack_callback_arg); Debug("Calling generate ACK callback for TB %d returned=%d\n", tb, dl_ack); @@ -418,19 +421,7 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) } } -int phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, - srslte_softbuffer_rx_t *softbuffer, int rv, - uint16_t rnti, uint32_t harq_pid, bool acks[SRSLTE_MAX_CODEWORDS]) { - int _rv [SRSLTE_MAX_TB] = {1}; - srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_TB] = {NULL}; - - _rv[0] = rv; - softbuffers[0] = softbuffer; - - return decode_pdsch_multi(grant, &payload, softbuffers, _rv, rnti, harq_pid, acks); -} - -int phch_worker::decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSLTE_MAX_CODEWORDS], +int phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSLTE_MAX_CODEWORDS], srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS], int rv[SRSLTE_MAX_CODEWORDS], uint16_t rnti, uint32_t harq_pid, bool acks[SRSLTE_MAX_CODEWORDS]) { @@ -518,8 +509,8 @@ int phch_worker::decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *payloa struct timeval t[3]; gettimeofday(&t[1], NULL); #endif - ret = srslte_pdsch_decode_multi(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffers, ue_dl.sf_symbols_m, - ue_dl.ce_m, noise_estimate, rnti, payload, acks); + ret = srslte_pdsch_decode(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffers, ue_dl.sf_symbols_m, + ue_dl.ce_m, noise_estimate, rnti, payload, acks); if (ret) { Error("Decoding PDSCH"); }