diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index 1ec9dc84b..1bc2d5230 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -86,7 +86,8 @@ srslte_pdsch_t pdsch; srslte_pdsch_cfg_t pdsch_cfg; srslte_softbuffer_tx_t softbuffers[SRSLTE_MAX_CODEWORDS]; srslte_regs_t regs; -srslte_ra_dl_dci_t ra_dl; +srslte_ra_dl_dci_t ra_dl; +int rvidx[SRSLTE_MAX_CODEWORDS] = {0, 0}; cf_t *sf_buffer[SRSLTE_MAX_PORTS] = {NULL}, *output_buffer [SRSLTE_MAX_PORTS] = {NULL}; int sf_n_re, sf_n_samples; @@ -423,7 +424,7 @@ int update_radl() { ra_dl.harq_process = 0; ra_dl.mcs_idx = mcs_idx; ra_dl.ndi = 0; - ra_dl.rv_idx = 0; + ra_dl.rv_idx = rvidx[0]; ra_dl.alloc_type = SRSLTE_RA_ALLOC_TYPE0; ra_dl.type0_alloc.rbg_bitmask = prbset_to_bitmask(); ra_dl.tb_en[0] = 1; @@ -431,7 +432,7 @@ int update_radl() { if (nof_tb > 1) { ra_dl.mcs_idx_1 = mcs_idx; ra_dl.ndi_1 = 0; - ra_dl.rv_idx_1 = 0; + ra_dl.rv_idx_1 = rvidx[1]; ra_dl.tb_en[1] = 1; } @@ -513,7 +514,7 @@ void *net_thread_fnc(void *arg) { n = srslte_netsource_read(&net_source, &data2[rpm], DATA_BUFF_SZ-rpm); if (n > 0) { // FIXME: I assume that both transport blocks have same size in case of 2 tb are active - int nbytes = 1 + (pdsch_cfg.grant.mcs.tbs + pdsch_cfg.grant.mcs2.tbs - 1) / 8; + int nbytes = 1 + (pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs - 1) / 8; rpm += n; INFO("received %d bytes. rpm=%d/%d\n",n,rpm,nbytes); wpm = 0; @@ -696,12 +697,11 @@ int main(int argc, char **argv) { INFO("Transmitting packet\n",0); } } else { - INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs.tbs); - for (i = 0; i < pdsch_cfg.grant.mcs.tbs / 8; i++) { - data[0][i] = rand() % 256; - } - for (i = 0; i < pdsch_cfg.grant.mcs2.tbs / 8; i++) { - data[1][i] = rand() % 256; + INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs); + for (uint32_t tb = 0; tb < pdsch_cfg.grant.nof_tb; tb++) { + for (i = 0; i < pdsch_cfg.grant.mcs[tb].tbs / 8; i++) { + data[tb][i] = (uint8_t) rand(); + } } /* Uncomment this to transmit on sf 0 and 5 only */ if (sf_idx != 0 && sf_idx != 5) { @@ -744,7 +744,7 @@ 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, 0, 0, pdsch_cfg.mimo_type, multiplex_pmi)) { + if (srslte_pdsch_cfg_multi(&pdsch_cfg, cell, &grant, cfi, sf_idx, rvidx, pdsch_cfg.mimo_type, multiplex_pmi)) { fprintf(stderr, "Error configuring PDSCH\n"); exit(-1); } @@ -757,13 +757,9 @@ int main(int argc, char **argv) { } if (net_port > 0 && net_packet_ready) { if (null_file_sink) { - srslte_bit_pack_vector(data[0], data_tmp, pdsch_cfg.grant.mcs.tbs); - if (srslte_netsink_write(&net_sink, data_tmp, 1+(pdsch_cfg.grant.mcs.tbs-1)/8) < 0) { - fprintf(stderr, "Error sending data through UDP socket\n"); - } - if (nof_tb > 1) { - srslte_bit_pack_vector(data[1], data_tmp, pdsch_cfg.grant.mcs2.tbs); - if (srslte_netsink_write(&net_sink, data_tmp, 1 + (pdsch_cfg.grant.mcs2.tbs - 1) / 8) < 0) { + for (uint32_t tb = 0; tb < pdsch_cfg.grant.nof_tb; tb++) { + srslte_bit_pack_vector(data[tb], data_tmp, pdsch_cfg.grant.mcs[tb].tbs); + if (srslte_netsink_write(&net_sink, data_tmp, 1 + (pdsch_cfg.grant.mcs[tb].tbs - 1) / 8) < 0) { fprintf(stderr, "Error sending data through UDP socket\n"); } } diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 931a983fa..60cc0a4db 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -594,8 +594,10 @@ int main(int argc, char **argv) { /* Send data if socket active */ if (prog_args.net_port > 0) { // FIXME: UDP Data transmission does not work - srslte_netsink_write(&net_sink, data[0], 1 + (ue_dl.pdsch_cfg.grant.mcs.tbs - 1) / 8); - srslte_netsink_write(&net_sink, data[1], 1 + (ue_dl.pdsch_cfg.grant.mcs2.tbs - 1) / 8); + for (uint32_t tb = 0; tb < ue_dl.pdsch_cfg.grant.nof_tb; tb++) { + srslte_netsink_write(&net_sink, data[tb], 1 + (ue_dl.pdsch_cfg.grant.mcs[tb].tbs - 1) / 8); + + } } #ifdef PRINT_CHANGE_SCHEDULIGN @@ -616,12 +618,12 @@ int main(int argc, char **argv) { nof_trials++; - rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&ue_dl.chest), rsrq, 0.1); - rsrp0 = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp_port(&ue_dl.chest, 0), rsrp0, 0.05); - rsrp1 = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp_port(&ue_dl.chest, 1), rsrp1, 0.05); - noise = SRSLTE_VEC_EMA(srslte_chest_dl_get_noise_estimate(&ue_dl.chest), noise, 0.05); - enodebrate = SRSLTE_VEC_EMA((ue_dl.pdsch_cfg.grant.mcs.tbs + ue_dl.pdsch_cfg.grant.mcs2.tbs)/1000.0, enodebrate, 0.05); - uerate = SRSLTE_VEC_EMA((n>0)?(ue_dl.pdsch_cfg.grant.mcs.tbs + ue_dl.pdsch_cfg.grant.mcs2.tbs)/1000.0:0.0, uerate, 0.01); + rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&ue_dl.chest), rsrq, 0.1f); + rsrp0 = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp_port(&ue_dl.chest, 0), rsrp0, 0.05f); + rsrp1 = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp_port(&ue_dl.chest, 1), rsrp1, 0.05f); + noise = SRSLTE_VEC_EMA(srslte_chest_dl_get_noise_estimate(&ue_dl.chest), noise, 0.05f); + enodebrate = SRSLTE_VEC_EMA((ue_dl.pdsch_cfg.grant.mcs[0].tbs + ue_dl.pdsch_cfg.grant.mcs[1].tbs)/1000.0f, enodebrate, 0.05f); + uerate = SRSLTE_VEC_EMA((n>0)?(ue_dl.pdsch_cfg.grant.mcs[0].tbs + ue_dl.pdsch_cfg.grant.mcs[1].tbs)/1000.0f:0.0f, uerate, 0.01f); nframes++; if (isnan(rsrq)) { @@ -812,7 +814,7 @@ void *plot_thread_run(void *arg) { while(1) { sem_wait(&plot_sem); - uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits.nof_re; + uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits[0].nof_re; if (!prog_args.disable_plots_except_constellation) { for (i = 0; i < nof_re; i++) { tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i])); diff --git a/lib/include/srslte/phy/phch/pdsch.h b/lib/include/srslte/phy/phch/pdsch.h index 9a9b16788..99710b965 100644 --- a/lib/include/srslte/phy/phch/pdsch.h +++ b/lib/include/srslte/phy/phch/pdsch.h @@ -104,15 +104,14 @@ SRSLTE_API int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, - uint32_t rvidx); + 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, - uint32_t rvidx, - uint32_t rvidx2, + int rvidx[SRSLTE_MAX_CODEWORDS], srslte_mimo_type_t mimo_type, uint32_t pmi); @@ -156,7 +155,7 @@ SRSLTE_API int srslte_pdsch_pmi_select(srslte_pdsch_t *q, uint32_t pmi[SRSLTE_MAX_LAYERS], float sinr[SRSLTE_MAX_LAYERS][SRSLTE_MAX_CODEBOOKS]); -SRSLTE_API void srslte_pdsch_set_max_noi(srslte_pdsch_t *q, int max_iter); +SRSLTE_API void srslte_pdsch_set_max_noi(srslte_pdsch_t *q, uint32_t max_iter); SRSLTE_API float srslte_pdsch_average_noi(srslte_pdsch_t *q); diff --git a/lib/include/srslte/phy/phch/pdsch_cfg.h b/lib/include/srslte/phy/phch/pdsch_cfg.h index 9664d826d..eb4927fbb 100644 --- a/lib/include/srslte/phy/phch/pdsch_cfg.h +++ b/lib/include/srslte/phy/phch/pdsch_cfg.h @@ -40,14 +40,11 @@ #include "srslte/phy/fec/cbsegm.h" typedef struct SRSLTE_API { - srslte_cbsegm_t cb_segm; - srslte_cbsegm_t cb_segm2; - srslte_ra_dl_grant_t grant; - srslte_ra_nbits_t nbits; - srslte_ra_nbits_t nbits2; - uint32_t rv; - uint32_t rv2; - uint32_t sf_idx; + srslte_cbsegm_t cb_segm[SRSLTE_MAX_CODEWORDS]; + srslte_ra_dl_grant_t grant; + srslte_ra_nbits_t nbits[SRSLTE_MAX_CODEWORDS]; + uint32_t rv[SRSLTE_MAX_CODEWORDS]; + uint32_t sf_idx; uint32_t nof_layers; uint32_t codebook_idx; srslte_mimo_type_t mimo_type; diff --git a/lib/include/srslte/phy/phch/ra.h b/lib/include/srslte/phy/phch/ra.h index 8a025ad97..c99dba1a1 100644 --- a/lib/include/srslte/phy/phch/ra.h +++ b/lib/include/srslte/phy/phch/ra.h @@ -102,10 +102,8 @@ typedef struct SRSLTE_API { typedef struct SRSLTE_API { bool prb_idx[2][SRSLTE_MAX_PRB]; uint32_t nof_prb; - uint32_t Qm; - uint32_t Qm2; - srslte_ra_mcs_t mcs; - srslte_ra_mcs_t mcs2; + uint32_t Qm[SRSLTE_MAX_CODEWORDS]; + srslte_ra_mcs_t mcs[SRSLTE_MAX_CODEWORDS]; uint32_t nof_tb; } srslte_ra_dl_grant_t; @@ -206,8 +204,8 @@ SRSLTE_API int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci, SRSLTE_API void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant, uint32_t cfi, srslte_cell_t cell, - uint32_t sf_idx, - srslte_ra_nbits_t *nbits); + uint32_t sf_idx, + srslte_ra_nbits_t nbits[SRSLTE_MAX_CODEWORDS]); SRSLTE_API void srslte_ra_dl_grant_to_nbits_multi(srslte_ra_dl_grant_t *grant, uint32_t cfi, diff --git a/lib/include/srslte/phy/phch/sch.h b/lib/include/srslte/phy/phch/sch.h index 4fa1b3b0f..a03387448 100644 --- a/lib/include/srslte/phy/phch/sch.h +++ b/lib/include/srslte/phy/phch/sch.h @@ -103,12 +103,6 @@ SRSLTE_API int srslte_dlsch_encode2(srslte_sch_t *q, uint8_t *e_bits, int codeword_idx); -SRSLTE_API int srslte_dlsch_encode_multi(srslte_sch_t *q, - srslte_pdsch_cfg_t *cfg, - srslte_softbuffer_tx_t softbuffers[SRSLTE_MAX_CODEWORDS], - uint8_t *data[SRSLTE_MAX_CODEWORDS], - uint8_t *e_bits[SRSLTE_MAX_CODEWORDS]); - SRSLTE_API int srslte_dlsch_decode(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, diff --git a/lib/include/srslte/phy/ue/ue_dl.h b/lib/include/srslte/phy/ue/ue_dl.h index 0fc8f9422..268a8c4d9 100644 --- a/lib/include/srslte/phy/ue/ue_dl.h +++ b/lib/include/srslte/phy/ue/ue_dl.h @@ -145,14 +145,13 @@ SRSLTE_API int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, - uint32_t rvidx); + int rvidx); SRSLTE_API int srslte_ue_dl_cfg_grant_multi(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, - uint32_t rvidx, - uint32_t rvidx2, + int rvidx[SRSLTE_MAX_CODEWORDS], srslte_mimo_type_t mimo_type, uint32_t pinfo); diff --git a/lib/include/srslte/phy/utils/debug.h b/lib/include/srslte/phy/utils/debug.h index e4b4756f8..c88e1a3ce 100644 --- a/lib/include/srslte/phy/utils/debug.h +++ b/lib/include/srslte/phy/utils/debug.h @@ -58,10 +58,10 @@ SRSLTE_API extern int srslte_verbose; #define PRINT_NONE srslte_verbose=SRSLTE_VERBOSE_NONE #define DEBUG(_fmt, ...) if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG) \ - fprintf(stdout, "[DEBUG]: " _fmt, __VA_ARGS__) + fprintf(stdout, "[DEBUG]: " _fmt, ##__VA_ARGS__) #define INFO(_fmt, ...) if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO) \ - fprintf(stdout, "[INFO]: " _fmt, __VA_ARGS__) + fprintf(stdout, "[INFO]: " _fmt, ##__VA_ARGS__) #if CMAKE_BUILD_TYPE==Debug /* In debug mode, it prints out the */ diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index 31642751f..35e10fedb 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -358,50 +358,35 @@ void srslte_pdsch_free(srslte_pdsch_t *q) { /* 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(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, uint32_t rvidx) -{ - if (cfg) { - if (grant) { - memcpy(&cfg->grant, grant, sizeof(srslte_ra_dl_grant_t)); - } - if (srslte_cbsegm(&cfg->cb_segm, cfg->grant.mcs.tbs)) { - fprintf(stderr, "Error computing Codeblock segmentation for TBS=%d\n", cfg->grant.mcs.tbs); - return SRSLTE_ERROR; - } - srslte_ra_dl_grant_to_nbits(&cfg->grant, cfi, cell, sf_idx, &cfg->nbits); - cfg->sf_idx = sf_idx; - cfg->rv = rvidx; +int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_grant_t *grant, uint32_t cfi, + uint32_t sf_idx, int rvidx) { + int _rvids[SRSLTE_MAX_CODEWORDS] = {1}; + _rvids[0] = rvidx; - return SRSLTE_SUCCESS; - } else { - return SRSLTE_ERROR_INVALID_INPUTS; - } + return srslte_pdsch_cfg_multi(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, - uint32_t sf_idx, uint32_t rvidx, uint32_t rvidx2, srslte_mimo_type_t mimo_type, uint32_t pmi) -{ + uint32_t sf_idx, int rvidx[SRSLTE_MAX_CODEWORDS], srslte_mimo_type_t mimo_type, + uint32_t pmi) { if (cfg) { if (grant) { memcpy(&cfg->grant, grant, sizeof(srslte_ra_dl_grant_t)); } - if (srslte_cbsegm(&cfg->cb_segm, (uint32_t) cfg->grant.mcs.tbs)) { - fprintf(stderr, "Error computing Codeblock (1) segmentation for TBS=%d\n", cfg->grant.mcs.tbs); - return SRSLTE_ERROR; - } - if (srslte_cbsegm(&cfg->cb_segm2, (uint32_t) cfg->grant.mcs2.tbs)) { - fprintf(stderr, "Error computing Codeblock (2) segmentation for TBS=%d\n", cfg->grant.mcs2.tbs); - return SRSLTE_ERROR; + for (int i = 0; i < grant->nof_tb; i++) { + if (srslte_cbsegm(&cfg->cb_segm[i], (uint32_t) cfg->grant.mcs[i].tbs)) { + fprintf(stderr, "Error computing Codeblock (1) segmentation for TBS=%d\n", cfg->grant.mcs[i].tbs); + return SRSLTE_ERROR; + } } + srslte_ra_dl_grant_to_nbits(&cfg->grant, cfi, cell, sf_idx, cfg->nbits); - srslte_ra_dl_grant_to_nbits_multi(&cfg->grant, cfi, cell, sf_idx, &cfg->nbits, &cfg->nbits2); cfg->sf_idx = sf_idx; - cfg->rv = rvidx; - cfg->rv2 = rvidx2; + memcpy(cfg->rv, rvidx, sizeof(uint32_t) * SRSLTE_MAX_CODEWORDS); cfg->mimo_type = mimo_type; /* Check and configure PDSCH transmission modes */ @@ -428,11 +413,12 @@ int srslte_pdsch_cfg_multi(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_r cfg->codebook_idx = pmi + 1; cfg->nof_layers = 2; } - INFO("PDSCH configured for Spatial Multiplex; nof_codewords=%d; nof_layers=%d; codebook_idx=%d;\n", grant->nof_tb, cfg->nof_layers, cfg->codebook_idx); + INFO("PDSCH configured for Spatial Multiplex; nof_codewords=%d; nof_layers=%d; codebook_idx=%d;\n", + grant->nof_tb, cfg->nof_layers, cfg->codebook_idx); break; case SRSLTE_MIMO_TYPE_CDD: if (grant->nof_tb != 2) { - ERROR("Number of transport blocks is not supported for CDD transmission mode."); + ERROR("Number of transport blocks (%d) is not supported for CDD transmission mode.", grant->nof_tb); return SRSLTE_ERROR; } cfg->nof_layers = 2; @@ -472,13 +458,14 @@ static int srslte_pdsch_codeword_encode(srslte_pdsch_t *pdsch, srslte_pdsch_cfg_ srslte_softbuffer_tx_t *softbuffer, uint16_t rnti, uint8_t *data, uint32_t codeword_idx) { srslte_sch_t *dl_sch = &pdsch->dl_sch[codeword_idx]; - srslte_ra_nbits_t *nbits = (codeword_idx == 0) ? &cfg->nbits : &cfg->nbits2; - srslte_ra_mcs_t *mcs = (codeword_idx == 0) ? &cfg->grant.mcs : &cfg->grant.mcs2; + srslte_ra_nbits_t *nbits = &cfg->nbits[codeword_idx]; + srslte_ra_mcs_t *mcs = &cfg->grant.mcs[codeword_idx]; + uint32_t rv = cfg->rv[codeword_idx]; if (nbits->nof_bits) { INFO("Encoding PDSCH SF: %d (TB %d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", cfg->sf_idx, codeword_idx, srslte_mod_string(mcs->mod), mcs->tbs, - nbits->nof_re, nbits->nof_bits, (codeword_idx == 0) ? cfg->rv : cfg->rv2); + nbits->nof_re, nbits->nof_bits, rv); /* Channel coding */ if (srslte_dlsch_encode2(dl_sch, cfg, softbuffer, data, pdsch->e[codeword_idx], codeword_idx)) { @@ -516,19 +503,20 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *pdsch, srslte_pdsch_cfg_ srslte_softbuffer_rx_t *softbuffer, uint16_t rnti, uint8_t *data, uint32_t codeword_idx) { srslte_sch_t *dl_sch = &pdsch->dl_sch[codeword_idx]; - srslte_ra_nbits_t *nbits = (codeword_idx == 0) ? &cfg->nbits : &cfg->nbits2; - srslte_ra_mcs_t *mcs = (codeword_idx == 0) ? &cfg->grant.mcs : &cfg->grant.mcs2; + srslte_ra_nbits_t *nbits = &cfg->nbits[codeword_idx]; + srslte_ra_mcs_t *mcs = &cfg->grant.mcs[codeword_idx]; + uint32_t rv = cfg->rv[codeword_idx]; if (nbits->nof_bits) { INFO("Decoding PDSCH SF: %d (TB %d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", cfg->sf_idx, codeword_idx, srslte_mod_string(mcs->mod), mcs->tbs, - nbits->nof_re, nbits->nof_bits, (codeword_idx == 0) ? cfg->rv : cfg->rv2); + nbits->nof_re, nbits->nof_bits, rv); /* demodulate symbols * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation, * thus we don't need tot set it in the LLRs normalization */ - srslte_demod_soft_demodulate_s(mcs->mod, pdsch->d[codeword_idx], pdsch->e[codeword_idx], cfg->nbits.nof_re); + srslte_demod_soft_demodulate_s(mcs->mod, pdsch->d[codeword_idx], pdsch->e[codeword_idx], nbits->nof_re); if (pdsch->users[rnti] && pdsch->users[rnti]->sequence_generated) { srslte_scrambling_s_offset(&pdsch->users[rnti]->seq[codeword_idx][cfg->sf_idx], pdsch->e[codeword_idx], @@ -596,23 +584,22 @@ int srslte_pdsch_decode_multi(srslte_pdsch_t *q, cfg != NULL) { - INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: [%d %d], C_prb=%d\n", - cfg->sf_idx, rnti, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, cfg->nbits.nof_re, - cfg->nbits.nof_bits, cfg->rv, cfg->rv2, cfg->grant.nof_prb); + 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); 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.lstart, cfg->sf_idx); - if (n != cfg->nbits.nof_re) { - fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n); + 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.lstart, cfg->sf_idx); - if (n != cfg->nbits.nof_re) { - fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n); + 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) { + fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits[0].nof_re, n); return SRSLTE_ERROR; } } @@ -620,35 +607,31 @@ 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); - if (q->cell.nof_ports == 1) { - /* no need for layer demapping */ - srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d[0], q->nof_rx_antennas, cfg->nbits.nof_re, noise_estimate); - } else { - int nof_symbols [SRSLTE_MAX_CODEWORDS]; - nof_symbols[0] = cfg->nbits.nof_re * cfg->grant.nof_tb / cfg->nof_layers; - nof_symbols[1] = cfg->nbits2.nof_re * cfg->grant.nof_tb / cfg->nof_layers; - - if (cfg->nof_layers == cfg->grant.nof_tb) { - for (i = 0; i < cfg->nof_layers; i++) { - x[i] = q->d[i]; - } + 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; + + if (cfg->nof_layers == cfg->grant.nof_tb) { + /* Skip layer demap */ + for (i = 0; i < cfg->nof_layers; i++) { + x[i] = q->d[i]; + } - 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.nof_re, cfg->mimo_type, noise_estimate); + 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); - } 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)); + } 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)); - 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.nof_re, cfg->mimo_type, noise_estimate); + 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); - srslte_layerdemap_type(x, q->d, cfg->nof_layers, cfg->grant.nof_tb, - nof_symbols[0], nof_symbols, cfg->mimo_type); - } + 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()) { @@ -671,7 +654,7 @@ int srslte_pdsch_decode_multi(srslte_pdsch_t *q, } } DEBUG("SAVED FILE pdsch_symbols.dat: symbols after equalization\n",0); - srslte_vec_save_file("pdsch_symbols.dat", q->d, cfg->nbits.nof_re*sizeof(cf_t)); + srslte_vec_save_file("pdsch_symbols.dat", q->d, cfg->nbits[0].nof_re*sizeof(cf_t)); } for (uint32_t tb = 0; tb < cfg->grant.nof_tb; tb ++) { @@ -680,7 +663,7 @@ int srslte_pdsch_decode_multi(srslte_pdsch_t *q, 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.nof_bits*sizeof(int16_t)); + srslte_vec_save_file("llr.dat", q->e, cfg->nbits[0].nof_bits*sizeof(int16_t)); } return ret; @@ -733,20 +716,20 @@ int srslte_pdsch_encode(srslte_pdsch_t *q, } } - if (cfg->grant.mcs.tbs == 0) { + if (cfg->grant.mcs[0].tbs == 0) { return SRSLTE_ERROR_INVALID_INPUTS; } - if (cfg->nbits.nof_re > q->max_re) { + 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.nof_re, q->max_re, q->cell.nof_prb); + 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.mod), cfg->grant.mcs.tbs, - cfg->nbits.nof_re, cfg->nbits.nof_bits, cfg->rv); + 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++) { @@ -761,30 +744,30 @@ int srslte_pdsch_encode(srslte_pdsch_t *q, /* 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.nof_bits); + 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.nof_bits)) { + 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.nof_bits); + 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.mod], (uint8_t*) q->e[0], q->d[0], cfg->nbits.nof_bits); + 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.nof_re); + 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.nof_re / q->cell.nof_ports); + cfg->nbits[0].nof_re / q->cell.nof_ports); } else { - memcpy(q->symbols[0], q->d, cfg->nbits.nof_re * sizeof(cf_t)); + 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.lstart, cfg->sf_idx); + srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx); } ret = SRSLTE_SUCCESS; @@ -810,15 +793,15 @@ int srslte_pdsch_encode_multi(srslte_pdsch_t *q, } } - /* If both transport block sizes are zero return error */ - if (cfg->grant.mcs.tbs == 0 && cfg->grant.mcs2.tbs == 0) { + /* If both transport block size is zero return error */ + if (cfg->grant.mcs[0].tbs == 0) { return SRSLTE_ERROR_INVALID_INPUTS; } - if (cfg->nbits.nof_re > q->max_re) { + 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.nof_re, q->max_re, q->cell.nof_prb); + cfg->nbits[0].nof_re, q->max_re, q->cell.nof_prb); return SRSLTE_ERROR_INVALID_INPUTS; } @@ -833,7 +816,7 @@ int srslte_pdsch_encode_multi(srslte_pdsch_t *q, for (i = 0; i < cfg->nof_layers; i++) { x[i] = q->d[i]; } - nof_symbols = cfg->nbits.nof_re; + nof_symbols = cfg->nbits[0].nof_re; } else { /* Initialise layer map pointers */ for (i = 0; i < cfg->nof_layers; i++) { @@ -842,20 +825,21 @@ int srslte_pdsch_encode_multi(srslte_pdsch_t *q, memset(&x[cfg->nof_layers], 0, sizeof(cf_t *) * (SRSLTE_MAX_LAYERS - cfg->nof_layers)); nof_symbols = srslte_layermap_type(q->d, x, cfg->grant.nof_tb, cfg->nof_layers, - (int[SRSLTE_MAX_CODEWORDS]) {cfg->nbits.nof_re, cfg->nbits2.nof_re}, cfg->mimo_type); + (int[SRSLTE_MAX_CODEWORDS]) {cfg->nbits[0].nof_re, cfg->nbits[1].nof_re}, + cfg->mimo_type); } /* Precode */ srslte_precoding_type(x, q->symbols, cfg->nof_layers, q->cell.nof_ports, cfg->codebook_idx, nof_symbols, cfg->mimo_type); } else { - memcpy(q->symbols[0], q->d[0], cfg->nbits.nof_re * sizeof(cf_t)); + memcpy(q->symbols[0], q->d[0], 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.lstart, cfg->sf_idx); + srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx); } ret = SRSLTE_SUCCESS; @@ -863,7 +847,7 @@ int srslte_pdsch_encode_multi(srslte_pdsch_t *q, return ret; } -void srslte_pdsch_set_max_noi(srslte_pdsch_t *q, int max_iter) { +void srslte_pdsch_set_max_noi(srslte_pdsch_t *q, uint32_t max_iter) { for (int cw = 0; cw < SRSLTE_MAX_CODEWORDS; cw++) { srslte_sch_set_max_noi(&q->dl_sch[cw], max_iter); } diff --git a/lib/src/phy/phch/ra.c b/lib/src/phy/phch/ra.c index 635172762..a7fef1e42 100644 --- a/lib/src/phy/phch/ra.c +++ b/lib/src/phy/phch/ra.c @@ -492,44 +492,43 @@ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *gr fprintf(stderr, "Error decoding DCI: P/SI/RA-RNTI supports Format1A/1C only\n"); return SRSLTE_ERROR; } - grant->mcs.mod = SRSLTE_MOD_QPSK; - grant->mcs.tbs = (uint32_t) tbs; + grant->mcs[0].mod = SRSLTE_MOD_QPSK; + grant->mcs[0].tbs = (uint32_t) tbs; } else { n_prb = grant->nof_prb; if (dci->tb_en[0]) { - grant->mcs.idx = dci->mcs_idx; - tbs = dl_fill_ra_mcs(&grant->mcs, n_prb); + grant->mcs[0].idx = dci->mcs_idx; + tbs = dl_fill_ra_mcs(&grant->mcs[0], n_prb); if (tbs) { last_dl_tbs[dci->harq_process%8] = tbs; } else { // For mcs>=29, set last TBS received for this PID - grant->mcs.tbs = last_dl_tbs[dci->harq_process%8]; + grant->mcs[0].tbs = last_dl_tbs[dci->harq_process%8]; } } else { - grant->mcs.tbs = 0; + grant->mcs[0].tbs = 0; } if (dci->tb_en[1]) { - grant->mcs2.idx = dci->mcs_idx_1; - tbs = dl_fill_ra_mcs(&grant->mcs2, n_prb); + grant->mcs[1].idx = dci->mcs_idx_1; + tbs = dl_fill_ra_mcs(&grant->mcs[1], n_prb); if (tbs) { last_dl_tbs2[dci->harq_process%8] = tbs; } else { // For mcs>=29, set last TBS received for this PID - grant->mcs2.tbs = last_dl_tbs2[dci->harq_process%8]; + grant->mcs[1].tbs = last_dl_tbs2[dci->harq_process%8]; } } else { - grant->mcs2.tbs = 0; + grant->mcs[1].tbs = 0; } } grant->nof_tb = 0; - if (dci->tb_en[0]) { - grant->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod); - grant->nof_tb++; - } - if (dci->tb_en[1]) { - grant->Qm2 = srslte_mod_bits_x_symbol(grant->mcs2.mod); - grant->nof_tb++; + for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { + if (dci->tb_en[tb]) { + grant->Qm[tb] = srslte_mod_bits_x_symbol(grant->mcs[tb].mod); + grant->nof_tb++; + } } + if (tbs < 0) { return SRSLTE_ERROR; } else { @@ -537,29 +536,16 @@ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *gr } } -void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant, uint32_t cfi, srslte_cell_t cell, uint32_t sf_idx, srslte_ra_nbits_t *nbits) +void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant, uint32_t cfi, srslte_cell_t cell, uint32_t sf_idx, + srslte_ra_nbits_t nbits [SRSLTE_MAX_CODEWORDS]) { // Compute number of RE - nbits->nof_re = srslte_ra_dl_grant_nof_re(grant, cell, sf_idx, cell.nof_prb<10?(cfi+1):cfi); - nbits->lstart = cell.nof_prb<10?(cfi+1):cfi; - nbits->nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-nbits->lstart; - nbits->nof_bits = nbits->nof_re * grant->Qm; -} - -void srslte_ra_dl_grant_to_nbits_multi(srslte_ra_dl_grant_t *grant, uint32_t cfi, srslte_cell_t cell, uint32_t sf_idx, - srslte_ra_nbits_t *nbits, srslte_ra_nbits_t *nbits2) { - /* Compute number of RE for first transport block */ - nbits->nof_re = srslte_ra_dl_grant_nof_re(grant, cell, sf_idx, cell.nof_prb<10?(cfi+1):cfi); - nbits->lstart = cell.nof_prb<10?(cfi+1):cfi; - nbits->nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-nbits->lstart; - nbits->nof_bits = nbits->nof_re * grant->Qm; - - /*/ Compute number of RE for second transport block */ - if (grant->nof_tb > 1) { - nbits2->nof_re = nbits->nof_re; - nbits2->lstart = nbits->lstart; - nbits2->nof_symb = 2 * SRSLTE_CP_NSYMB(cell.cp) - nbits2->lstart; - nbits2->nof_bits = nbits2->nof_re * grant->Qm2; + for (int i = 0; i < grant->nof_tb; i++) { + /* Compute number of RE for first transport block */ + nbits[i].nof_re = srslte_ra_dl_grant_nof_re(grant, cell, sf_idx, cell.nof_prb < 10 ? (cfi + 1) : cfi); + nbits[i].lstart = cell.nof_prb < 10 ? (cfi + 1) : cfi; + nbits[i].nof_symb = 2 * SRSLTE_CP_NSYMB(cell.cp) - nbits[0].lstart; + nbits[i].nof_bits = nbits[i].nof_re * grant->Qm[i]; } } @@ -834,10 +820,11 @@ void srslte_ra_dl_grant_fprint(FILE *f, srslte_ra_dl_grant_t *grant) { srslte_ra_prb_fprint(f, grant); fprintf(f, " - Number of PRBs:\t\t\t%d\n", grant->nof_prb); fprintf(f, " - Number of TBs:\t\t\t%d\n", grant->nof_tb); - fprintf(f, " - Modulation type:\t\t\t%s\n", srslte_mod_string(grant->mcs.mod)); - fprintf(f, " - Transport block size:\t\t%d\n", grant->mcs.tbs); - fprintf(f, " - Modulation type (TB2):\t\t%s\n", srslte_mod_string(grant->mcs2.mod)); - fprintf(f, " - Transport block size (TB2):\t\t%d\n", grant->mcs2.tbs); + for (int i = 0; i < grant->nof_tb; i++) { + fprintf(f, " - Transport block:\t\t\t%d\n", i); + fprintf(f, " -> Modulation type:\t\t\t%s\n", srslte_mod_string(grant->mcs[i].mod)); + fprintf(f, " -> Transport block size:\t\t%d\n", grant->mcs[i].tbs); + } } void srslte_ra_prb_fprint(FILE *f, srslte_ra_dl_grant_t *grant) { diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index 4b78f6228..e0002429e 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -514,39 +514,23 @@ static int decode_tb(srslte_sch_t *q, } } -int srslte_dlsch_decode(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, - int16_t *e_bits, uint8_t *data) -{ - return decode_tb(q, - softbuffer, &cfg->cb_segm, - cfg->grant.Qm, cfg->rv, cfg->nbits.nof_bits, - e_bits, data); +int srslte_dlsch_decode(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, + int16_t *e_bits, uint8_t *data) { + return srslte_dlsch_decode2(q, cfg, softbuffer, e_bits, data, 0); } int srslte_dlsch_decode2(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, - int16_t *e_bits, uint8_t *data, int codeword_idx) -{ + int16_t *e_bits, uint8_t *data, int codeword_idx) { uint32_t Nl = 1; - int ret = SRSLTE_ERROR; if (cfg->nof_layers != cfg->grant.nof_tb) { Nl = 2; } - if (codeword_idx == 0) { - ret = decode_tb(q, softbuffer, &cfg->cb_segm, - cfg->grant.Qm*Nl, cfg->rv, cfg->nbits.nof_bits, - e_bits, data); - } else if (codeword_idx == 1) { - ret = decode_tb(q, softbuffer, &cfg->cb_segm2, - cfg->grant.Qm2*Nl, cfg->rv2, cfg->nbits2.nof_bits, - e_bits, data); - } else { - ERROR("Not implemented"); - } - - return ret; + return decode_tb(q, softbuffer, &cfg->cb_segm[codeword_idx], + cfg->grant.Qm[codeword_idx] * Nl, cfg->rv[codeword_idx], cfg->nbits[codeword_idx].nof_bits, + e_bits, data); } /** @@ -562,64 +546,22 @@ int srslte_dlsch_decode2(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbu int srslte_dlsch_encode(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, uint8_t *data, uint8_t *e_bits) { - return encode_tb(q, - softbuffer, &cfg->cb_segm, - cfg->grant.Qm, cfg->rv, cfg->nbits.nof_bits, - data, e_bits); + return srslte_dlsch_encode2(q, cfg, softbuffer, data, e_bits, 0); } int srslte_dlsch_encode2(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, uint8_t *data, uint8_t *e_bits, int codeword_idx) { - int ret = SRSLTE_ERROR; uint32_t Nl = 1; if (cfg->nof_layers != cfg->grant.nof_tb) { Nl = 2; } - if(codeword_idx == 0) { - /* Codeword 1 shall be encoded */ - ret = encode_tb(q, softbuffer, &cfg->cb_segm, cfg->grant.Qm*Nl, cfg->rv, cfg->nbits.nof_bits, data, e_bits); - } else if(codeword_idx == 1) { - /* Codeword 2 shall be encoded */ - ret = encode_tb(q, softbuffer, &cfg->cb_segm2, cfg->grant.Qm2*Nl, cfg->rv2, cfg->nbits2.nof_bits, data, e_bits); - } else { - ERROR("Not implemented"); - } - - return ret; -} - -int srslte_dlsch_encode_multi(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t softbuffers[SRSLTE_MAX_CODEWORDS], - uint8_t *data[SRSLTE_MAX_CODEWORDS], uint8_t *e_bits[SRSLTE_MAX_CODEWORDS]) -{ - int ret = 0; - uint32_t Nl = 1; - - if (cfg->nof_layers != cfg->grant.nof_tb) { - Nl = 2; - } - - /* Check if codeword 1 shall be encoded */ - if(cfg->nbits.nof_bits) { - ret |= encode_tb(q, - &softbuffers[0], &cfg->cb_segm, - cfg->grant.Qm*Nl, cfg->rv, cfg->nbits.nof_bits, - data[0], e_bits[0]); - } - - /* Check if codeword 2 shall be encoded */ - if(cfg->nbits2.nof_bits) { - ret |= encode_tb(q, - &softbuffers[1], &cfg->cb_segm2, - cfg->grant.Qm2*Nl, cfg->rv2, cfg->nbits2.nof_bits, - data[1], e_bits[1]); - } - - return ret; + return encode_tb(q, softbuffer, &cfg->cb_segm[codeword_idx], cfg->grant.Qm[codeword_idx]*Nl, cfg->rv[codeword_idx], + cfg->nbits[codeword_idx].nof_bits, data, e_bits); } -/* Compute the interleaving function on-the-fly, because it depends on number of RI bits +/* Compute the interleaving function on-the-fly, because it depends on number of RI bits * Profiling show that the computation of this matrix is neglegible. */ static void ulsch_interleave_gen(uint32_t H_prime_total, uint32_t N_pusch_symbs, uint32_t Qm, diff --git a/lib/src/phy/phch/test/pdsch_test.c b/lib/src/phy/phch/test/pdsch_test.c index 180e689d6..777481d6a 100644 --- a/lib/src/phy/phch/test/pdsch_test.c +++ b/lib/src/phy/phch/test/pdsch_test.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -55,11 +54,9 @@ srslte_cell_t cell = { char mimo_type_str [32] = "single"; srslte_mimo_type_t mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; uint32_t cfi = 2; -uint32_t mcs = 0; -uint32_t mcs2 = 0; +uint32_t mcs[SRSLTE_MAX_CODEWORDS] = {0, 0}; uint32_t subframe = 1; -uint32_t rv_idx = 0; -uint32_t rv_idx2 = 1; +int rv_idx[SRSLTE_MAX_CODEWORDS] = {0, 1}; uint16_t rnti = 1234; uint32_t nof_rx_antennas = 1; uint32_t pmi = 0; @@ -68,12 +65,12 @@ char *input_file = NULL; void usage(char *prog) { printf("Usage: %s [fmMcsrtRFpnwav] \n", prog); printf("\t-f read signal from file [Default generate it with pdsch_encode()]\n"); - printf("\t-m MCS [Default %d]\n", mcs); - printf("\t-M MCS2 [Default %d]\n", mcs2); + printf("\t-m MCS [Default %d]\n", mcs[0]); + printf("\t-M MCS2 [Default %d]\n", mcs[1]); printf("\t-c cell id [Default %d]\n", cell.id); printf("\t-s subframe [Default %d]\n", subframe); - printf("\t-r rv_idx [Default %d]\n", rv_idx); - printf("\t-t rv_idx2 [Default %d]\n", rv_idx2); + printf("\t-r rv_idx [Default %d]\n", rv_idx[0]); + printf("\t-t rv_idx2 [Default %d]\n", rv_idx[1]); printf("\t-R rnti [Default %d]\n", rnti); printf("\t-F cfi [Default %d]\n", cfi); printf("\t-x Transmission mode [single|diversity|cdd|multiplex] [Default %s]\n", mimo_type_str); @@ -91,19 +88,19 @@ void parse_args(int argc, char **argv) { input_file = argv[optind]; break; case 'm': - mcs = atoi(argv[optind]); + mcs[0] = (uint32_t) atoi(argv[optind]); break; case 'M': - mcs2 = (uint32_t) atoi(argv[optind]); + mcs[1] = (uint32_t) atoi(argv[optind]); break; case 's': subframe = atoi(argv[optind]); break; case 'r': - rv_idx = atoi(argv[optind]); + rv_idx[0] = (uint32_t) atoi(argv[optind]); break; case 't': - rv_idx2 = (uint32_t) atoi(argv[optind]); + rv_idx[1] = (uint32_t) atoi(argv[optind]); break; case 'R': rnti = atoi(argv[optind]); @@ -197,16 +194,16 @@ int main(int argc, char **argv) { dci.type0_alloc.rbg_bitmask = 0xffffffff; /* If transport block 0 is enabled */ - if (mcs != 0 || rv_idx != 1) { - dci.mcs_idx = mcs; - dci.rv_idx = rv_idx; + if (mcs[0] != 0 || rv_idx[0] != 1) { + dci.mcs_idx = mcs[0]; + dci.rv_idx = rv_idx[0]; dci.tb_en[0] = true; } /* If transport block 0 is disabled */ - if (mcs2 != 0 || rv_idx2 != 1) { - dci.mcs_idx_1 = mcs2; - dci.rv_idx_1 = rv_idx2; + if (mcs[1] != 0 || rv_idx[1] != 1) { + dci.mcs_idx_1 = mcs[1]; + dci.rv_idx_1 = rv_idx[1]; dci.tb_en[1] = true; } @@ -235,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, rv_idx2, mimo_type, pmi)) { + if (srslte_pdsch_cfg_multi(&pdsch_cfg, cell, &grant, cfi, subframe, rv_idx, mimo_type, pmi)) { fprintf(stderr, "Error configuring PDSCH\n"); goto quit; } @@ -260,22 +257,15 @@ int main(int argc, char **argv) { } - if (grant.mcs.tbs) { - data[0] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs.tbs); - if (!data[0]) { - perror("srslte_vec_malloc"); - goto quit; - } - bzero(data[0], sizeof(uint8_t) * grant.mcs.tbs); - } - - if (grant.mcs2.tbs) { - data[1] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs2.tbs); - if (!data[1]) { - perror("srslte_vec_malloc"); - goto quit; + for (int i = 0; i < grant.nof_tb; i++) { + if (grant.mcs[i].tbs) { + data[i] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs[i].tbs); + if (!data[i]) { + perror("srslte_vec_malloc"); + goto quit; + } + bzero(data[i], sizeof(uint8_t) * grant.mcs[i].tbs); } - bzero(data[1], sizeof(uint8_t) * grant.mcs2.tbs); } if (srslte_pdsch_init_rx_multi(&pdsch_rx, cell, nof_rx_antennas)) { @@ -292,6 +282,7 @@ int main(int argc, char **argv) { } } + INFO(" Global:\n"); INFO(" nof_prb=%d\n", cell.nof_prb); INFO(" nof_ports=%d\n", cell.nof_ports); INFO(" id=%d\n", cell.id); @@ -300,28 +291,22 @@ int main(int argc, char **argv) { INFO(" phich_resources=%d\n", (int) cell.phich_resources); INFO(" nof_tb=%d\n", pdsch_cfg.grant.nof_tb); INFO(" nof_prb=%d\n", pdsch_cfg.grant.nof_prb); - INFO(" Qm=%d\n", pdsch_cfg.grant.Qm); - INFO(" Qm2=%d\n", pdsch_cfg.grant.Qm2); - INFO(" mcs.idx=0x%X\n", pdsch_cfg.grant.mcs.idx); - INFO(" mcs.tbs=%d\n", pdsch_cfg.grant.mcs.tbs); - INFO(" mcs.mod=%s\n", srslte_mod_string(pdsch_cfg.grant.mcs.mod)); - INFO(" mcs2.idx=0x%X\n", pdsch_cfg.grant.mcs2.idx); - INFO(" mcs2.tbs=%d\n", pdsch_cfg.grant.mcs2.tbs); - INFO(" mcs2.mod=%s\n", srslte_mod_string(pdsch_cfg.grant.mcs2.mod)); - INFO(" nof_layers=%d\n", pdsch_cfg.nof_layers); - INFO(" rv=%d\n", pdsch_cfg.rv); - INFO(" rv2=%d\n", pdsch_cfg.rv2); INFO(" sf_idx=%d\n", pdsch_cfg.sf_idx); - INFO(" mimo_type=%d\n", (int) pdsch_cfg.mimo_type); + INFO(" mimo_type=%s\n", srslte_mimotype2str(pdsch_cfg.mimo_type)); + INFO(" nof_layers=%d\n", pdsch_cfg.nof_layers); INFO(" nof_tb=%d\n", pdsch_cfg.grant.nof_tb); - INFO(" lstart=%d\n", pdsch_cfg.nbits.lstart); - INFO(" nof_bits=%d\n", pdsch_cfg.nbits.nof_bits); - INFO(" nof_re=%d\n", pdsch_cfg.nbits.nof_re); - INFO(" nof_symb=%d\n", pdsch_cfg.nbits.nof_symb); - INFO(" lstart=%d\n", pdsch_cfg.nbits2.lstart); - INFO(" nof_bits=%d\n", pdsch_cfg.nbits2.nof_bits); - INFO(" nof_re=%d\n", pdsch_cfg.nbits2.nof_re); - INFO(" nof_symb=%d\n", pdsch_cfg.nbits2.nof_symb); + for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { + INFO(" Tranport block index %d:\n", i); + INFO(" Qm=%d\n", pdsch_cfg.grant.Qm[i]); + INFO(" mcs.idx=0x%X\n", pdsch_cfg.grant.mcs[i].idx); + INFO(" mcs.tbs=%d\n", pdsch_cfg.grant.mcs[i].tbs); + INFO(" mcs.mod=%s\n", srslte_mod_string(pdsch_cfg.grant.mcs[i].mod)); + INFO(" rv=%d\n", pdsch_cfg.rv[i]); + INFO(" lstart=%d\n", pdsch_cfg.nbits[i].lstart); + INFO(" nof_bits=%d\n", pdsch_cfg.nbits[i].nof_bits); + INFO(" nof_re=%d\n", pdsch_cfg.nbits[i].nof_re); + INFO(" nof_symb=%d\n", pdsch_cfg.nbits[i].nof_symb); + } if (input_file) { srslte_filesource_t fsrc; @@ -368,29 +353,25 @@ int main(int argc, char **argv) { } } - for (i = 0; i < grant.mcs.tbs / 8; i++) { - data[0][i] = (uint8_t) (rand() % 256); - } - - for (i = 0; i < grant.mcs2.tbs / 8; i++) { - data[1][i] = (uint8_t) (rand() % 256); + for (i = 0; i< grant.nof_tb; i++) { + for (i = 0; i < grant.mcs[i].tbs / 8; i++) { + data[i][i] = (uint8_t) (rand() % 256); + } } /*uint8_t databit[100000]; srslte_bit_unpack_vector(data, databit, grant.mcs.tbs); srslte_vec_save_file("data_in", databit, grant.mcs.tbs);*/ - if (rv_idx) { + if (rv_idx[0] != 0 || rv_idx[1] != 0) { /* Do 1st transmission for rv_idx!=0 */ - pdsch_cfg.rv = 0; - pdsch_cfg.rv2 = 0; + bzero(pdsch_cfg.rv, sizeof(uint32_t)*SRSLTE_MAX_CODEWORDS); if (srslte_pdsch_encode_multi(&pdsch_tx, &pdsch_cfg, softbuffers_tx, data, rnti, tx_slot_symbols)) { fprintf(stderr, "Error encoding PDSCH\n"); goto quit; } } - pdsch_cfg.rv = rv_idx; - pdsch_cfg.rv2 = rv_idx2; + 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, rnti, tx_slot_symbols)) { @@ -401,8 +382,8 @@ int main(int argc, char **argv) { gettimeofday(&t[2], NULL); get_time_interval(t); printf("ENCODED in %.2f (PHY bitrate=%.2f Mbps. Processing bitrate=%.2f Mbps)\n", - (float) t[0].tv_usec/M, (float) (grant.mcs.tbs + grant.mcs2.tbs)/1000.0f, - (float) (grant.mcs.tbs + grant.mcs2.tbs)*M/t[0].tv_usec); + (float) t[0].tv_usec/M, (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)/1000.0f, + (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)*M/t[0].tv_usec); #ifdef DO_OFDM for (i = 0; i < cell.nof_ports; i++) { @@ -444,19 +425,18 @@ int main(int argc, char **argv) { srslte_ofdm_rx_sf(&ofdm_rx, tx_sf_symbols[i], rx_slot_symbols[i]); } #endif - if (grant.mcs.tbs) { - srslte_softbuffer_rx_reset_tbs(&softbuffers_rx[0], (uint32_t) grant.mcs.tbs); - } - if (grant.mcs2.tbs) { - srslte_softbuffer_rx_reset_tbs(&softbuffers_rx[1], (uint32_t) grant.mcs2.tbs); + for (i = 0; i < grant.nof_tb; i++) { + if (grant.mcs[i].tbs) { + 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); } gettimeofday(&t[2], NULL); get_time_interval(t); printf("DECODED %s in %.2f (PHY bitrate=%.2f Mbps. Processing bitrate=%.2f Mbps)\n", r?"Error":"OK", - (float) t[0].tv_usec/M, (float) (grant.mcs.tbs + grant.mcs2.tbs)/1000.0f, - (float) (grant.mcs.tbs + grant.mcs2.tbs)*M/t[0].tv_usec); + (float) t[0].tv_usec/M, (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)/1000.0f, + (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)*M/t[0].tv_usec); if (r) { ret = -1; goto quit; diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 3f51a3036..47337a109 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -282,14 +282,16 @@ int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t *c } -int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, uint32_t rvidx) -{ - return srslte_pdsch_cfg_multi(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx, 0, SRSLTE_MIMO_TYPE_SINGLE_ANTENNA, 0); +int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, + int rvidx) { + int _rvidx [SRSLTE_MAX_CODEWORDS] = {1}; + _rvidx[0] = rvidx; + + return srslte_pdsch_cfg_multi(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, _rvidx, SRSLTE_MIMO_TYPE_SINGLE_ANTENNA, 0); } int srslte_ue_dl_cfg_grant_multi(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, - uint32_t rvidx, uint32_t rvidx2, srslte_mimo_type_t mimo_type, uint32_t pinfo) -{ + int rvidx[SRSLTE_MAX_CODEWORDS], srslte_mimo_type_t mimo_type, uint32_t pinfo) { uint32_t pmi = 0; /* Translates Precoding Information (pinfo) to Precoding matrix Index (pmi) as 3GPP 36.212 Table 5.3.3.1.5-4 */ @@ -310,7 +312,7 @@ int srslte_ue_dl_cfg_grant_multi(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, } } } - return srslte_pdsch_cfg_multi(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx, rvidx2, mimo_type, pmi); + return srslte_pdsch_cfg_multi(&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) @@ -357,23 +359,28 @@ int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_POR /* ===== These lines of code are supposed to be MAC functionality === */ - uint32_t rvidx = 0; - uint32_t rvidx2 = 0; + int rvidx[SRSLTE_MAX_CODEWORDS] = {1}; if (dci_unpacked.rv_idx < 0) { uint32_t sfn = tti/10; - uint32_t k = (sfn/2)%4; - rvidx = ((uint32_t) ceilf((float)1.5*k))%4; - srslte_softbuffer_rx_reset_tbs(&q->softbuffers[0], (uint32_t) grant.mcs.tbs); - if (grant.nof_tb > 1) { - rvidx2 = ((uint32_t) ceilf((float)1.5*k))%4; - srslte_softbuffer_rx_reset_tbs(&q->softbuffers[1], (uint32_t) grant.mcs2.tbs); + uint32_t k = (sfn/2)%4; + for (int i = 0; i < grant.nof_tb; i++) { + rvidx[i] = ((uint32_t) ceilf((float) 1.5 * k)) % 4; + srslte_softbuffer_rx_reset_tbs(&q->softbuffers[i], (uint32_t) grant.mcs[i].tbs); } } else { - rvidx = (uint32_t) dci_unpacked.rv_idx; - srslte_softbuffer_rx_reset_tbs(&q->softbuffers[0], (uint32_t) grant.mcs.tbs); - if (grant.nof_tb > 1) { - rvidx2 = (uint32_t) dci_unpacked.rv_idx_1; - srslte_softbuffer_rx_reset_tbs(&q->softbuffers[1], (uint32_t) grant.mcs2.tbs); + for (int i = 0; i < grant.nof_tb; i++) { + switch(i) { + case 0: + rvidx[i] = (uint32_t) dci_unpacked.rv_idx; + break; + case 1: + rvidx[i] = (uint32_t) dci_unpacked.rv_idx_1; + break; + default: + ERROR("Wrong number of transport blocks"); + return SRSLTE_ERROR; + } + srslte_softbuffer_rx_reset_tbs(&q->softbuffers[i], (uint32_t) grant.mcs[i].tbs); } } @@ -408,7 +415,7 @@ int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_POR return SRSLTE_ERROR; } - if (srslte_ue_dl_cfg_grant_multi(q, &grant, cfi, sf_idx, rvidx, rvidx2, mimo_type, dci_unpacked.pinfo)) { + if (srslte_ue_dl_cfg_grant_multi(q, &grant, cfi, sf_idx, rvidx, mimo_type, dci_unpacked.pinfo)) { ERROR("Configuing PDSCH"); return SRSLTE_ERROR; } @@ -418,7 +425,7 @@ int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_POR q->nof_detected++; - if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) { + 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, @@ -446,7 +453,7 @@ int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_POR q->pkts_total++; if (found_dci == 1 && ret == SRSLTE_SUCCESS) { - return q->pdsch_cfg.grant.mcs.tbs; + return q->pdsch_cfg.grant.mcs[0].tbs; } else { return 0; } @@ -723,16 +730,16 @@ void srslte_ue_dl_save_signal(srslte_ue_dl_t *q, srslte_softbuffer_rx_t *softbuf srslte_vec_save_file("pdcch_llr", q->pdcch.llr, q->pdcch.nof_cce*72*sizeof(float)); - srslte_vec_save_file("pdsch_symbols", q->pdsch.d, q->pdsch_cfg.nbits.nof_re*sizeof(cf_t)); - srslte_vec_save_file("llr", q->pdsch.e, q->pdsch_cfg.nbits.nof_bits*sizeof(cf_t)); - int cb_len = q->pdsch_cfg.cb_segm.K1; - for (int i=0;ipdsch_cfg.cb_segm.C;i++) { + srslte_vec_save_file("pdsch_symbols", q->pdsch.d, q->pdsch_cfg.nbits[0].nof_re*sizeof(cf_t)); + srslte_vec_save_file("llr", q->pdsch.e, q->pdsch_cfg.nbits[0].nof_bits*sizeof(cf_t)); + int cb_len = q->pdsch_cfg.cb_segm[0].K1; + for (int i=0;ipdsch_cfg.cb_segm[0].C;i++) { char tmpstr[64]; snprintf(tmpstr,64,"rmout_%d.dat",i); srslte_vec_save_file(tmpstr, softbuffer->buffer_f[i], (3*cb_len+12)*sizeof(int16_t)); } printf("Saved files for tti=%d, sf=%d, cfi=%d, mcs=%d, rv=%d, rnti=0x%x\n", tti, tti%10, cfi, - q->pdsch_cfg.grant.mcs.idx, rv_idx, rnti); + q->pdsch_cfg.grant.mcs[0].idx, rv_idx, rnti); } diff --git a/srsenb/src/phy/phch_worker.cc b/srsenb/src/phy/phch_worker.cc index eca637635..40fbe4b1f 100644 --- a/srsenb/src/phy/phch_worker.cc +++ b/srsenb/src/phy/phch_worker.cc @@ -632,7 +632,7 @@ int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants if (LOG_THIS(rnti)) { uint8_t x = 0; uint8_t *ptr = grants[i].data; - uint32_t len = phy_grant.mcs.tbs/8; + uint32_t len = phy_grant.mcs[0].tbs / (uint32_t) 8; if (!ptr) { ptr = &x; len = 1; @@ -640,7 +640,7 @@ int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants log_h->info_hex(ptr, len, "PDSCH: rnti=0x%x, l_crb=%2d, %s, harq=%d, tbs=%d, mcs=%d, rv=%d, tti_tx=%d\n", rnti, phy_grant.nof_prb, grant_str, grants[i].grant.harq_process, - phy_grant.mcs.tbs/8, phy_grant.mcs.idx, grants[i].grant.rv_idx, tti_tx); + 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)) @@ -650,7 +650,7 @@ int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants } // Save metrics stats - ue_db[rnti].metrics_dl(phy_grant.mcs.idx); + ue_db[rnti].metrics_dl(phy_grant.mcs[0].idx); } } return SRSLTE_SUCCESS; diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index 8cdec22c2..ed1d7af26 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -76,9 +76,20 @@ private: /* ... for DL */ bool decode_pdcch_ul(mac_interface_phy::mac_grant_t *grant); bool decode_pdcch_dl(mac_interface_phy::mac_grant_t *grant); - bool decode_phich(bool *ack); - bool 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 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, uint16_t rnti, uint32_t pid); + bool decode_phich(bool *ack); + + bool 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 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); /* ... 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 fce931837..231190fb1 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -204,9 +204,9 @@ void phch_worker::work_imp() /* Decode PDSCH if instructed to do so */ dl_ack = dl_action.default_ack; if (dl_action.decode_enabled) { - dl_ack = decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr, + dl_ack = decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr, dl_action.softbuffer, dl_action.rv, dl_action.rnti, - dl_mac_grant.pid); + dl_mac_grant.pid); } if (dl_action.generate_ack_callback && dl_action.decode_enabled) { phy->mac->tb_decoded(dl_ack, dl_mac_grant.rnti_type, dl_mac_grant.pid); @@ -382,7 +382,7 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) /* Fill MAC grant structure */ grant->ndi = dci_unpacked.ndi; grant->pid = dci_unpacked.harq_process; - grant->n_bytes = grant->phy_grant.dl.mcs.tbs/8; + grant->n_bytes = grant->phy_grant.dl.mcs[0].tbs/8; grant->tti = tti; grant->rv = dci_unpacked.rv_idx; grant->rnti = dl_rnti; @@ -406,23 +406,70 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) } bool 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) -{ - return decode_pdsch_multi(grant, &payload, softbuffer, rv, rnti, harq_pid); + srslte_softbuffer_rx_t *softbuffer, int rv, + uint16_t rnti, uint32_t harq_pid) { + int _rv [SRSLTE_MAX_CODEWORDS] = {1}; + _rv[0] = rv; + + return decode_pdsch_multi(grant, &payload, softbuffer, _rv, rnti, harq_pid); } bool phch_worker::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, uint16_t rnti, uint32_t harq_pid) -{ + srslte_softbuffer_rx_t softbuffers[SRSLTE_MAX_CODEWORDS], + int rv[SRSLTE_MAX_CODEWORDS], + uint16_t rnti, uint32_t harq_pid) { char timestr[64]; + bool valid_config = true; timestr[0]='\0'; - + srslte_mimo_type_t mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; + + for (uint32_t tb = 0; tb < grant->nof_tb; tb++) { + if (rv[tb] < 0 || rv[tb] > 3) { + valid_config = false; + Error("Wrong RV (%d) for TB index %d", rv[tb], tb); + } + } + + switch(phy->config->dedicated.antenna_info_explicit_value.tx_mode) { + case LIBLTE_RRC_TRANSMISSION_MODE_1: + mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; + break; + case LIBLTE_RRC_TRANSMISSION_MODE_2: + mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY; + break; + case LIBLTE_RRC_TRANSMISSION_MODE_3: + if (grant->nof_tb == 1) { + mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY; + } else if (grant->nof_tb == 2) { + mimo_type = SRSLTE_MIMO_TYPE_CDD; + } else { + Error("Wrong number of transport blocks (%d) for TM3\n", grant->nof_tb); + valid_config = false; + } + break; + + /* Not implemented cases */ + case LIBLTE_RRC_TRANSMISSION_MODE_4: + case LIBLTE_RRC_TRANSMISSION_MODE_5: + case LIBLTE_RRC_TRANSMISSION_MODE_6: + case LIBLTE_RRC_TRANSMISSION_MODE_7: + case LIBLTE_RRC_TRANSMISSION_MODE_8: + Error("Not implemented Tx mode (%d)\n", phy->config->dedicated.antenna_info_explicit_value.tx_mode); + break; + + /* Error cases */ + case LIBLTE_RRC_TRANSMISSION_MODE_N_ITEMS: + default: + Error("Wrong Tx mode (%d)\n", phy->config->dedicated.antenna_info_explicit_value.tx_mode); + valid_config = false; + } + Debug("DL Buffer TTI %d: Decoding PDSCH\n", tti); /* Setup PDSCH configuration for this CFI, SFIDX and RVIDX */ - if (rv >= 0 && rv <= 3) { - if (!srslte_ue_dl_cfg_grant(&ue_dl, grant, cfi, tti%10, rv)) { - if (ue_dl.pdsch_cfg.grant.mcs.mod > 0 && ue_dl.pdsch_cfg.grant.mcs.tbs >= 0) { + if (valid_config) { + if (!srslte_ue_dl_cfg_grant_multi(&ue_dl, grant, cfi, tti%10, rv, mimo_type, 0)) { + if (ue_dl.pdsch_cfg.grant.mcs[0].mod > 0 && ue_dl.pdsch_cfg.grant.mcs[0].tbs >= 0) { float noise_estimate = srslte_chest_dl_get_noise_estimate(&ue_dl.chest); @@ -451,7 +498,7 @@ bool phch_worker::decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *paylo Info("PDSCH: l_crb=%2d, harq=%d, tbs=%d, mcs=%d, rv=%d, crc=%s, snr=%.1f dB, n_iter=%d%s\n", grant->nof_prb, harq_pid, - grant->mcs.tbs/8, grant->mcs.idx, rv, + grant->mcs[0].tbs/8, grant->mcs[0].idx, rv, ack?"OK":"KO", 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), srslte_pdsch_last_noi(&ue_dl.pdsch), @@ -461,7 +508,7 @@ bool phch_worker::decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *paylo //srslte_vec_save_file("pdsch", signal_buffer, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb)); // Store metrics - dl_metrics.mcs = grant->mcs.idx; + dl_metrics.mcs = grant->mcs[0].idx; return ack; } else { @@ -470,8 +517,6 @@ bool phch_worker::decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *paylo } else { Error("Error configuring DL grant\n"); } - } else { - Error("Error RV is not set or is invalid (%d)\n", rv); } return true; } @@ -973,8 +1018,9 @@ int phch_worker::read_ce_abs(float *ce_abs) { int phch_worker::read_pdsch_d(cf_t* pdsch_d) { - memcpy(pdsch_d, ue_dl.pdsch.d, ue_dl.pdsch_cfg.nbits.nof_re*sizeof(cf_t)); - return ue_dl.pdsch_cfg.nbits.nof_re; + + memcpy(pdsch_d, ue_dl.pdsch.d, ue_dl.pdsch_cfg.nbits[0].nof_re*sizeof(cf_t)); + return ue_dl.pdsch_cfg.nbits[0].nof_re; }