for_review_then_squash
This commit is contained in:
@@ -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,
|
||||
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])
|
||||
c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
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,
|
||||
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]);
|
||||
c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
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,11 +53,22 @@ 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,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
int pbch_initial_symbol,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||
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])
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
|
||||
@@ -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
|
||||
// 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++) {
|
||||
// initialization of structure
|
||||
*current_ssb = (NR_UE_SSB){.i_ssb = l, .n_hf = hf};
|
||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||
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);
|
||||
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,
|
||||
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,
|
||||
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;
|
||||
LOG_W(PHY, "[UE%d] Initial sync: pbch not decoded, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
|
||||
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];
|
||||
|
||||
Reference in New Issue
Block a user