Commit 0b05fce7 authored by Roberto Louro Magueta's avatar Roberto Louro Magueta

Time shift estimation based on DMRS-PUSCH

parent d379bbae
...@@ -38,34 +38,28 @@ ...@@ -38,34 +38,28 @@
extern openair0_config_t openair0_cfg[MAX_CARDS]; extern openair0_config_t openair0_cfg[MAX_CARDS];
int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) void nr_est_timing_advance_pusch(const NR_DL_FRAME_PARMS *frame_parms, const int32_t *ul_ch_estimates_time, struct delay_s *delay)
{ {
int max_pos = 0, max_val = 0; int max_pos = delay->pusch_delay_max_pos;
int max_val = delay->pusch_delay_max_val;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
NR_gNB_PUSCH *gNB_pusch_vars = gNB->pusch_vars[UE_id];
int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time;
const int sync_pos = 0; const int sync_pos = 0;
for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) { for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) {
int temp = 0; int Re = ((int16_t *)ul_ch_estimates_time)[(i << 1)];
int Im = ((int16_t *)ul_ch_estimates_time)[1 + (i << 1)];
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { int temp = (Re * Re / 2) + (Im * Im / 2);
int Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
int Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
temp += (Re*Re/2) + (Im*Im/2);
}
if (temp > max_val) { if (temp > max_val) {
max_pos = i; max_pos = i;
max_val = temp; max_val = temp;
} }
} }
if (max_pos > frame_parms->ofdm_symbol_size/2) if (max_pos > frame_parms->ofdm_symbol_size / 2)
max_pos = max_pos - frame_parms->ofdm_symbol_size; max_pos = max_pos - frame_parms->ofdm_symbol_size;
return max_pos - sync_pos; delay->pusch_delay_max_pos = max_pos;
delay->pusch_delay_max_val = max_val;
delay->pusch_est_delay = max_pos - sync_pos;
} }
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
......
...@@ -172,6 +172,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -172,6 +172,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#endif #endif
c16_t ul_ls_est[symbolSize];
memset(ul_ls_est, 0, sizeof(c16_t) * symbolSize);
memset(&gNB->measurements.delay[ul_id], 0, sizeof(gNB->measurements.delay[ul_id]));
for (int aarx=0; aarx<gNB->frame_parms.nb_antennas_rx; aarx++) { for (int aarx=0; aarx<gNB->frame_parms.nb_antennas_rx; aarx++) {
c16_t *rxdataF = (c16_t *)&gNB->common_vars.rxdataF[aarx][symbol_offset]; c16_t *rxdataF = (c16_t *)&gNB->common_vars.rxdataF[aarx][symbol_offset];
c16_t *ul_ch = &ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset]; c16_t *ul_ch = &ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset];
...@@ -193,39 +197,55 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -193,39 +197,55 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
int pilot_cnt = 0; int pilot_cnt = 0;
int delta = nr_pusch_dmrs_delta(pusch_dmrs_type1, p); int delta = nr_pusch_dmrs_delta(pusch_dmrs_type1, p);
for (int n = 0; n < 3*nb_rb_pusch; n++) { for (int n = 0; n < 3 * nb_rb_pusch; n++) {
// LS estimation // LS estimation
c32_t ch = {0}; c32_t ch = {0};
for (int k_line = 0; k_line <= 1; k_line++) { for (int k_line = 0; k_line <= 1; k_line++) {
re_offset = (k0 + (n << 2) + (k_line << 1) + delta) % symbolSize; re_offset = (k0 + (n << 2) + (k_line << 1) + delta) % symbolSize;
ch=c32x16maddShift(*pil, ch = c32x16maddShift(*pil, rxdataF[soffset + re_offset], ch, 16);
rxdataF[soffset + re_offset],
ch,
16);
pil++; pil++;
} }
c16_t ch16= {.r=(int16_t)ch.r, .i=(int16_t)ch.i}; 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))); *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;
pilot_cnt += 2;
}
freq2time(symbolSize,
(int16_t *) ul_ls_est,
(int16_t *) gNB->pusch_vars[ul_id]->ul_ch_estimates_time[aarx]);
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;
#ifdef DEBUG_PUSCH
printf("Estimated delay = %i\n", delay >> 1);
#endif
pilot_cnt = 0;
for (int n = 0; n < 3*nb_rb_pusch; n++) {
// Channel interpolation // Channel interpolation
for (int k_line = 0; k_line <= 1; k_line++) { for (int k_line = 0; k_line <= 1; k_line++) {
#ifdef DEBUG_PUSCH #ifdef DEBUG_PUSCH
re_offset = (k0 + (n << 2) + (k_line << 1)) % symbolSize; re_offset = (k0 + (n << 2) + (k_line << 1)) % symbolSize;
c16_t *rxF = &rxdataF[soffset + re_offset]; c16_t *rxF = &rxdataF[soffset + re_offset];
printf("pilot %4u: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d)\n", printf("pilot %4u: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d)\n",
pilot_cnt, pil->r, pil->i, rxF->r, rxF->i, ch.r, ch.i); pilot_cnt, pil->r, pil->i, rxF->r, rxF->i, ul_ls_est[pilot_cnt << 1].r, ul_ls_est[pilot_cnt << 1].i);
#endif #endif
if (pilot_cnt == 0) { if (pilot_cnt == 0) {
c16multaddVectRealComplex(filt16_ul_p0, &ch16, ul_ch, 16); c16multaddVectRealComplex(filt16_ul_p0, &ul_ls_est[pilot_cnt << 1], ul_ch, 16);
} else if (pilot_cnt == 1 || pilot_cnt == 2) { } else if (pilot_cnt == 1 || pilot_cnt == 2) {
c16multaddVectRealComplex(filt16_ul_p1p2, &ch16, ul_ch, 16); c16multaddVectRealComplex(filt16_ul_p1p2, &ul_ls_est[pilot_cnt << 1], ul_ch, 16);
} else if (pilot_cnt == (6 * nb_rb_pusch - 1)) { } else if (pilot_cnt == (6 * nb_rb_pusch - 1)) {
c16multaddVectRealComplex(filt16_ul_last, &ch16, ul_ch, 16); c16multaddVectRealComplex(filt16_ul_last, &ul_ls_est[pilot_cnt << 1], ul_ch, 16);
} else { } else {
c16multaddVectRealComplex(filt16_ul_middle, &ch16, ul_ch, 16); c16multaddVectRealComplex(filt16_ul_middle, &ul_ls_est[pilot_cnt << 1], ul_ch, 16);
if (pilot_cnt % 2 == 0) { if (pilot_cnt % 2 == 0) {
ul_ch += 4; ul_ch += 4;
} }
...@@ -442,11 +462,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -442,11 +462,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
printf("%d\n",idxP); printf("%d\n",idxP);
} }
#endif #endif
// Convert to time domain
freq2time(symbolSize,
(int16_t *) &ul_ch_estimates[aarx][symbol_offset],
(int16_t *) gNB->pusch_vars[ul_id]->ul_ch_estimates_time[aarx]);
} }
#ifdef DEBUG_CH #ifdef DEBUG_CH
......
...@@ -55,7 +55,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot,int first_symb,int num_symb) ...@@ -55,7 +55,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot,int first_symb,int num_symb)
void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol, uint8_t nrOfLayers); void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol, uint8_t nrOfLayers);
int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id); void nr_est_timing_advance_pusch(const NR_DL_FRAME_PARMS *frame_parms, const int32_t *ul_ch_estimates_time, struct delay_s *delay);
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]); const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]);
......
...@@ -545,6 +545,16 @@ typedef struct { ...@@ -545,6 +545,16 @@ typedef struct {
int subband_cqi_tot_dB[NUMBER_OF_NR_ULSCH_MAX][275]; int subband_cqi_tot_dB[NUMBER_OF_NR_ULSCH_MAX][275];
/// PRACH background noise level /// PRACH background noise level
int prach_I0; int prach_I0;
struct delay_s {
/// Time shift in number of samples estimated based on DMRS-PUSCH
int pusch_est_delay;
/// Max position in OFDM symbol related to time shift estimation based on DMRS-PUSCH
int pusch_delay_max_pos;
/// Max value related to time shift estimation based on DMRS-PUSCH
int pusch_delay_max_val;
} delay[NUMBER_OF_NR_ULSCH_MAX];
} PHY_MEASUREMENTS_gNB; } PHY_MEASUREMENTS_gNB;
......
...@@ -401,8 +401,8 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, ...@@ -401,8 +401,8 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
nfapi_nr_pusch_pdu_t *pusch_pdu = &harq_process->ulsch_pdu; nfapi_nr_pusch_pdu_t *pusch_pdu = &harq_process->ulsch_pdu;
// pdu->data = gNB->ulsch[ULSCH_id+1]->harq_processes[harq_pid]->b; // Get estimated timing advance for MAC
int sync_pos = nr_est_timing_advance_pusch(gNB, ULSCH_id); // estimate timing advance for MAC int sync_pos = gNB->measurements.delay[ULSCH_id].pusch_est_delay;
// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048; uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048;
......
...@@ -1040,6 +1040,12 @@ int main(int argc, char **argv) ...@@ -1040,6 +1040,12 @@ int main(int argc, char **argv)
double berStats[16] = {0}; double berStats[16] = {0};
clear_pusch_stats(gNB); clear_pusch_stats(gNB);
uint64_t sum_pusch_delay = 0;
int min_pusch_delay = INT_MAX;
int max_pusch_delay = INT_MIN;
int delay_pusch_est_count = 0;
for (trial = 0; trial < n_trials; trial++) { for (trial = 0; trial < n_trials; trial++) {
uint8_t round = 0; uint8_t round = 0;
...@@ -1552,6 +1558,12 @@ int main(int argc, char **argv) ...@@ -1552,6 +1558,12 @@ int main(int argc, char **argv)
roundStats += ((float)round); roundStats += ((float)round);
if (!crc_status) if (!crc_status)
effRate += ((double)TBS) / (double)round; effRate += ((double)TBS) / (double)round;
sum_pusch_delay += gNB->measurements.delay[UE_id].pusch_est_delay;
min_pusch_delay = gNB->measurements.delay[UE_id].pusch_est_delay < min_pusch_delay ? gNB->measurements.delay[UE_id].pusch_est_delay : min_pusch_delay;
max_pusch_delay = gNB->measurements.delay[UE_id].pusch_est_delay > max_pusch_delay ? gNB->measurements.delay[UE_id].pusch_est_delay : max_pusch_delay;
delay_pusch_est_count++;
} // trial loop } // trial loop
roundStats/=((float)n_trials); roundStats/=((float)n_trials);
...@@ -1581,6 +1593,12 @@ int main(int argc, char **argv) ...@@ -1581,6 +1593,12 @@ int main(int argc, char **argv)
printf(",%e", berStats[r]); printf(",%e", berStats[r]);
printf(") Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", roundStats,effRate,effTP,TBS); printf(") Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", roundStats,effRate,effTP,TBS);
printf("DMRS-PUSCH delay estimation: min %i, max %i, average %f\n",
min_pusch_delay >> 1, max_pusch_delay >> 1, (double)sum_pusch_delay / (2 * delay_pusch_est_count));
printf("*****************************************\n");
printf("\n");
FILE *fd=fopen("nr_ulsim.log","w"); FILE *fd=fopen("nr_ulsim.log","w");
if (fd == NULL) { if (fd == NULL) {
printf("Problem with filename %s\n", "nr_ulsim.log"); printf("Problem with filename %s\n", "nr_ulsim.log");
...@@ -1589,9 +1607,6 @@ int main(int argc, char **argv) ...@@ -1589,9 +1607,6 @@ int main(int argc, char **argv)
dump_pusch_stats(fd,gNB); dump_pusch_stats(fd,gNB);
fclose(fd); fclose(fd);
printf("*****************************************\n");
printf("\n");
if (print_perf==1) { if (print_perf==1) {
printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx"); printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
printStatIndent(&gNB->rx_pusch_stats,"RX PUSCH time"); printStatIndent(&gNB->rx_pusch_stats,"RX PUSCH time");
......
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