Commit 39a50faa authored by rmagueta's avatar rmagueta Committed by Laurent THOMAS

Delay compensation for PUCCH2

parent f7d3b728
......@@ -138,6 +138,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB;
init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table);
init_delay_table(128, MAX_DELAY_COMP, 128, fp->delay_table128);
gNB->bad_pucch = 0;
if (gNB->TX_AMP == 0)
......
......@@ -53,6 +53,7 @@
#include "SCHED_NR/sched_nr.h"
#include "T.h"
#include "nr_phy_common.h"
//#define DEBUG_NR_PUCCH_RX 1
......@@ -1086,15 +1087,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
pucch2_lev /= Prx * pucch_pdu->nr_of_symbols;
int pucch2_levdB = dB_fixed(pucch2_lev);
int scaling = 0;
if (pucch2_levdB > 72)
scaling = 4;
else if (pucch2_levdB > 66)
scaling = 3;
else if (pucch2_levdB > 60)
scaling = 2;
else if (pucch2_levdB > 54)
scaling = 1;
int scaling = max((log2_approx64(pucch2_lev) >> 1) - 8, 0);
LOG_D(NR_PHY,
"%d.%d Decoding pucch2 for %d symbols, %d PRB, nb_harq %d, nb_sr %d, nb_csi %d/%d, pucch2_lev %d dB (scaling %d)\n",
......@@ -1180,6 +1173,140 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
slot,pucch_pdu->start_symbol_index,symb,pucch_pdu->dmrs_scrambling_id);
#endif
uint32_t *sGold = gold_cache(x2, pucch_pdu->prb_start / 4 + ngroup / 2);
// Compute pilot conjugate
int16_t pil_re16[4 * pucch_pdu->prb_size] __attribute__((aligned(32)));
int16_t pil_im16[4 * pucch_pdu->prb_size] __attribute__((aligned(32)));
simde__m128i m1 = simde_mm_set_epi16(-1, -1, -1, -1, -1, -1, -1, -1);
for (int group = 0, goldIdx = pucch_pdu->prb_start / 4; group < ngroup; group++) {
uint8_t *sGold8 = (uint8_t *)&sGold[goldIdx];
((simde__m64 *)&pil_re16[8 * group])[0] = byte2m64_re[sGold8[(group & 1) << 1]];
((simde__m64 *)&pil_re16[8 * group])[1] = byte2m64_re[sGold8[1 + ((group & 1) << 1)]];
simde__m128i dmrs_im;
((simde__m64 *)&dmrs_im)[0] = byte2m64_im[sGold8[(group & 1) << 1]];
((simde__m64 *)&dmrs_im)[1] = byte2m64_im[sGold8[1 + ((group & 1) << 1)]];
*((simde__m128i *)&pil_im16[8 * group]) = simde_mm_mullo_epi16(dmrs_im, m1);
if ((group & 1) == 1)
goldIdx++;
}
// Compute delay
c16_t ch_ls[128] __attribute__((aligned(32))) = {0};
int prb_size_loop = (pucch_pdu->prb_size >> 1) << 1;
for (int aa = 0; aa < Prx; aa++) {
int prb = 0;
for (; prb < prb_size_loop; prb += 2) {
simde__m128i res_re, res_im;
complex_mult_simd(*(simde__m128i *)&pil_re16[4 * prb],
*(simde__m128i *)&pil_im16[4 * prb],
*(simde__m128i *)&rd_re_ext[aa][symb][4 * prb],
*(simde__m128i *)&rd_im_ext[aa][symb][4 * prb],
&res_re,
&res_im,
0,
0,
0);
int16_t *re = (int16_t *)&res_re;
int16_t *im = (int16_t *)&res_im;
for (int idx = 0; idx < 8; idx++) {
for (int k = 0; k < 3 && 12 * prb + 3 * idx + k < 128; k++) {
ch_ls[12 * prb + 3 * idx + k] = (c16_t){re[idx], im[idx]};
}
}
}
for (; prb < pucch_pdu->prb_size; prb++) {
int16_t *rd_re_ext_p = &rd_re_ext[aa][symb][4 * prb];
int16_t *rd_im_ext_p = &rd_im_ext[aa][symb][4 * prb];
for (int idx = 0; idx < 4; idx++) {
c16_t ch = c16mulShift((c16_t){pil_re16[idx + 4 * prb], pil_im16[idx + 4 * prb]},
(c16_t){rd_re_ext_p[idx], rd_im_ext_p[idx]},
0);
for (int k = 0; k < 3 && 12 * prb + 3 * idx + k < 128; k++) {
ch_ls[12 * prb + 3 * idx + k] = ch;
}
}
}
}
c16_t ch_temp[128] __attribute__((aligned(32))) = {0};
delay_t delay = {0};
nr_est_delay(128, ch_ls, ch_temp, &delay);
int delay_idx = get_delay_idx(delay.est_delay, MAX_DELAY_COMP);
c16_t *delay_table = frame_parms->delay_table128[delay_idx];
// Apply delay compensation
for (int aa = 0; aa < Prx; aa++) {
for (int prb = 0; prb < pucch_pdu->prb_size; prb++) {
int prb12 = 12 * prb;
simde__m128i delay_table_128_re = simde_mm_set_epi16(delay_table[prb12 + 11].r,
delay_table[prb12 + 9].r,
delay_table[prb12 + 8].r,
delay_table[prb12 + 6].r,
delay_table[prb12 + 5].r,
delay_table[prb12 + 3].r,
delay_table[prb12 + 2].r,
delay_table[prb12].r);
simde__m128i delay_table_128_im = simde_mm_set_epi16(delay_table[prb12 + 11].i,
delay_table[prb12 + 9].i,
delay_table[prb12 + 8].i,
delay_table[prb12 + 6].i,
delay_table[prb12 + 5].i,
delay_table[prb12 + 3].i,
delay_table[prb12 + 2].i,
delay_table[prb12].i);
int prb8 = 8 * prb;
complex_mult_simd(*(simde__m128i *)&r_re_ext[aa][symb][prb8],
*(simde__m128i *)&r_im_ext[aa][symb][prb8],
delay_table_128_re,
delay_table_128_im,
(simde__m128i *)&r_re_ext[aa][symb][prb8],
(simde__m128i *)&r_im_ext[aa][symb][prb8],
0,
3,
5);
}
int prb = 0;
for (; prb < prb_size_loop; prb += 2) {
int prb12 = 12 * prb;
simde__m128i delay_table_128_re = simde_mm_set_epi16(delay_table[prb12 + 22].r,
delay_table[prb12 + 19].r,
delay_table[prb12 + 16].r,
delay_table[prb12 + 13].r,
delay_table[prb12 + 10].r,
delay_table[prb12 + 7].r,
delay_table[prb12 + 4].r,
delay_table[prb12 + 1].r);
simde__m128i delay_table_128_im = simde_mm_set_epi16(delay_table[prb12 + 22].i,
delay_table[prb12 + 19].i,
delay_table[prb12 + 16].i,
delay_table[prb12 + 13].i,
delay_table[prb12 + 10].i,
delay_table[prb12 + 7].i,
delay_table[prb12 + 4].i,
delay_table[prb12 + 1].i);
int prb4 = 4 * prb;
complex_mult_simd(*(simde__m128i *)&rd_re_ext[aa][symb][prb4],
*(simde__m128i *)&rd_im_ext[aa][symb][prb4],
delay_table_128_re,
delay_table_128_im,
(simde__m128i *)&rd_re_ext[aa][symb][prb4],
(simde__m128i *)&rd_im_ext[aa][symb][prb4],
0,
3,
5);
}
for (; prb < pucch_pdu->prb_size; prb++) {
int16_t *rd_re_ext_p = &rd_re_ext[aa][symb][4 * prb];
int16_t *rd_im_ext_p = &rd_im_ext[aa][symb][4 * prb];
for (int idx = 0; idx < 4; idx++) {
int k = 3 * idx + 12 * prb;
c16_t tmp = c16mulShift((c16_t){rd_re_ext_p[idx], rd_im_ext_p[idx]}, delay_table[k + 1], 8);
rd_re_ext_p[idx] = tmp.r;
rd_im_ext_p[idx] = tmp.i;
}
}
}
for (int group = 0, goldIdx = pucch_pdu->prb_start / 4; group < ngroup; group++) {
// each group has 8*nc_group_size elements, compute 1 complex correlation with DMRS per group
// non-coherent combining across groups
......
......@@ -217,6 +217,8 @@ struct NR_DL_FRAME_PARMS {
c16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16)));
/// Table used to apply the delay compensation in DL/UL
c16_t delay_table[2 * MAX_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE];
/// Table used to apply the delay compensation in PUCCH2
c16_t delay_table128[2 * MAX_DELAY_COMP + 1][128];
/// SRS configuration from TS 38.331 RRC
SRS_NR srs_nr;
/// Power used by SSB in order to estimate signal strength and path loss
......
......@@ -25,6 +25,8 @@
#define USE_128BIT
#endif
#define PEAK_DETECT_THRESHOLD 15
int16_t saturating_sub(int16_t a, int16_t b)
{
int32_t result = (int32_t)a - (int32_t)b;
......@@ -367,20 +369,28 @@ void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates
int max_val = delay->delay_max_val;
const int sync_pos = 0;
uint64_t mean_val = 0;
for (int i = 0; i < ofdm_symbol_size; i++) {
int temp = c16amp2(ch_estimates_time[i]) >> 1;
mean_val += temp;
if (temp > max_val) {
max_pos = i;
max_val = temp;
}
}
mean_val /= ofdm_symbol_size;
if (max_pos > ofdm_symbol_size / 2)
max_pos = max_pos - ofdm_symbol_size;
delay->delay_max_pos = max_pos;
delay->delay_max_val = max_val;
delay->est_delay = max_pos - sync_pos;
// The peak in general is quite clear. It only gives a small peak when the noise is high, generally obtaining an incorrect
// estimated delay, and causing the delay compensation to worsen the result instead of improving it. After analyzing several
// peaks, and doing many tests, a PEAK_DETECT_THRESHOLD = 15 is an adequate value, to apply delay compensation only when there is
// clearly a peak
delay->est_delay = mean_val > 0 && max_val / mean_val > PEAK_DETECT_THRESHOLD ? max_pos - sync_pos : 0;
}
unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int total_nb_rb, int nb_rb)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment