Commit f1e5d1fb authored by Laurent THOMAS's avatar Laurent THOMAS Committed by Robert Schmidt

try to work around compiler bug (internal segv)

Signed-off-by: default avatarLaurent THOMAS <laurent.thomas@open-cells.com>
parent 885e5e88
...@@ -53,15 +53,18 @@ ...@@ -53,15 +53,18 @@
#define SYNCHRO_RATE_CHANGE_FACTOR (1) #define SYNCHRO_RATE_CHANGE_FACTOR (1)
#endif #endif
pss_detection_result_t pss_search_time_nr(const c16_t **rxdata, typedef struct {
int ofdm_symbol_size, c16_t **rxdata;
int nb_antennas_rx, int nb_antennas_rx;
int subcarrier_spacing, int rxdata_length;
const c16_t pssTime[NUMBER_PSS_SEQUENCE][ofdm_symbol_size], int ofdm_symbol_size;
bool fo_flag, int subcarrier_spacing;
int target_Nid_cell, bool fo_flag;
int search_start, int target_Nid_cell;
int search_length); c16_t *pssTime;
} pss_search_t;
pss_detection_result_t pss_search_time_nr(const pss_search_t *p);
void generate_pss_nr_time(int ofdm_symbol_size, void generate_pss_nr_time(int ofdm_symbol_size,
int first_carrier_offset, int first_carrier_offset,
......
...@@ -283,18 +283,20 @@ static bool validate_known_pci(NR_DL_FRAME_PARMS *frame_parms, ...@@ -283,18 +283,20 @@ static bool validate_known_pci(NR_DL_FRAME_PARMS *frame_parms,
{ {
int known_pci = nr_neighboring_cell->Nid_cell; int known_pci = nr_neighboring_cell->Nid_cell;
int start = neighboring_cell_info->pss_search_start;
int length = neighboring_cell_info->pss_search_length; int length = neighboring_cell_info->pss_search_length;
c16_t *rx[frame_parms->nb_antennas_rx];
for (int i=0; i<frame_parms->nb_antennas_rx; i++)
rx[i]=rxdata[i]+neighboring_cell_info->pss_search_start;
pss_detection_result_t pss_res = pss_search_time_nr((const c16_t **)rxdata, pss_search_t p_pss = (pss_search_t){.rxdata = rx,
frame_parms->ofdm_symbol_size, .nb_antennas_rx = frame_parms->nb_antennas_rx,
frame_parms->nb_antennas_rx, .rxdata_length = length,
frame_parms->subcarrier_spacing, .ofdm_symbol_size = frame_parms->ofdm_symbol_size,
pssTime, .subcarrier_spacing = frame_parms->subcarrier_spacing,
false, // no frequency offset estimation for tracking .fo_flag = false,
known_pci, .target_Nid_cell = known_pci,
start, .pssTime = (c16_t *)pssTime};
length); pss_detection_result_t pss_res = pss_search_time_nr(&p_pss);
if (!pss_res.success) { if (!pss_res.success) {
if (neighboring_cell_info->valid_meas) if (neighboring_cell_info->valid_meas)
...@@ -302,7 +304,7 @@ static bool validate_known_pci(NR_DL_FRAME_PARMS *frame_parms, ...@@ -302,7 +304,7 @@ static bool validate_known_pci(NR_DL_FRAME_PARMS *frame_parms,
LOG_D(NR_PHY, LOG_D(NR_PHY,
"PSS validation failed for PCI=%d (search window: start=%d, length=%d, peak=%d dB, avg=%d dB), consec_fail=%d\n", "PSS validation failed for PCI=%d (search window: start=%d, length=%d, peak=%d dB, avg=%d dB), consec_fail=%d\n",
known_pci, known_pci,
start, neighboring_cell_info->pss_search_start,
length, length,
pss_res.peak, pss_res.peak,
pss_res.avg, pss_res.avg,
...@@ -310,7 +312,7 @@ static bool validate_known_pci(NR_DL_FRAME_PARMS *frame_parms, ...@@ -310,7 +312,7 @@ static bool validate_known_pci(NR_DL_FRAME_PARMS *frame_parms,
return false; return false;
} }
int ssb_time_offset = pss_res.pos - frame_parms->nb_prefix_samples; int ssb_time_offset = neighboring_cell_info->pss_search_start + pss_res.pos - frame_parms->nb_prefix_samples;
if (ssb_time_offset < 0) if (ssb_time_offset < 0)
return false; // pss position is too close to buffer begining return false; // pss position is too close to buffer begining
...@@ -327,13 +329,13 @@ static bool validate_known_pci(NR_DL_FRAME_PARMS *frame_parms, ...@@ -327,13 +329,13 @@ static bool validate_known_pci(NR_DL_FRAME_PARMS *frame_parms,
sizeof(c16_t) * frame_parms->ofdm_symbol_size); sizeof(c16_t) * frame_parms->ofdm_symbol_size);
} }
nr_sss_params_t p = (nr_sss_params_t){.nb_antennas_rx = frame_parms->nb_antennas_rx, nr_sss_params_t p_sss = (nr_sss_params_t){.nb_antennas_rx = frame_parms->nb_antennas_rx,
.samples_per_slot_wCP = frame_parms->samples_per_slot_wCP, .samples_per_slot_wCP = frame_parms->samples_per_slot_wCP,
.ofdm_symbol_size = frame_parms->ofdm_symbol_size, .ofdm_symbol_size = frame_parms->ofdm_symbol_size,
.first_carrier_offset = frame_parms->first_carrier_offset, .first_carrier_offset = frame_parms->first_carrier_offset,
.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier, .ssb_start_subcarrier = frame_parms->ssb_start_subcarrier,
.subcarrier_spacing = frame_parms->subcarrier_spacing}; .subcarrier_spacing = frame_parms->subcarrier_spacing};
sss_detection_result_t res = rx_sss_nr(&p, &pss_res, known_pci, rxdataF); sss_detection_result_t res = rx_sss_nr(&p_sss, &pss_res, known_pci, rxdataF);
if (!res.success) { if (!res.success) {
if (neighboring_cell_info->valid_meas) if (neighboring_cell_info->valid_meas)
......
...@@ -201,15 +201,15 @@ bool nr_search_ssb_common(nr_ssb_search_params_t *params) ...@@ -201,15 +201,15 @@ bool nr_search_ssb_common(nr_ssb_search_params_t *params)
c16_t(*pssTime)[pssTime_sz] = (c16_t(*)[pssTime_sz])params->pssTime; c16_t(*pssTime)[pssTime_sz] = (c16_t(*)[pssTime_sz])params->pssTime;
// Perform PSS search // Perform PSS search
params->pss_res = pss_search_time_nr((const c16_t **)params->rxdata, pss_search_t p_pss = (pss_search_t){.rxdata = params->rxdata,
params->ofdm_symbol_size, .nb_antennas_rx = params->nb_antennas_rx,
params->nb_antennas_rx, .rxdata_length = params->rxdata_size,
params->subcarrier_spacing, .ofdm_symbol_size = params->ofdm_symbol_size,
pssTime, .subcarrier_spacing = params->subcarrier_spacing,
params->fo_flag, .fo_flag = params->fo_flag,
params->target_nid_cell, .target_Nid_cell = params->target_nid_cell,
0, .pssTime = (c16_t *)pssTime};
params->rxdata_size); params->pss_res = pss_search_time_nr(&p_pss);
if (!params->pss_res.success) if (!params->pss_res.success)
return false; return false;
...@@ -240,7 +240,7 @@ bool nr_search_ssb_common(nr_ssb_search_params_t *params) ...@@ -240,7 +240,7 @@ bool nr_search_ssb_common(nr_ssb_search_params_t *params)
do_time_to_freq(params, ssb_time_offset); do_time_to_freq(params, ssb_time_offset);
// Perform SSS detection // Perform SSS detection
nr_sss_params_t p = (nr_sss_params_t){.nb_antennas_rx = params->nb_antennas_rx, nr_sss_params_t p_sss = (nr_sss_params_t){.nb_antennas_rx = params->nb_antennas_rx,
.samples_per_slot_wCP = params->samples_per_slot_wCP, .samples_per_slot_wCP = params->samples_per_slot_wCP,
.ofdm_symbol_size = params->ofdm_symbol_size, .ofdm_symbol_size = params->ofdm_symbol_size,
.first_carrier_offset = params->first_carrier_offset, .first_carrier_offset = params->first_carrier_offset,
...@@ -249,7 +249,7 @@ bool nr_search_ssb_common(nr_ssb_search_params_t *params) ...@@ -249,7 +249,7 @@ bool nr_search_ssb_common(nr_ssb_search_params_t *params)
c16_t(*rxdataF)[params->nb_antennas_rx][params->ofdm_symbol_size] = c16_t(*rxdataF)[params->nb_antennas_rx][params->ofdm_symbol_size] =
(c16_t(*)[params->nb_antennas_rx][params->ofdm_symbol_size])params->rxdataF; (c16_t(*)[params->nb_antennas_rx][params->ofdm_symbol_size])params->rxdataF;
params->sss_res = rx_sss_nr(&p, &params->pss_res, -1, rxdataF); params->sss_res = rx_sss_nr(&p_sss, &params->pss_res, -1, rxdataF);
if (!params->sss_res.success || params->sss_res.nid_cell < 0) { if (!params->sss_res.success || params->sss_res.nid_cell < 0) {
return false; return false;
......
...@@ -159,25 +159,18 @@ void generate_pss_nr_time(int ofdm_symbol_size, ...@@ -159,25 +159,18 @@ void generate_pss_nr_time(int ofdm_symbol_size,
* *
*********************************************************************/ *********************************************************************/
pss_detection_result_t pss_search_time_nr(const c16_t **rxdata, pss_detection_result_t pss_search_time_nr(const pss_search_t *p)
int ofdm_symbol_size,
int nb_antennas_rx,
int subcarrier_spacing,
const c16_t pssTime[NUMBER_PSS_SEQUENCE][ofdm_symbol_size],
bool fo_flag,
int target_Nid_cell,
int start,
int length)
{ {
if (start < 0 || length == 0) { if (p->rxdata_length == 0) {
LOG_E(PHY, "inconsistent call to pss_search_time_nr %d, %d\n", start, length); LOG_E(PHY, "inconsistent call to pss_search_time_nr %d\n", p->rxdata_length);
return (pss_detection_result_t){.success = false}; return (pss_detection_result_t){.success = false};
} }
c16_t(*pssTime)[p->ofdm_symbol_size] = (c16_t(*)[p->ofdm_symbol_size])p->pssTime;
int maxval=0; int maxval=0;
int max_size = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL; int max_size = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL;
for (int j = 0; j < max_size; j++) for (int j = 0; j < max_size; j++)
for (int i = 0; i < ofdm_symbol_size; i++) { for (int i = 0; i < p->ofdm_symbol_size; i++) {
maxval = max(maxval, abs(pssTime[j][i].r)); maxval = max(maxval, abs(pssTime[j][i].r));
maxval = max(maxval, abs(pssTime[j][i].i)); maxval = max(maxval, abs(pssTime[j][i].i));
} }
...@@ -187,60 +180,57 @@ pss_detection_result_t pss_search_time_nr(const c16_t **rxdata, ...@@ -187,60 +180,57 @@ pss_detection_result_t pss_search_time_nr(const c16_t **rxdata,
/* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors. */ /* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors. */
/* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */ /* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */
int pss_index_start; int pss_space[NUMBER_PSS_SEQUENCE+1]={0,1,2,-1};
int pss_index_end; if (p->target_Nid_cell != -1) {
if (target_Nid_cell != -1) { pss_space[0] = GET_NID2(p->target_Nid_cell);
pss_index_start = GET_NID2(target_Nid_cell); pss_space[1] = -1;
pss_index_end = pss_index_start + 1;
} else {
pss_index_start = 0;
pss_index_end = max_size;
} }
int64_t avg[NUMBER_PSS_SEQUENCE] = {0}; int64_t avg[NUMBER_PSS_SEQUENCE] = {0};
int64_t peak_value = 0; int64_t peak_value = 0;
unsigned int peak_position = 0; unsigned int peak_position = 0;
unsigned int pss_source = 0; unsigned int pss_source = 0;
for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++) { for (int i=0; pss_space[i] != -1; i++) {
for (int n = start; n < start + length; n += 4) { // const int pss=pss_space[i];
for (int n = 0; n < p->rxdata_length; n += 4) { //
int64_t pss_corr_ue = 0; int64_t pss_corr_ue = 0;
/* calculate dot product of primary_synchro_time_nr and rxdata[ar][n] /* calculate dot product of primary_synchro_time_nr and rxdata[ar][n]
* (ar=0..nb_ant_rx) and store the sum in temp[n]; */ * (ar=0..nb_ant_rx) and store the sum in temp[n]; */
for (int ar = 0; ar < nb_antennas_rx; ar++) { for (int ar = 0; ar < p->nb_antennas_rx; ar++) {
/* perform correlation of rx data and pss sequence ie it is a dot product */ /* perform correlation of rx data and pss sequence ie it is a dot product */
const c32_t result = dot_product(pssTime[pss_index], &rxdata[ar][n], ofdm_symbol_size, shift); const c32_t result = dot_product(pssTime[pss], &p->rxdata[ar][n], p->ofdm_symbol_size, shift);
const c64_t r64 = {.r = result.r, .i = result.i}; const c64_t r64 = {.r = result.r, .i = result.i};
pss_corr_ue += squaredMod(r64); pss_corr_ue += squaredMod(r64);
} }
/* calculate the absolute value of sync_corr[n] */ /* calculate the absolute value of sync_corr[n] */
avg[pss_index] += pss_corr_ue; avg[pss] += pss_corr_ue;
if (pss_corr_ue > peak_value) { if (pss_corr_ue > peak_value) {
peak_value = pss_corr_ue; peak_value = pss_corr_ue;
peak_position = n; peak_position = n;
pss_source = pss_index; pss_source = pss;
#ifdef DEBUG_PSS_NR #ifdef DEBUG_PSS_NR
printf("pss_index %d: n %6u peak_value %lu\n", pss_index, n, pss_corr_ue); printf("pss_index %d: n %6u peak_value %lu\n", pss, n, pss_corr_ue);
#endif #endif
} }
} }
avg[pss_index] /= (length / 4); avg[pss] /= (p->rxdata_length / 4);
} }
double ffo_est = 0; double ffo_est = 0;
if (fo_flag) { if (p->fo_flag) {
// fractional frequency offset computation according to Cross-correlation Synchronization Algorithm Using PSS // fractional frequency offset computation according to Cross-correlation Synchronization Algorithm Using PSS
// Shoujun Huang, Yongtao Su, Ying He and Shan Tang, "Joint time and frequency offset estimation in LTE downlink," 7th // Shoujun Huang, Yongtao Su, Ying He and Shan Tang, "Joint time and frequency offset estimation in LTE downlink," 7th
// International Conference on Communications and Networking in China, 2012. // International Conference on Communications and Networking in China, 2012.
// Computing cross-correlation at peak on half the symbol size for first half of data // Computing cross-correlation at peak on half the symbol size for first half of data
c32_t r1 = dot_product(pssTime[pss_source], &(rxdata[0][peak_position]), ofdm_symbol_size >> 1, shift); c32_t r1 = dot_product(pssTime[pss_source], &p->rxdata[0][peak_position], p->ofdm_symbol_size >> 1, shift);
// Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size // Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size
// as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift // as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift
c32_t r2 = dot_product(pssTime[pss_source] + (ofdm_symbol_size >> 1), c32_t r2 = dot_product(pssTime[pss_source] + (p->ofdm_symbol_size >> 1),
&(rxdata[0][peak_position]) + (ofdm_symbol_size >> 1), &p->rxdata[0][peak_position] + (p->ofdm_symbol_size >> 1),
ofdm_symbol_size >> 1, p->ofdm_symbol_size >> 1,
shift); shift);
cd_t r1d = {r1.r, r1.i}, r2d = {r2.r, r2.i}; cd_t r1d = {r1.r, r1.i}, r2d = {r2.r, r2.i};
// estimation of fractional frequency offset: angle[(result1)'*(result2)]/pi // estimation of fractional frequency offset: angle[(result1)'*(result2)]/pi
...@@ -276,7 +266,7 @@ pss_detection_result_t pss_search_time_nr(const c16_t **rxdata, ...@@ -276,7 +266,7 @@ pss_detection_result_t pss_search_time_nr(const c16_t **rxdata,
return (pss_detection_result_t){.success = true, return (pss_detection_result_t){.success = true,
.nid2 = pss_source, .nid2 = pss_source,
.pos = peak_position, .pos = peak_position,
.freq_offset = ffo_est * subcarrier_spacing, .freq_offset = ffo_est * p->subcarrier_spacing,
.peak = dB_fixed64(peak_value), .peak = dB_fixed64(peak_value),
.avg = dB_fixed64(avg[pss_source])}; .avg = dB_fixed64(avg[pss_source])};
} }
......
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