Commit e0ab96ee authored by rmagueta's avatar rmagueta

Implementation of delay compensation in NFAPI_NR_DMRS_TYPE1_linear_interp() at UE

parent 7611fe67
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <stdint.h> #include <stdint.h>
#include "assertions.h" #include "assertions.h"
#include "nr_common.h" #include "nr_common.h"
#include <complex.h>
const char *duplex_mode[]={"FDD","TDD"}; const char *duplex_mode[]={"FDD","TDD"};
...@@ -738,3 +739,27 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB, ...@@ -738,3 +739,27 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
AssertFatal(sco % scs_scaling == 0, "ssb offset %d can create frequency offset\n", sco); AssertFatal(sco % scs_scaling == 0, "ssb offset %d can create frequency offset\n", sco);
return ssb_offset_point_a; return ssb_offset_point_a;
} }
int get_delay_idx(int delay, int max_delay_comp)
{
int delay_idx = max_delay_comp + delay;
// If the measured delay is less than -MAX_DELAY_COMP, a -MAX_DELAY_COMP delay is compensated.
delay_idx = max(delay_idx, 0);
// If the measured delay is greater than +MAX_DELAY_COMP, a +MAX_DELAY_COMP delay is compensated.
delay_idx = min(delay_idx, max_delay_comp << 1);
return delay_idx;
}
void init_delay_table(uint16_t ofdm_symbol_size,
int max_delay_comp,
int max_ofdm_symbol_size,
c16_t delay_table[][max_ofdm_symbol_size])
{
for (int delay = -max_delay_comp; delay <= max_delay_comp; delay++) {
for (int k = 0; k < ofdm_symbol_size; k++) {
double complex delay_cexp = cexp(I * (2.0 * M_PI * k * delay / ofdm_symbol_size));
delay_table[max_delay_comp + delay][k].r = (int16_t)round(256 * creal(delay_cexp));
delay_table[max_delay_comp + delay][k].i = (int16_t)round(256 * cimag(delay_cexp));
}
}
}
...@@ -123,6 +123,7 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB, ...@@ -123,6 +123,7 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
int ssbSubcarrierSpacing, int ssbSubcarrierSpacing,
int frequency_range); int frequency_range);
int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA); int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA);
int get_delay_idx(int delay, int max_delay_comp);
#define CEILIDIV(a,b) ((a+b-1)/b) #define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
......
...@@ -66,17 +66,6 @@ int l1_north_init_gNB() { ...@@ -66,17 +66,6 @@ int l1_north_init_gNB() {
return(0); 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));
}
}
}
NR_gNB_PHY_STATS_t *get_phy_stats(PHY_VARS_gNB *gNB, uint16_t rnti) NR_gNB_PHY_STATS_t *get_phy_stats(PHY_VARS_gNB *gNB, uint16_t rnti)
{ {
NR_gNB_PHY_STATS_t *stats; NR_gNB_PHY_STATS_t *stats;
...@@ -544,7 +533,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) ...@@ -544,7 +533,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB; gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB;
init_codebook_gNB(gNB); init_codebook_gNB(gNB);
init_ul_delay_table(fp); init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table);
// PBCH DMRS gold sequences generation // PBCH DMRS gold sequences generation
nr_init_pbch_dmrs(gNB); nr_init_pbch_dmrs(gNB);
......
...@@ -674,6 +674,7 @@ void init_N_TA_offset(PHY_VARS_NR_UE *ue){ ...@@ -674,6 +674,7 @@ void init_N_TA_offset(PHY_VARS_NR_UE *ue){
void phy_init_nr_top(PHY_VARS_NR_UE *ue) { void phy_init_nr_top(PHY_VARS_NR_UE *ue) {
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
init_delay_table(frame_parms->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, frame_parms->delay_table);
crcTableInit(); crcTableInit();
init_scrambling_luts(); init_scrambling_luts();
load_dftslib(); load_dftslib();
......
...@@ -56,5 +56,9 @@ void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES], ...@@ -56,5 +56,9 @@ void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES],
void phy_init_nr_top(PHY_VARS_NR_UE *ue); void phy_init_nr_top(PHY_VARS_NR_UE *ue);
void phy_term_nr_top(void); void phy_term_nr_top(void);
void init_delay_table(uint16_t ofdm_symbol_size,
int max_delay_comp,
int max_ofdm_symbol_size,
c16_t delay_table[][max_ofdm_symbol_size]);
#endif #endif
...@@ -104,19 +104,6 @@ __attribute__((always_inline)) inline c16_t c32x16cumulVectVectWithSteps(c16_t * ...@@ -104,19 +104,6 @@ __attribute__((always_inline)) inline c16_t c32x16cumulVectVectWithSteps(c16_t *
return c16x32div(cumul, N); return c16x32div(cumul, N);
} }
int get_delay_idx(int delay) {
int delay_idx = MAX_UL_DELAY_COMP + delay;
// If the measured delay is less than -MAX_UL_DELAY_COMP, a -MAX_UL_DELAY_COMP delay is compensated.
if (delay_idx < 0) {
delay_idx = 0;
}
// If the measured delay is greater than +MAX_UL_DELAY_COMP, a +MAX_UL_DELAY_COMP delay is compensated.
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, int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
unsigned char Ns, unsigned char Ns,
unsigned short p, unsigned short p,
...@@ -240,12 +227,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -240,12 +227,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
freq2time(symbolSize, (int16_t *)ul_ls_est, (int16_t *)pusch_vars->ul_ch_estimates_time[aarx]); freq2time(symbolSize, (int16_t *)ul_ls_est, (int16_t *)pusch_vars->ul_ch_estimates_time[aarx]);
nr_est_timing_advance_pusch(&gNB->frame_parms, pusch_vars->ul_ch_estimates_time[aarx], delay); nr_est_timing_advance_pusch(&gNB->frame_parms, pusch_vars->ul_ch_estimates_time[aarx], delay);
int pusch_delay = delay->est_delay; int delay_idx = get_delay_idx(delay->est_delay, MAX_DELAY_COMP);
int delay_idx = get_delay_idx(pusch_delay); c16_t *ul_delay_table = gNB->frame_parms.delay_table[delay_idx];
c16_t *ul_delay_table = gNB->frame_parms.ul_delay_table[delay_idx];
#ifdef DEBUG_PUSCH #ifdef DEBUG_PUSCH
printf("Estimated delay = %i\n", pusch_delay >> 1); printf("Estimated delay = %i\n", delay->est_delay >> 1);
#endif #endif
pilot_cnt = 0; pilot_cnt = 0;
...@@ -285,8 +271,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -285,8 +271,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
// Revert delay // Revert delay
pilot_cnt = 0; pilot_cnt = 0;
ul_ch = &ul_ch_estimates[p * gNB->frame_parms.nb_antennas_rx + aarx][ch_offset]; ul_ch = &ul_ch_estimates[p * gNB->frame_parms.nb_antennas_rx + aarx][ch_offset];
int inv_delay_idx = get_delay_idx(-pusch_delay); int inv_delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP);
c16_t *ul_inv_delay_table = gNB->frame_parms.ul_delay_table[inv_delay_idx]; c16_t *ul_inv_delay_table = gNB->frame_parms.delay_table[inv_delay_idx];
for (int n = 0; n < 3 * nb_rb_pusch; n++) { for (int n = 0; n < 3 * nb_rb_pusch; n++) {
for (int k_line = 0; k_line <= 1; k_line++) { for (int k_line = 0; k_line <= 1; k_line++) {
int k = pilot_cnt << 1; int k = pilot_cnt << 1;
...@@ -326,9 +312,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -326,9 +312,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
// Delay compensation // Delay compensation
freq2time(symbolSize, (int16_t *)ul_ls_est, (int16_t *)pusch_vars->ul_ch_estimates_time[aarx]); freq2time(symbolSize, (int16_t *)ul_ls_est, (int16_t *)pusch_vars->ul_ch_estimates_time[aarx]);
nr_est_timing_advance_pusch(&gNB->frame_parms, pusch_vars->ul_ch_estimates_time[aarx], delay); nr_est_timing_advance_pusch(&gNB->frame_parms, pusch_vars->ul_ch_estimates_time[aarx], delay);
int pusch_delay = delay->est_delay; int delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP);
int delay_idx = get_delay_idx(-pusch_delay); c16_t *ul_delay_table = gNB->frame_parms.delay_table[delay_idx];
c16_t *ul_delay_table = gNB->frame_parms.ul_delay_table[delay_idx];
for (int n = 0; n < nb_rb_pusch * NR_NB_SC_PER_RB; n++) { for (int n = 0; n < nb_rb_pusch * NR_NB_SC_PER_RB; n++) {
ul_ch[n] = c16mulShift(ul_ls_est[n], ul_delay_table[n % 6], 8); ul_ch[n] = c16mulShift(ul_ls_est[n], ul_delay_table[n % 6], 8);
} }
......
...@@ -1377,6 +1377,7 @@ void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms, ...@@ -1377,6 +1377,7 @@ void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
int8_t delta, int8_t delta,
delay_t *delay) delay_t *delay)
{ {
c16_t *dl_ch0 = dl_ch;
int re_offset = bwp_start_subcarrier % frame_parms->ofdm_symbol_size; int re_offset = bwp_start_subcarrier % frame_parms->ofdm_symbol_size;
c16_t dl_ls_est[frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); c16_t dl_ls_est[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
...@@ -1409,21 +1410,33 @@ void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms, ...@@ -1409,21 +1410,33 @@ void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
} }
nr_est_delay_pdsch(frame_parms, dl_ls_est, delay); nr_est_delay_pdsch(frame_parms, dl_ls_est, delay);
int delay_idx = get_delay_idx(delay->est_delay, MAX_DELAY_COMP);
c16_t *dl_delay_table = frame_parms->delay_table[delay_idx];
for (int pilot_cnt = 0; pilot_cnt < 6 * nb_rb_pdsch; pilot_cnt++) { for (int pilot_cnt = 0; pilot_cnt < 6 * nb_rb_pdsch; pilot_cnt++) {
int k = pilot_cnt << 1;
c16_t ch = c16mulShift(dl_ls_est[k], dl_delay_table[k], 8);
if (pilot_cnt == 0) { // Treat first pilot if (pilot_cnt == 0) { // Treat first pilot
c16multaddVectRealComplex(filt16_ul_p0, &dl_ls_est[pilot_cnt << 1], dl_ch, 16); c16multaddVectRealComplex(filt16_ul_p0, &ch, dl_ch, 16);
} else if (pilot_cnt == 1 || pilot_cnt == 2) { } else if (pilot_cnt == 1 || pilot_cnt == 2) {
c16multaddVectRealComplex(filt16_ul_p1p2, &dl_ls_est[pilot_cnt << 1], dl_ch, 16); c16multaddVectRealComplex(filt16_ul_p1p2, &ch, dl_ch, 16);
} else if (pilot_cnt == 6 * nb_rb_pdsch - 1) { // Treat last pilot } else if (pilot_cnt == 6 * nb_rb_pdsch - 1) { // Treat last pilot
c16multaddVectRealComplex(filt16_ul_last, &dl_ls_est[pilot_cnt << 1], dl_ch, 16); c16multaddVectRealComplex(filt16_ul_last, &ch, dl_ch, 16);
} else { // Treat middle pilots } else { // Treat middle pilots
c16multaddVectRealComplex(filt16_ul_middle, &dl_ls_est[pilot_cnt << 1], dl_ch, 16); c16multaddVectRealComplex(filt16_ul_middle, &ch, dl_ch, 16);
if (pilot_cnt % 2 == 0) { if (pilot_cnt % 2 == 0) {
dl_ch += 4; dl_ch += 4;
} }
} }
} }
// Revert delay
dl_ch = dl_ch0;
int inv_delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP);
c16_t *dl_inv_delay_table = frame_parms->delay_table[inv_delay_idx];
for (int k = 0; k < 12 * nb_rb_pdsch; k++) {
dl_ch[k] = c16mulShift(dl_ch[k], dl_inv_delay_table[k], 8);
}
} }
void NFAPI_NR_DMRS_TYPE1_average_prb(NR_DL_FRAME_PARMS *frame_parms, void NFAPI_NR_DMRS_TYPE1_average_prb(NR_DL_FRAME_PARMS *frame_parms,
......
...@@ -95,7 +95,7 @@ ...@@ -95,7 +95,7 @@
#define NR_NB_NSCID 2 #define NR_NB_NSCID 2
#define MAX_UL_DELAY_COMP 20 #define MAX_DELAY_COMP 20
typedef enum { typedef enum {
NR_MU_0=0, NR_MU_0=0,
...@@ -227,8 +227,8 @@ struct NR_DL_FRAME_PARMS { ...@@ -227,8 +227,8 @@ struct NR_DL_FRAME_PARMS {
/// sequence used to compensate the phase rotation due to timeshifted OFDM symbols /// sequence used to compensate the phase rotation due to timeshifted OFDM symbols
/// First dimenstion is for different CP lengths /// First dimenstion is for different CP lengths
c16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16))); c16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16)));
/// Table used to apply the delay compensation in UL /// Table used to apply the delay compensation in DL/UL
c16_t ul_delay_table[2 * MAX_UL_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE * 2]; c16_t delay_table[2 * MAX_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE];
/// shift of pilot position in one RB /// shift of pilot position in one RB
uint8_t nushift; uint8_t nushift;
/// SRS configuration from TS 38.331 RRC /// 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