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 @@
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;
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;
int max_pos = delay->pusch_delay_max_pos;
int max_val = delay->pusch_delay_max_val;
const int sync_pos = 0;
for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) {
int temp = 0;
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
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);
}
int Re = ((int16_t *)ul_ch_estimates_time)[(i << 1)];
int Im = ((int16_t *)ul_ch_estimates_time)[1 + (i << 1)];
int temp = (Re * Re / 2) + (Im * Im / 2);
if (temp > max_val) {
max_pos = i;
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;
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,
......
......@@ -172,6 +172,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#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++) {
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];
......@@ -193,39 +197,55 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
int pilot_cnt = 0;
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
c32_t ch = {0};
for (int k_line = 0; k_line <= 1; k_line++) {
re_offset = (k0 + (n << 2) + (k_line << 1) + delta) % symbolSize;
ch=c32x16maddShift(*pil,
rxdataF[soffset + re_offset],
ch,
16);
ch = c32x16maddShift(*pil, rxdataF[soffset + re_offset], ch, 16);
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)));
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
for (int k_line = 0; k_line <= 1; k_line++) {
#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, 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
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) {
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)) {
c16multaddVectRealComplex(filt16_ul_last, &ch16, ul_ch, 16);
c16multaddVectRealComplex(filt16_ul_last, &ul_ls_est[pilot_cnt << 1], ul_ch, 16);
} 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) {
ul_ch += 4;
}
......@@ -442,11 +462,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
printf("%d\n",idxP);
}
#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
......
......@@ -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);
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,
const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]);
......
......@@ -545,6 +545,16 @@ typedef struct {
int subband_cqi_tot_dB[NUMBER_OF_NR_ULSCH_MAX][275];
/// PRACH background noise level
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;
......
......@@ -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;
// pdu->data = gNB->ulsch[ULSCH_id+1]->harq_processes[harq_pid]->b;
int sync_pos = nr_est_timing_advance_pusch(gNB, ULSCH_id); // estimate timing advance for MAC
// Get estimated 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
uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048;
......
......@@ -1040,6 +1040,12 @@ int main(int argc, char **argv)
double berStats[16] = {0};
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++) {
uint8_t round = 0;
......@@ -1552,6 +1558,12 @@ int main(int argc, char **argv)
roundStats += ((float)round);
if (!crc_status)
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
roundStats/=((float)n_trials);
......@@ -1581,6 +1593,12 @@ int main(int argc, char **argv)
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("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");
if (fd == NULL) {
printf("Problem with filename %s\n", "nr_ulsim.log");
......@@ -1589,9 +1607,6 @@ int main(int argc, char **argv)
dump_pusch_stats(fd,gNB);
fclose(fd);
printf("*****************************************\n");
printf("\n");
if (print_perf==1) {
printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
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