Increased compatibility for TM3 and TM4 with one Rx antenna

This commit is contained in:
Xavier Arteaga 2017-09-19 10:32:29 +02:00
parent f58f74b102
commit 336a6b6217
4 changed files with 71 additions and 45 deletions

View File

@ -1367,7 +1367,7 @@ int srslte_predecoding_multiplex(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_P
int nof_rxant, int nof_ports, int nof_layers, int codebook_idx, int nof_symbols,
float noise_estimate)
{
if (nof_ports == 2 && nof_rxant == 2) {
if (nof_ports == 2 && nof_rxant <= 2) {
if (nof_layers == 2) {
switch (mimo_decoder) {
case SRSLTE_MIMO_DECODER_ZF:
@ -1407,7 +1407,7 @@ int srslte_predecoding_multiplex(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_P
} else if (nof_ports == 4) {
ERROR("Error predecoding multiplex: not implemented for %d Tx ports", nof_ports);
} else {
ERROR("Error predecoding multiplex: Invalid combination of ports %d and rx antennax %d\n", nof_ports, nof_rxant);
ERROR("Error predecoding multiplex: Invalid combination of ports %d and rx antennas %d\n", nof_ports, nof_rxant);
}
return SRSLTE_ERROR;
}

View File

@ -246,7 +246,7 @@ static int pdsch_init(srslte_pdsch_t *q, uint32_t max_prb, bool is_ue, uint32_t
goto clean;
}
if (q->is_ue) {
for (int j=0;j<q->nof_rx_antennas;j++) {
for (int j = 0; j < SRSLTE_MAX_PORTS; j++) {
q->ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
if (!q->ce[i][j]) {
goto clean;
@ -309,7 +309,7 @@ void srslte_pdsch_free(srslte_pdsch_t *q) {
free(q->symbols[i]);
}
if (q->is_ue) {
for (int j=0;j<q->nof_rx_antennas;j++) {
for (int j = 0; j < SRSLTE_MAX_PORTS; j++) {
if (q->ce[i][j]) {
free(q->ce[i][j]);
}
@ -713,8 +713,9 @@ int srslte_pdsch_pmi_select(srslte_pdsch_t *q,
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], float noise_estimate, uint32_t nof_ce,
uint32_t pmi[SRSLTE_MAX_LAYERS], float sinr[SRSLTE_MAX_LAYERS][SRSLTE_MAX_CODEBOOKS]) {
if (q->cell.nof_ports == 2 && q->nof_rx_antennas == 2) {
for (int nof_layers = 1; nof_layers <= 2; nof_layers++ ) {
if (q->cell.nof_ports == 2 && q->nof_rx_antennas <= 2) {
int nof_layers = 1;
for (; nof_layers <= q->nof_rx_antennas; nof_layers++ ) {
if (sinr[nof_layers - 1] && pmi) {
if (srslte_precoding_pmi_select(ce, nof_ce, noise_estimate, nof_layers, &pmi[nof_layers - 1],
sinr[nof_layers - 1]) < 0) {
@ -723,6 +724,16 @@ int srslte_pdsch_pmi_select(srslte_pdsch_t *q,
}
}
}
/* FIXME: Set other layers to 0 */
for (; nof_layers <= SRSLTE_MAX_LAYERS; nof_layers++ ) {
if (sinr[nof_layers - 1] && pmi) {
for (int cb = 0; cb < SRSLTE_MAX_CODEBOOKS; cb++) {
sinr[nof_layers - 1][cb] = -INFINITY;
}
pmi[nof_layers - 1] = 0;
}
}
} else {
ERROR("Not implemented configuration");
return SRSLTE_ERROR_INVALID_INPUTS;

View File

@ -115,7 +115,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q,
}
srslte_cfo_set_tol(&q->sfo_correct, 1e-5f/q->fft.symbol_sz);
for (int j=0;j<nof_rx_antennas;j++) {
for (int j = 0; j < SRSLTE_MAX_PORTS; j++) {
q->sf_symbols_m[j] = srslte_vec_malloc(MAX_SFLEN_RE * sizeof(cf_t));
if (!q->sf_symbols_m[j]) {
perror("malloc");
@ -127,6 +127,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q,
perror("malloc");
goto clean_exit;
}
bzero(q->ce_m[i][j], MAX_SFLEN_RE * sizeof(cf_t));
}
}
@ -163,7 +164,7 @@ void srslte_ue_dl_free(srslte_ue_dl_t *q) {
free(q->softbuffers[i]);
}
}
for (int j=0;j<q->nof_rx_antennas;j++) {
for (int j = 0; j < SRSLTE_MAX_PORTS; j++) {
if (q->sf_symbols_m[j]) {
free(q->sf_symbols_m[j]);
}
@ -516,10 +517,10 @@ int srslte_ue_dl_ri_pmi_select(srslte_ue_dl_t *q, uint8_t *ri, uint8_t *pmi, flo
float best_sinr = -INFINITY;
uint8_t best_pmi = 0, best_ri = 0;
if (q->cell.nof_ports < 2 || q->nof_rx_antennas < 2) {
if (q->cell.nof_ports < 2) {
/* Do nothing */
return SRSLTE_SUCCESS;
} else if (q->cell.nof_ports == 2 && q->nof_rx_antennas == 2) {
} else {
if (srslte_pdsch_pmi_select(&q->pdsch, &q->pdsch_cfg, q->ce_m, noise_estimate,
SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp), q->pmi, q->sinr)) {
ERROR("SINR calculation error");
@ -527,7 +528,7 @@ int srslte_ue_dl_ri_pmi_select(srslte_ue_dl_t *q, uint8_t *ri, uint8_t *pmi, flo
}
/* Select the best Rank indicator (RI) and Precoding Matrix Indicator (PMI) */
for (uint32_t nof_layers = 1; nof_layers <= 2; nof_layers++) {
for (uint32_t nof_layers = 1; nof_layers <= SRSLTE_MAX_LAYERS; nof_layers++) {
float _sinr = q->sinr[nof_layers - 1][q->pmi[nof_layers - 1]] * nof_layers * nof_layers;
if (_sinr > best_sinr + 0.1) {
best_sinr = _sinr;
@ -535,37 +536,34 @@ int srslte_ue_dl_ri_pmi_select(srslte_ue_dl_t *q, uint8_t *ri, uint8_t *pmi, flo
best_ri = (uint8_t) (nof_layers - 1);
}
}
}
/* Set RI */
if (ri != NULL) {
*ri = best_ri;
}
/* Print Trace */
if (ri != NULL && pmi != NULL && current_sinr != NULL) {
INFO("PDSCH Select RI=%d; PMI=%d; Current SINR=%.1fdB (nof_layers=%d, codebook_idx=%d)\n", *ri, *pmi,
10*log10(*current_sinr), q->pdsch_cfg.nof_layers, q->pdsch_cfg.codebook_idx);
}
/* Set PMI */
if (pmi != NULL) {
*pmi = best_pmi;
}
/* Set RI */
if (ri != NULL) {
*ri = best_ri;
}
/* Set current SINR */
if (current_sinr != NULL && q->pdsch_cfg.mimo_type == SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX) {
if (q->pdsch_cfg.nof_layers == 1) {
*current_sinr = q->sinr[0][q->pdsch_cfg.codebook_idx];
} else if (q->pdsch_cfg.nof_layers == 2) {
*current_sinr = q->sinr[1][q->pdsch_cfg.codebook_idx - 1];
} else {
ERROR("Not implemented number of layers (%d)", q->pdsch_cfg.nof_layers);
return SRSLTE_ERROR;
}
}
/* Set PMI */
if (pmi != NULL) {
*pmi = best_pmi;
}
/* Print Trace */
if (ri != NULL && pmi != NULL && current_sinr != NULL) {
INFO("PDSCH Select RI=%d; PMI=%d; Current SINR=%.1fdB (nof_layers=%d, codebook_idx=%d)\n", *ri, *pmi,
10*log10(*current_sinr), q->pdsch_cfg.nof_layers, q->pdsch_cfg.codebook_idx);
/* Set current SINR */
if (current_sinr != NULL && q->pdsch_cfg.mimo_type == SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX) {
if (q->pdsch_cfg.nof_layers == 1) {
*current_sinr = q->sinr[0][q->pdsch_cfg.codebook_idx];
} else if (q->pdsch_cfg.nof_layers == 2) {
*current_sinr = q->sinr[1][q->pdsch_cfg.codebook_idx - 1];
} else {
ERROR("Not implemented number of layers (%d)", q->pdsch_cfg.nof_layers);
return SRSLTE_ERROR;
}
} else {
ERROR("Not implemented configuration");
return SRSLTE_ERROR_INVALID_INPUTS;
}
return SRSLTE_SUCCESS;

View File

@ -255,9 +255,17 @@ void phch_worker::work_imp()
/* Select Rank Indicator by computing Condition Number */
if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_3) {
float cn = 0.0f;
srslte_ue_dl_ri_select(&ue_dl, &uci_data.uci_ri, &cn);
uci_data.uci_ri_len = 1;
if (ue_dl.nof_rx_antennas > 1) {
/* If 2 ort more receiving antennas, select RI */
float cn = 0.0f;
srslte_ue_dl_ri_select(&ue_dl, &uci_data.uci_ri, &cn);
uci_data.uci_ri_len = 1;
} else {
/* If only one receiving antenna, force RI for 1 layer */
uci_data.uci_ri = 0;
uci_data.uci_ri_len = 1;
Warning("Only one receiving antenna with TM3. Forcing RI=1 layer.\n");
}
} else if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4){
float sinr = 0.0f;
uint8 packed_pmi = 0;
@ -271,6 +279,11 @@ void phch_worker::work_imp()
uci_data.uci_pmi_len = 1;
uci_data.uci_dif_cqi_len = 3;
}
/* If only one antenna in TM4 print limitation warning */
if (ue_dl.nof_rx_antennas < 2) {
Warning("Only one receiving antenna with TM4. Forcing RI=1 layer (PMI=%d).\n", packed_pmi);
}
}
}
}
@ -508,20 +521,22 @@ int phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSL
case LIBLTE_RRC_TRANSMISSION_MODE_3:
if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 1) {
mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
} else if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 2) {
} else if (ue_dl.nof_rx_antennas > 1 && 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", SRSLTE_RA_DL_GRANT_NOF_TB(grant));
Error("Wrong combination of antennas (%d) or transport blocks (%d) for TM3\n", ue_dl.nof_rx_antennas,
SRSLTE_RA_DL_GRANT_NOF_TB(grant));
valid_config = false;
}
break;
case LIBLTE_RRC_TRANSMISSION_MODE_4:
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 (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 2) {
} else if (ue_dl.nof_rx_antennas > 1 && 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", SRSLTE_RA_DL_GRANT_NOF_TB(grant));
Error("Wrong combination of antennas (%d) or transport blocks (%d) for TM3\n", ue_dl.nof_rx_antennas,
SRSLTE_RA_DL_GRANT_NOF_TB(grant));
valid_config = false;
}
break;
@ -923,12 +938,14 @@ void phch_worker::encode_pucch()
float tx_power = srslte_ue_ul_pucch_power(&ue_ul, phy->pathloss, ue_ul.last_pucch_format, uci_data.uci_cqi_len, uci_data.uci_ack_len);
float gain = set_power(tx_power);
Info("PUCCH: power=%.2f dBm, tti_tx=%d, n_cce=%3d, n_pucch=%d, n_prb=%d, ack=%s%s, ri=%s, sr=%s, cfo=%.1f Hz%s\n",
Info("PUCCH: power=%.2f dBm, tti_tx=%d, n_cce=%3d, n_pucch=%d, n_prb=%d, ack=%s%s, ri=%s, pmi=%s%s, sr=%s, cfo=%.1f Hz%s\n",
tx_power, (tti+4)%10240,
last_dl_pdcch_ncce, ue_ul.pucch.last_n_pucch, ue_ul.pucch.last_n_prb,
uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",
uci_data.uci_ack_len>1?(uci_data.uci_ack_2?"1":"0"):"",
uci_data.uci_ri_len>0?(uci_data.uci_ri?"1":"0"):"no",
uci_data.uci_pmi_len>0?(uci_data.uci_pmi[1]?"1":"0"):"no",
uci_data.uci_pmi_len>0?(uci_data.uci_pmi[0]?"1":"0"):"",
uci_data.scheduling_request?"yes":"no",
cfo*15000, timestr);
}