Refactored grant: removed nof_tb from grant. Use tb_en instead.

master
Xavier Arteaga 7 years ago
parent 1486911e32
commit 338be7d0c2

@ -774,11 +774,13 @@ int main(int argc, char **argv) {
} }
} else { } else {
INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs); 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 (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++) { for (i = 0; i < pdsch_cfg.grant.mcs[tb].tbs / 8; i++) {
data[tb][i] = (uint8_t) rand(); data[tb][i] = (uint8_t) rand();
} }
} }
}
/* Uncomment this to transmit on sf 0 and 5 only */ /* Uncomment this to transmit on sf 0 and 5 only */
if (sf_idx != 0 && sf_idx != 5) { if (sf_idx != 0 && sf_idx != 5) {
send_data = true; send_data = true;
@ -832,13 +834,15 @@ int main(int argc, char **argv) {
} }
if (net_port > 0 && net_packet_ready) { if (net_port > 0 && net_packet_ready) {
if (null_file_sink) { if (null_file_sink) {
for (uint32_t tb = 0; tb < pdsch_cfg.grant.nof_tb; tb++) { 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); 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) { 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"); fprintf(stderr, "Error sending data through UDP socket\n");
} }
} }
} }
}
net_packet_ready = false; net_packet_ready = false;
sem_post(&net_sem); sem_post(&net_sem);
} }

