Added Time-domain EMA filter for channel estimation

master
ismagom 10 years ago
parent f475069033
commit 5d122ee44f

@ -478,8 +478,9 @@ int main(int argc, char **argv) {
#ifdef PRINT_CHANGE_SCHEDULIGN #ifdef PRINT_CHANGE_SCHEDULIGN
if (ue_dl.dl_dci.mcs_idx != old_dl_dci.mcs_idx || if (ue_dl.dl_dci.mcs_idx != old_dl_dci.mcs_idx ||
ue_dl.dl_dci.alloc_type != old_dl_dci.alloc_type || memcmp(&ue_dl.dl_dci.type0_alloc, &old_dl_dci.type0_alloc, sizeof(srslte_ra_type0_t)) ||
ue_dl.dl_dci.type2_alloc.riv != ue_dl.dl_dci.type2_alloc.riv) memcmp(&ue_dl.dl_dci.type1_alloc, &old_dl_dci.type1_alloc, sizeof(srslte_ra_type1_t)) ||
memcmp(&ue_dl.dl_dci.type2_alloc, &old_dl_dci.type2_alloc, sizeof(srslte_ra_type2_t)))
{ {
memcpy(&old_dl_dci, &ue_dl.dl_dci, sizeof(srslte_ra_dl_dci_t)); memcpy(&old_dl_dci, &ue_dl.dl_dci, sizeof(srslte_ra_dl_dci_t));
fflush(stdout);printf("\nCFI:\t%d\n", ue_dl.cfi); fflush(stdout);printf("\nCFI:\t%d\n", ue_dl.cfi);
@ -514,15 +515,14 @@ int main(int argc, char **argv) {
if (gain < 0) { if (gain < 0) {
gain = 10*log10(srslte_agc_get_gain(&ue_sync.agc)); gain = 10*log10(srslte_agc_get_gain(&ue_sync.agc));
} }
printf("CFO: %+6.2f KHz, SFO: %+6.2f Khz, " printf("CFO: %+6.2f KHz, "
"RSRP: %+5.1f dBm, SNR: %4.1f dB, " "SNR: %4.1f dB, "
"PDCCH-Miss: %5.2f%%, PDSCH-BLER: %5.2f%% Peak: %.2f Gain: %.1f dB\r", "PDCCH-Miss: %5.2f%%, PDSCH-BLER: %5.2f%%\r",
srslte_ue_sync_get_cfo(&ue_sync)/1000, srslte_ue_sync_get_sfo(&ue_sync)/1000,
10*log10(rsrp*1000)-gain-cuhd_get_rx_gain_offset(uhd), srslte_ue_sync_get_cfo(&ue_sync)/1000,
10*log10(rsrp/noise), 10*log10(rsrp/noise),
100*(1-(float) ue_dl.nof_detected/nof_trials), 100*(1-(float) ue_dl.nof_detected/nof_trials),
(float) 100*ue_dl.pkt_errors/ue_dl.pkts_total, (float) 100*ue_dl.pkt_errors/ue_dl.pkts_total);
srslte_agc_get_output_level(&ue_sync.agc), gain);
} }
break; break;
} }

@ -76,6 +76,7 @@ typedef struct {
float rssi[SRSLTE_MAX_PORTS]; float rssi[SRSLTE_MAX_PORTS];
float rsrp[SRSLTE_MAX_PORTS]; float rsrp[SRSLTE_MAX_PORTS];
float noise_estimate[SRSLTE_MAX_PORTS]; float noise_estimate[SRSLTE_MAX_PORTS];
float filter_time_ema;
} srslte_chest_dl_t; } srslte_chest_dl_t;
@ -92,6 +93,9 @@ SRSLTE_API int srslte_chest_dl_set_filter_time(srslte_chest_dl_t *q,
float *filter, float *filter,
uint32_t filter_len); uint32_t filter_len);
SRSLTE_API void srslte_chest_dl_set_filter_time_ema(srslte_chest_dl_t *q,
float ema_coefficient);
SRSLTE_API int srslte_chest_dl_estimate(srslte_chest_dl_t *q, SRSLTE_API int srslte_chest_dl_estimate(srslte_chest_dl_t *q,
cf_t *input, cf_t *input,
cf_t *ce[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS],

@ -83,6 +83,9 @@ SRSLTE_API void srslte_vec_sum_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len);
SRSLTE_API void srslte_vec_sub_fff(float *x, float *y, float *z, uint32_t len); SRSLTE_API void srslte_vec_sub_fff(float *x, float *y, float *z, uint32_t len);
SRSLTE_API void srslte_vec_sub_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len); SRSLTE_API void srslte_vec_sub_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len);
/* EMA filter: output=coeff*new_data + (1-coeff)*average */
SRSLTE_API void srslte_vec_ema_filter(cf_t *new_data, cf_t *average, cf_t *output, float coeff, uint32_t len);
/* Square distance */ /* Square distance */
SRSLTE_API void srslte_vec_square_dist(cf_t symbol, cf_t *points, float *distance, uint32_t npoints); SRSLTE_API void srslte_vec_square_dist(cf_t symbol, cf_t *points, float *distance, uint32_t npoints);

