Limit uplink signal normalization to avoid clipping

master
Ismael Gomez 6 years ago
parent 91e1b27219
commit e18ba937dc

@ -98,8 +98,10 @@ typedef struct SRSLTE_API {
cf_t *refsignal;
cf_t *srs_signal;
cf_t *sf_symbols;
cf_t *sf_symbols;
float last_amplitude;
uint16_t current_rnti;
bool signals_pregenerated;
}srslte_ue_ul_t;
@ -126,7 +128,9 @@ SRSLTE_API void srslte_ue_ul_set_cfo_enable(srslte_ue_ul_t *q,
bool enabled);
SRSLTE_API void srslte_ue_ul_set_normalization(srslte_ue_ul_t *q,
bool enabled);
bool enabled);
SRSLTE_API float srslte_ue_ul_get_last_amplitude(srslte_ue_ul_t *q);
SRSLTE_API void srslte_ue_ul_set_cfg(srslte_ue_ul_t *q,
srslte_refsignal_dmrs_pusch_cfg_t *dmrs_cfg,

@ -138,6 +138,7 @@ SRSLTE_API float srslte_vec_corr_ccc(const cf_t *x, cf_t *y, const uint32_t len)
/* return the index of the maximum value in the vector */
SRSLTE_API uint32_t srslte_vec_max_fi(const float *x, const uint32_t len);
SRSLTE_API uint32_t srslte_vec_max_abs_fi(const float *x, const uint32_t len);
SRSLTE_API uint32_t srslte_vec_max_abs_ci(const cf_t *x, const uint32_t len);
/* quantify vector of floats or int16 and convert to uint8_t */

@ -294,6 +294,25 @@ void pucch_encode_bits(srslte_uci_data_t *uci_data, srslte_pucch_format_t format
}
}
static float limit_norm_factor(srslte_ue_ul_t *q, float norm_factor, cf_t *output_signal)
{
uint32_t p = srslte_vec_max_abs_fi((float*) output_signal, 2*SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
float amp = fabsf(*((float*) output_signal + p));
if (amp*norm_factor > 0.95) {
norm_factor = 0.95/amp;
}
if (amp*norm_factor < 0.1) {
norm_factor = 0.1/amp;
}
q->last_amplitude = norm_factor*amp;
return norm_factor;
}
float srslte_ue_ul_get_last_amplitude(srslte_ue_ul_t *q) {
return q->last_amplitude;
}
/* Choose PUCCH format as in Sec 10.1 of 36.213 and generate PUCCH signal
*/
int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
@ -353,7 +372,10 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
}
if (q->normalize_en) {
float norm_factor = (float) q->cell.nof_prb/15/10;
float norm_factor = (float) q->cell.nof_prb/15/40;
norm_factor = limit_norm_factor(q, norm_factor, output_signal);
srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
}
ret = SRSLTE_SUCCESS;
@ -424,6 +446,9 @@ int srslte_ue_ul_srs_encode(srslte_ue_ul_t *q, uint32_t tti, cf_t *output_signal
if (q->normalize_en) {
float norm_factor = (float) q->cell.nof_prb/15/sqrtf(srslte_refsignal_srs_M_sc(&q->signals));
norm_factor = limit_norm_factor(q, norm_factor, output_signal);
srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
}
@ -491,7 +516,10 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q,
}
if (q->normalize_en) {
float norm_factor = (float) q->cell.nof_prb/15/sqrtf(q->pusch_cfg.grant.L_prb);
float norm_factor = (float) q->cell.nof_prb/15/sqrtf(q->pusch_cfg.grant.L_prb)/2;
norm_factor = limit_norm_factor(q, norm_factor, output_signal);
srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
}

@ -368,6 +368,10 @@ uint32_t srslte_vec_max_fi(const float *x, const uint32_t len) {
return srslte_vec_max_fi_simd(x, len);
}
uint32_t srslte_vec_max_abs_fi(const float *x, const uint32_t len) {
return srslte_vec_max_fi_simd(x, len);
}
// CP autocorr
uint32_t srslte_vec_max_abs_ci(const cf_t *x, const uint32_t len) {
return srslte_vec_max_ci_simd(x, len);

@ -1296,8 +1296,8 @@ void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, ui
uint8_t dummy[2] = {0,0};
log_h->info_hex(payload, grant->mcs.tbs/8,
"PUSCH: tti_tx=%d, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s\n",
(tti + HARQ_DELAY_MS) % 10240,
"PUSCH: tti_tx=%d, amp=%.2f, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s\n",
(tti + HARQ_DELAY_MS) % 10240, srslte_ue_ul_get_last_amplitude(&ue_ul),
grant->n_prb[0], grant->n_prb[0] + grant->L_prb,
grant->mcs.tbs / 8, grant->mcs.idx, rv,
uci_data.uci_ack_len > 0 ? (uci_data.uci_ack ? ", ack=1" : ", ack=0") : "",
@ -1350,8 +1350,8 @@ void phch_worker::encode_pucch()
srslte_cqi_value_tostring(&cqi_report, cqi_str, SRSLTE_CQI_STR_MAX_CHAR);
}
Info("PUCCH: tti_tx=%d, n_pucch=%d, n_prb=%d, ack=%s%s%s%s, sr=%s, cfo=%.1f KHz%s\n",
(tti + 4) % 10240,
Info("PUCCH: tti_tx=%d, amp=%.2f, n_pucch=%d, n_prb=%d, ack=%s%s%s%s, sr=%s, cfo=%.1f KHz%s\n",
(tti + 4) % 10240, srslte_ue_ul_get_last_amplitude(&ue_ul),
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") : "",
@ -1384,7 +1384,8 @@ void phch_worker::encode_srs()
float tx_power = srslte_ue_ul_srs_power(&ue_ul, phy->pathloss);
float gain = set_power(tx_power);
Info("SRS: power=%.2f dBm, tti_tx=%d%s\n", tx_power, TTI_TX(tti), timestr);
Info("SRS: power=%.2f dBm, amp=%.2f, tti_tx=%d%s\n", tx_power, srslte_ue_ul_get_last_amplitude(&ue_ul), TTI_TX(tti), timestr);
}
void phch_worker::enable_pregen_signals(bool enabled)

Loading…
Cancel
Save