From 338be7d0c2b97421a7fa4374dc3f7200867eb456 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 5 Sep 2017 13:17:33 +0200 Subject: [PATCH] Refactored grant: removed nof_tb from grant. Use tb_en instead. --- lib/examples/pdsch_enodeb.c | 18 ++-- lib/examples/pdsch_ue.c | 9 +- lib/include/srslte/interfaces/ue_interfaces.h | 2 + lib/include/srslte/phy/phch/ra.h | 4 +- lib/src/phy/phch/pdsch.c | 72 +++++++++------- lib/src/phy/phch/ra.c | 29 ++++--- lib/src/phy/phch/sch.c | 4 +- lib/src/phy/phch/test/pdsch_test.c | 39 +++++---- lib/src/phy/ue/ue_dl.c | 61 +++++++------ srsue/hdr/mac/dl_harq.h | 6 +- srsue/hdr/phy/phch_worker.h | 2 +- srsue/src/phy/phch_worker.cc | 85 +++++++++++-------- 12 files changed, 191 insertions(+), 140 deletions(-) diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index 35f7d3e9f..afbe44b91 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -774,9 +774,11 @@ int main(int argc, char **argv) { } } else { 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(); + for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { + if (pdsch_cfg.grant.tb_en[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 */ @@ -832,10 +834,12 @@ int main(int argc, char **argv) { } if (net_port > 0 && net_packet_ready) { if (null_file_sink) { - 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"); + for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { + if (pdsch_cfg.grant.tb_en[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 2ace49d6d..aa3e13257 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -641,9 +641,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 - 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); - + for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { + if (ue_dl.pdsch_cfg.grant.tb_en[tb]) { + srslte_netsink_write(&net_sink, data[tb], 1 + (ue_dl.pdsch_cfg.grant.mcs[tb].tbs - 1) / 8); + } } } @@ -704,7 +705,7 @@ int main(int argc, char **argv) { /* Print basic Parameters */ PRINT_LINE(" nof layers: %d", ue_dl.pdsch_cfg.nof_layers); - PRINT_LINE("nof codewords: %d", ue_dl.pdsch_cfg.grant.nof_tb); + PRINT_LINE("nof codewords: %d", SRSLTE_RA_DL_GRANT_NOF_TB(&ue_dl.pdsch_cfg.grant)); PRINT_LINE(" CFO: %+5.2f kHz", srslte_ue_sync_get_cfo(&ue_sync) / 1000); PRINT_LINE(" SNR: %+5.1f dB | %+5.1f dB", 10 * log10(rsrp0 / noise), 10 * log10(rsrp1 / noise)); PRINT_LINE(" Rb: %6.2f / %6.2f Mbps (net/maximum)", uerate, enodebrate); diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 879118021..5907d164b 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -281,6 +281,8 @@ public: bool last_ndi[SRSLTE_MAX_CODEWORDS]; uint32_t n_bytes[SRSLTE_MAX_CODEWORDS]; int rv[SRSLTE_MAX_CODEWORDS]; + bool tb_en[SRSLTE_MAX_CODEWORDS]; + bool tb_cw_swap; uint16_t rnti; bool is_from_rar; bool is_sps_release; diff --git a/lib/include/srslte/phy/phch/ra.h b/lib/include/srslte/phy/phch/ra.h index 9f31a0218..94cc9a084 100644 --- a/lib/include/srslte/phy/phch/ra.h +++ b/lib/include/srslte/phy/phch/ra.h @@ -104,10 +104,12 @@ typedef struct SRSLTE_API { uint32_t nof_prb; uint32_t Qm[SRSLTE_MAX_CODEWORDS]; srslte_ra_mcs_t mcs[SRSLTE_MAX_CODEWORDS]; - uint32_t nof_tb; + bool tb_en[SRSLTE_MAX_CODEWORDS]; uint32_t pinfo; } srslte_ra_dl_grant_t; +#define SRSLTE_RA_DL_GRANT_NOF_TB(G) ((((G)->tb_en[0])?1:0)+(((G)->tb_en[1])?1:0)) + /** Unpacked DCI message for DL grant */ typedef struct SRSLTE_API { diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index bc62df7fd..fe10791d7 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -427,15 +427,17 @@ int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_g 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) { - if (grant) { - memcpy(&cfg->grant, grant, sizeof(srslte_ra_dl_grant_t)); - } + if (cfg && grant) { + uint32_t nof_tb = SRSLTE_RA_DL_GRANT_NOF_TB(grant); + memcpy(&cfg->grant, grant, sizeof(srslte_ra_dl_grant_t)); - 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; + + for (int cw = 0; cw < SRSLTE_MAX_CODEWORDS; cw++) { + if (grant->tb_en[cw]) { + if (srslte_cbsegm(&cfg->cb_segm[cw], (uint32_t) cfg->grant.mcs[cw].tbs)) { + fprintf(stderr, "Error computing Codeblock (1) segmentation for TBS=%d\n", cfg->grant.mcs[cw].tbs); + return SRSLTE_ERROR; + } } } srslte_ra_dl_grant_to_nbits(&cfg->grant, cfi, cell, sf_idx, cfg->nbits); @@ -447,33 +449,36 @@ int srslte_pdsch_cfg_mimo(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra /* Check and configure PDSCH transmission modes */ switch(mimo_type) { case SRSLTE_MIMO_TYPE_SINGLE_ANTENNA: - if (grant->nof_tb != 1) { - ERROR("Number of transport blocks is not supported for single transmission mode."); + if (nof_tb != 1) { + ERROR("Wrong number of transport blocks (%d) for single antenna.", nof_tb); return SRSLTE_ERROR; } cfg->nof_layers = 1; break; case SRSLTE_MIMO_TYPE_TX_DIVERSITY: - if (grant->nof_tb != 1) { - ERROR("Number of transport blocks is not supported for transmit diversity mode."); + if (nof_tb != 1) { + ERROR("Wrong number of transport blocks (%d) for transmit diversity.", nof_tb); return SRSLTE_ERROR; } cfg->nof_layers = 2; break; case SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX: - if (grant->nof_tb == 1) { + if (nof_tb == 1) { cfg->codebook_idx = pmi; cfg->nof_layers = 1; - } else { + } else if (nof_tb == 2) { cfg->codebook_idx = pmi + 1; cfg->nof_layers = 2; + } else { + ERROR("Wrong number of transport blocks (%d) for spatial multiplexing.", nof_tb); + return SRSLTE_ERROR; } 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); + nof_tb, cfg->nof_layers, cfg->codebook_idx); break; case SRSLTE_MIMO_TYPE_CDD: - if (grant->nof_tb != 2) { - ERROR("Number of transport blocks (%d) is not supported for CDD transmission mode.", grant->nof_tb); + if (nof_tb != 2) { + ERROR("Wrong number of transport blocks (%d) for CDD.", nof_tb); return SRSLTE_ERROR; } cfg->nof_layers = 2; @@ -585,9 +590,10 @@ int srslte_pdsch_decode(srslte_pdsch_t *q, data != NULL && cfg != NULL) { + uint32_t nof_tb = SRSLTE_RA_DL_GRANT_NOF_TB(&cfg->grant); 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); + cfg->sf_idx, rnti, cfg->nbits[0].nof_re, cfg->grant.nof_prb, cfg->nof_layers, nof_tb); // Extract Symbols and Channel Estimates for (int j=0;jnof_rx_antennas;j++) { @@ -608,10 +614,10 @@ int srslte_pdsch_decode(srslte_pdsch_t *q, // 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; + nof_symbols[0] = cfg->nbits[0].nof_re * nof_tb / cfg->nof_layers; + nof_symbols[1] = cfg->nbits[1].nof_re * nof_tb / cfg->nof_layers; - if (cfg->nof_layers == cfg->grant.nof_tb) { + if (cfg->nof_layers == nof_tb) { /* Skip layer demap */ for (i = 0; i < cfg->nof_layers; i++) { x[i] = q->d[i]; @@ -629,15 +635,17 @@ int srslte_pdsch_decode(srslte_pdsch_t *q, 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, + if (cfg->nof_layers != nof_tb) { + srslte_layerdemap_type(x, q->d, cfg->nof_layers, nof_tb, nof_symbols[0], nof_symbols, cfg->mimo_type); } // 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); + for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb ++) { + if (cfg->grant.tb_en[tb]) { + int ret = srslte_pdsch_codeword_decode(q, cfg, softbuffers[tb], rnti, data[tb], tb); + acks[tb] = (ret == SRSLTE_SUCCESS); + } } pdsch_decode_debug(q, cfg, sf_symbols, ce); @@ -689,6 +697,8 @@ int srslte_pdsch_encode(srslte_pdsch_t *q, if (q != NULL && cfg != NULL) { + uint32_t nof_tb = SRSLTE_RA_DL_GRANT_NOF_TB(&cfg->grant); + for (i = 0; i < q->cell.nof_ports; i++) { if (sf_symbols[i] == NULL) { @@ -708,15 +718,17 @@ int srslte_pdsch_encode(srslte_pdsch_t *q, return SRSLTE_ERROR_INVALID_INPUTS; } - for (uint32_t tb = 0; tb < cfg->grant.nof_tb; tb ++) { - ret |= srslte_pdsch_codeword_encode(q, cfg, softbuffers[tb], rnti, data[tb], tb); + for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb ++) { + if (cfg->grant.tb_en[tb]) { + 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 */ - if (cfg->nof_layers == cfg->grant.nof_tb) { + if (cfg->nof_layers == nof_tb) { for (i = 0; i < cfg->nof_layers; i++) { x[i] = q->d[i]; } @@ -728,7 +740,7 @@ int srslte_pdsch_encode(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, + nof_symbols = srslte_layermap_type(q->d, x, nof_tb, cfg->nof_layers, (int[SRSLTE_MAX_CODEWORDS]) {cfg->nbits[0].nof_re, cfg->nbits[1].nof_re}, cfg->mimo_type); } diff --git a/lib/src/phy/phch/ra.c b/lib/src/phy/phch/ra.c index 00713e6c1..b85d2ea2f 100644 --- a/lib/src/phy/phch/ra.c +++ b/lib/src/phy/phch/ra.c @@ -521,11 +521,10 @@ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *gr grant->mcs[1].tbs = 0; } } - grant->nof_tb = 0; for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { + grant->tb_en[tb] = dci->tb_en[tb]; if (dci->tb_en[tb]) { grant->Qm[tb] = srslte_mod_bits_x_symbol(grant->mcs[tb].mod); - grant->nof_tb++; } } grant->pinfo = dci->pinfo; @@ -541,12 +540,14 @@ void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant, uint32_t cfi, srsl srslte_ra_nbits_t nbits [SRSLTE_MAX_CODEWORDS]) { // Compute number of RE - 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]; + for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { + if (grant->tb_en[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]; + } } } @@ -820,11 +821,13 @@ void srslte_ra_pdsch_fprint(FILE *f, srslte_ra_dl_dci_t *dci, uint32_t nof_prb) 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); - 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); + fprintf(f, " - Number of TBs:\t\t\t%d\n", SRSLTE_RA_DL_GRANT_NOF_TB(grant)); + for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { + if (grant->tb_en[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); + } } } diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index e0002429e..72ee50ee9 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -524,7 +524,7 @@ int srslte_dlsch_decode2(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbu int16_t *e_bits, uint8_t *data, int codeword_idx) { uint32_t Nl = 1; - if (cfg->nof_layers != cfg->grant.nof_tb) { + if (cfg->nof_layers != SRSLTE_RA_DL_GRANT_NOF_TB(&cfg->grant)) { Nl = 2; } @@ -553,7 +553,7 @@ int srslte_dlsch_encode2(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbu uint8_t *data, uint8_t *e_bits, int codeword_idx) { uint32_t Nl = 1; - if (cfg->nof_layers != cfg->grant.nof_tb) { + if (cfg->nof_layers != SRSLTE_RA_DL_GRANT_NOF_TB(&cfg->grant)) { Nl = 2; } diff --git a/lib/src/phy/phch/test/pdsch_test.c b/lib/src/phy/phch/test/pdsch_test.c index b98d75c22..ae0bff64e 100644 --- a/lib/src/phy/phch/test/pdsch_test.c +++ b/lib/src/phy/phch/test/pdsch_test.c @@ -257,8 +257,8 @@ int main(int argc, char **argv) { } - for (int i = 0; i < grant.nof_tb; i++) { - if (grant.mcs[i].tbs) { + for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { + if (grant.tb_en[i]) { data_tx[i] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs[i].tbs); if (!data_tx[i]) { perror("srslte_vec_malloc"); @@ -303,12 +303,11 @@ int main(int argc, char **argv) { INFO(" cp=%s\n", srslte_cp_string(cell.cp)); INFO(" phich_length=%d\n", (int) cell.phich_length); 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(" sf_idx=%d\n", pdsch_cfg.sf_idx); 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(" nof_tb=%d\n", SRSLTE_RA_DL_GRANT_NOF_TB(&pdsch_cfg.grant)); for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { INFO(" Tranport block index %d:\n", i); INFO(" Qm=%d\n", pdsch_cfg.grant.Qm[i]); @@ -372,9 +371,11 @@ int main(int argc, char **argv) { } } - for (int tb = 0; tb < grant.nof_tb; tb++) { - for (int byte = 0; byte < grant.mcs[tb].tbs / 8; byte++) { - data_tx[tb][byte] = (uint8_t)(rand() % 256); + for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { + if (grant.tb_en[tb]) { + for (int byte = 0; byte < grant.mcs[tb].tbs / 8; byte++) { + data_tx[tb][byte] = (uint8_t) (rand() % 256); + } } } @@ -444,8 +445,8 @@ int main(int argc, char **argv) { srslte_ofdm_rx_sf(&ofdm_rx, tx_sf_symbols[i], rx_slot_symbols[i]); } #endif - for (i = 0; i < grant.nof_tb; i++) { - if (grant.mcs[i].tbs) { + for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { + if (grant.tb_en[i]) { srslte_softbuffer_rx_reset_tbs(softbuffers_rx[i], (uint32_t) grant.mcs[i].tbs); } } @@ -464,19 +465,23 @@ int main(int argc, char **argv) { } /* Check Tx and Rx bytes */ - for (int tb = 0; tb < grant.nof_tb; tb++) { - for (int byte = 0; byte < grant.mcs[tb].tbs / 8; byte++) { - if (data_tx[tb][byte] != data_rx[tb][byte]) { - ERROR("Found BYTE error in TB %d (%02X != %02X), quiting...", tb, data_tx[tb][byte], data_rx[tb][byte]); - ret = SRSLTE_ERROR; - goto quit; + for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { + if (grant.tb_en[tb]) { + for (int byte = 0; byte < grant.mcs[tb].tbs / 8; byte++) { + if (data_tx[tb][byte] != data_rx[tb][byte]) { + ERROR("Found BYTE error in TB %d (%02X != %02X), quiting...", tb, data_tx[tb][byte], data_rx[tb][byte]); + ret = SRSLTE_ERROR; + goto quit; + } } } } /* Check all transport blocks have been decoded OK */ - for (int tb = 0; tb < grant.nof_tb; tb++) { - ret |= (acks[tb]) ? SRSLTE_SUCCESS : SRSLTE_ERROR; + for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { + if (grant.tb_en[tb]) { + ret |= (acks[tb]) ? SRSLTE_SUCCESS : SRSLTE_ERROR; + } } ret = SRSLTE_SUCCESS; diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 888b0d9b3..a67538ff7 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -280,21 +280,22 @@ 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, int rvidx[SRSLTE_MAX_CODEWORDS], srslte_mimo_type_t mimo_type) { uint32_t pmi = 0; + uint32_t nof_tb = SRSLTE_RA_DL_GRANT_NOF_TB(grant); /* Translates Precoding Information (pinfo) to Precoding matrix Index (pmi) as 3GPP 36.212 Table 5.3.3.1.5-4 */ if (mimo_type == SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX) { - if (grant->nof_tb == 1) { + if (nof_tb == 1) { if (grant->pinfo > 0 && grant->pinfo < 5) { pmi = grant->pinfo - 1; } else { - ERROR("Not Implemented (nof_tb=%d, pinfo=%d)", q->pdsch_cfg.grant.nof_tb, grant->pinfo); + ERROR("Not Implemented (nof_tb=%d, pinfo=%d)", nof_tb, grant->pinfo); return SRSLTE_ERROR; } } else { if (grant->pinfo < 2) { pmi = grant->pinfo; } else { - ERROR("Not Implemented (nof_tb=%d, pinfo=%d)", q->pdsch_cfg.grant.nof_tb, grant->pinfo); + ERROR("Not Implemented (nof_tb=%d, pinfo=%d)", nof_tb, grant->pinfo); return SRSLTE_ERROR; } } @@ -336,29 +337,33 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], /* ===== These lines of code are supposed to be MAC functionality === */ - + int rvidx[SRSLTE_MAX_CODEWORDS] = {1}; if (dci_unpacked.rv_idx < 0) { - uint32_t sfn = tti/10; - 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); + uint32_t sfn = tti / 10; + uint32_t k = (sfn / 2) % 4; + for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { + if (grant.tb_en[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 { - 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; + for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { + if (grant.tb_en[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); } - srslte_softbuffer_rx_reset_tbs(q->softbuffers[i], (uint32_t) grant.mcs[i].tbs); } } @@ -372,14 +377,14 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], } break; case SRSLTE_DCI_FORMAT2: - if (grant.nof_tb == 1 && dci_unpacked.pinfo == 0) { + if (SRSLTE_RA_DL_GRANT_NOF_TB(&grant) == 1 && dci_unpacked.pinfo == 0) { mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY; } else { mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX; } break; case SRSLTE_DCI_FORMAT2A: - if (grant.nof_tb == 1 && dci_unpacked.pinfo == 0) { + if (SRSLTE_RA_DL_GRANT_NOF_TB(&grant) == 1 && dci_unpacked.pinfo == 0) { mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY; } else { mimo_type = SRSLTE_MIMO_TYPE_CDD; @@ -413,11 +418,13 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], noise_estimate, rnti, data, acks); - for (int tb = 0; tb < q->pdsch_cfg.grant.nof_tb; tb++) { - if (!acks[tb]) { - q->pkt_errors++; + for (int tb = 0; tb < SRSLTE_MAX_TB; tb++) { + if (grant.tb_en[tb]) { + if (!acks[tb]) { + q->pkt_errors++; + } + q->pkts_total++; } - q->pkts_total++; } if (ret == SRSLTE_ERROR) { diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 963551150..a9949cc3a 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -166,8 +166,10 @@ private: } void new_grant_dl(Tgrant grant, Taction *action) { - for (uint32_t tb = 0; tb < grant.phy_grant.dl.nof_tb; tb++) { - subproc[tb].new_grant_dl(grant, action); + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + if (grant.tb_en[tb]) { + subproc[tb].new_grant_dl(grant, action); + } } } diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index 7b196f948..145f70e46 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -95,7 +95,7 @@ private: void set_uci_sr(); void set_uci_periodic_cqi(); void set_uci_aperiodic_cqi(); - void set_uci_ack(bool ack[SRSLTE_MAX_CODEWORDS], uint32_t nof_tb); + void set_uci_ack(bool ack[SRSLTE_MAX_CODEWORDS], bool tb_en[SRSLTE_MAX_CODEWORDS]); bool srs_is_ready_to_send(); float set_power(float tx_power); void setup_tx_gain(); diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 53dc232dc..8f9726a46 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -218,15 +218,17 @@ void phch_worker::work_imp() if (dl_action.generate_ack_callback && dl_action.decode_enabled) { // 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[tb]); + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + if (dl_mac_grant.tb_en[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[tb]); + } } } Debug("dl_ack={%d, %d}, generate_ack=%d\n", dl_ack[0], dl_ack[1], dl_action.generate_ack); if (dl_action.generate_ack) { - set_uci_ack(dl_ack, dl_mac_grant.phy_grant.dl.nof_tb); + set_uci_ack(dl_ack, dl_mac_grant.tb_en); } } } @@ -292,8 +294,10 @@ void phch_worker::work_imp() if (dl_mac_grant.rnti_type == SRSLTE_RNTI_PCH) { phy->mac->pch_decoded_ok(dl_mac_grant.n_bytes[0]); } else { - for (uint32_t tb = 0; tb < dl_mac_grant.phy_grant.dl.nof_tb; tb++) { - phy->mac->tb_decoded(dl_ack[tb], tb, dl_mac_grant.rnti_type, dl_mac_grant.pid); + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + if (dl_mac_grant.tb_en[tb]) { + phy->mac->tb_decoded(dl_ack[tb], tb, dl_mac_grant.rnti_type, dl_mac_grant.pid); + } } } } @@ -405,7 +409,15 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) grant->rnti = dl_rnti; grant->rnti_type = type; grant->last_tti = 0; - + grant->tb_en[0] = dci_unpacked.tb_en[0]; + grant->tb_en[1] = dci_unpacked.tb_en[1]; + grant->tb_cw_swap = dci_unpacked.tb_cw_swap; + + if (grant->tb_cw_swap) { + Info("tb_cw_swap = true\n"); + printf("tb_cw_swap = true\n"); + } + last_dl_pdcch_ncce = srslte_ue_dl_get_ncce(&ue_dl); char hexstr[16]; @@ -432,8 +444,8 @@ int phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSL srslte_mimo_type_t mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; int ret = SRSLTE_SUCCESS; - for (uint32_t tb = 0; tb < grant->nof_tb; tb++) { - if (rv[tb] < 0 || rv[tb] > 3) { + for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { + if (grant->tb_en[tb] && (rv[tb] < 0 || rv[tb] > 3)) { valid_config = false; Error("Wrong RV (%d) for TB index %d", rv[tb], tb); } @@ -452,22 +464,22 @@ int phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSL } break; case LIBLTE_RRC_TRANSMISSION_MODE_3: - if (grant->nof_tb == 1) { + if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 1) { mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY; - } else if (grant->nof_tb == 2) { + } else if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 2) { mimo_type = SRSLTE_MIMO_TYPE_CDD; } else { - Error("Wrong number of transport blocks (%d) for TM3\n", grant->nof_tb); + Error("Wrong number of transport blocks (%d) for TM3\n", SRSLTE_RA_DL_GRANT_NOF_TB(grant)); valid_config = false; } break; case LIBLTE_RRC_TRANSMISSION_MODE_4: - if (grant->nof_tb == 1) { + if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 1) { mimo_type = (grant->pinfo == 0) ? SRSLTE_MIMO_TYPE_TX_DIVERSITY : SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX; - } else if (grant->nof_tb == 2) { + } else if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 2) { mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX; } else { - Error("Wrong number of transport blocks (%d) for TM4\n", grant->nof_tb); + Error("Wrong number of transport blocks (%d) for TM4\n", SRSLTE_RA_DL_GRANT_NOF_TB(grant)); valid_config = false; } break; @@ -521,13 +533,14 @@ int phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSL snprintf(timestr, 64, ", dec_time=%4d us", (int) t[0].tv_usec); #endif - Info("PDSCH: l_crb=%2d, harq=%d, nof_tb=%d, tbs={%d, %d}, mcs={%d, %d}, rv={%d, %d}, crc={%s, %s}, snr=%.1f dB, n_iter=%d%s\n", - grant->nof_prb, harq_pid, - grant->nof_tb, grant->mcs[0].tbs / 8, grant->mcs[1].tbs / 8, grant->mcs[0].idx, grant->mcs[1].idx, - rv[0], rv[1], acks[0] ? "OK" : "KO", acks[1] ? "OK" : "KO", - 10 * log10(srslte_chest_dl_get_snr(&ue_dl.chest)), - srslte_pdsch_last_noi(&ue_dl.pdsch), - timestr); + Info( + "PDSCH: l_crb=%2d, harq=%d, tb_en={%s, %s}, tbs={%d, %d}, mcs={%d, %d}, rv={%d, %d}, crc={%s, %s}, snr=%.1f dB, n_iter=%d%s\n", + grant->nof_prb, harq_pid, grant->tb_en[0] ? "on" : "off", grant->tb_en[1] ? "on" : "off", + grant->mcs[0].tbs / 8, grant->mcs[1].tbs / 8, grant->mcs[0].idx, + grant->mcs[1].idx, rv[0], rv[1], acks[0] ? "OK" : "KO", acks[1] ? "OK" : "KO", + 10 * log10(srslte_chest_dl_get_snr(&ue_dl.chest)), + srslte_pdsch_last_noi(&ue_dl.pdsch), + timestr); //printf("tti=%d, cfo=%f\n", tti, cfo*15000); //srslte_vec_save_file("pdsch", signal_buffer, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb)); @@ -660,22 +673,22 @@ void phch_worker::reset_uci() bzero(&uci_data, sizeof(srslte_uci_data_t)); } - void phch_worker::set_uci_ack(bool ack[SRSLTE_MAX_CODEWORDS], uint32_t nof_tb) { - if (nof_tb > 0) { - uci_data.uci_ack = (uint8_t) ((ack[0]) ? 1 : 0); - } - - if (nof_tb > 1) { - uci_data.uci_ack_2 = (uint8_t) ((ack[1]) ? 1 : 0); - } +void phch_worker::set_uci_ack(bool ack[SRSLTE_MAX_CODEWORDS], bool tb_en[SRSLTE_MAX_CODEWORDS]) +{ + uint32_t nof_tb = 0; + if (tb_en[0]) { + uci_data.uci_ack = (uint8_t) ((ack[0]) ? 1 : 0); + nof_tb++; + } - if (nof_tb > 2) { - Error("Number of transport blocks is not supported"); - } + if (tb_en[1]) { + uci_data.uci_ack_2 = (uint8_t) ((ack[1]) ? 1 : 0); + nof_tb++; + } - uci_data.uci_ack_len = nof_tb; + uci_data.uci_ack_len = nof_tb; - } +} void phch_worker::set_uci_sr() {