Commit 9a4294eb authored by Laurent THOMAS's avatar Laurent THOMAS

for_review_then_squash

parent a95dffc8
...@@ -202,7 +202,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, ...@@ -202,7 +202,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
return(0); return(0);
} }
int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, c16_t *output) void nr_pbch_dmrs_rx(const int symbol, const unsigned int *nr_gold_pbch, c16_t *output)
{ {
int m,m0,m1; int m,m0,m1;
uint8_t idx=0; uint8_t idx=0;
...@@ -232,8 +232,6 @@ int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, c16_t *output) ...@@ -232,8 +232,6 @@ int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, c16_t *output)
} }
#endif #endif
} }
return(0);
} }
/*! /*!
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS. /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
*/ */
int nr_pbch_dmrs_rx(int dmrss, unsigned int *nr_gold_pbch, c16_t *output); void nr_pbch_dmrs_rx(const int dmrss, const unsigned int *nr_gold_pbch, c16_t *output);
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS. /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
......
...@@ -631,28 +631,19 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ...@@ -631,28 +631,19 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
return(0); return(0);
} }
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
unsigned char symbol, const int symbol,
int dmrss, const int dmrss,
NR_UE_SSB *current_ssb, const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{ {
c16_t pilot[200] __attribute__((aligned(16))); AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
unsigned int pilot_cnt;
int symbol_offset;
uint8_t ssb_index=current_ssb->i_ssb;
uint8_t n_hf=current_ssb->n_hf;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size; if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
AssertFatal(dmrss >= 0 && dmrss < 3, int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol;
"symbol %d is illegal for PBCH DM-RS \n",
dmrss);
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
unsigned int k = ue->frame_parms.Nid_cell % 4; unsigned int k = ue->frame_parms.Nid_cell % 4;
...@@ -665,64 +656,64 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, ...@@ -665,64 +656,64 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
// generate pilot // generate pilot
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], pilot); c16_t pilot[200] __attribute__((aligned(16)));
nr_pbch_dmrs_rx(dmrss, nr_gold_pbch, pilot);
c32_t computed_val = {0};
for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
int re_offset = ssb_offset; int re_offset = ssb_offset;
c16_t *pil = pilot; c16_t *pil = pilot;
c16_t *rxF = &rxdataF[aarx][symbol_offset + k]; const c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", ue->frame_parms.N_RB_DL); DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", ue->frame_parms.N_RB_DL);
DEBUG_PBCH("k %d, first_carrier %d\n", k, ue->frame_parms.first_carrier_offset); DEBUG_PBCH("k %d, first_carrier %d\n", k, ue->frame_parms.first_carrier_offset);
//if ((ue->frame_parms.N_RB_DL&1)==0) {
// Treat first 2 pilots specially (left edge) // Treat first 2 pilots specially (left edge)
current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("ch 0 %d\n", pil->r * rxF[re_offset].r - pil->i * rxF[re_offset].i); DEBUG_PBCH("ch 0 %d\n", pil->r * rxF[re_offset].r - pil->i * rxF[re_offset].i);
DEBUG_PBCH("pilot 0 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); DEBUG_PBCH("pilot 0 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++; pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot 1 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); DEBUG_PBCH("pilot 1 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++; pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot 2 : rxF - > (%d,%d), pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); DEBUG_PBCH("pilot 2 : rxF - > (%d,%d), pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++; pil++;
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size;
for (pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) { for (int pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) {
// in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS)
if (dmrss == 1 && pilot_cnt == 12) { if (dmrss == 1 && pilot_cnt == 12) {
pilot_cnt=48; pilot_cnt=48;
re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size;
} }
current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++; pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 1, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 1, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++; pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 2, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 2, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++; pil++;
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size;
} }
} }
return(0); return computed_val;
} }
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
......
...@@ -57,12 +57,12 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -57,12 +57,12 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
c16_t pdcch_dl_ch_estimates[][pdcch_est_size], c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
unsigned char symbol, const int symbol,
int dmrss, const int dmrss,
NR_UE_SSB *current_ssb, const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
int estimateSz, int estimateSz,
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "PHY/NR_REFSIG/pss_nr.h" #include "PHY/NR_REFSIG/pss_nr.h"
#include "PHY/NR_REFSIG/sss_nr.h" #include "PHY/NR_REFSIG/sss_nr.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/TOOLS/tools_defs.h"
//static nfapi_nr_config_request_t config_t; //static nfapi_nr_config_request_t config_t;
//static nfapi_nr_config_request_t* config =&config_t; //static nfapi_nr_config_request_t* config =&config_t;
...@@ -52,11 +53,22 @@ int cnt=0; ...@@ -52,11 +53,22 @@ int cnt=0;
// #define DEBUG_INITIAL_SYNCH // #define DEBUG_INITIAL_SYNCH
#define DUMP_PBCH_CH_ESTIMATES 0 #define DUMP_PBCH_CH_ESTIMATES 0
// structure used for multiple SSB detection
typedef struct NR_UE_SSB {
uint i_ssb; // i_ssb between 0 and 7 (it corresponds to ssb_index only for Lmax=4,8)
uint n_hf; // n_hf = 0,1 for Lmax =4 or n_hf = 0 for Lmax =8,64
uint32_t metric; // metric to order SSB hypothesis
} NR_UE_SSB;
int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, static int ssb_sort(const void *a, const void *b)
PHY_VARS_NR_UE *ue, {
int pbch_initial_symbol, return ((NR_UE_SSB *)b)->metric - ((NR_UE_SSB *)a)->metric;
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) }
static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *ue,
int pbch_initial_symbol,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{ {
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
...@@ -64,54 +76,62 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, ...@@ -64,54 +76,62 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
const int N_hf = (frame_parms->Lmax == 4) ? 2 : 1; const int N_hf = (frame_parms->Lmax == 4) ? 2 : 1;
NR_UE_SSB best_ssb[N_L * N_hf]; NR_UE_SSB best_ssb[N_L * N_hf];
NR_UE_SSB *current_ssb = best_ssb; NR_UE_SSB *current_ssb = best_ssb;
// loops over possible pbch dmrs cases to retrive best estimated i_ssb (and n_hf for Lmax=4) for multiple ssb detection // loops over possible pbch dmrs cases to retrieve best estimated i_ssb (and n_hf for Lmax=4) for multiple ssb detection
start_meas(&ue->dlsch_channel_estimation_stats);
for (int hf = 0; hf < N_hf; hf++) { for (int hf = 0; hf < N_hf; hf++) {
for (int l = 0; l < N_L ; l++) { for (int l = 0; l < N_L; l++) {
// initialization of structure
*current_ssb = (NR_UE_SSB){.i_ssb = l, .n_hf = hf};
start_meas(&ue->dlsch_channel_estimation_stats);
// computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf // computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++) c32_t cumul = {0};
nr_pbch_dmrs_correlation(ue, proc, i, i - pbch_initial_symbol, current_ssb, rxdataF); for (int i = pbch_initial_symbol; i < pbch_initial_symbol + 3; i++) {
stop_meas(&ue->dlsch_channel_estimation_stats); c32_t meas = nr_pbch_dmrs_correlation(ue, proc, i, i - pbch_initial_symbol, ue->nr_gold_pbch[hf][l], rxdataF);
csum(cumul, cumul, meas);
}
// initialization of structure
*current_ssb = (NR_UE_SSB){.i_ssb = l, .n_hf = hf, .metric = squaredMod(cumul)};
current_ssb++; current_ssb++;
} }
} }
qsort(best_ssb, N_L * N_hf, sizeof(NR_UE_SSB), ssb_sort);
stop_meas(&ue->dlsch_channel_estimation_stats);
for (NR_UE_SSB *temp_ptr = best_ssb; ret != 0 && temp_ptr < best_ssb + N_L * N_hf; temp_ptr++) { const int nb_ant = frame_parms->nb_antennas_rx;
for (NR_UE_SSB *ssb = best_ssb; ssb < best_ssb + N_L * N_hf; ssb++) {
start_meas(&ue->dlsch_channel_estimation_stats); start_meas(&ue->dlsch_channel_estimation_stats);
// computing channel estimation for selected best ssb // computing channel estimation for selected best ssb
const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz]; __attribute__((aligned(32))) c16_t dl_ch_estimates[nb_ant][estimateSz];
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; __attribute__((aligned(32))) c16_t dl_ch_estimates_time[nb_ant][frame_parms->ofdm_symbol_size];
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++) for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
nr_pbch_channel_estimation(ue,estimateSz, dl_ch_estimates, dl_ch_estimates_time, nr_pbch_channel_estimation(ue,
proc,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf,rxdataF); estimateSz,
dl_ch_estimates,
dl_ch_estimates_time,
proc,
i,
i - pbch_initial_symbol,
ssb->i_ssb,
ssb->n_hf,
rxdataF);
stop_meas(&ue->dlsch_channel_estimation_stats); stop_meas(&ue->dlsch_channel_estimation_stats);
fapiPbch_t result = {0}; fapiPbch_t result = {0};
if (0 == nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, frame_parms, ssb->i_ssb, &result, rxdataF)) {
int pbch_res = nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, frame_parms, temp_ptr->i_ssb, &result, rxdataF); if (DUMP_PBCH_CH_ESTIMATES) {
ret = pbch_res == 0; write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, nb_ant * estimateSz, 1, 1);
write_output("pbch_ch_estimates_time.m",
if (DUMP_PBCH_CH_ESTIMATES && ret) { "pbch_ch_estimates_time",
write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, frame_parms->nb_antennas_rx*estimateSz, 1, 1); dl_ch_estimates_time,
write_output("pbch_ch_estimates_time.m", nb_ant * frame_parms->ofdm_symbol_size,
"pbch_ch_estimates_time", 1,
dl_ch_estimates_time, 1);
frame_parms->nb_antennas_rx * frame_parms->ofdm_symbol_size, }
1, return false;
1);
} }
} }
if (ret == 0) { LOG_W(PHY, "[UE%d] Initial sync: pbch not decoded, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); return true;
} else {
LOG_W(PHY, "[UE%d] Initial sync: pbch not decoded, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
}
return ret;
} }
nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa) nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa)
......
...@@ -307,13 +307,6 @@ typedef struct { ...@@ -307,13 +307,6 @@ typedef struct {
fapi_nr_ul_config_srs_pdu srs_config_pdu; fapi_nr_ul_config_srs_pdu srs_config_pdu;
} NR_UE_SRS; } NR_UE_SRS;
// structure used for multiple SSB detection
typedef struct NR_UE_SSB {
uint8_t i_ssb; // i_ssb between 0 and 7 (it corresponds to ssb_index only for Lmax=4,8)
uint8_t n_hf; // n_hf = 0,1 for Lmax =4 or n_hf = 0 for Lmax =8,64
c32_t c;
} NR_UE_SSB;
typedef struct UE_NR_SCAN_INFO_s { typedef struct UE_NR_SCAN_INFO_s {
/// 10 best amplitudes (linear) for each pss signals /// 10 best amplitudes (linear) for each pss signals
int32_t amp[3][10]; int32_t amp[3][10];
......
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