@ -641,9 +641,10 @@ int main(int argc, char **argv) {
/* Send data if socket active */ /* Send data if socket active */
if (prog_args.net_port > 0) { if (prog_args.net_port > 0) {
// FIXME: UDP Data transmission does not work // FIXME: UDP Data transmission does not work
for (uint32_t tb = 0; tb < ue_dl.pdsch_cfg.grant.nof_tb; tb++) { 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); 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 basic Parameters */
PRINT_LINE(" nof layers: %d", ue_dl.pdsch_cfg.nof_layers); 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(" 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(" 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); PRINT_LINE(" Rb: %6.2f / %6.2f Mbps (net/maximum)", uerate, enodebrate);

@ -281,6 +281,8 @@ public:
bool last_ndi[SRSLTE_MAX_CODEWORDS]; bool last_ndi[SRSLTE_MAX_CODEWORDS];
uint32_t n_bytes[SRSLTE_MAX_CODEWORDS]; uint32_t n_bytes[SRSLTE_MAX_CODEWORDS];
int rv[SRSLTE_MAX_CODEWORDS]; int rv[SRSLTE_MAX_CODEWORDS];
bool tb_en[SRSLTE_MAX_CODEWORDS];
bool tb_cw_swap;
uint16_t rnti; uint16_t rnti;
bool is_from_rar; bool is_from_rar;
bool is_sps_release; bool is_sps_release;

@ -104,10 +104,12 @@ typedef struct SRSLTE_API {
uint32_t nof_prb; uint32_t nof_prb;
uint32_t Qm[SRSLTE_MAX_CODEWORDS]; uint32_t Qm[SRSLTE_MAX_CODEWORDS];
srslte_ra_mcs_t mcs[SRSLTE_MAX_CODEWORDS]; srslte_ra_mcs_t mcs[SRSLTE_MAX_CODEWORDS];
uint32_t nof_tb; bool tb_en[SRSLTE_MAX_CODEWORDS];
uint32_t pinfo; uint32_t pinfo;
} srslte_ra_dl_grant_t; } 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 */ /** Unpacked DCI message for DL grant */
typedef struct SRSLTE_API { typedef struct SRSLTE_API {

@ -427,17 +427,19 @@ 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, 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 sf_idx, int rvidx[SRSLTE_MAX_CODEWORDS], srslte_mimo_type_t mimo_type,
uint32_t pmi) { uint32_t pmi) {
if (cfg) { if (cfg && grant) {
if (grant) { uint32_t nof_tb = SRSLTE_RA_DL_GRANT_NOF_TB(grant);
memcpy(&cfg->grant, grant, sizeof(srslte_ra_dl_grant_t)); 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)) { for (int cw = 0; cw < SRSLTE_MAX_CODEWORDS; cw++) {
fprintf(stderr, "Error computing Codeblock (1) segmentation for TBS=%d\n", cfg->grant.mcs[i].tbs); 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; return SRSLTE_ERROR;
} }
} }
}
srslte_ra_dl_grant_to_nbits(&cfg->grant, cfi, cell, sf_idx, cfg->nbits); srslte_ra_dl_grant_to_nbits(&cfg->grant, cfi, cell, sf_idx, cfg->nbits);
cfg->sf_idx = sf_idx; cfg->sf_idx = sf_idx;
@ -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 */ /* Check and configure PDSCH transmission modes */
switch(mimo_type) { switch(mimo_type) {
case SRSLTE_MIMO_TYPE_SINGLE_ANTENNA: case SRSLTE_MIMO_TYPE_SINGLE_ANTENNA:
if (grant->nof_tb != 1) { if (nof_tb != 1) {
ERROR("Number of transport blocks is not supported for single transmission mode."); ERROR("Wrong number of transport blocks (%d) for single antenna.", nof_tb);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
cfg->nof_layers = 1; cfg->nof_layers = 1;
break; break;
case SRSLTE_MIMO_TYPE_TX_DIVERSITY: case SRSLTE_MIMO_TYPE_TX_DIVERSITY:
if (grant->nof_tb != 1) { if (nof_tb != 1) {
ERROR("Number of transport blocks is not supported for transmit diversity mode."); ERROR("Wrong number of transport blocks (%d) for transmit diversity.", nof_tb);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
cfg->nof_layers = 2; cfg->nof_layers = 2;
break; break;
case SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX: case SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX:
if (grant->nof_tb == 1) { if (nof_tb == 1) {
cfg->codebook_idx = pmi; cfg->codebook_idx = pmi;
cfg->nof_layers = 1; cfg->nof_layers = 1;
} else { } else if (nof_tb == 2) {
cfg->codebook_idx = pmi + 1; cfg->codebook_idx = pmi + 1;
cfg->nof_layers = 2; 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", 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; break;
case SRSLTE_MIMO_TYPE_CDD: case SRSLTE_MIMO_TYPE_CDD:
if (grant->nof_tb != 2) { if (nof_tb != 2) {
ERROR("Number of transport blocks (%d) is not supported for CDD transmission mode.", grant->nof_tb); ERROR("Wrong number of transport blocks (%d) for CDD.", nof_tb);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
cfg->nof_layers = 2; cfg->nof_layers = 2;
@ -585,9 +590,10 @@ int srslte_pdsch_decode(srslte_pdsch_t *q,
data != NULL && data != NULL &&
cfg != 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", 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 // Extract Symbols and Channel Estimates
for (int j=0;j<q->nof_rx_antennas;j++) { for (int j=0;j<q->nof_rx_antennas;j++) {
@ -608,10 +614,10 @@ int srslte_pdsch_decode(srslte_pdsch_t *q,
// Prepare layers // Prepare layers
int nof_symbols [SRSLTE_MAX_CODEWORDS]; int nof_symbols [SRSLTE_MAX_CODEWORDS];
nof_symbols[0] = cfg->nbits[0].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 * cfg->grant.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 */ /* Skip layer demap */
for (i = 0; i < cfg->nof_layers; i++) { for (i = 0; i < cfg->nof_layers; i++) {
x[i] = q->d[i]; x[i] = q->d[i];
@ -629,16 +635,18 @@ int srslte_pdsch_decode(srslte_pdsch_t *q,
cfg->codebook_idx, cfg->nbits[0].nof_re, cfg->mimo_type, noise_estimate); cfg->codebook_idx, cfg->nbits[0].nof_re, cfg->mimo_type, noise_estimate);
// Layer demapping only if necessary // Layer demapping only if necessary
if (cfg->nof_layers != cfg->grant.nof_tb) { if (cfg->nof_layers != nof_tb) {
srslte_layerdemap_type(x, q->d, cfg->nof_layers, cfg->grant.nof_tb, srslte_layerdemap_type(x, q->d, cfg->nof_layers, nof_tb,
nof_symbols[0], nof_symbols, cfg->mimo_type); nof_symbols[0], nof_symbols, cfg->mimo_type);
} }
// Codeword decoding // Codeword decoding
for (uint32_t tb = 0; tb < cfg->grant.nof_tb; tb ++) { 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); int ret = srslte_pdsch_codeword_decode(q, cfg, softbuffers[tb], rnti, data[tb], tb);
acks[tb] = (ret == SRSLTE_SUCCESS); acks[tb] = (ret == SRSLTE_SUCCESS);
} }
}
pdsch_decode_debug(q, cfg, sf_symbols, ce); pdsch_decode_debug(q, cfg, sf_symbols, ce);
@ -689,6 +697,8 @@ int srslte_pdsch_encode(srslte_pdsch_t *q,
if (q != NULL && if (q != NULL &&
cfg != NULL) { cfg != NULL) {
uint32_t nof_tb = SRSLTE_RA_DL_GRANT_NOF_TB(&cfg->grant);
for (i = 0; i < q->cell.nof_ports; i++) { for (i = 0; i < q->cell.nof_ports; i++) {
if (sf_symbols[i] == NULL) { if (sf_symbols[i] == NULL) {
@ -708,15 +718,17 @@ int srslte_pdsch_encode(srslte_pdsch_t *q,
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
} }
for (uint32_t tb = 0; tb < cfg->grant.nof_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); ret |= srslte_pdsch_codeword_encode(q, cfg, softbuffers[tb], rnti, data[tb], tb);
} }
}
// Layer mapping & precode if necessary // Layer mapping & precode if necessary
if (q->cell.nof_ports > 1) { if (q->cell.nof_ports > 1) {
int nof_symbols; int nof_symbols;
/* If number of layers is equal to transport blocks (codewords) skip layer mapping */ /* 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++) { for (i = 0; i < cfg->nof_layers; i++) {
x[i] = q->d[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)); 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}, (int[SRSLTE_MAX_CODEWORDS]) {cfg->nbits[0].nof_re, cfg->nbits[1].nof_re},
cfg->mimo_type); cfg->mimo_type);
} }

@ -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->mcs[1].tbs = 0;
} }
} }
grant->nof_tb = 0;
for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
grant->tb_en[tb] = dci->tb_en[tb];
if (dci->tb_en[tb]) { if (dci->tb_en[tb]) {
grant->Qm[tb] = srslte_mod_bits_x_symbol(grant->mcs[tb].mod); grant->Qm[tb] = srslte_mod_bits_x_symbol(grant->mcs[tb].mod);
grant->nof_tb++;
} }
} }
grant->pinfo = dci->pinfo; grant->pinfo = dci->pinfo;
@ -541,7 +540,8 @@ 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]) srslte_ra_nbits_t nbits [SRSLTE_MAX_CODEWORDS])
{ {
// Compute number of RE // Compute number of RE
for (int i = 0; i < grant->nof_tb; i++) { for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
if (grant->tb_en[i]) {
/* Compute number of RE for first transport block */ /* 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].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].lstart = cell.nof_prb < 10 ? (cfi + 1) : cfi;
@ -549,6 +549,7 @@ void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant, uint32_t cfi, srsl
nbits[i].nof_bits = nbits[i].nof_re * grant->Qm[i]; nbits[i].nof_bits = nbits[i].nof_re * grant->Qm[i];
} }
} }
}
/** Obtains a DL grant from a DCI grant for PDSCH */ /** Obtains a DL grant from a DCI grant for PDSCH */
int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci, int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci,
@ -820,13 +821,15 @@ 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) { void srslte_ra_dl_grant_fprint(FILE *f, srslte_ra_dl_grant_t *grant) {
srslte_ra_prb_fprint(f, grant); srslte_ra_prb_fprint(f, grant);
fprintf(f, " - Number of PRBs:\t\t\t%d\n", grant->nof_prb); 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, " - Number of TBs:\t\t\t%d\n", SRSLTE_RA_DL_GRANT_NOF_TB(grant));
for (int i = 0; i < grant->nof_tb; i++) { 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, " - 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, " -> 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, " -> Transport block size:\t\t%d\n", grant->mcs[i].tbs);
} }
} }
}
void srslte_ra_prb_fprint(FILE *f, srslte_ra_dl_grant_t *grant) { void srslte_ra_prb_fprint(FILE *f, srslte_ra_dl_grant_t *grant) {
if (grant->nof_prb > 0) { if (grant->nof_prb > 0) {

@ -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) { int16_t *e_bits, uint8_t *data, int codeword_idx) {
uint32_t Nl = 1; 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; 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) { uint8_t *data, uint8_t *e_bits, int codeword_idx) {
uint32_t Nl = 1; 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; Nl = 2;
} }

@ -257,8 +257,8 @@ int main(int argc, char **argv) {
} }
for (int i = 0; i < grant.nof_tb; i++) { for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
if (grant.mcs[i].tbs) { if (grant.tb_en[i]) {
data_tx[i] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs[i].tbs); data_tx[i] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs[i].tbs);
if (!data_tx[i]) { if (!data_tx[i]) {
perror("srslte_vec_malloc"); perror("srslte_vec_malloc");
@ -303,12 +303,11 @@ int main(int argc, char **argv) {
INFO(" cp=%s\n", srslte_cp_string(cell.cp)); INFO(" cp=%s\n", srslte_cp_string(cell.cp));
INFO(" phich_length=%d\n", (int) cell.phich_length); INFO(" phich_length=%d\n", (int) cell.phich_length);
INFO(" phich_resources=%d\n", (int) cell.phich_resources); 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(" nof_prb=%d\n", pdsch_cfg.grant.nof_prb);
INFO(" sf_idx=%d\n", pdsch_cfg.sf_idx); INFO(" sf_idx=%d\n", pdsch_cfg.sf_idx);
INFO(" mimo_type=%s\n", srslte_mimotype2str(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_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++) { for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
INFO(" Tranport block index %d:\n", i); INFO(" Tranport block index %d:\n", i);
INFO(" Qm=%d\n", pdsch_cfg.grant.Qm[i]); INFO(" Qm=%d\n", pdsch_cfg.grant.Qm[i]);
@ -372,11 +371,13 @@ int main(int argc, char **argv) {
} }
} }
for (int tb = 0; tb < grant.nof_tb; tb++) { 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++) { for (int byte = 0; byte < grant.mcs[tb].tbs / 8; byte++) {
data_tx[tb][byte] = (uint8_t) (rand() % 256); data_tx[tb][byte] = (uint8_t) (rand() % 256);
} }
} }
}
/*uint8_t databit[100000]; /*uint8_t databit[100000];
srslte_bit_unpack_vector(data, databit, grant.mcs.tbs); srslte_bit_unpack_vector(data, databit, grant.mcs.tbs);
@ -444,8 +445,8 @@ int main(int argc, char **argv) {
srslte_ofdm_rx_sf(&ofdm_rx, tx_sf_symbols[i], rx_slot_symbols[i]); srslte_ofdm_rx_sf(&ofdm_rx, tx_sf_symbols[i], rx_slot_symbols[i]);
} }
#endif #endif
for (i = 0; i < grant.nof_tb; i++) { for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
if (grant.mcs[i].tbs) { if (grant.tb_en[i]) {
srslte_softbuffer_rx_reset_tbs(softbuffers_rx[i], (uint32_t) grant.mcs[i].tbs); srslte_softbuffer_rx_reset_tbs(softbuffers_rx[i], (uint32_t) grant.mcs[i].tbs);
} }
} }
@ -464,7 +465,8 @@ int main(int argc, char **argv) {
} }
/* Check Tx and Rx bytes */ /* Check Tx and Rx bytes */
for (int tb = 0; tb < grant.nof_tb; tb++) { 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++) { for (int byte = 0; byte < grant.mcs[tb].tbs / 8; byte++) {
if (data_tx[tb][byte] != data_rx[tb][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]); ERROR("Found BYTE error in TB %d (%02X != %02X), quiting...", tb, data_tx[tb][byte], data_rx[tb][byte]);
@ -473,11 +475,14 @@ int main(int argc, char **argv) {
} }
} }
} }
}
/* Check all transport blocks have been decoded OK */ /* Check all transport blocks have been decoded OK */
for (int tb = 0; tb < grant.nof_tb; tb++) { for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
if (grant.tb_en[tb]) {
ret |= (acks[tb]) ? SRSLTE_SUCCESS : SRSLTE_ERROR; ret |= (acks[tb]) ? SRSLTE_SUCCESS : SRSLTE_ERROR;
} }
}
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;

@ -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 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) { int rvidx[SRSLTE_MAX_CODEWORDS], srslte_mimo_type_t mimo_type) {
uint32_t pmi = 0; 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 */ /* 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 (mimo_type == SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX) {
if (grant->nof_tb == 1) { if (nof_tb == 1) {
if (grant->pinfo > 0 && grant->pinfo < 5) { if (grant->pinfo > 0 && grant->pinfo < 5) {
pmi = grant->pinfo - 1; pmi = grant->pinfo - 1;
} else { } 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; return SRSLTE_ERROR;
} }
} else { } else {
if (grant->pinfo < 2) { if (grant->pinfo < 2) {
pmi = grant->pinfo; pmi = grant->pinfo;
} else { } 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; return SRSLTE_ERROR;
} }
} }
@ -341,12 +342,15 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS],
if (dci_unpacked.rv_idx < 0) { if (dci_unpacked.rv_idx < 0) {
uint32_t sfn = tti / 10; uint32_t sfn = tti / 10;
uint32_t k = (sfn / 2) % 4; uint32_t k = (sfn / 2) % 4;
for (int i = 0; i < grant.nof_tb; i++) { for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
if (grant.tb_en[i]) {
rvidx[i] = ((uint32_t) ceilf((float) 1.5 * k)) % 4; rvidx[i] = ((uint32_t) ceilf((float) 1.5 * k)) % 4;
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);
} }
}
} else { } else {
for (int i = 0; i < grant.nof_tb; i++) { for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
if (grant.tb_en[i]) {
switch (i) { switch (i) {
case 0: case 0:
rvidx[i] = (uint32_t) dci_unpacked.rv_idx; rvidx[i] = (uint32_t) dci_unpacked.rv_idx;
@ -361,6 +365,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS],
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);
} }
} }
}
switch(dci_msg.format) { switch(dci_msg.format) {
case SRSLTE_DCI_FORMAT1: case SRSLTE_DCI_FORMAT1:
@ -372,14 +377,14 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS],
} }
break; break;
case SRSLTE_DCI_FORMAT2: 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; mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
} else { } else {
mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX; mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
} }
break; break;
case SRSLTE_DCI_FORMAT2A: 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; mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
} else { } else {
mimo_type = SRSLTE_MIMO_TYPE_CDD; mimo_type = SRSLTE_MIMO_TYPE_CDD;
@ -413,12 +418,14 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS],
noise_estimate, noise_estimate,
rnti, data, acks); rnti, data, acks);
for (int tb = 0; tb < q->pdsch_cfg.grant.nof_tb; tb++) { for (int tb = 0; tb < SRSLTE_MAX_TB; tb++) {
if (grant.tb_en[tb]) {
if (!acks[tb]) { if (!acks[tb]) {
q->pkt_errors++; q->pkt_errors++;
} }
q->pkts_total++; q->pkts_total++;
} }
}
if (ret == SRSLTE_ERROR) { if (ret == SRSLTE_ERROR) {
} else if (ret == SRSLTE_ERROR_INVALID_INPUTS) { } else if (ret == SRSLTE_ERROR_INVALID_INPUTS) {

@ -166,10 +166,12 @@ private:
} }
void new_grant_dl(Tgrant grant, Taction *action) { void new_grant_dl(Tgrant grant, Taction *action) {
for (uint32_t tb = 0; tb < grant.phy_grant.dl.nof_tb; tb++) { for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
if (grant.tb_en[tb]) {
subproc[tb].new_grant_dl(grant, action); subproc[tb].new_grant_dl(grant, action);
} }
} }
}
int get_current_tbs(uint32_t tb_idx) { return subproc[tb_idx].get_current_tbs(); } int get_current_tbs(uint32_t tb_idx) { return subproc[tb_idx].get_current_tbs(); }

@ -95,7 +95,7 @@ private:
void set_uci_sr(); void set_uci_sr();
void set_uci_periodic_cqi(); void set_uci_periodic_cqi();
void set_uci_aperiodic_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(); bool srs_is_ready_to_send();
float set_power(float tx_power); float set_power(float tx_power);
void setup_tx_gain(); void setup_tx_gain();

@ -218,15 +218,17 @@ void phch_worker::work_imp()
if (dl_action.generate_ack_callback && dl_action.decode_enabled) { if (dl_action.generate_ack_callback && dl_action.decode_enabled) {
// NOTE: Currently hard-coded to 1st TB only // NOTE: Currently hard-coded to 1st TB only
for (uint32_t tb = 0; tb < 1; 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); 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); 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("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); Debug("dl_ack={%d, %d}, generate_ack=%d\n", dl_ack[0], dl_ack[1], dl_action.generate_ack);
if (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,11 +294,13 @@ void phch_worker::work_imp()
if (dl_mac_grant.rnti_type == SRSLTE_RNTI_PCH) { if (dl_mac_grant.rnti_type == SRSLTE_RNTI_PCH) {
phy->mac->pch_decoded_ok(dl_mac_grant.n_bytes[0]); phy->mac->pch_decoded_ok(dl_mac_grant.n_bytes[0]);
} else { } else {
for (uint32_t tb = 0; tb < dl_mac_grant.phy_grant.dl.nof_tb; 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); phy->mac->tb_decoded(dl_ack[tb], tb, dl_mac_grant.rnti_type, dl_mac_grant.pid);
} }
} }
} }
}
update_measurements(); update_measurements();
@ -405,6 +409,14 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant)
grant->rnti = dl_rnti; grant->rnti = dl_rnti;
grant->rnti_type = type; grant->rnti_type = type;
grant->last_tti = 0; 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); last_dl_pdcch_ncce = srslte_ue_dl_get_ncce(&ue_dl);
@ -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; srslte_mimo_type_t mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
int ret = SRSLTE_SUCCESS; int ret = SRSLTE_SUCCESS;
for (uint32_t tb = 0; tb < grant->nof_tb; tb++) { for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
if (rv[tb] < 0 || rv[tb] > 3) { if (grant->tb_en[tb] && (rv[tb] < 0 || rv[tb] > 3)) {
valid_config = false; valid_config = false;
Error("Wrong RV (%d) for TB index %d", rv[tb], tb); 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; break;
case LIBLTE_RRC_TRANSMISSION_MODE_3: 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; 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; mimo_type = SRSLTE_MIMO_TYPE_CDD;
} else { } 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; valid_config = false;
} }
break; break;
case LIBLTE_RRC_TRANSMISSION_MODE_4: 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; 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; mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
} else { } 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; valid_config = false;
} }
break; break;
@ -521,10 +533,11 @@ 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); snprintf(timestr, 64, ", dec_time=%4d us", (int) t[0].tv_usec);
#endif #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", Info(
grant->nof_prb, harq_pid, "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_tb, grant->mcs[0].tbs / 8, grant->mcs[1].tbs / 8, grant->mcs[0].idx, grant->mcs[1].idx, grant->nof_prb, harq_pid, grant->tb_en[0] ? "on" : "off", grant->tb_en[1] ? "on" : "off",
rv[0], rv[1], acks[0] ? "OK" : "KO", acks[1] ? "OK" : "KO", 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)), 10 * log10(srslte_chest_dl_get_snr(&ue_dl.chest)),
srslte_pdsch_last_noi(&ue_dl.pdsch), srslte_pdsch_last_noi(&ue_dl.pdsch),
timestr); timestr);
@ -660,17 +673,17 @@ void phch_worker::reset_uci()
bzero(&uci_data, sizeof(srslte_uci_data_t)); bzero(&uci_data, sizeof(srslte_uci_data_t));
} }
void phch_worker::set_uci_ack(bool ack[SRSLTE_MAX_CODEWORDS], uint32_t nof_tb) { void phch_worker::set_uci_ack(bool ack[SRSLTE_MAX_CODEWORDS], bool tb_en[SRSLTE_MAX_CODEWORDS])
if (nof_tb > 0) { {
uint32_t nof_tb = 0;
if (tb_en[0]) {
uci_data.uci_ack = (uint8_t) ((ack[0]) ? 1 : 0); uci_data.uci_ack = (uint8_t) ((ack[0]) ? 1 : 0);
nof_tb++;
} }
if (nof_tb > 1) { if (tb_en[1]) {
uci_data.uci_ack_2 = (uint8_t) ((ack[1]) ? 1 : 0); uci_data.uci_ack_2 = (uint8_t) ((ack[1]) ? 1 : 0);
} nof_tb++;
if (nof_tb > 2) {
Error("Number of transport blocks is not supported");
} }
uci_data.uci_ack_len = nof_tb; uci_data.uci_ack_len = nof_tb;

Loading…
Cancel
Save