Commit e223f4ee authored by Roberto Louro Magueta's avatar Roberto Louro Magueta

Apply delay compensation for UL in nr_pusch_channel_estimation()

parent 0b05fce7
......@@ -66,6 +66,17 @@ int l1_north_init_gNB() {
return(0);
}
void init_ul_delay_table(NR_DL_FRAME_PARMS *fp)
{
for (int delay = -MAX_UL_DELAY_COMP; delay <= MAX_UL_DELAY_COMP; delay++) {
for (int k = 0; k < fp->ofdm_symbol_size; k++) {
double complex delay_cexp = cexp(I * (2.0 * M_PI * k * delay / fp->ofdm_symbol_size));
fp->ul_delay_table[MAX_UL_DELAY_COMP + delay][k].r = (int16_t)round(256 * creal(delay_cexp));
fp->ul_delay_table[MAX_UL_DELAY_COMP + delay][k].i = (int16_t)round(256 * cimag(delay_cexp));
}
}
}
int init_codebook_gNB(PHY_VARS_gNB *gNB) {
if(gNB->frame_parms.nb_antennas_tx>1){
......@@ -500,6 +511,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
load_nrLDPClib_offload();
init_codebook_gNB(gNB);
init_ul_delay_table(fp);
// PBCH DMRS gold sequences generation
nr_init_pbch_dmrs(gNB);
......
......@@ -100,6 +100,17 @@ __attribute__((always_inline)) inline c16_t c32x16cumulVectVectWithSteps(c16_t *
return c16x32div(cumul, N);
}
int get_delay_idx(int delay) {
int delay_idx = MAX_UL_DELAY_COMP + delay;
if (delay_idx < 0) {
delay_idx = 0;
}
if (delay_idx > MAX_UL_DELAY_COMP<<1) {
delay_idx = MAX_UL_DELAY_COMP<<1;
}
return delay_idx;
}
int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
unsigned char Ns,
unsigned short p,
......@@ -209,9 +220,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
c16_t ch16 = {.r = (int16_t)ch.r, .i = (int16_t)ch.i};
*max_ch = max(*max_ch, max(abs(ch.r), abs(ch.i)));
ul_ls_est[pilot_cnt << 1] = ch16;
ul_ls_est[(pilot_cnt + 1) << 1] = ch16;
for (int k = pilot_cnt << 1; k < (pilot_cnt << 1) + 4; k++) {
ul_ls_est[k] = ch16;
}
pilot_cnt += 2;
}
......@@ -221,6 +232,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
nr_est_timing_advance_pusch(&gNB->frame_parms, gNB->pusch_vars[ul_id]->ul_ch_estimates_time[aarx], &gNB->measurements.delay[ul_id]);
int delay = gNB->measurements.delay[ul_id].pusch_est_delay;
int delay_idx = get_delay_idx(delay);
c16_t *ul_delay_table = gNB->frame_parms.ul_delay_table[delay_idx];
#ifdef DEBUG_PUSCH
printf("Estimated delay = %i\n", delay >> 1);
......@@ -231,21 +244,25 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
// Channel interpolation
for (int k_line = 0; k_line <= 1; k_line++) {
// Apply delay
int k = pilot_cnt << 1;
c16_t ch16 = c16mulShift(ul_ls_est[k], ul_delay_table[k], 8);
#ifdef DEBUG_PUSCH
re_offset = (k0 + (n << 2) + (k_line << 1)) % symbolSize;
c16_t *rxF = &rxdataF[soffset + re_offset];
printf("pilot %4u: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d)\n",
pilot_cnt, pil->r, pil->i, rxF->r, rxF->i, ul_ls_est[pilot_cnt << 1].r, ul_ls_est[pilot_cnt << 1].i);
printf("ch -> (%4d,%4d), ch_delay_comp -> (%4d,%4d)\n", ul_ls_est[k].r, ul_ls_est[k].i, ch16.r, ch16.i);
#endif
if (pilot_cnt == 0) {
c16multaddVectRealComplex(filt16_ul_p0, &ul_ls_est[pilot_cnt << 1], ul_ch, 16);
c16multaddVectRealComplex(filt16_ul_p0, &ch16, ul_ch, 16);
} else if (pilot_cnt == 1 || pilot_cnt == 2) {
c16multaddVectRealComplex(filt16_ul_p1p2, &ul_ls_est[pilot_cnt << 1], ul_ch, 16);
c16multaddVectRealComplex(filt16_ul_p1p2, &ch16, ul_ch, 16);
} else if (pilot_cnt == (6 * nb_rb_pusch - 1)) {
c16multaddVectRealComplex(filt16_ul_last, &ul_ls_est[pilot_cnt << 1], ul_ch, 16);
c16multaddVectRealComplex(filt16_ul_last, &ch16, ul_ch, 16);
} else {
c16multaddVectRealComplex(filt16_ul_middle, &ul_ls_est[pilot_cnt << 1], ul_ch, 16);
c16multaddVectRealComplex(filt16_ul_middle, &ch16, ul_ch, 16);
if (pilot_cnt % 2 == 0) {
ul_ch += 4;
}
......@@ -255,19 +272,24 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
}
}
// Revert delay
pilot_cnt = 0;
ul_ch = &ul_ch_estimates[p * gNB->frame_parms.nb_antennas_rx + aarx][ch_offset];
int inv_delay_idx = get_delay_idx(-delay);
c16_t *ul_inv_delay_table = gNB->frame_parms.ul_delay_table[inv_delay_idx];
for (int n = 0; n < 3 * nb_rb_pusch; n++) {
for (int k_line = 0; k_line <= 1; k_line++) {
int k = pilot_cnt << 1;
ul_ch[k] = c16mulShift(ul_ch[k], ul_inv_delay_table[k], 8);
ul_ch[k + 1] = c16mulShift(ul_ch[k + 1], ul_inv_delay_table[k + 1], 8);
#ifdef DEBUG_PUSCH
ul_ch = &ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset];
for(uint16_t idxP=0; idxP<ceil((float)nb_rb_pusch*12/8); idxP++) {
printf("(%3d)\t",idxP);
for(uint8_t idxI=0; idxI<8; idxI++) {
printf("%d\t%d\t",ul_ch[idxP*8+idxI].r,ul_ch[idxP*8+idxI].i);
re_offset = (k0 + (n << 2) + (k_line << 1)) % symbolSize;
c16_t *rxF = &rxdataF[soffset + re_offset];
printf("ch -> (%4d,%4d), ch_inter -> (%4d,%4d)\n", ul_ls_est[k].r, ul_ls_est[k].i, ul_ch[k].r, ul_ch[k].i);
#endif
pilot_cnt++;
}
printf("\n");
}
#endif
} else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type2 && chest_freq == 0) { // pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d|
LOG_D(PHY, "PUSCH estimation DMRS type 2, Freq-domain interpolation\n");
......@@ -452,16 +474,15 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
}
#ifdef DEBUG_PUSCH
ul_ch = &ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset];
for(int idxP=0; idxP<ceil((float)nb_rb_pusch*12/8); idxP++) {
for(int idxI=0; idxI<8; idxI++) {
printf("%d\t%d\t",ul_ch[idxP*8+idxI].r,ul_ch[idxP*8+idxI].i);
ul_ch = &ul_ch_estimates[p * gNB->frame_parms.nb_antennas_rx + aarx][ch_offset];
for (int idxP = 0; idxP < ceil((float)nb_rb_pusch * 12 / 8); idxP++) {
for (int idxI = 0; idxI < 8; idxI++) {
printf("%d\t%d\t", ul_ch[idxP * 8 + idxI].r, ul_ch[idxP * 8 + idxI].i);
}
printf("%d\n",idxP);
printf("%d\n", idxP);
}
#endif
}
#ifdef DEBUG_CH
......
......@@ -95,6 +95,8 @@
#define NR_NB_NSCID 2
#define MAX_UL_DELAY_COMP 20
typedef enum {
NR_MU_0=0,
NR_MU_1,
......@@ -219,6 +221,8 @@ struct NR_DL_FRAME_PARMS {
/// sequence used to compensate the phase rotation due to timeshifted OFDM symbols
/// First dimenstion is for different CP lengths
c16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16)));
/// Table used to apply the delay compensation in UL
c16_t ul_delay_table[2 * MAX_UL_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE * 2];
/// shift of pilot position in one RB
uint8_t nushift;
/// SRS configuration from TS 38.331 RRC
......
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