@ -126,11 +126,10 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, srslte_cell_t cell)
//float f[3]={0.2, 0.6, 0.2}; //float f[3]={0.2, 0.6, 0.2};
//srslte_chest_dl_set_filter_freq(q, f, 3); //srslte_chest_dl_set_filter_freq(q, f, 3);
float f[5]={0.1, 0.2, 0.4, 0.2, 0.1}; float f[9]={0.025, 0.075, 0.05, 0.15, 0.4, 0.15, 0.05, 0.075, 0.025};
srslte_chest_dl_set_filter_freq(q, f, 5); srslte_chest_dl_set_filter_freq(q, f, 9);
float t[2]={0.5, 0.5}; //srslte_chest_dl_set_filter_time_ema(q, 0.8);
srslte_chest_dl_set_filter_time(q, t, 0);
q->cell = cell; q->cell = cell;
} }
@ -191,6 +190,10 @@ int srslte_chest_dl_set_filter_freq(srslte_chest_dl_t *q, float *filter, uint32_
} }
} }
void srslte_chest_dl_set_filter_time_ema(srslte_chest_dl_t *q, float ema_coefficient) {
q->filter_time_ema = ema_coefficient;
}
int srslte_chest_dl_set_filter_time(srslte_chest_dl_t *q, float *filter, uint32_t filter_len) { int srslte_chest_dl_set_filter_time(srslte_chest_dl_t *q, float *filter, uint32_t filter_len) {
if (filter_len <= SRSLTE_CHEST_MAX_FILTER_TIME_LEN) { if (filter_len <= SRSLTE_CHEST_MAX_FILTER_TIME_LEN) {
q->filter_time_len = filter_len; q->filter_time_len = filter_len;
@ -263,31 +266,62 @@ static void average_pilots(srslte_chest_dl_t *q, uint32_t port_id)
q->noise_estimate[port_id] = estimate_noise_port(q, port_id, q->tmp_freqavg); q->noise_estimate[port_id] = estimate_noise_port(q, port_id, q->tmp_freqavg);
#endif #endif
for (l=0;l<srslte_refsignal_cs_nof_symbols(port_id);l++) {
/* Filter in time domain. */ //#define EMA_VEC
if (q->filter_time_len > 0) {
/* Move last symbols */ /* Filter with Exponential moving average (IIR) */
for (i=0;i<q->filter_time_len-1;i++) { if (q->filter_time_ema > 0) {
memcpy(q->tmp_timeavg[i], q->tmp_timeavg[i+1], nref*sizeof(cf_t)); #ifdef EMA_VEC
} srslte_vec_ema_filter(&q->tmp_freqavg[0],
/* Save last symbol to buffer */ &q->pilot_estimates_average[port_id][2*q->cell.nof_prb*srslte_refsignal_cs_nof_symbols(port_id)],
memcpy(q->tmp_timeavg[q->filter_time_len-1], &pilot_tmp(0), nref*sizeof(cf_t)); &q->pilot_estimates_average[port_id][0],
q->filter_time_ema,
/* Multiply all symbols by filter and add them */ nref);
if (l > 0) { for (l=1;l<srslte_refsignal_cs_nof_symbols(port_id);l++) {
bzero(&pilot_avg(0), nref * sizeof(cf_t)); srslte_vec_ema_filter(&q->tmp_freqavg[2*q->cell.nof_prb*l],
for (i=0;i<q->filter_time_len;i++) { &q->pilot_estimates_average[port_id][2*q->cell.nof_prb*(l-1)],
srslte_vec_sc_prod_cfc(q->tmp_timeavg[i], q->filter_time[i], q->tmp_timeavg_mult, nref); &q->pilot_estimates_average[port_id][2*q->cell.nof_prb*l],
srslte_vec_sum_ccc(q->tmp_timeavg_mult, &pilot_avg(0), &pilot_avg(0), nref); q->filter_time_ema,
} nref);
}
#else
for (i=0;i<nref;i++) {
l=0;
pilot_avg(i) = SRSLTE_VEC_EMA(pilot_tmp(i), q->pilot_estimates_average[port_id][
SRSLTE_REFSIGNAL_PILOT_IDX(i,srslte_refsignal_cs_nof_symbols(port_id),q->cell)], q->filter_time_ema);
for (l=1;l<srslte_refsignal_cs_nof_symbols(port_id);l++) {
pilot_avg(i) = SRSLTE_VEC_EMA(pilot_tmp(i), q->pilot_estimates_average[port_id][SRSLTE_REFSIGNAL_PILOT_IDX(i,l-1,q->cell)], q->filter_time_ema);
}
}
#endif
} else {
/* Filter with FIR or don't filter */
for (l=0;l<srslte_refsignal_cs_nof_symbols(port_id);l++) {
/* Filter in time domain. */
if (q->filter_time_len > 0) {
/* Move last symbols */
for (i=0;i<q->filter_time_len-1;i++) {
memcpy(q->tmp_timeavg[i], q->tmp_timeavg[i+1], nref*sizeof(cf_t));
}
/* Save last symbol to buffer */
memcpy(q->tmp_timeavg[q->filter_time_len-1], &pilot_tmp(0), nref*sizeof(cf_t));
/* Multiply all symbols by filter and add them */
if (l > 0) {
bzero(&pilot_avg(0), nref * sizeof(cf_t));
for (i=0;i<q->filter_time_len;i++) {
srslte_vec_sc_prod_cfc(q->tmp_timeavg[i], q->filter_time[i], q->tmp_timeavg_mult, nref);
srslte_vec_sum_ccc(q->tmp_timeavg_mult, &pilot_avg(0), &pilot_avg(0), nref);
}
} else {
memcpy(&pilot_avg(0), &pilot_tmp(0), nref * sizeof(cf_t));
}
} else { } else {
memcpy(&pilot_avg(0), &pilot_tmp(0), nref * sizeof(cf_t)); memcpy(&pilot_avg(0), &pilot_tmp(0), nref * sizeof(cf_t));
} }
} else { }
memcpy(&pilot_avg(0), &pilot_tmp(0), nref * sizeof(cf_t));
}
} }
} }
#define cesymb(i) ce[SRSLTE_RE_IDX(q->cell.nof_prb,i,0)] #define cesymb(i) ce[SRSLTE_RE_IDX(q->cell.nof_prb,i,0)]

@ -38,6 +38,8 @@
#define MAX_CANDIDATES 64 #define MAX_CANDIDATES 64
#define PDSCH_DO_ZF
int srslte_ue_dl_init(srslte_ue_dl_t *q, int srslte_ue_dl_init(srslte_ue_dl_t *q,
srslte_cell_t cell) srslte_cell_t cell)
{ {
@ -225,9 +227,18 @@ int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_
if (q->pdsch_cfg.rv == 0) { if (q->pdsch_cfg.rv == 0) {
srslte_softbuffer_rx_reset(&q->softbuffer); srslte_softbuffer_rx_reset(&q->softbuffer);
} }
#ifdef PDSCH_DO_ZF
float noise_estimate = 0;
#else
float noise_estimate = srslte_chest_dl_get_noise_estimate(&q->chest);
#endif
if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) { if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) {
ret = srslte_pdsch_decode_rnti(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, ret = srslte_pdsch_decode_rnti(&q->pdsch, &q->pdsch_cfg, &q->softbuffer,
q->sf_symbols, q->ce, 0, rnti, data); q->sf_symbols, q->ce,
noise_estimate,
rnti, data);
if (ret == SRSLTE_ERROR) { if (ret == SRSLTE_ERROR) {
q->pkt_errors++; q->pkt_errors++;

@ -62,6 +62,12 @@ float srslte_vec_acc_ff(float *x, uint32_t len) {
#endif #endif
} }
void srslte_vec_ema_filter(cf_t *new_data, cf_t *average, cf_t *output, float coeff, uint32_t len) {
srslte_vec_sc_prod_cfc(new_data, coeff, new_data, len);
srslte_vec_sc_prod_cfc(average, 1-coeff, output, len);
srslte_vec_sum_ccc(output, new_data, output, len);
}
cf_t srslte_vec_acc_cc(cf_t *x, uint32_t len) { cf_t srslte_vec_acc_cc(cf_t *x, uint32_t len) {
int i; int i;
cf_t z=0; cf_t z=0;

Loading…
Cancel
Save