fixed PUCCH correlation estimator

This commit is contained in:
Ismael Gomez 2017-08-24 15:16:13 +02:00
parent dea557f345
commit 616e18c570
7 changed files with 43 additions and 22 deletions

View File

@ -108,7 +108,6 @@ typedef struct SRSLTE_API {
bool group_hopping_en; bool group_hopping_en;
float threshold_format1; float threshold_format1;
float threshold_format1a;
float last_corr; float last_corr;
uint32_t last_n_prb; uint32_t last_n_prb;
uint32_t last_n_pucch; uint32_t last_n_pucch;
@ -125,9 +124,8 @@ SRSLTE_API bool srslte_pucch_set_cfg(srslte_pucch_t* q,
srslte_pucch_cfg_t* cfg, srslte_pucch_cfg_t* cfg,
bool group_hopping_en); bool group_hopping_en);
SRSLTE_API void srslte_pucch_set_threshold(srslte_pucch_t *q, SRSLTE_API void srslte_pucch_set_threshold(srslte_pucch_t *q,
float format1, float format1_threshold);
float format1a);
SRSLTE_API int srslte_pucch_set_crnti(srslte_pucch_t *q, SRSLTE_API int srslte_pucch_set_crnti(srslte_pucch_t *q,
uint16_t c_rnti); uint16_t c_rnti);

View File

@ -152,6 +152,9 @@ SRSLTE_API void srslte_vec_conj_cc(cf_t *x, cf_t *y, uint32_t len);
/* average vector power */ /* average vector power */
SRSLTE_API float srslte_vec_avg_power_cf(cf_t *x, uint32_t len); SRSLTE_API float srslte_vec_avg_power_cf(cf_t *x, uint32_t len);
/* Correlation between complex vectors x and y */
SRSLTE_API float srslte_vec_corr_ccc(cf_t *x, cf_t *y, uint32_t len);
/* return the index of the maximum value in the vector */ /* return the index of the maximum value in the vector */
SRSLTE_API uint32_t srslte_vec_max_fi(float *x, uint32_t len); SRSLTE_API uint32_t srslte_vec_max_fi(float *x, uint32_t len);
SRSLTE_API uint32_t srslte_vec_max_abs_ci(cf_t *x, uint32_t len); SRSLTE_API uint32_t srslte_vec_max_abs_ci(cf_t *x, uint32_t len);

View File

