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, int nof_rxant, int nof_ports, int nof_layers, int codebook_idx, int nof_symbols,
float noise_estimate) float noise_estimate)
{ {
if (nof_ports == 2 && nof_rxant == 2) { if (nof_ports == 2 && nof_rxant <= 2) {
if (nof_layers == 2) { if (nof_layers == 2) {
switch (mimo_decoder) { switch (mimo_decoder) {
case SRSLTE_MIMO_DECODER_ZF: 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) { } else if (nof_ports == 4) {
ERROR("Error predecoding multiplex: not implemented for %d Tx ports", nof_ports); ERROR("Error predecoding multiplex: not implemented for %d Tx ports", nof_ports);
} else { } 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; 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; goto clean;
} }
if (q->is_ue) { 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); q->ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
if (!q->ce[i][j]) { if (!q->ce[i][j]) {
goto clean; goto clean;
@ -309,7 +309,7 @@ void srslte_pdsch_free(srslte_pdsch_t *q) {
free(q->symbols[i]); free(q->symbols[i]);
} }
if (q->is_ue) { 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]) { if (q->ce[i][j]) {
free(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, 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]) { 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) { if (q->cell.nof_ports == 2 && q->nof_rx_antennas <= 2) {
for (int nof_layers = 1; nof_layers <= 2; nof_layers++ ) { int nof_layers = 1;
for (; nof_layers <= q->nof_rx_antennas; nof_layers++ ) {
if (sinr[nof_layers - 1] && pmi) { if (sinr[nof_layers - 1] && pmi) {
if (srslte_precoding_pmi_select(ce, nof_ce, noise_estimate, nof_layers, &pmi[nof_layers - 1], if (srslte_precoding_pmi_select(ce, nof_ce, noise_estimate, nof_layers, &pmi[nof_layers - 1],
sinr[nof_layers - 1]) < 0) { 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 { } else {
ERROR("Not implemented configuration"); ERROR("Not implemented configuration");
return SRSLTE_ERROR_INVALID_INPUTS; 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); 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)); q->sf_symbols_m[j] = srslte_vec_malloc(MAX_SFLEN_RE * sizeof(cf_t));
if (!q->sf_symbols_m[j]) { if (!q->sf_symbols_m[j]) {
perror("malloc"); perror("malloc");
@ -127,6 +127,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q,
perror("malloc"); perror("malloc");
goto clean_exit; 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]); 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]) { if (q->sf_symbols_m[j]) {
free(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; float best_sinr = -INFINITY;
uint8_t best_pmi = 0, best_ri = 0; 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 */ /* Do nothing */
return SRSLTE_SUCCESS; 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, 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)) { SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp), q->pmi, q->sinr)) {
ERROR("SINR calculation error"); 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) */ /* 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; float _sinr = q->sinr[nof_layers - 1][q->pmi[nof_layers - 1]] * nof_layers * nof_layers;
if (_sinr > best_sinr + 0.1) { if (_sinr > best_sinr + 0.1) {
best_sinr = _sinr; 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); best_ri = (uint8_t) (nof_layers - 1);
} }
} }
}
/* Set RI */ /* Print Trace */
if (ri != NULL) { if (ri != NULL && pmi != NULL && current_sinr != NULL) {
*ri = best_ri; 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 */ /* Set RI */
if (pmi != NULL) { if (ri != NULL) {
*pmi = best_pmi; *ri = best_ri;
} }
/* Set current SINR */ /* Set PMI */
if (current_sinr != NULL && q->pdsch_cfg.mimo_type == SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX) { if (pmi != NULL) {
if (q->pdsch_cfg.nof_layers == 1) { *pmi = best_pmi;
*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;
}
}
/* Print Trace */ /* Set current SINR */
if (ri != NULL && pmi != NULL && current_sinr != NULL) { if (current_sinr != NULL && q->pdsch_cfg.mimo_type == SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX) {
INFO("PDSCH Select RI=%d; PMI=%d; Current SINR=%.1fdB (nof_layers=%d, codebook_idx=%d)\n", *ri, *pmi, if (q->pdsch_cfg.nof_layers == 1) {
10*log10(*current_sinr), q->pdsch_cfg.nof_layers, q->pdsch_cfg.codebook_idx); *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; return SRSLTE_SUCCESS;

View File

@ -255,9 +255,17 @@ void phch_worker::work_imp()
/* Select Rank Indicator by computing Condition Number */ /* Select Rank Indicator by computing Condition Number */
if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_3) { if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_3) {
float cn = 0.0f; if (ue_dl.nof_rx_antennas > 1) {
srslte_ue_dl_ri_select(&ue_dl, &uci_data.uci_ri, &cn); /* If 2 ort more receiving antennas, select RI */
uci_data.uci_ri_len = 1; 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){ } else if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4){
float sinr = 0.0f; float sinr = 0.0f;
uint8 packed_pmi = 0; uint8 packed_pmi = 0;
@ -271,6 +279,11 @@ void phch_worker::work_imp()
uci_data.uci_pmi_len = 1; uci_data.uci_pmi_len = 1;
uci_data.uci_dif_cqi_len = 3; 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: case LIBLTE_RRC_TRANSMISSION_MODE_3:
if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 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 (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; mimo_type = SRSLTE_MIMO_TYPE_CDD;
} else { } 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; valid_config = false;
} }
break; break;
case LIBLTE_RRC_TRANSMISSION_MODE_4: case LIBLTE_RRC_TRANSMISSION_MODE_4:
if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 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 (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; mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
} else { } 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; valid_config = false;
} }
break; 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 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); 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, tx_power, (tti+4)%10240,
last_dl_pdcch_ncce, ue_ul.pucch.last_n_pucch, ue_ul.pucch.last_n_prb, 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>0?(uci_data.uci_ack?"1":"0"):"no",
uci_data.uci_ack_len>1?(uci_data.uci_ack_2?"1":"0"):"", 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_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", uci_data.scheduling_request?"yes":"no",
cfo*15000, timestr); cfo*15000, timestr);
} }