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 @@
#define SYNCHRO_RATE_CHANGE_FACTOR (1)
#endif
pss_detection_result_t pss_search_time_nr(const c16_t **rxdata,
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 search_start,
int search_length);
typedef struct {
c16_t **rxdata;
int nb_antennas_rx;
int rxdata_length;
int ofdm_symbol_size;
int subcarrier_spacing;
bool fo_flag;
int target_Nid_cell;
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,
int first_carrier_offset,
......
......@@ -283,18 +283,20 @@ static bool validate_known_pci(NR_DL_FRAME_PARMS *frame_parms,
{
int known_pci = nr_neighboring_cell->Nid_cell;
int start = neighboring_cell_info->pss_search_start;
int length = neighboring_cell_info->pss_search_length;
pss_detection_result_t pss_res = pss_search_time_nr((const c16_t **)rxdata,
frame_parms->ofdm_symbol_size,
frame_parms->nb_antennas_rx,
frame_parms->subcarrier_spacing,
pssTime,
false, // no frequency offset estimation for tracking
known_pci,
start,
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_search_t p_pss = (pss_search_t){.rxdata = rx,
.nb_antennas_rx = frame_parms->nb_antennas_rx,
.rxdata_length = length,
.ofdm_symbol_size = frame_parms->ofdm_symbol_size,
.subcarrier_spacing = frame_parms->subcarrier_spacing,
.fo_flag = false,
.target_Nid_cell = known_pci,
.pssTime = (c16_t *)pssTime};
pss_detection_result_t pss_res = pss_search_time_nr(&p_pss);
if (!pss_res.success) {
if (neighboring_cell_info->valid_meas)
......@@ -302,7 +304,7 @@ static bool validate_known_pci(NR_DL_FRAME_PARMS *frame_parms,
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",
known_pci,
start,
neighboring_cell_info->pss_search_start,
length,
pss_res.peak,
pss_res.avg,
......@@ -310,7 +312,7 @@ static bool validate_known_pci(NR_DL_FRAME_PARMS *frame_parms,
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)
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,
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,
.samples_per_slot_wCP = frame_parms->samples_per_slot_wCP,
.ofdm_symbol_size = frame_parms->ofdm_symbol_size,
.first_carrier_offset = frame_parms->first_carrier_offset,
.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier,
.subcarrier_spacing = frame_parms->subcarrier_spacing};
sss_detection_result_t res = rx_sss_nr(&p, &pss_res, known_pci, rxdataF);
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,
.ofdm_symbol_size = frame_parms->ofdm_symbol_size,
.first_carrier_offset = frame_parms->first_carrier_offset,
.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier,
.subcarrier_spacing = frame_parms->subcarrier_spacing};
sss_detection_result_t res = rx_sss_nr(&p_sss, &pss_res, known_pci, rxdataF);
if (!res.success) {
if (neighboring_cell_info->valid_meas)
......
......@@ -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;
// Perform PSS search
params->pss_res = pss_search_time_nr((const c16_t **)params->rxdata,
params->ofdm_symbol_size,
params->nb_antennas_rx,
params->subcarrier_spacing,
pssTime,
params->fo_flag,
params->target_nid_cell,
0,
params->rxdata_size);
pss_search_t p_pss = (pss_search_t){.rxdata = params->rxdata,
.nb_antennas_rx = params->nb_antennas_rx,
.rxdata_length = params->rxdata_size,
.ofdm_symbol_size = params->ofdm_symbol_size,
.subcarrier_spacing = params->subcarrier_spacing,
.fo_flag = params->fo_flag,
.target_Nid_cell = params->target_nid_cell,
.pssTime = (c16_t *)pssTime};
params->pss_res = pss_search_time_nr(&p_pss);
if (!params->pss_res.success)
return false;
......@@ -240,16 +240,16 @@ bool nr_search_ssb_common(nr_ssb_search_params_t *params)
do_time_to_freq(params, ssb_time_offset);
// Perform SSS detection
nr_sss_params_t p = (nr_sss_params_t){.nb_antennas_rx = params->nb_antennas_rx,
.samples_per_slot_wCP = params->samples_per_slot_wCP,
.ofdm_symbol_size = params->ofdm_symbol_size,
.first_carrier_offset = params->first_carrier_offset,
.ssb_start_subcarrier = params->ssb_start_subcarrier,
.subcarrier_spacing = params->subcarrier_spacing};
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,
.ofdm_symbol_size = params->ofdm_symbol_size,
.first_carrier_offset = params->first_carrier_offset,
.ssb_start_subcarrier = params->ssb_start_subcarrier,
.subcarrier_spacing = params->subcarrier_spacing};
c16_t(*rxdataF)[params->nb_antennas_rx][params->ofdm_symbol_size] =
(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) {
return false;
......
......@@ -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,
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)
pss_detection_result_t pss_search_time_nr(const pss_search_t *p)
{
if (start < 0 || length == 0) {
LOG_E(PHY, "inconsistent call to pss_search_time_nr %d, %d\n", start, length);
if (p->rxdata_length == 0) {
LOG_E(PHY, "inconsistent call to pss_search_time_nr %d\n", p->rxdata_length);
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 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 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].i));
}
......@@ -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. */
/* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */
int pss_index_start;
int pss_index_end;
if (target_Nid_cell != -1) {
pss_index_start = GET_NID2(target_Nid_cell);
pss_index_end = pss_index_start + 1;
} else {
pss_index_start = 0;
pss_index_end = max_size;
int pss_space[NUMBER_PSS_SEQUENCE+1]={0,1,2,-1};
if (p->target_Nid_cell != -1) {
pss_space[0] = GET_NID2(p->target_Nid_cell);
pss_space[1] = -1;
}
int64_t avg[NUMBER_PSS_SEQUENCE] = {0};
int64_t peak_value = 0;
unsigned int peak_position = 0;
unsigned int pss_source = 0;
for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++) {
for (int n = start; n < start + length; n += 4) { //
for (int i=0; pss_space[i] != -1; i++) {
const int pss=pss_space[i];
for (int n = 0; n < p->rxdata_length; n += 4) { //
int64_t pss_corr_ue = 0;
/* calculate dot product of primary_synchro_time_nr and rxdata[ar][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 */
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};
pss_corr_ue += squaredMod(r64);
}
/* 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) {
peak_value = pss_corr_ue;
peak_position = n;
pss_source = pss_index;
pss_source = pss;
#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
}
}
avg[pss_index] /= (length / 4);
avg[pss] /= (p->rxdata_length / 4);
}
double ffo_est = 0;
if (fo_flag) {
if (p->fo_flag) {
// 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
// International Conference on Communications and Networking in China, 2012.
// 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
// 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),
&(rxdata[0][peak_position]) + (ofdm_symbol_size >> 1),
ofdm_symbol_size >> 1,
c32_t r2 = dot_product(pssTime[pss_source] + (p->ofdm_symbol_size >> 1),
&p->rxdata[0][peak_position] + (p->ofdm_symbol_size >> 1),
p->ofdm_symbol_size >> 1,
shift);
cd_t r1d = {r1.r, r1.i}, r2d = {r2.r, r2.i};
// 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,
return (pss_detection_result_t){.success = true,
.nid2 = pss_source,
.pos = peak_position,
.freq_offset = ffo_est * subcarrier_spacing,
.freq_offset = ffo_est * p->subcarrier_spacing,
.peak = dB_fixed64(peak_value),
.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