@ -91,7 +91,7 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell,
srslte_prach_set_detect_factor(&q->prach, 60); srslte_prach_set_detect_factor(&q->prach, 60);
} }
srslte_pucch_set_threshold(&q->pucch, 0.5, 0.5); srslte_pucch_set_threshold(&q->pucch, 0.8);
if (srslte_chest_ul_init(&q->chest, cell)) { if (srslte_chest_ul_init(&q->chest, cell)) {
fprintf(stderr, "Error initiating channel estimator\n"); fprintf(stderr, "Error initiating channel estimator\n");

View File

@ -214,15 +214,15 @@ uint32_t srslte_pucch_get_npucch(uint32_t n_cce, srslte_pucch_format_t format, b
{ {
uint32_t n_pucch = 0; uint32_t n_pucch = 0;
if (has_scheduling_request) { if (has_scheduling_request) {
n_pucch = pucch_sched->n_pucch_sr; n_pucch = pucch_sched->n_pucch_sr;
} else if (format < SRSLTE_PUCCH_FORMAT_2) { } else if (format < SRSLTE_PUCCH_FORMAT_2) {
if (pucch_sched->sps_enabled) { if (pucch_sched->sps_enabled) {
n_pucch = pucch_sched->n_pucch_1[pucch_sched->tpc_for_pucch%4]; n_pucch = pucch_sched->n_pucch_1[pucch_sched->tpc_for_pucch%4];
} else { } else {
n_pucch = n_cce + pucch_sched->N_pucch_1; n_pucch = n_cce + pucch_sched->N_pucch_1;
} }
} else { } else {
n_pucch = pucch_sched->n_pucch_2; n_pucch = pucch_sched->n_pucch_2;
} }
return n_pucch; return n_pucch;
} }
@ -411,9 +411,8 @@ static int pucch_get(srslte_pucch_t *q, srslte_pucch_format_t format, uint32_t n
return pucch_cp(q, format, n_pucch, input, z, true); return pucch_cp(q, format, n_pucch, input, z, true);
} }
void srslte_pucch_set_threshold(srslte_pucch_t *q, float format1, float format1a) { void srslte_pucch_set_threshold(srslte_pucch_t *q, float format1_threshold) {
q->threshold_format1 = format1; q->threshold_format1 = format1_threshold;
q->threshold_format1a = format1a;
} }
/** Initializes the PDCCH transmitter and receiver */ /** Initializes the PDCCH transmitter and receiver */
@ -452,6 +451,8 @@ int srslte_pucch_init(srslte_pucch_t *q, srslte_cell_t cell) {
q->z_tmp = srslte_vec_malloc(sizeof(cf_t)*SRSLTE_PUCCH_MAX_SYMBOLS); q->z_tmp = srslte_vec_malloc(sizeof(cf_t)*SRSLTE_PUCCH_MAX_SYMBOLS);
q->ce = srslte_vec_malloc(sizeof(cf_t)*SRSLTE_PUCCH_MAX_SYMBOLS); q->ce = srslte_vec_malloc(sizeof(cf_t)*SRSLTE_PUCCH_MAX_SYMBOLS);
q->threshold_format1 = 0.8;
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
} }
return ret; return ret;
@ -612,6 +613,10 @@ static int uci_mod_bits(srslte_pucch_t *q, srslte_pucch_format_t format, uint8_t
// Declare this here, since we can not include refsignal_ul.h // Declare this here, since we can not include refsignal_ul.h
void srslte_refsignal_r_uv_arg_1prb(float *arg, uint32_t u); void srslte_refsignal_r_uv_arg_1prb(float *arg, uint32_t u);
float tmp_alpha;
uint32_t tmp_noc, tmp_nprime, tmp_woc;
static int pucch_encode_(srslte_pucch_t* q, srslte_pucch_format_t format, static int pucch_encode_(srslte_pucch_t* q, srslte_pucch_format_t format,
uint32_t n_pucch, uint32_t sf_idx, uint16_t rnti, uint32_t n_pucch, uint32_t sf_idx, uint16_t rnti,
uint8_t bits[SRSLTE_PUCCH_MAX_BITS], cf_t z[SRSLTE_PUCCH_MAX_SYMBOLS], bool signal_only) uint8_t bits[SRSLTE_PUCCH_MAX_BITS], cf_t z[SRSLTE_PUCCH_MAX_SYMBOLS], bool signal_only)
@ -655,8 +660,14 @@ static int pucch_encode_(srslte_pucch_t* q, srslte_pucch_format_t format,
if (n_prime_ns%2) { if (n_prime_ns%2) {
S_ns = M_PI/2; S_ns = M_PI/2;
} }
DEBUG("PUCCH d_0: %.1f+%.1fi, alpha: %.1f, n_oc: %d, n_prime_ns: %d, n_rb_2=%d\n", DEBUG("PUCCH d_0: %.1f+%.1fi, alpha: %.1f, n_oc: %d, n_prime_ns: %d, n_rb_2=%d\n",
__real__ q->d[0], __imag__ q->d[0], alpha, n_oc, n_prime_ns, q->pucch_cfg.n_rb_2); __real__ q->d[0], __imag__ q->d[0], alpha, n_oc, n_prime_ns, q->pucch_cfg.n_rb_2);
tmp_alpha = alpha;
tmp_noc = n_oc;
tmp_nprime = n_prime_ns;
tmp_woc = w_n_oc[N_sf_widx][n_oc%3][m];
for (uint32_t n=0;n<SRSLTE_PUCCH_N_SEQ;n++) { for (uint32_t n=0;n<SRSLTE_PUCCH_N_SEQ;n++) {
z[(ns%2)*N_sf_0*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] = z[(ns%2)*N_sf_0*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] =
q->d[0]*cexpf(I*(w_n_oc[N_sf_widx][n_oc%3][m]+q->tmp_arg[n]+alpha*n+S_ns)); q->d[0]*cexpf(I*(w_n_oc[N_sf_widx][n_oc%3][m]+q->tmp_arg[n]+alpha*n+S_ns));
@ -767,7 +778,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format,
case SRSLTE_PUCCH_FORMAT_1: case SRSLTE_PUCCH_FORMAT_1:
bzero(bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t)); bzero(bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t));
pucch_encode(q, format, n_pucch, sf_idx, rnti, bits, q->z_tmp); pucch_encode(q, format, n_pucch, sf_idx, rnti, bits, q->z_tmp);
corr = crealf(srslte_vec_dot_prod_conj_ccc(q->z, q->z_tmp, nof_re))/nof_re; corr = srslte_vec_corr_ccc(q->z, q->z_tmp, nof_re);
if (corr >= q->threshold_format1) { if (corr >= q->threshold_format1) {
ret = 1; ret = 1;
} else { } else {
@ -778,11 +789,11 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format,
break; break;
case SRSLTE_PUCCH_FORMAT_1A: case SRSLTE_PUCCH_FORMAT_1A:
bzero(bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t)); bzero(bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t));
ret = 0; ret = 0;
for (int b=0;b<2;b++) { for (int b=0;b<2;b++) {
bits[0] = b; bits[0] = b;
pucch_encode(q, format, n_pucch, sf_idx, rnti, bits, q->z_tmp); pucch_encode(q, format, n_pucch, sf_idx, rnti, bits, q->z_tmp);
corr = crealf(srslte_vec_dot_prod_conj_ccc(q->z, q->z_tmp, nof_re))/nof_re; corr = srslte_vec_corr_ccc(q->z, q->z_tmp, nof_re);
if (corr > corr_max) { if (corr > corr_max) {
corr_max = corr; corr_max = corr;
b_max = b; b_max = b;
@ -790,7 +801,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format,
if (corr_max > q->threshold_format1) { // check with format1 in case ack+sr because ack only is binary if (corr_max > q->threshold_format1) { // check with format1 in case ack+sr because ack only is binary
ret = 1; ret = 1;
} }
DEBUG("format1a b=%d, corr=%f, nof_re=%d, th=%f\n", b, corr, nof_re, q->threshold_format1a); DEBUG("format1a b=%d, corr=%f, nof_re=%d\n", b, corr, nof_re);
} }
q->last_corr = corr_max; q->last_corr = corr_max;
bits[0] = b_max; bits[0] = b_max;

View File

@ -681,6 +681,15 @@ float srslte_vec_avg_power_cf(cf_t *x, uint32_t len) {
return crealf(srslte_vec_dot_prod_conj_ccc(x,x,len)) / len; return crealf(srslte_vec_dot_prod_conj_ccc(x,x,len)) / len;
} }
// Correlation assumes zero-mean x and y
float srslte_vec_corr_ccc(cf_t *x, cf_t *y, uint32_t len) {
// return crealf(srslte_vec_dot_prod_conj_ccc(x,y,len)) / len;
float s_x = crealf(srslte_vec_dot_prod_conj_ccc(x, x, len))/len;
float s_y = crealf(srslte_vec_dot_prod_conj_ccc(y, y, len))/len;
float cov = crealf(srslte_vec_dot_prod_conj_ccc(x, y, len))/len;
return cov/(sqrt(s_x*s_y));
}
void srslte_vec_abs_cf(cf_t *x, float *abs, uint32_t len) { void srslte_vec_abs_cf(cf_t *x, float *abs, uint32_t len) {
#ifndef HAVE_VOLK_MAG_FUNCTION #ifndef HAVE_VOLK_MAG_FUNCTION
int i; int i;

View File

@ -248,12 +248,12 @@ bool ue::process_ce(srslte::sch_subh *subh) {
idx = subh->get_bsr(buff_size); idx = subh->get_bsr(buff_size);
if (idx > 0) { if (idx > 0) {
// Indicate BSR to scheduler // Indicate BSR to scheduler
sched->ul_bsr(rnti, idx, buff_size[idx]); sched->ul_bsr(rnti, idx, 2*buff_size[idx]);
Info("CE: Received BSR rnti=0x%x, lcid=%d, value=%d\n", rnti, idx, buff_size[idx]); Info("CE: Received BSR rnti=0x%x, lcid=%d, value=%d\n", rnti, idx, buff_size[idx]);
} else if (idx == 0) { } else if (idx == 0) {
// TODO: map lcid group to lcid // TODO: map lcid group to lcid
for (int i=0;i<4;i++) { for (int i=0;i<4;i++) {
sched->ul_bsr(rnti, i, buff_size[i]); sched->ul_bsr(rnti, i, 2*buff_size[i]);
} }
Info("CE: Received Long BSR rnti=0x%x, value=%d,%d,%d,%d\n", rnti, Info("CE: Received Long BSR rnti=0x%x, value=%d,%d,%d,%d\n", rnti,
buff_size[0], buff_size[1], buff_size[2], buff_size[3]); buff_size[0], buff_size[1], buff_size[2], buff_size[3]);

View File

@ -109,7 +109,7 @@ void phch_worker::init(phch_common* phy_, srslte::log *log_h_)
return; return;
} }
srslte_pucch_set_threshold(&enb_ul.pucch, 0.5, 0.5); srslte_pucch_set_threshold(&enb_ul.pucch, 0.8);
srslte_sch_set_max_noi(&enb_ul.pusch.ul_sch, phy->params.pusch_max_its); srslte_sch_set_max_noi(&enb_ul.pusch.ul_sch, phy->params.pusch_max_its);
srslte_enb_dl_set_amp(&enb_dl, phy->params.tx_amplitude); srslte_enb_dl_set_amp(&enb_dl, phy->params.tx_amplitude);
@ -178,8 +178,8 @@ void phch_worker::set_config_dedicated(uint16_t rnti,
srslte_enb_ul_cfg_ue(&enb_ul, rnti, uci_cfg, pucch_sched, srs_cfg); srslte_enb_ul_cfg_ue(&enb_ul, rnti, uci_cfg, pucch_sched, srs_cfg);
ue_db[rnti].I_sr = I_sr; ue_db[rnti].I_sr = I_sr;
ue_db[rnti].I_sr_en = true; ue_db[rnti].I_sr_en = true;
if (pucch_cqi) { if (pucch_cqi) {
ue_db[rnti].pmi_idx = pmi_idx; ue_db[rnti].pmi_idx = pmi_idx;
ue_db[rnti].cqi_en = true; ue_db[rnti].cqi_en = true;