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,
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;
uint8_t idx=0;
......@@ -232,8 +232,6 @@ int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, c16_t *output)
}
#endif
}
return(0);
}
/*!
......
......@@ -30,7 +30,7 @@
/*!\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
*/
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.
@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,
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,
unsigned char symbol,
int dmrss,
NR_UE_SSB *current_ssb,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
const int symbol,
const int dmrss,
const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD],
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
c16_t pilot[200] __attribute__((aligned(16)));
unsigned int pilot_cnt;
int symbol_offset;
uint8_t ssb_index=current_ssb->i_ssb;
uint8_t n_hf=current_ssb->n_hf;
AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
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;
AssertFatal(dmrss >= 0 && dmrss < 3,
"symbol %d is illegal for PBCH DM-RS \n",
dmrss);
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol;
unsigned int k = ue->frame_parms.Nid_cell % 4;
......@@ -665,64 +656,64 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
// generate pilot
// 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++) {
int re_offset = ssb_offset;
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("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)
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("pilot 0 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
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);
pil++;
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);
pil++;
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)
if (dmrss == 1 && pilot_cnt == 12) {
pilot_cnt=48;
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);
pil++;
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);
pil++;
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);
pil++;
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,
......
......@@ -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 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,
unsigned char symbol,
int dmrss,
NR_UE_SSB *current_ssb,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
const int symbol,
const int dmrss,
const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD],
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
int estimateSz,
......
......@@ -44,6 +44,7 @@
#include "PHY/NR_REFSIG/pss_nr.h"
#include "PHY/NR_REFSIG/sss_nr.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 =&config_t;
......@@ -52,8 +53,19 @@ int cnt=0;
// #define DEBUG_INITIAL_SYNCH
#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)
{
return ((NR_UE_SSB *)b)->metric - ((NR_UE_SSB *)a)->metric;
}
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])
......@@ -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;
NR_UE_SSB best_ssb[N_L * N_hf];
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
for (int hf = 0; hf < N_hf; hf++) {
for (int l = 0; l < N_L ; l++) {
// initialization of structure
*current_ssb = (NR_UE_SSB){.i_ssb = l, .n_hf = hf};
// 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 l = 0; l < N_L; l++) {
// 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++)
nr_pbch_dmrs_correlation(ue, proc, i, i - pbch_initial_symbol, current_ssb, rxdataF);
stop_meas(&ue->dlsch_channel_estimation_stats);
c32_t cumul = {0};
for (int i = pbch_initial_symbol; i < pbch_initial_symbol + 3; i++) {
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++;
}
}
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);
// computing channel estimation for selected best ssb
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))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
__attribute__((aligned(32))) c16_t dl_ch_estimates[nb_ant][estimateSz];
__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++)
nr_pbch_channel_estimation(ue,estimateSz, dl_ch_estimates, dl_ch_estimates_time,
proc,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf,rxdataF);
nr_pbch_channel_estimation(ue,
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);
fapiPbch_t result = {0};
int pbch_res = nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, frame_parms, temp_ptr->i_ssb, &result, rxdataF);
ret = pbch_res == 0;
if (DUMP_PBCH_CH_ESTIMATES && ret) {
write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, frame_parms->nb_antennas_rx*estimateSz, 1, 1);
if (0 == nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, frame_parms, ssb->i_ssb, &result, rxdataF)) {
if (DUMP_PBCH_CH_ESTIMATES) {
write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, nb_ant * estimateSz, 1, 1);
write_output("pbch_ch_estimates_time.m",
"pbch_ch_estimates_time",
dl_ch_estimates_time,
frame_parms->nb_antennas_rx * frame_parms->ofdm_symbol_size,
nb_ant * frame_parms->ofdm_symbol_size,
1,
1);
}
return false;
}
}
if (ret == 0) {
LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
} else {
LOG_W(PHY, "[UE%d] Initial sync: pbch not decoded, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
}
return ret;
return true;
}
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 {
fapi_nr_ul_config_srs_pdu srs_config_pdu;
} 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 {
/// 10 best amplitudes (linear) for each pss signals
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