Commit 9a2e080f authored by Robert Schmidt's avatar Robert Schmidt

Apply clang-format

parent 94b23d1e
...@@ -33,11 +33,11 @@ ...@@ -33,11 +33,11 @@
#ifndef __NR_POLAR_PSBCH_DEFS__H__ #ifndef __NR_POLAR_PSBCH_DEFS__H__
#define __NR_POLAR_PSBCH_DEFS__H__ #define __NR_POLAR_PSBCH_DEFS__H__
//PSBCH related polar parameters. // PSBCH related polar parameters.
//PSBCH symbols sent in 11RBS, 9 symbols. 11*9*(12-3(for DMRS))*2bits = 1782 bits // PSBCH symbols sent in 11RBS, 9 symbols. 11*9*(12-3(for DMRS))*2bits = 1782 bits
#define SL_NR_POLAR_PSBCH_E_NORMAL_CP 1782 #define SL_NR_POLAR_PSBCH_E_NORMAL_CP 1782
//PSBCH symbols sent in 11RBS, 7 symbols. 11*7*(12-3(for DMRS))*2bits = 1386 bits // PSBCH symbols sent in 11RBS, 7 symbols. 11*7*(12-3(for DMRS))*2bits = 1386 bits
#define SL_NR_POLAR_PSBCH_E_EXT_CP 1386 #define SL_NR_POLAR_PSBCH_E_EXT_CP 1386
// SL_NR_POLAR_PSBCH_E_NORMAL_CP/32 // SL_NR_POLAR_PSBCH_E_NORMAL_CP/32
#define SL_NR_POLAR_PSBCH_E_DWORD 56 #define SL_NR_POLAR_PSBCH_E_DWORD 56
......
...@@ -192,7 +192,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui ...@@ -192,7 +192,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode->payloadBits = messageLength; newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS; newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS;
//LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level); //LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level);
} else if (messageType == SL_NR_POLAR_PSBCH_MESSAGE_TYPE) { //PSBCH } else if (messageType == SL_NR_POLAR_PSBCH_MESSAGE_TYPE) { // PSBCH
newPolarInitNode->n_max = SL_NR_POLAR_PSBCH_N_MAX; newPolarInitNode->n_max = SL_NR_POLAR_PSBCH_N_MAX;
newPolarInitNode->i_il = SL_NR_POLAR_PSBCH_I_IL; newPolarInitNode->i_il = SL_NR_POLAR_PSBCH_I_IL;
newPolarInitNode->i_seg = SL_NR_POLAR_PSBCH_I_SEG; newPolarInitNode->i_seg = SL_NR_POLAR_PSBCH_I_SEG;
...@@ -203,8 +203,11 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui ...@@ -203,8 +203,11 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode->payloadBits = SL_NR_POLAR_PSBCH_PAYLOAD_BITS; newPolarInitNode->payloadBits = SL_NR_POLAR_PSBCH_PAYLOAD_BITS;
newPolarInitNode->encoderLength = SL_NR_POLAR_PSBCH_E_NORMAL_CP + 2; newPolarInitNode->encoderLength = SL_NR_POLAR_PSBCH_E_NORMAL_CP + 2;
newPolarInitNode->crcCorrectionBits = SL_NR_POLAR_PSBCH_CRC_ERROR_CORRECTION_BITS; newPolarInitNode->crcCorrectionBits = SL_NR_POLAR_PSBCH_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits); // G_P
LOG_D(PHY,"SIDELINK: Initializing polar parameters for PSBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength); LOG_D(PHY,
"SIDELINK: Initializing polar parameters for PSBCH (K %d, E %d)\n",
newPolarInitNode->payloadBits,
newPolarInitNode->encoderLength);
} else { } else {
AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType); AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType);
} }
......
...@@ -385,7 +385,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) ...@@ -385,7 +385,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
static void sl_ue_free(PHY_VARS_NR_UE *UE) static void sl_ue_free(PHY_VARS_NR_UE *UE)
{ {
if (UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation) { if (UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation) {
free_and_zero(UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[0]); free_and_zero(UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[0]);
free_and_zero(UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[1]); free_and_zero(UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[1]);
...@@ -716,21 +715,20 @@ void phy_term_nr_top(void) ...@@ -716,21 +715,20 @@ void phy_term_nr_top(void)
void sl_ue_phy_init(PHY_VARS_NR_UE *UE) void sl_ue_phy_init(PHY_VARS_NR_UE *UE)
{ {
uint16_t scaling_value = ONE_OVER_SQRT2_Q15; uint16_t scaling_value = ONE_OVER_SQRT2_Q15;
NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
if (!UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation) { if (!UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation) {
UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation = (int32_t **)malloc16_clear(SL_NR_NUM_IDs_IN_PSS *sizeof(int32_t *) ); UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation = malloc16_clear(SL_NR_NUM_IDs_IN_PSS * sizeof(int32_t *));
UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[0] = (int32_t *)malloc16_clear( sizeof(int32_t)*sl_fp->ofdm_symbol_size); UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[0] = malloc16_clear(sizeof(int32_t) * sl_fp->ofdm_symbol_size);
UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[1] = (int32_t *)malloc16_clear( sizeof(int32_t)*sl_fp->ofdm_symbol_size); UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[1] = malloc16_clear(sizeof(int32_t) * sl_fp->ofdm_symbol_size);
} }
LOG_I(PHY, "SIDELINK INIT: GENERATE PSS, SSS, GOLD SEQUENCES AND PSBCH DMRS SEQUENCES FOR ALL possible SLSS IDs 0- 671\n"); LOG_I(PHY, "SIDELINK INIT: GENERATE PSS, SSS, GOLD SEQUENCES AND PSBCH DMRS SEQUENCES FOR ALL possible SLSS IDs 0- 671\n");
// Generate PSS sequences for IDs 0,1 used in PSS // Generate PSS sequences for IDs 0,1 used in PSS
sl_generate_pss(&UE->SL_UE_PHY_PARAMS.init_params,0, scaling_value); sl_generate_pss(&UE->SL_UE_PHY_PARAMS.init_params, 0, scaling_value);
sl_generate_pss(&UE->SL_UE_PHY_PARAMS.init_params,1, scaling_value); sl_generate_pss(&UE->SL_UE_PHY_PARAMS.init_params, 1, scaling_value);
// Generate psbch dmrs Gold Sequences and modulated dmrs symbols // Generate psbch dmrs Gold Sequences and modulated dmrs symbols
sl_init_psbch_dmrs_gold_sequences(UE); sl_init_psbch_dmrs_gold_sequences(UE);
...@@ -745,4 +743,3 @@ void sl_ue_phy_init(PHY_VARS_NR_UE *UE) ...@@ -745,4 +743,3 @@ void sl_ue_phy_init(PHY_VARS_NR_UE *UE)
init_symbol_rotation(sl_fp); init_symbol_rotation(sl_fp);
init_timeshift_rotation(sl_fp); init_timeshift_rotation(sl_fp);
} }
...@@ -425,8 +425,7 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp) ...@@ -425,8 +425,7 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame); LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame);
LOG_I(PHY,"fp->dl_CarrierFreq=%lu\n",fp->dl_CarrierFreq); LOG_I(PHY,"fp->dl_CarrierFreq=%lu\n",fp->dl_CarrierFreq);
LOG_I(PHY,"fp->ul_CarrierFreq=%lu\n",fp->ul_CarrierFreq); LOG_I(PHY,"fp->ul_CarrierFreq=%lu\n",fp->ul_CarrierFreq);
LOG_I(PHY,"fp->Nid_cell=%d\n",fp->Nid_cell); LOG_I(PHY, "fp->Nid_cell=%d\n", fp->Nid_cell);
LOG_I(PHY,"fp->first_carrier_offset=%d\n",fp->first_carrier_offset); LOG_I(PHY, "fp->first_carrier_offset=%d\n", fp->first_carrier_offset);
LOG_I(PHY,"fp->ssb_start_subcarrier=%d\n",fp->ssb_start_subcarrier); LOG_I(PHY, "fp->ssb_start_subcarrier=%d\n", fp->ssb_start_subcarrier);
} }
...@@ -55,11 +55,11 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -55,11 +55,11 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
c16_t rxdataF[][frame_parms->samples_per_slot_wCP], c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
uint32_t linktype); uint32_t linktype);
int sl_nr_slot_fep(PHY_VARS_NR_UE *ue, int sl_nr_slot_fep(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc, UE_nr_rxtx_proc_t *proc,
unsigned char symbol, unsigned char symbol,
unsigned char Ns, unsigned char Ns,
uint32_t sample_offset, uint32_t sample_offset,
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]); c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]);
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
......
...@@ -35,33 +35,34 @@ ...@@ -35,33 +35,34 @@
#endif*/ #endif*/
int sl_nr_slot_fep(PHY_VARS_NR_UE *ue, int sl_nr_slot_fep(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc, UE_nr_rxtx_proc_t *proc,
unsigned char symbol, unsigned char symbol,
unsigned char Ns, unsigned char Ns,
uint32_t sample_offset, uint32_t sample_offset,
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]) c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP])
{ {
NR_DL_FRAME_PARMS *frame_params = &ue->SL_UE_PHY_PARAMS.sl_frame_params; NR_DL_FRAME_PARMS *frame_params = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
NR_UE_COMMON *common_vars = &ue->common_vars; NR_UE_COMMON *common_vars = &ue->common_vars;
AssertFatal(symbol < frame_params->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_params->symbols_per_slot-1); AssertFatal(symbol < frame_params->symbols_per_slot,
AssertFatal(Ns < frame_params->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_params->slots_per_frame-1); "slot_fep: symbol must be between 0 and %d\n",
frame_params->symbols_per_slot - 1);
AssertFatal(Ns < frame_params->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_params->slots_per_frame - 1);
unsigned int nb_prefix_samples = frame_params->nb_prefix_samples; unsigned int nb_prefix_samples = frame_params->nb_prefix_samples;
unsigned int nb_prefix_samples0 = frame_params->nb_prefix_samples0; unsigned int nb_prefix_samples0 = frame_params->nb_prefix_samples0;
dft_size_idx_t dftsize = get_dft(frame_params->ofdm_symbol_size); dft_size_idx_t dftsize = get_dft(frame_params->ofdm_symbol_size);
// This is for misalignment issues // This is for misalignment issues
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); int32_t tmp_dft_in[8192] __attribute__((aligned(32)));
unsigned int rx_offset = frame_params->get_samples_slot_timestamp(Ns,frame_params,0); unsigned int rx_offset = frame_params->get_samples_slot_timestamp(Ns, frame_params, 0);
unsigned int abs_symbol = Ns * frame_params->symbols_per_slot + symbol; unsigned int abs_symbol = Ns * frame_params->symbols_per_slot + symbol;
rx_offset += sample_offset; rx_offset += sample_offset;
for (int idx_symb = Ns*frame_params->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++) for (int idx_symb = Ns * frame_params->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (idx_symb%(0x7<<frame_params->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; rx_offset += (idx_symb % (0x7 << frame_params->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rx_offset += frame_params->ofdm_symbol_size * symbol; rx_offset += frame_params->ofdm_symbol_size * symbol;
// use OFDM symbol from within 1/8th of the CP to avoid ISI // use OFDM symbol from within 1/8th of the CP to avoid ISI
...@@ -69,58 +70,61 @@ int sl_nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -69,58 +70,61 @@ int sl_nr_slot_fep(PHY_VARS_NR_UE *ue,
#ifdef SL_DEBUG_SLOT_FEP #ifdef SL_DEBUG_SLOT_FEP
// if (ue->frame <100) // if (ue->frame <100)
LOG_I(PHY, "slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n", LOG_I(PHY,
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset); "slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n",
Ns,
symbol,
nb_prefix_samples,
nb_prefix_samples0,
rx_offset);
#endif #endif
for (unsigned char aa=0; aa<frame_params->nb_antennas_rx; aa++) { for (unsigned char aa = 0; aa < frame_params->nb_antennas_rx; aa++) {
memset(&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],0,frame_params->ofdm_symbol_size*sizeof(int32_t)); memset(&rxdataF[aa][frame_params->ofdm_symbol_size * symbol], 0, frame_params->ofdm_symbol_size * sizeof(int32_t));
int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset]; int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset];
// if input to dft is not 256-bit aligned // if input to dft is not 256-bit aligned
if ((rx_offset & 7) != 0) { if ((rx_offset & 7) != 0) {
memcpy((void *)&tmp_dft_in[0], memcpy((void *)&tmp_dft_in[0], (void *)&common_vars->rxdata[aa][rx_offset], frame_params->ofdm_symbol_size * sizeof(int32_t));
(void *)&common_vars->rxdata[aa][rx_offset],
frame_params->ofdm_symbol_size * sizeof(int32_t));
rxdata_ptr = (int16_t *)tmp_dft_in; rxdata_ptr = (int16_t *)tmp_dft_in;
} }
dft(dftsize, dft(dftsize, rxdata_ptr, (int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size * symbol], 1);
rxdata_ptr,
(int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],
1);
int symb_offset = (Ns%frame_params->slots_per_subframe)*frame_params->symbols_per_slot; int symb_offset = (Ns % frame_params->slots_per_subframe) * frame_params->symbols_per_slot;
int32_t rot2 = ((uint32_t*)frame_params->symbol_rotation[1])[symbol+symb_offset]; int32_t rot2 = ((uint32_t *)frame_params->symbol_rotation[1])[symbol + symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; ((int16_t *)&rot2)[1] = -((int16_t *)&rot2)[1];
#ifdef SL_DEBUG_SLOT_FEP #ifdef SL_DEBUG_SLOT_FEP
// if (ue->frame <100) // if (ue->frame <100)
LOG_I(PHY, "slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset, LOG_I(PHY,
symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); "slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n",
Ns,
symbol,
rx_offset,
symbol + symb_offset,
((int16_t *)&rot2)[0],
((int16_t *)&rot2)[1]);
#endif #endif
rotate_cpx_vector((c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], rotate_cpx_vector((c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size * symbol],
(c16_t *)&rot2, (c16_t *)&rot2,
(c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], (c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size * symbol],
frame_params->ofdm_symbol_size, frame_params->ofdm_symbol_size,
15); 15);
int16_t *shift_rot = (int16_t *)frame_params->timeshift_symbol_rotation; int16_t *shift_rot = (int16_t *)frame_params->timeshift_symbol_rotation;
multadd_cpx_vector((int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], multadd_cpx_vector((int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size * symbol],
shift_rot, shift_rot,
(int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], (int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size * symbol],
1, 1,
frame_params->ofdm_symbol_size, frame_params->ofdm_symbol_size,
15); 15);
} }
LOG_D(PHY, "SIDELINK RX: Slot FEP: done for symbol:%d\n", symbol); LOG_D(PHY, "SIDELINK RX: Slot FEP: done for symbol:%d\n", symbol);
return 0; return 0;
...@@ -133,7 +137,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -133,7 +137,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
c16_t rxdataF[][frame_parms->samples_per_slot_wCP], c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
uint32_t linktype) uint32_t linktype)
{ {
NR_UE_COMMON *common_vars = &ue->common_vars; NR_UE_COMMON *common_vars = &ue->common_vars;
int Ns = proc->nr_slot_rx; int Ns = proc->nr_slot_rx;
...@@ -190,14 +193,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -190,14 +193,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
stop_meas(&ue->rx_dft_stats); stop_meas(&ue->rx_dft_stats);
apply_nr_rotation_RX(frame_parms, apply_nr_rotation_RX(frame_parms, rxdataF[aa], frame_parms->symbol_rotation[linktype], Ns, frame_parms->N_RB_DL, 0, symbol, 1);
rxdataF[aa],
frame_parms->symbol_rotation[linktype],
Ns,
frame_parms->N_RB_DL,
0,
symbol,
1);
} }
#ifdef DEBUG_FEP #ifdef DEBUG_FEP
......
...@@ -202,31 +202,26 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, ...@@ -202,31 +202,26 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
return(0); return(0);
} }
void nr_pbch_dmrs_rx(int symbol, void nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, c16_t *output, bool sidelink)
unsigned int *nr_gold_pbch,
c16_t *output,
bool sidelink)
{ {
int m,m0,m1; int m,m0,m1;
uint8_t idx=0; uint8_t idx=0;
if (sidelink) { if (sidelink) {
AssertFatal(symbol== 0 || (symbol>=5 && symbol <=12),"illegal symbol %d\n",symbol); AssertFatal(symbol == 0 || (symbol >= 5 && symbol <= 12), "illegal symbol %d\n", symbol);
m0 = (symbol) ? (symbol - 4) * 33 : 0; m0 = (symbol) ? (symbol - 4) * 33 : 0;
m1 = (symbol) ? (symbol - 3) * 33 : 33; m1 = (symbol) ? (symbol - 3) * 33 : 33;
} else { } else {
AssertFatal(symbol>=0 && symbol <3,"illegal symbol %d\n",symbol); AssertFatal(symbol >= 0 && symbol < 3, "illegal symbol %d\n", symbol);
if (symbol == 0) { if (symbol == 0) {
m0=0; m0 = 0;
m1=60; m1 = 60;
} } else if (symbol == 1) {
else if (symbol == 1) { m0 = 60;
m0=60; m1 = 84;
m1=84; } else {
} m0 = 84;
else { m1 = 144;
m0=84;
m1=144;
} }
} }
// printf("Generating pilots symbol %d, m0 %d, m1 %d\n",symbol,m0,m1); // printf("Generating pilots symbol %d, m0 %d, m1 %d\n",symbol,m0,m1);
......
...@@ -157,31 +157,26 @@ void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE) ...@@ -157,31 +157,26 @@ void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE)
uint8_t reset; uint8_t reset;
for (slss_id = 0; slss_id < SL_NR_NUM_SLSS_IDs; slss_id++) { for (slss_id = 0; slss_id < SL_NR_NUM_SLSS_IDs; slss_id++) {
reset = 1; reset = 1;
x2 = slss_id; x2 = slss_id;
#ifdef SL_DEBUG_INIT #ifdef SL_DEBUG_INIT
printf("\nPSBCH DMRS GOLD SEQ for SLSSID :%d :\n", slss_id); printf("\nPSBCH DMRS GOLD SEQ for SLSSID :%d :\n", slss_id);
#endif #endif
for (uint8_t n=0; n<SL_NR_NUM_PSBCH_DMRS_RE_DWORD; n++) { for (uint8_t n = 0; n < SL_NR_NUM_PSBCH_DMRS_RE_DWORD; n++) {
UE->SL_UE_PHY_PARAMS.init_params.psbch_dmrs_gold_sequences[slss_id][n] = lte_gold_generic(&x1, &x2, reset); UE->SL_UE_PHY_PARAMS.init_params.psbch_dmrs_gold_sequences[slss_id][n] = lte_gold_generic(&x1, &x2, reset);
reset = 0; reset = 0;
#ifdef SL_DEBUG_INIT_DATA #ifdef SL_DEBUG_INIT_DATA
printf("%x\n",SL_UE_INIT_PARAMS.sl_psbch_dmrs_gold_sequences[slss_id][n]); printf("%x\n", SL_UE_INIT_PARAMS.sl_psbch_dmrs_gold_sequences[slss_id][n]);
#endif #endif
} }
} }
} }
void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, struct complex16 *modulated_dmrs_sym, uint16_t slss_id)
struct complex16 *modulated_dmrs_sym,
uint16_t slss_id)
{ {
uint8_t idx = 0; uint8_t idx = 0;
uint32_t *sl_dmrs_sequence = UE->SL_UE_PHY_PARAMS.init_params.psbch_dmrs_gold_sequences[slss_id]; uint32_t *sl_dmrs_sequence = UE->SL_UE_PHY_PARAMS.init_params.psbch_dmrs_gold_sequences[slss_id];
c16_t *mod_table = (c16_t *)nr_qpsk_mod_table; c16_t *mod_table = (c16_t *)nr_qpsk_mod_table;
...@@ -191,24 +186,27 @@ void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, ...@@ -191,24 +186,27 @@ void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE,
#endif #endif
/// QPSK modulation /// QPSK modulation
for (int m=0; m<SL_NR_NUM_PSBCH_DMRS_RE; m++) { for (int m = 0; m < SL_NR_NUM_PSBCH_DMRS_RE; m++) {
idx = (((sl_dmrs_sequence[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3);
idx = (((sl_dmrs_sequence[(m<<1)>>5])>>((m<<1)&0x1f))&3);
modulated_dmrs_sym[m].r = mod_table[idx].r; modulated_dmrs_sym[m].r = mod_table[idx].r;
modulated_dmrs_sym[m].i = mod_table[idx].i; modulated_dmrs_sym[m].i = mod_table[idx].i;
#ifdef SL_DEBUG_INIT_DATA #ifdef SL_DEBUG_INIT_DATA
printf("m:%d gold seq: %d b0-b1: %d-%d DMRS Symbols: %d %d\n", m, sl_dmrs_sequence[(m<<1)>>5], (((sl_dmrs_sequence[(m<<1)>>5])>>((m<<1)&0x1f))&1), printf("m:%d gold seq: %d b0-b1: %d-%d DMRS Symbols: %d %d\n",
(((sl_dmrs_sequence[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1), modulated_dmrs_sym[m].r, modulated_dmrs_sym[m].i); m,
sl_dmrs_sequence[(m << 1) >> 5],
(((sl_dmrs_sequence[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 1),
(((sl_dmrs_sequence[((m << 1) + 1) >> 5]) >> (((m << 1) + 1) & 0x1f)) & 1),
modulated_dmrs_sym[m].r,
modulated_dmrs_sym[m].i);
printf("idx:%d, qpsk_table.r:%d, qpsk_table.i:%d\n", idx, mod_table[idx].r, mod_table[idx].i); printf("idx:%d, qpsk_table.r:%d, qpsk_table.i:%d\n", idx, mod_table[idx].r, mod_table[idx].i);
#endif #endif
} }
#ifdef SL_DUMP_INIT_SAMPLES #ifdef SL_DUMP_INIT_SAMPLES
char filename[40], varname[25]; char filename[40], varname[25];
sprintf(filename,"sl_psbch_dmrs_slssid_%d.m", slss_id); sprintf(filename, "sl_psbch_dmrs_slssid_%d.m", slss_id);
sprintf(varname,"sl_dmrs_id_%d.m", slss_id); sprintf(varname, "sl_dmrs_id_%d.m", slss_id);
LOG_M(filename, varname, (void*)modulated_dmrs_sym, SL_NR_NUM_PSBCH_DMRS_RE, 1, 1); LOG_M(filename, varname, (void *)modulated_dmrs_sym, SL_NR_NUM_PSBCH_DMRS_RE, 1, 1);
#endif #endif
} }
...@@ -30,10 +30,7 @@ ...@@ -30,10 +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
*/ */
void nr_pbch_dmrs_rx(int dmrss, void nr_pbch_dmrs_rx(int dmrss, unsigned int *nr_gold_pbch, c16_t *output, bool sidelink);
unsigned int *nr_gold_pbch,
c16_t *output,
bool sidelink);
/*!\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
...@@ -73,7 +70,5 @@ void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, u ...@@ -73,7 +70,5 @@ void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, u
void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params); void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params);
void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling); void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling);
void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE); void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE);
void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, struct complex16 *modulated_dmrs_sym, uint16_t slss_id);
struct complex16 *modulated_dmrs_sym,
uint16_t slss_id);
#endif #endif
...@@ -72,11 +72,22 @@ ...@@ -72,11 +72,22 @@
static const c16_t phase_nr[PHASE_HYPOTHESIS_NUMBER] = { static const c16_t phase_nr[PHASE_HYPOTHESIS_NUMBER] = {
// {pi/3 ---- pi/3, -pi/3 ---- pi/3} // {pi/3 ---- pi/3, -pi/3 ---- pi/3}
{16384, -28377}, {20173, -25821}, {23571, -22762}, {26509, -19260}, {16384, -28377},
{28932, -15383}, {30791, -11207}, {32051, -6813}, {32687, -2286}, {20173, -25821},
{32687, 2286}, {32051, 6813}, {30791, 11207}, {28932, 15383}, {23571, -22762},
{26509, 19260}, {23571, 22762}, {20173, 25821}, {16384, 28377} {26509, -19260},
}; {28932, -15383},
{30791, -11207},
{32051, -6813},
{32687, -2286},
{32687, 2286},
{32051, 6813},
{30791, 11207},
{28932, 15383},
{26509, 19260},
{23571, 22762},
{20173, 25821},
{16384, 28377}};
void init_context_sss_nr(int amp); void init_context_sss_nr(int amp);
void free_context_sss_nr(void); void free_context_sss_nr(void);
......
...@@ -717,7 +717,7 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, ...@@ -717,7 +717,7 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
} }
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
NR_DL_FRAME_PARMS *fp, NR_DL_FRAME_PARMS *fp,
int estimateSz, int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz], struct complex16 dl_ch_estimates[][estimateSz],
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size], struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
...@@ -738,47 +738,42 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -738,47 +738,42 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
uint32_t *gold_seq = NULL; uint32_t *gold_seq = NULL;
if (sidelink) { if (sidelink) {
AssertFatal(dmrss == 0 || (dmrss >= 5 && dmrss <= 12), "symbol %d is illegal for PSBCH DM-RS \n", dmrss);
AssertFatal(dmrss == 0 || (dmrss >= 5 && dmrss <= 12),
"symbol %d is illegal for PSBCH DM-RS \n",
dmrss);
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
LOG_D(PHY,"PSBCH Channel Estimation SLSSID:%d\n", Nid); LOG_D(PHY, "PSBCH Channel Estimation SLSSID:%d\n", Nid);
gold_seq = sl_phy_params->init_params.psbch_dmrs_gold_sequences[Nid]; gold_seq = sl_phy_params->init_params.psbch_dmrs_gold_sequences[Nid];
lastsymbol = 12; lastsymbol = 12;
num_rbs = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL; num_rbs = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL;
} else { } else {
nushift = fp->Nid_cell % 4;
nushift = fp->Nid_cell%4; AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
AssertFatal(dmrss >= 0 && dmrss < 3,
"symbol %d is illegal for PBCH DM-RS \n",
dmrss);
gold_seq = ue->nr_gold_pbch[n_hf][ssb_index]; gold_seq = ue->nr_gold_pbch[n_hf][ssb_index];
lastsymbol = 2; lastsymbol = 2;
num_rbs = 20; num_rbs = 20;
} }
unsigned int ssb_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier; unsigned int ssb_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier;
if (ssb_offset>= fp->ofdm_symbol_size) ssb_offset-= fp->ofdm_symbol_size; if (ssb_offset >= fp->ofdm_symbol_size)
ssb_offset -= fp->ofdm_symbol_size;
const int ch_offset = fp->ofdm_symbol_size*symbol; const int ch_offset = fp->ofdm_symbol_size * symbol;
const int symbol_offset = fp->ofdm_symbol_size*symbol; const int symbol_offset = fp->ofdm_symbol_size * symbol;
const int k = nushift; const int k = nushift;
DEBUG_PBCH("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", DEBUG_PBCH("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",
proc->gNB_id, proc->gNB_id,
ch_offset, ch_offset,
fp->ofdm_symbol_size, fp->ofdm_symbol_size,
fp->Ncp, fp->Ncp,
Ns, Ns,
k, k,
symbol); symbol);
const c16_t *fl, *fm, *fr; const c16_t *fl, *fm, *fr;
...@@ -814,59 +809,58 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -814,59 +809,58 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
} }
idft_size_idx_t idftsizeidx; idft_size_idx_t idftsizeidx;
switch (fp->ofdm_symbol_size) { switch (fp->ofdm_symbol_size) {
case 128: case 128:
idftsizeidx = IDFT_128; idftsizeidx = IDFT_128;
break; break;
case 256:
idftsizeidx = IDFT_256;
break;
case 512:
idftsizeidx = IDFT_512;
break;
case 768:
idftsizeidx = IDFT_768;
break;
case 1024: case 256:
idftsizeidx = IDFT_1024; idftsizeidx = IDFT_256;
break; break;
case 1536: case 512:
idftsizeidx = IDFT_1536; idftsizeidx = IDFT_512;
break; break;
case 2048: case 768:
idftsizeidx = IDFT_2048; idftsizeidx = IDFT_768;
break; break;
case 3072: case 1024:
idftsizeidx = IDFT_3072; idftsizeidx = IDFT_1024;
break; break;
case 4096: case 1536:
idftsizeidx = IDFT_4096; idftsizeidx = IDFT_1536;
break; break;
case 6144: case 2048:
idftsizeidx = IDFT_6144; idftsizeidx = IDFT_2048;
break; break;
default: case 3072:
printf("unsupported ofdm symbol size \n"); idftsizeidx = IDFT_3072;
assert(0); break;
case 4096:
idftsizeidx = IDFT_4096;
break;
case 6144:
idftsizeidx = IDFT_6144;
break;
default:
printf("unsupported ofdm symbol size \n");
assert(0);
} }
// 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,gold_seq, &pilot[0], sidelink); nr_pbch_dmrs_rx(dmrss, gold_seq, &pilot[0], sidelink);
for (int aarx=0; aarx<fp->nb_antennas_rx; aarx++) {
for (int aarx = 0; aarx < fp->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]; c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
...@@ -922,7 +916,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -922,7 +916,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
multaddRealVectorComplexScalar(fl, ch, dl_ch, 16); multaddRealVectorComplexScalar(fl, ch, dl_ch, 16);
pil++; pil++;
re_offset = (re_offset+4) % fp->ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
ch = c16mulShift(*pil, rxF[re_offset], 15); ch = c16mulShift(*pil, rxF[re_offset], 15);
DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n",
pilot_cnt + 1, pilot_cnt + 1,
...@@ -934,7 +928,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -934,7 +928,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
pil->i); pil->i);
multaddRealVectorComplexScalar(fm, ch, dl_ch, 16); multaddRealVectorComplexScalar(fm, ch, dl_ch, 16);
pil++; pil++;
re_offset = (re_offset+4) % fp->ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
ch = c16mulShift(*pil, rxF[re_offset], 15); ch = c16mulShift(*pil, rxF[re_offset], 15);
DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n",
pilot_cnt + 2, pilot_cnt + 2,
...@@ -950,7 +944,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -950,7 +944,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
dl_ch += 12; dl_ch += 12;
} }
if( dmrss == lastsymbol) // update time statistics for last PBCH symbol if (dmrss == lastsymbol) // update time statistics for last PBCH symbol
{ {
// do ifft of channel estimate // do ifft of channel estimate
LOG_D(PHY,"Channel Impulse Computation Slot %d Symbol %d ch_offset %d\n", Ns, symbol, ch_offset); LOG_D(PHY,"Channel Impulse Computation Slot %d Symbol %d ch_offset %d\n", Ns, symbol, ch_offset);
...@@ -962,13 +956,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -962,13 +956,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
} }
if (!sidelink && dmrss == lastsymbol) if (!sidelink && dmrss == lastsymbol)
UEscopeCopy(ue, UEscopeCopy(ue, pbchDlChEstimateTime, (void *)dl_ch_estimates_time, sizeof(c16_t), fp->nb_antennas_rx, fp->ofdm_symbol_size, 0);
pbchDlChEstimateTime,
(void *)dl_ch_estimates_time,
sizeof(c16_t),
fp->nb_antennas_rx,
fp->ofdm_symbol_size,
0);
return(0); return(0);
} }
......
...@@ -65,7 +65,7 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, ...@@ -65,7 +65,7 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
const 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,
NR_DL_FRAME_PARMS *fp, NR_DL_FRAME_PARMS *fp,
int estimateSz, int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz], struct complex16 dl_ch_estimates[][estimateSz],
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size], struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
......
...@@ -310,56 +310,50 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, ...@@ -310,56 +310,50 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
- ((int)rx_gain - (int)rx_gain_offset)); - ((int)rx_gain - (int)rx_gain_offset));
} }
//PSBCH RSRP calculations according to 38.215 section 5.1.22 // PSBCH RSRP calculations according to 38.215 section 5.1.22
void nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params, void nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
NR_DL_FRAME_PARMS *fp, NR_DL_FRAME_PARMS *fp,
c16_t rxdataF[][fp->samples_per_slot_wCP], c16_t rxdataF[][fp->samples_per_slot_wCP],
bool use_SSS) bool use_SSS)
{ {
SL_NR_UE_PSBCH_t *psbch_rx = &sl_phy_params->psbch; SL_NR_UE_PSBCH_t *psbch_rx = &sl_phy_params->psbch;
uint8_t numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP uint8_t numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
: SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
uint32_t re_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier; uint32_t re_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier;
uint32_t rsrp = 0, num_re = 0; uint32_t rsrp = 0, num_re = 0;
LOG_D(PHY, "PSBCH RSRP MEAS: numsym:%d, re_offset:%d\n",numsym, re_offset); LOG_D(PHY, "PSBCH RSRP MEAS: numsym:%d, re_offset:%d\n", numsym, re_offset);
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) { for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
// Calculate PSBCH RSRP based from DMRS REs
for (uint8_t symbol = 0; symbol < numsym;) {
struct complex16 *rxF = &rxdataF[aarx][symbol * fp->ofdm_symbol_size];
//Calculate PSBCH RSRP based from DMRS REs for (int re = 0; re < SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL; re++) {
for (uint8_t symbol=0; symbol<numsym;) { if (re % 4 == 0) { // DMRS RE
struct complex16 *rxF = &rxdataF[aarx][symbol*fp->ofdm_symbol_size];
for (int re=0;re<SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL;re++) {
if (re%4 == 0) { //DMRS RE
uint16_t offset = (re_offset + re) % fp->ofdm_symbol_size; uint16_t offset = (re_offset + re) % fp->ofdm_symbol_size;
rsrp += c16amp2(rxF[offset]); rsrp += c16amp2(rxF[offset]);
num_re++; num_re++;
} }
} }
symbol = (symbol == 0) ? 5 : symbol+1; symbol = (symbol == 0) ? 5 : symbol + 1;
} }
} }
if (use_SSS) { if (use_SSS) {
//TBD... // TBD...
//UE can decide between using only PSBCH DMRS or PSBCH DMRS and SSS for PSBCH RSRP computation. // UE can decide between using only PSBCH DMRS or PSBCH DMRS and SSS for PSBCH RSRP computation.
//If needed this can be implemented. Reference Spec 38.215 // If needed this can be implemented. Reference Spec 38.215
} }
psbch_rx->rsrp_dB_per_RE = 10*log10(rsrp / num_re); psbch_rx->rsrp_dB_per_RE = 10 * log10(rsrp / num_re);
psbch_rx->rsrp_dBm_per_RE = psbch_rx->rsrp_dB_per_RE + psbch_rx->rsrp_dBm_per_RE = psbch_rx->rsrp_dB_per_RE + 30 - 10 * log10(pow(2, 30))
30 - 10*log10(pow(2,30)) - - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0])
((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - - dB_fixed(fp->ofdm_symbol_size);
dB_fixed(fp->ofdm_symbol_size);
LOG_I(PHY, "PSBCH RSRP (DMRS REs): numREs:%d RSRP :%d dB/RE ,RSRP:%d dBm/RE\n",
num_re, psbch_rx->rsrp_dB_per_RE, psbch_rx->rsrp_dBm_per_RE);
LOG_I(PHY,
"PSBCH RSRP (DMRS REs): numREs:%d RSRP :%d dB/RE ,RSRP:%d dBm/RE\n",
num_re,
psbch_rx->rsrp_dB_per_RE,
psbch_rx->rsrp_dBm_per_RE);
} }
...@@ -6,18 +6,17 @@ ...@@ -6,18 +6,17 @@
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "SCHED_NR_UE/defs.h" #include "SCHED_NR_UE/defs.h"
//Number of symbols carrying SLSS signal - PSS+SSS+PSBCH // Number of symbols carrying SLSS signal - PSS+SSS+PSBCH
#define SL_NR_NUMSYM_SLSS_NORMAL_CP 14 #define SL_NR_NUMSYM_SLSS_NORMAL_CP 14
#define SL_NR_MAX_RX_ANTENNA 1 #define SL_NR_MAX_RX_ANTENNA 1
#define SL_NR_FIRST_PSS_SYMBOL 1 #define SL_NR_FIRST_PSS_SYMBOL 1
#define SL_NR_FIRST_SSS_SYMBOL 3 #define SL_NR_FIRST_SSS_SYMBOL 3
#define SL_NR_NUM_PSS_SSS_SYMBOLS 4 #define SL_NR_NUM_PSS_SSS_SYMBOLS 4
//#define SL_DEBUG // #define SL_DEBUG
static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index)
{ {
sl_nr_ue_phy_params_t *sl_ue = &UE->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_ue = &UE->SL_UE_PHY_PARAMS;
SL_NR_SYNC_PARAMS_t *sync_params = &sl_ue->sync_params; SL_NR_SYNC_PARAMS_t *sync_params = &sl_ue->sync_params;
NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
...@@ -28,52 +27,49 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) ...@@ -28,52 +27,49 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index)
#ifdef SL_DEBUG #ifdef SL_DEBUG
char fname[50], sname[25]; char fname[50], sname[25];
sprintf(fname,"rxdata_frame_%d.m",frame_index); sprintf(fname, "rxdata_frame_%d.m", frame_index);
sprintf(sname,"rxd_frame%d",frame_index); sprintf(sname, "rxd_frame%d", frame_index);
LOG_M(fname,sname, &rxdata[0][frame_index * sl_fp->samples_per_frame],sl_fp->samples_per_frame,1,1); LOG_M(fname, sname, &rxdata[0][frame_index * sl_fp->samples_per_frame], sl_fp->samples_per_frame, 1, 1);
LOG_M("pss_for_correlation0.m","pss_id0", pss_for_correlation[0],2048,1,1); LOG_M("pss_for_correlation0.m", "pss_id0", pss_for_correlation[0], 2048, 1, 1);
LOG_M("pss_for_correlation1.m","pss_id1", pss_for_correlation[1],2048,1,1); LOG_M("pss_for_correlation1.m", "pss_id1", pss_for_correlation[1], 2048, 1, 1);
int64_t *pss_corr_debug_values[SL_NR_NUM_IDs_IN_PSS]; int64_t *pss_corr_debug_values[SL_NR_NUM_IDs_IN_PSS];
#endif #endif
int maxval=0; int maxval = 0;
for (int i=0;i<2*(sl_fp->ofdm_symbol_size);i++) { for (int i = 0; i < 2 * (sl_fp->ofdm_symbol_size); i++) {
maxval = max(maxval,pss_for_correlation[0][i]); maxval = max(maxval, pss_for_correlation[0][i]);
maxval = max(maxval,-pss_for_correlation[0][i]); maxval = max(maxval, -pss_for_correlation[0][i]);
maxval = max(maxval,pss_for_correlation[1][i]); maxval = max(maxval, pss_for_correlation[1][i]);
maxval = max(maxval,-pss_for_correlation[1][i]); maxval = max(maxval, -pss_for_correlation[1][i]);
} }
int shift = log2_approx(maxval);//*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)*2); int shift = log2_approx(maxval); //*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)*2);
#ifdef SL_DEBUG #ifdef SL_DEBUG
LOG_I(PHY,"SIDELINK SLSS SEARCH: Function:%s\n", __func__); LOG_I(PHY, "SIDELINK SLSS SEARCH: Function:%s\n", __func__);
LOG_I(PHY,"maxval:%d, shift:%d\n", maxval, shift); LOG_I(PHY, "maxval:%d, shift:%d\n", maxval, shift);
#endif #endif
int64_t avg[SL_NR_NUM_IDs_IN_PSS] = {0}; int64_t avg[SL_NR_NUM_IDs_IN_PSS] = {0};
int64_t peak_value = 0, psss_corr_value = 0; int64_t peak_value = 0, psss_corr_value = 0;
unsigned int peak_position = 0, pss_source = 0; unsigned int peak_position = 0, pss_source = 0;
for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++)
avg[pss_index]=0; avg[pss_index] = 0;
#ifdef SL_DEBUG #ifdef SL_DEBUG
int64_t *pss_corr_debug_values[SL_NR_NUM_IDs_IN_PSS]; int64_t *pss_corr_debug_values[SL_NR_NUM_IDs_IN_PSS];
for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++)
pss_corr_debug_values[pss_index] = malloc16_clear(length*sizeof(int64_t)); pss_corr_debug_values[pss_index] = malloc16_clear(length * sizeof(int64_t));
#endif #endif
for (int n=0; n < length - sl_fp->ofdm_symbol_size; n+=4) { // for (int n = 0; n < length - sl_fp->ofdm_symbol_size; n += 4) { //
for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) { for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) {
psss_corr_value = 0; psss_corr_value = 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]; // 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<sl_fp->nb_antennas_rx; ar++) { for (int ar = 0; ar < sl_fp->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((c16_t *)pss_for_correlation[pss_index], const c32_t result = dot_product((c16_t *)pss_for_correlation[pss_index],
(c16_t *)&(rxdata[ar][n + frame_index * sl_fp->samples_per_frame]), (c16_t *)&(rxdata[ar][n + frame_index * sl_fp->samples_per_frame]),
...@@ -86,8 +82,12 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) ...@@ -86,8 +82,12 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index)
#ifdef SL_DEBUG #ifdef SL_DEBUG
pss_corr_debug_values[pss_index][n] = psss_corr_value; pss_corr_debug_values[pss_index][n] = psss_corr_value;
printf("frame:%d n:%d, pss_index:%d, pss_for_correlation[pss_index][0]:%x, rxdata[n]:%x\n", printf("frame:%d n:%d, pss_index:%d, pss_for_correlation[pss_index][0]:%x, rxdata[n]:%x\n",
frame_index, n, pss_index, pss_for_correlation[pss_index][0], rxdata[ar][n + frame_index * sl_fp->samples_per_frame]); frame_index,
printf("result %lld, pss_corr_values[%d][%d]:%ld\n",result, pss_index, n, pss_corr_debug_values[pss_index][n]); n,
pss_index,
pss_for_correlation[pss_index][0],
rxdata[ar][n + frame_index * sl_fp->samples_per_frame]);
printf("result %lld, pss_corr_values[%d][%d]:%ld\n", result, pss_index, n, pss_corr_debug_values[pss_index][n]);
printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_debug_values[pss_index][n]); printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_debug_values[pss_index][n]);
printf("peak_value:%ld, peak_position:%d, pss_source:%d\n", peak_value, peak_position, pss_source); printf("peak_value:%ld, peak_position:%d, pss_source:%d\n", peak_value, peak_position, pss_source);
#endif #endif
...@@ -108,23 +108,24 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) ...@@ -108,23 +108,24 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index)
} }
#ifdef SL_DEBUG #ifdef SL_DEBUG
LOG_M("pss_corr_debug_values_0.m","pss_corr0", &pss_corr_debug_values[0][0],length,1,6); LOG_M("pss_corr_debug_values_0.m", "pss_corr0", &pss_corr_debug_values[0][0], length, 1, 6);
LOG_M("pss_corr_debug_values_1.m","pss_corr1", &pss_corr_debug_values[1][0],length,1,6); LOG_M("pss_corr_debug_values_1.m", "pss_corr1", &pss_corr_debug_values[1][0], length, 1, 6);
for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) { for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) {
free(pss_corr_debug_values[pss_index]); free(pss_corr_debug_values[pss_index]);
} }
#endif #endif
double ffo_est=0; double ffo_est = 0;
if (UE->UE_fo_compensation) { // Not tested if (UE->UE_fo_compensation) { // Not tested
// 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 International Conference on Communications and Networking in China, 2012. // 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.
c16_t *pss = (c16_t *)pss_for_correlation[pss_source]; c16_t *pss = (c16_t *)pss_for_correlation[pss_source];
c16_t *rxd = (c16_t *)&(rxdata[0][peak_position + frame_index * sl_fp->samples_per_frame]); c16_t *rxd = (c16_t *)&(rxdata[0][peak_position + frame_index * sl_fp->samples_per_frame]);
int half_symbol = sl_fp->ofdm_symbol_size>>1; int half_symbol = sl_fp->ofdm_symbol_size >> 1;
// 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(pss, rxd, half_symbol, shift); c32_t r1 = dot_product(pss, rxd, half_symbol, shift);
...@@ -138,125 +139,133 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) ...@@ -138,125 +139,133 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index)
ffo_est = atan2(r1d.r * r2d.i - r2d.r * r1d.i, r1d.r * r2d.r + r1d.i * r2d.i) / M_PI; ffo_est = atan2(r1d.r * r2d.i - r2d.r * r1d.i, r1d.r * r2d.r + r1d.i * r2d.i) / M_PI;
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("ffo %lf\n",ffo_est); printf("ffo %lf\n", ffo_est);
#endif #endif
} }
// computing absolute value of frequency offset // computing absolute value of frequency offset
sync_params->freq_offset = ffo_est*sl_fp->subcarrier_spacing; sync_params->freq_offset = ffo_est * sl_fp->subcarrier_spacing;
for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) avg[pss_index]/=(length/4); for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++)
avg[pss_index] /= (length / 4);
sync_params->N_sl_id2 = pss_source; sync_params->N_sl_id2 = pss_source;
LOG_I(PHY,"PSS Source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf, freq offset:%d Hz\n", LOG_I(PHY,
pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]),ffo_est, sync_params->freq_offset); "PSS Source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf, freq offset:%d Hz\n",
pss_source,
peak_position,
(unsigned long long)peak_value,
dB_fixed64(peak_value),
dB_fixed64(avg[pss_source]),
ffo_est,
sync_params->freq_offset);
if (peak_value < 5*avg[pss_source]) if (peak_value < 5 * avg[pss_source])
return(-1); return (-1);
return peak_position; return peak_position;
} }
static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue,
int32_t *tot_metric, uint8_t *phase_max, UE_nr_rxtx_proc_t *proc,
int32_t *tot_metric,
uint8_t *phase_max,
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]) c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP])
{ {
c16_t pss_ext[SL_NR_MAX_RX_ANTENNA][SL_NR_NUM_PSS_SYMBOLS][SL_NR_PSS_SEQUENCE_LENGTH]; c16_t pss_ext[SL_NR_MAX_RX_ANTENNA][SL_NR_NUM_PSS_SYMBOLS][SL_NR_PSS_SEQUENCE_LENGTH];
c16_t sss_ext[SL_NR_MAX_RX_ANTENNA][SL_NR_NUM_SSS_SYMBOLS][SL_NR_PSS_SEQUENCE_LENGTH]; c16_t sss_ext[SL_NR_MAX_RX_ANTENNA][SL_NR_NUM_SSS_SYMBOLS][SL_NR_PSS_SEQUENCE_LENGTH];
uint8_t Nid2 = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2; uint8_t Nid2 = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2;
NR_DL_FRAME_PARMS *sl_fp=&ue->SL_UE_PHY_PARAMS.sl_frame_params; NR_DL_FRAME_PARMS *sl_fp = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
int16_t *d; int16_t *d;
uint16_t Nid1 = 0; uint16_t Nid1 = 0;
uint8_t phase; uint8_t phase;
c16_t *rxF_ext; c16_t *rxF_ext;
for (int aarx=0; aarx < sl_fp->nb_antennas_rx; aarx++) { for (int aarx = 0; aarx < sl_fp->nb_antennas_rx; aarx++) {
unsigned int ofdm_symbol_size = sl_fp->ofdm_symbol_size; unsigned int ofdm_symbol_size = sl_fp->ofdm_symbol_size;
// pss, sss extraction // pss, sss extraction
for (int sym = SL_NR_FIRST_PSS_SYMBOL; sym < SL_NR_FIRST_PSS_SYMBOL + SL_NR_NUM_PSS_SSS_SYMBOLS;sym ++) { for (int sym = SL_NR_FIRST_PSS_SYMBOL; sym < SL_NR_FIRST_PSS_SYMBOL + SL_NR_NUM_PSS_SSS_SYMBOLS; sym++) {
if (sym < SL_NR_FIRST_PSS_SYMBOL + SL_NR_NUM_PSS_SYMBOLS) { if (sym < SL_NR_FIRST_PSS_SYMBOL + SL_NR_NUM_PSS_SYMBOLS) {
rxF_ext = &pss_ext[aarx][sym-SL_NR_FIRST_PSS_SYMBOL][0]; rxF_ext = &pss_ext[aarx][sym - SL_NR_FIRST_PSS_SYMBOL][0];
} else { } else {
rxF_ext = &sss_ext[aarx][sym-SL_NR_FIRST_SSS_SYMBOL][0]; rxF_ext = &sss_ext[aarx][sym - SL_NR_FIRST_SSS_SYMBOL][0];
} }
unsigned int k = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier + 2; unsigned int k = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier + 2;
if (k >= ofdm_symbol_size) k -= ofdm_symbol_size; if (k >= ofdm_symbol_size)
k -= ofdm_symbol_size;
LOG_D(PHY, "firstcarrieroffset:%d, ssb_sc:%d, k:%d, symbol:%d\n",sl_fp->first_carrier_offset, sl_fp->ssb_start_subcarrier, k, sym); LOG_D(PHY,
"firstcarrieroffset:%d, ssb_sc:%d, k:%d, symbol:%d\n",
sl_fp->first_carrier_offset,
sl_fp->ssb_start_subcarrier,
k,
sym);
for (int i=0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { for (int i = 0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) {
rxF_ext[i] = rxdataF[aarx][sym*ofdm_symbol_size + k]; rxF_ext[i] = rxdataF[aarx][sym * ofdm_symbol_size + k];
k++; k++;
if (k == ofdm_symbol_size) k=0; if (k == ofdm_symbol_size)
k = 0;
} }
} }
LOG_D(PHY, "SIDELINK SLSS SEARCH: EXTRACTION OF PSS, SSS done\n"); LOG_D(PHY, "SIDELINK SLSS SEARCH: EXTRACTION OF PSS, SSS done\n");
#ifdef SL_DEBUG #ifdef SL_DEBUG
LOG_M("pss_ext_sym1.m","pss_ext1",&pss_ext[aarx][0][0],SL_NR_PSS_SEQUENCE_LENGTH,1,1); LOG_M("pss_ext_sym1.m", "pss_ext1", &pss_ext[aarx][0][0], SL_NR_PSS_SEQUENCE_LENGTH, 1, 1);
LOG_M("pss_ext_sym2.m","pss_ext2",&pss_ext[aarx][1][0],SL_NR_PSS_SEQUENCE_LENGTH,1,1); LOG_M("pss_ext_sym2.m", "pss_ext2", &pss_ext[aarx][1][0], SL_NR_PSS_SEQUENCE_LENGTH, 1, 1);
LOG_M("sss_ext_sym3.m","sss_ext3",&sss_ext[aarx][0][0],SL_NR_PSS_SEQUENCE_LENGTH,1,1); LOG_M("sss_ext_sym3.m", "sss_ext3", &sss_ext[aarx][0][0], SL_NR_PSS_SEQUENCE_LENGTH, 1, 1);
LOG_M("sss_ext_sym4.m","sss_ext4",&sss_ext[aarx][1][0],SL_NR_PSS_SEQUENCE_LENGTH,1,1); LOG_M("sss_ext_sym4.m", "sss_ext4", &sss_ext[aarx][1][0], SL_NR_PSS_SEQUENCE_LENGTH, 1, 1);
#endif #endif
// get conjugated channel estimate from PSS, H* = R* \cdot PSS // get conjugated channel estimate from PSS, H* = R* \cdot PSS
// and do channel estimation and compensation based on PSS // and do channel estimation and compensation based on PSS
int16_t *pss = ue->SL_UE_PHY_PARAMS.init_params.sl_pss_for_sync[Nid2]; int16_t *pss = ue->SL_UE_PHY_PARAMS.init_params.sl_pss_for_sync[Nid2];
c16_t *pss_ext2,*sss_ext2; c16_t *pss_ext2, *sss_ext2;
//2 Symbols each for PSS and SSS
for (int j=0; j<SL_NR_NUM_PSS_OR_SSS_SYMBOLS;j++) {
// 2 Symbols each for PSS and SSS
for (int j = 0; j < SL_NR_NUM_PSS_OR_SSS_SYMBOLS; j++) {
sss_ext2 = &sss_ext[aarx][j][0]; sss_ext2 = &sss_ext[aarx][j][0];
pss_ext2 = &pss_ext[aarx][j][0]; pss_ext2 = &pss_ext[aarx][j][0];
for (int i = 0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { for (int i = 0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) {
// This is H*(PSS) = R* \cdot PSS // This is H*(PSS) = R* \cdot PSS
c16_t tmp = {.r = (pss_ext2[i].r * pss[i]), .i = (-pss_ext2[i].i * pss[i])}; c16_t tmp = {.r = (pss_ext2[i].r * pss[i]), .i = (-pss_ext2[i].i * pss[i])};
int amp = c16amp2(tmp); int amp = c16amp2(tmp);
int shift = log2_approx(amp)/2; int shift = log2_approx(amp) / 2;
// This is R(SSS) \cdot H*(PSS) // This is R(SSS) \cdot H*(PSS)
c16_t tmp2 = c16mulShift(tmp, sss_ext2[i], shift); c16_t tmp2 = c16mulShift(tmp, sss_ext2[i], shift);
// MRC on RX antennas // MRC on RX antennas
// sss_ext now contains the compensated SSS // sss_ext now contains the compensated SSS
if (aarx==0) { if (aarx == 0) {
sss_ext2[i].r = tmp2.r; sss_ext2[i].r = tmp2.r;
sss_ext2[i].i = tmp2.i; sss_ext2[i].i = tmp2.i;
} else { } else {
AssertFatal(1==0,"SIDELINK MORE THAN 1 RX ANTENNA NOT YET SUPPORTED\n"); AssertFatal(1 == 0, "SIDELINK MORE THAN 1 RX ANTENNA NOT YET SUPPORTED\n");
} }
} }
} }
LOG_D(PHY, "SIDELINK SLSS SEARCH: Ch. estimation SSS done\n"); LOG_D(PHY, "SIDELINK SLSS SEARCH: Ch. estimation SSS done\n");
} }
/*
/* #ifdef SL_DEBUG
#ifdef SL_DEBUG write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_subframe,1,1);
write_output("rxdataF0_pss.m","rxF0_pss",&ue->common_vars.rxdataF[0][0],frame_parms->ofdm_symbol_size,1,1);
write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_subframe,1,1); write_output("rxdataF0_sss.m","rxF0_sss",&ue->common_vars.rxdataF[0][(SSS_SYMBOL_NB-PSS_SYMBOL_NB)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
write_output("rxdataF0_pss.m","rxF0_pss",&ue->common_vars.rxdataF[0][0],frame_parms->ofdm_symbol_size,1,1); write_output("pss_ext.m","pss_ext",pss_ext,LENGTH_PSS_NR,1,1);
write_output("rxdataF0_sss.m","rxF0_sss",&ue->common_vars.rxdataF[0][(SSS_SYMBOL_NB-PSS_SYMBOL_NB)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
write_output("pss_ext.m","pss_ext",pss_ext,LENGTH_PSS_NR,1,1);
#endif #endif
*/ */
/* for phase evaluation, one uses an array of possible phase shifts */ /* for phase evaluation, one uses an array of possible phase shifts */
/* then a correlation is done between received signal with a shift pĥase and the reference signal */ /* then a correlation is done between received signal with a shift pĥase and the reference signal */
...@@ -268,16 +277,16 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, ...@@ -268,16 +277,16 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc,
*tot_metric = INT_MIN; *tot_metric = INT_MIN;
c16_t *sss = &sss_ext[0][0][0]; c16_t *sss = &sss_ext[0][0][0];
for (uint16_t id1 = 0 ; id1 < SL_NR_NUM_IDs_IN_SSS; id1++) { // all possible SSS Nid1 values for (uint16_t id1 = 0; id1 < SL_NR_NUM_IDs_IN_SSS; id1++) { // all possible SSS Nid1 values
for (phase=0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS for (phase = 0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS
int32_t metric = 0, metric_re = 0; int32_t metric = 0, metric_re = 0;
d = (int16_t *)&ue->SL_UE_PHY_PARAMS.init_params.sl_sss_for_sync[Nid2 * SL_NR_NUM_IDs_IN_SSS + id1]; d = (int16_t *)&ue->SL_UE_PHY_PARAMS.init_params.sl_sss_for_sync[Nid2 * SL_NR_NUM_IDs_IN_SSS + id1];
// This is the inner product using one particular value of each unknown parameter // This is the inner product using one particular value of each unknown parameter
for (int i=0; i < SL_NR_SSS_SEQUENCE_LENGTH; i++) { for (int i = 0; i < SL_NR_SSS_SEQUENCE_LENGTH; i++) {
metric_re += d[i] * (((int64_t) phase_nr[phase].r * sss[i].r - phase_nr[phase].i * sss[i].i) >> 15); metric_re += d[i] * (((int64_t)phase_nr[phase].r * sss[i].r - phase_nr[phase].i * sss[i].i) >> 15);
} }
metric = metric_re; metric = metric_re;
...@@ -288,23 +297,29 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, ...@@ -288,23 +297,29 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc,
Nid1 = id1; Nid1 = id1;
*phase_max = phase; *phase_max = phase;
LOG_D(PHY, "(phase,Nid1) (%d,%d), metric_phase %d tot_metric %d, phase_max %d \n", LOG_D(PHY,
phase, Nid1, metric, *tot_metric, *phase_max); "(phase,Nid1) (%d,%d), metric_phase %d tot_metric %d, phase_max %d \n",
phase,
Nid1,
metric,
*tot_metric,
*phase_max);
} }
} }
} }
ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1 = Nid1; ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1 = Nid1;
ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1 + ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id =
SL_NR_NUM_IDs_IN_SSS * ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2; ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1 + SL_NR_NUM_IDs_IN_SSS * ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2;
LOG_I(PHY, "UE[%d]NR-SL SLSS SEARCH: SSS Processing over. id2 from SSS:%d, id1 from PSS:%d, SLSS id:%d\n", LOG_I(PHY,
ue->Mod_id, ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1, ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2, "UE[%d]NR-SL SLSS SEARCH: SSS Processing over. id2 from SSS:%d, id1 from PSS:%d, SLSS id:%d\n",
ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id); ue->Mod_id,
ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1,
ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2,
ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id);
#ifdef SL_DEBUG #ifdef SL_DEBUG
#define SSS_METRIC_FLOOR_NR (30000) #define SSS_METRIC_FLOOR_NR (30000)
if (*tot_metric > SSS_METRIC_FLOOR_NR) { if (*tot_metric > SSS_METRIC_FLOOR_NR) {
Nid2 = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2; Nid2 = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2;
Nid1 = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1; Nid1 = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1;
...@@ -315,22 +330,20 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, ...@@ -315,22 +330,20 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc,
return; return;
} }
// Right now 2 frames worth of samples get processed for PSS in OAI. // Right now 2 frames worth of samples get processed for PSS in OAI.
// For PSS in Sidelink, worst case 1 SSB in 16 frames can be present // For PSS in Sidelink, worst case 1 SSB in 16 frames can be present
// Hence 16 frames worth of samples needs to be correlated to find the PSS. // Hence 16 frames worth of samples needs to be correlated to find the PSS.
nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, int num_frames) nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, int num_frames)
{ {
sl_nr_ue_phy_params_t *sl_ue = &UE->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_ue = &UE->SL_UE_PHY_PARAMS;
SL_NR_SYNC_PARAMS_t *sync_params = &sl_ue->sync_params; SL_NR_SYNC_PARAMS_t *sync_params = &sl_ue->sync_params;
NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
int32_t sync_pos = -1;// sync_pos_frame = -1; int32_t sync_pos = -1; // sync_pos_frame = -1;
int32_t metric_tdd_ncp=0; int32_t metric_tdd_ncp = 0;
uint8_t phase_tdd_ncp; uint8_t phase_tdd_ncp;
double im, re; double im, re;
int ret=-1; int ret = -1;
uint16_t rx_slss_id = 65535; uint16_t rx_slss_id = 65535;
nr_initial_sync_t result = {true, 0}; nr_initial_sync_t result = {true, 0};
...@@ -341,32 +354,31 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, ...@@ -341,32 +354,31 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
/* Initial synchronisation /* Initial synchronisation
* *
* 1 radio frame = 10 ms * 1 radio frame = 10 ms
* <---------------------------------------------------------------------------> * <--------------------------------------------------------------------------->
* | Received UE data buffer | * | Received UE data buffer |
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* <-------------->|psbch|pss|pss|sss|sss|psbch sym5-sym 12|sym13 - guard| * <-------------->|psbch|pss|pss|sss|sss|psbch sym5-sym 12|sym13 - guard|
* sync_pos SS/PSBCH block * sync_pos SS/PSBCH block
*/ */
// initial sync performed on 16 successive frames. Worst case - one PSBCH can be sent in 16 frames. // initial sync performed on 16 successive frames. Worst case - one PSBCH can be sent in 16 frames.
//If psbch passes on first frame, no need to process second frame // If psbch passes on first frame, no need to process second frame
// Problem with the frame approach is that // Problem with the frame approach is that
// --------- SSB can be on the boundary between frames. In this case if only 1 SSB is sent we will miss it. // --------- SSB can be on the boundary between frames. In this case if only 1 SSB is sent we will miss it.
// rxdata will hold 16 frames + slot worth of samples. This needs to be processed to find the best SSB // rxdata will hold 16 frames + slot worth of samples. This needs to be processed to find the best SSB
for(int frame_index = 0; frame_index < num_frames; frame_index++) { for (int frame_index = 0; frame_index < num_frames; frame_index++) {
/* process pss search on received buffer */ /* process pss search on received buffer */
sync_pos = sl_nr_pss_correlation(UE, frame_index); sync_pos = sl_nr_pss_correlation(UE, frame_index);
if (sync_pos == -1) { if (sync_pos == -1) {
LOG_I(PHY,"SIDELINK SEARCH SLSS: No PSSS found in this frame\n"); LOG_I(PHY, "SIDELINK SEARCH SLSS: No PSSS found in this frame\n");
continue; continue;
} }
sync_pos += frame_index * sl_fp->samples_per_frame; // position in the num_frames frame samples sync_pos += frame_index * sl_fp->samples_per_frame; // position in the num_frames frame samples
for (int pss_sym = 1; pss_sym < 3;pss_sym++) { for (int pss_sym = 1; pss_sym < 3; pss_sym++) {
// Now Sync pos can point to PSS 1st symbol or 2nd symbol. // Now Sync pos can point to PSS 1st symbol or 2nd symbol.
// Right now implemented the strategy to try both locations for FFT // Right now implemented the strategy to try both locations for FFT
// Think about a better correlation strategy // Think about a better correlation strategy
...@@ -374,62 +386,68 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, ...@@ -374,62 +386,68 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
if (sync_pos > sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples) if (sync_pos > sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)
sync_params->ssb_offset = sync_pos - (sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples); sync_params->ssb_offset = sync_pos - (sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples);
else else
sync_params->ssb_offset = sync_pos + sl_fp->samples_per_frame - (sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples); sync_params->ssb_offset = sync_pos + sl_fp->samples_per_frame
- (sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples);
} else { // Check if sync pos points to SYMBOL2 - second symbol of PSS location } else { // Check if sync pos points to SYMBOL2 - second symbol of PSS location
if (sync_pos >= sl_fp->nb_prefix_samples0 + 2*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)) if (sync_pos >= sl_fp->nb_prefix_samples0 + 2 * (sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples))
sync_params->ssb_offset = sync_pos - (sl_fp->nb_prefix_samples0 + 2*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)); sync_params->ssb_offset =
sync_pos - (sl_fp->nb_prefix_samples0 + 2 * (sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples));
else else
sync_params->ssb_offset = sync_pos + sl_fp->samples_per_frame - (sl_fp->nb_prefix_samples0 + 2*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)); sync_params->ssb_offset = sync_pos + sl_fp->samples_per_frame
- (sl_fp->nb_prefix_samples0 + 2 * (sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples));
} }
LOG_I(PHY,"UE[%d]SIDELINK SEARCH SLSS: PSS Peak at %d, PSS sym:%d, Estimated PSS position %d\n", LOG_I(PHY,
UE->Mod_id,sync_pos,pss_sym,sync_params->ssb_offset); "UE[%d]SIDELINK SEARCH SLSS: PSS Peak at %d, PSS sym:%d, Estimated PSS position %d\n",
UE->Mod_id,
sync_pos,
pss_sym,
sync_params->ssb_offset);
int slss_block_samples = (SL_NR_NUMSYM_SLSS_NORMAL_CP * sl_fp->ofdm_symbol_size) + int slss_block_samples = (SL_NR_NUMSYM_SLSS_NORMAL_CP * sl_fp->ofdm_symbol_size)
(SL_NR_NUMSYM_SLSS_NORMAL_CP -1) * sl_fp->nb_prefix_samples + sl_fp->nb_prefix_samples0; + (SL_NR_NUMSYM_SLSS_NORMAL_CP - 1) * sl_fp->nb_prefix_samples + sl_fp->nb_prefix_samples0;
int ssb_end_position = sync_params->ssb_offset + slss_block_samples; int ssb_end_position = sync_params->ssb_offset + slss_block_samples;
LOG_D(PHY, "ssb_end:%d ssb block samples:%d total samples: %d\n", ssb_end_position, slss_block_samples, num_frames * sl_fp->samples_per_frame); LOG_D(PHY,
"ssb_end:%d ssb block samples:%d total samples: %d\n",
ssb_end_position,
slss_block_samples,
num_frames * sl_fp->samples_per_frame);
/* check that SSS/PBCH block is continuous inside the received buffer */ /* check that SSS/PBCH block is continuous inside the received buffer */
if (ssb_end_position < num_frames * sl_fp->samples_per_frame) { if (ssb_end_position < num_frames * sl_fp->samples_per_frame) {
// digital compensation of FFO for SSB symbols // digital compensation of FFO for SSB symbols
if (UE->UE_fo_compensation){ // This code to be checked. Why do we do this before PSS detection is successful? if (UE->UE_fo_compensation) { // This code to be checked. Why do we do this before PSS detection is successful?
double s_time = 1/(1.0e3 * sl_fp->samples_per_subframe); // sampling time double s_time = 1 / (1.0e3 * sl_fp->samples_per_subframe); // sampling time
double off_angle = -2 * M_PI * s_time * (sync_params->freq_offset); // offset rotation angle compensation per sample double off_angle = -2 * M_PI * s_time * (sync_params->freq_offset); // offset rotation angle compensation per sample
int start = sync_params->ssb_offset; // start for offset correction is at ssb_offset (pss time position) int start = sync_params->ssb_offset; // start for offset correction is at ssb_offset (pss time position)
// Adapt this for other numerologies number of symbols with larger cp increases TBD // Adapt this for other numerologies number of symbols with larger cp increases TBD
int end = ssb_end_position; // loop over samples in all symbols (ssb size), including prefix int end = ssb_end_position; // loop over samples in all symbols (ssb size), including prefix
LOG_I(PHY,
LOG_I(PHY,"SLSS SEARCH: FREQ comp of SLSS samples. Freq_OFSET:%d, startpos:%d, end_pos:%d\n", "SLSS SEARCH: FREQ comp of SLSS samples. Freq_OFSET:%d, startpos:%d, end_pos:%d\n",
sync_params->freq_offset, start, end); sync_params->freq_offset,
for(int n=start; n<end; n++) { start,
for (int ar=0; ar<sl_fp->nb_antennas_rx; ar++) { end);
re = ((double)(((short *)UE->common_vars.rxdata[ar]))[2*n]); for (int n = start; n < end; n++) {
im = ((double)(((short *)UE->common_vars.rxdata[ar]))[2*n+1]); for (int ar = 0; ar < sl_fp->nb_antennas_rx; ar++) {
((short *)UE->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle))); re = ((double)(((short *)UE->common_vars.rxdata[ar]))[2 * n]);
((short *)UE->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle))); im = ((double)(((short *)UE->common_vars.rxdata[ar]))[2 * n + 1]);
((short *)UE->common_vars.rxdata[ar])[2 * n] = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle)));
((short *)UE->common_vars.rxdata[ar])[2 * n + 1] = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle)));
} }
} }
} }
NR_DL_FRAME_PARMS *frame_parms = &UE->SL_UE_PHY_PARAMS.sl_frame_params; NR_DL_FRAME_PARMS *frame_parms = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
const uint32_t rxdataF_sz = frame_parms->samples_per_slot_wCP; const uint32_t rxdataF_sz = frame_parms->samples_per_slot_wCP;
__attribute__ ((aligned(32))) c16_t rxdataF[frame_parms->nb_antennas_rx][rxdataF_sz]; __attribute__((aligned(32))) c16_t rxdataF[frame_parms->nb_antennas_rx][rxdataF_sz];
/* In order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */ /* In order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */
for(int symbol=0; symbol<SL_NR_NUMSYM_SLSS_NORMAL_CP;symbol++) { for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP; symbol++) {
sl_nr_slot_fep(UE, sl_nr_slot_fep(UE, NULL, symbol, 0, sync_params->ssb_offset, rxdataF);
NULL,
symbol,
0,
sync_params->ssb_offset,
rxdataF);
} }
sl_nr_extract_sss(UE, NULL, &metric_tdd_ncp, &phase_tdd_ncp, rxdataF); sl_nr_extract_sss(UE, NULL, &metric_tdd_ncp, &phase_tdd_ncp, rxdataF);
...@@ -437,36 +455,31 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, ...@@ -437,36 +455,31 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
// save detected cell id to psbch // save detected cell id to psbch
rx_slss_id = UE->SL_UE_PHY_PARAMS.sync_params.N_sl_id; rx_slss_id = UE->SL_UE_PHY_PARAMS.sync_params.N_sl_id;
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][rxdataF_sz]; __attribute__((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][rxdataF_sz];
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; __attribute__((
aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
uint8_t decoded_output[4]; uint8_t decoded_output[4];
for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP-1;) { for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP - 1;) {
nr_pbch_channel_estimation(UE, nr_pbch_channel_estimation(UE,
frame_parms, frame_parms,
rxdataF_sz, rxdataF_sz,
dl_ch_estimates, dl_ch_estimates,
dl_ch_estimates_time, dl_ch_estimates_time,
proc, proc,
symbol, symbol,
symbol, symbol,
0, 0,
0, 0,
rxdataF, rxdataF,
1, 1,
rx_slss_id); rx_slss_id);
symbol = (symbol == 0) ? 5 : symbol+1; symbol = (symbol == 0) ? 5 : symbol + 1;
} }
ret = nr_rx_psbch(UE,proc, ret = nr_rx_psbch(UE, proc, rxdataF_sz, dl_ch_estimates, frame_parms, decoded_output, rxdataF, rx_slss_id);
rxdataF_sz,
dl_ch_estimates,
frame_parms,
decoded_output,
rxdataF,
rx_slss_id);
result.cell_detected = (ret == 0) ? true : false; result.cell_detected = (ret == 0) ? true : false;
...@@ -474,23 +487,30 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, ...@@ -474,23 +487,30 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
// sync at symbol ue->symbol_offset // sync at symbol ue->symbol_offset
// computing the offset wrt the beginning of the frame // computing the offset wrt the beginning of the frame
// SSB located at symbol 0 // SSB located at symbol 0
sync_params->remaining_frames = (num_frames * sl_fp->samples_per_frame - sync_params->ssb_offset)/sl_fp->samples_per_frame; sync_params->remaining_frames =
//ssb_offset points to start of sl-ssb (num_frames * sl_fp->samples_per_frame - sync_params->ssb_offset) / sl_fp->samples_per_frame;
//rx_offset points to remaining samples needed to fill a frame // ssb_offset points to start of sl-ssb
// rx_offset points to remaining samples needed to fill a frame
sync_params->rx_offset = sync_params->ssb_offset % sl_fp->samples_per_frame; sync_params->rx_offset = sync_params->ssb_offset % sl_fp->samples_per_frame;
LOG_I(PHY,"UE[%d]SIDELINK SLSS SEARCH: PSBCH RX OK. Remainingframes:%d, rx_offset:%d\n", LOG_I(PHY,
UE->Mod_id,sync_params->remaining_frames, sync_params->rx_offset); "UE[%d]SIDELINK SLSS SEARCH: PSBCH RX OK. Remainingframes:%d, rx_offset:%d\n",
UE->Mod_id,
sync_params->remaining_frames,
sync_params->rx_offset);
uint32_t psbch_payload = (*(uint32_t *)decoded_output); uint32_t psbch_payload = (*(uint32_t *)decoded_output);
//retrieve DFN and slot number from SL-MIB // retrieve DFN and slot number from SL-MIB
sync_params->DFN = (((psbch_payload & 0x0700) >> 1) | ((psbch_payload & 0xFE0000) >> 17)); sync_params->DFN = (((psbch_payload & 0x0700) >> 1) | ((psbch_payload & 0xFE0000) >> 17));
sync_params->slot_offset = (((psbch_payload & 0x010000) >> 10) | ((psbch_payload & 0xFC000000) >> 26)); sync_params->slot_offset = (((psbch_payload & 0x010000) >> 10) | ((psbch_payload & 0xFC000000) >> 26));
LOG_I(PHY, "UE[%d]SIDELINK SLSS SEARCH: SL-MIB: DFN:%d, slot:%d.\n", LOG_I(PHY,
UE->Mod_id, sync_params->DFN, sync_params->slot_offset); "UE[%d]SIDELINK SLSS SEARCH: SL-MIB: DFN:%d, slot:%d.\n",
UE->Mod_id,
sync_params->DFN,
sync_params->slot_offset);
nr_sl_psbch_rsrp_measurements(sl_ue,frame_parms,rxdataF, false); nr_sl_psbch_rsrp_measurements(sl_ue, frame_parms, rxdataF, false);
UE->init_sync_frame = sync_params->remaining_frames; UE->init_sync_frame = sync_params->remaining_frames;
result.rx_offset = sync_params->rx_offset; result.rx_offset = sync_params->rx_offset;
...@@ -501,28 +521,31 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, ...@@ -501,28 +521,31 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, UE, NULL); nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, UE, NULL);
nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, UE, number_pdus, proc, (void *)decoded_output, rx_slss_id); nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, UE, number_pdus, proc, (void *)decoded_output, rx_slss_id);
LOG_D(PHY, "Sidelink SLSS SEARCH PSBCH RX OK. Send SL-SSB TO MAC\n");
LOG_D(PHY,"Sidelink SLSS SEARCH PSBCH RX OK. Send SL-SSB TO MAC\n");
if (UE->if_inst && UE->if_inst->sl_indication) if (UE->if_inst && UE->if_inst->sl_indication)
UE->if_inst->sl_indication(&sl_indication); UE->if_inst->sl_indication(&sl_indication);
break; break;
} }
LOG_I(PHY,"SIDELINK SLSS SEARCH: SLSS ID: %d metric %d, phase %d, psbch CRC %s\n", LOG_I(PHY,
sl_ue->sync_params.N_sl_id,metric_tdd_ncp,phase_tdd_ncp,(ret == 0) ? "OK" : "NOT OK"); "SIDELINK SLSS SEARCH: SLSS ID: %d metric %d, phase %d, psbch CRC %s\n",
sl_ue->sync_params.N_sl_id,
metric_tdd_ncp,
phase_tdd_ncp,
(ret == 0) ? "OK" : "NOT OK");
} else { } else {
LOG_W(PHY,"SIDELINK SLSS SEARCH: Error: Not enough samples to process PSBCH. sync_pos %d\n", sync_pos); LOG_W(PHY, "SIDELINK SLSS SEARCH: Error: Not enough samples to process PSBCH. sync_pos %d\n", sync_pos);
} }
} }
if (result.cell_detected) break; if (result.cell_detected)
break;
} }
if (!result.cell_detected) { // PSBCH not found so indicate sync to higher layers and configure frame parameters if (!result.cell_detected) { // PSBCH not found so indicate sync to higher layers and configure frame parameters
LOG_E(PHY,"SIDELINK SLSS SEARCH: PSBCH not received. Estimated PSS position:%d\n", sync_pos); LOG_E(PHY, "SIDELINK SLSS SEARCH: PSBCH not received. Estimated PSS position:%d\n", sync_pos);
} }
return result; return result;
......
...@@ -241,7 +241,7 @@ void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER ...@@ -241,7 +241,7 @@ void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER
simde__m128i *rxdataF128 = (simde__m128i *)rxdataF_ext[aarx]; simde__m128i *rxdataF128 = (simde__m128i *)rxdataF_ext[aarx];
simde__m128i *rxdataF_comp128 = (simde__m128i *)rxdataF_comp[aarx]; simde__m128i *rxdataF_comp128 = (simde__m128i *)rxdataF_comp[aarx];
for (int re=0; re<nb_re; re+=4) { for (int re = 0; re < nb_re; re += 4) {
*rxdataF_comp128++ = mulByConjugate128(rxdataF128++, dl_ch128++, output_shift); *rxdataF_comp128++ = mulByConjugate128(rxdataF128++, dl_ch128++, output_shift);
} }
} }
...@@ -271,14 +271,14 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, ...@@ -271,14 +271,14 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
} }
void nr_pbch_unscrambling(int16_t *demod_pbch_e, void nr_pbch_unscrambling(int16_t *demod_pbch_e,
uint16_t Nid, uint16_t Nid,
uint8_t nushift, uint8_t nushift,
uint16_t M, uint16_t M,
uint16_t length, uint16_t length,
uint8_t bitwise, uint8_t bitwise,
uint32_t unscrambling_mask, uint32_t unscrambling_mask,
uint32_t pbch_a_prime, uint32_t pbch_a_prime,
uint32_t *pbch_a_interleaved) uint32_t *pbch_a_interleaved)
{ {
uint8_t reset, offset; uint8_t reset, offset;
uint32_t x1 = 0, x2 = 0, s = 0; uint32_t x1 = 0, x2 = 0, s = 0;
...@@ -332,9 +332,8 @@ void nr_pbch_unscrambling(int16_t *demod_pbch_e, ...@@ -332,9 +332,8 @@ void nr_pbch_unscrambling(int16_t *demod_pbch_e,
} }
} }
void nr_pbch_quantize(int16_t *pbch_llr8, void nr_pbch_quantize(int16_t *pbch_llr8, int16_t *pbch_llr, uint16_t len)
int16_t *pbch_llr, {
uint16_t len) {
for (int i=0; i<len; i++) { for (int i=0; i<len; i++) {
if (pbch_llr[i]>31) if (pbch_llr[i]>31)
pbch_llr8[i]=32; pbch_llr8[i]=32;
......
...@@ -25,59 +25,68 @@ ...@@ -25,59 +25,68 @@
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
// #define DEBUG_PSBCH
//#define DEBUG_PSBCH
static void nr_psbch_extract(uint32_t rxdataF_sz, static void nr_psbch_extract(uint32_t rxdataF_sz,
c16_t rxdataF[][rxdataF_sz], c16_t rxdataF[][rxdataF_sz],
int estimateSz, int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz], struct complex16 dl_ch_estimates[][estimateSz],
struct complex16 rxdataF_ext[][SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL], struct complex16 rxdataF_ext[][SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL],
struct complex16 dl_ch_estimates_ext[][SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL], struct complex16 dl_ch_estimates_ext[][SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL],
uint32_t symbol, uint32_t symbol,
NR_DL_FRAME_PARMS *frame_params) NR_DL_FRAME_PARMS *frame_params)
{ {
uint16_t rb; uint16_t rb;
uint8_t i,j,aarx; uint8_t i, j, aarx;
struct complex16 *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; struct complex16 *dl_ch0, *dl_ch0_ext, *rxF, *rxF_ext;
const uint8_t nb_rb = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL; const uint8_t nb_rb = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL;
AssertFatal((symbol == 0 || symbol >= 5), "SIDELINK: PSBCH DMRS not contained in symbol %d \n", symbol); AssertFatal((symbol == 0 || symbol >= 5), "SIDELINK: PSBCH DMRS not contained in symbol %d \n", symbol);
for (aarx=0; aarx<frame_params->nb_antennas_rx; aarx++) { for (aarx = 0; aarx < frame_params->nb_antennas_rx; aarx++) {
unsigned int rx_offset = frame_params->first_carrier_offset + frame_params->ssb_start_subcarrier; unsigned int rx_offset = frame_params->first_carrier_offset + frame_params->ssb_start_subcarrier;
rx_offset = rx_offset % frame_params->ofdm_symbol_size; rx_offset = rx_offset % frame_params->ofdm_symbol_size;
rxF = &rxdataF[aarx][symbol*frame_params->ofdm_symbol_size]; rxF = &rxdataF[aarx][symbol * frame_params->ofdm_symbol_size];
rxF_ext = &rxdataF_ext[aarx][0]; rxF_ext = &rxdataF_ext[aarx][0];
dl_ch0 = &dl_ch_estimates[aarx][symbol*frame_params->ofdm_symbol_size]; dl_ch0 = &dl_ch_estimates[aarx][symbol * frame_params->ofdm_symbol_size];
dl_ch0_ext = &dl_ch_estimates_ext[aarx][0]; dl_ch0_ext = &dl_ch_estimates_ext[aarx][0];
#ifdef DEBUG_PSBCH #ifdef DEBUG_PSBCH
LOG_I(PHY, "extract_rbs: rx_offset=%d, symbol %u\n", (rx_offset + (symbol*frame_params->ofdm_symbol_size)),symbol); LOG_I(PHY, "extract_rbs: rx_offset=%d, symbol %u\n", (rx_offset + (symbol * frame_params->ofdm_symbol_size)), symbol);
#endif #endif
for (rb=0; rb<nb_rb; rb++) { for (rb = 0; rb < nb_rb; rb++) {
j=0; j = 0;
for (i=0; i<NR_NB_SC_PER_RB; i++) { for (i = 0; i < NR_NB_SC_PER_RB; i++) {
if (i%4 != 0) { if (i % 4 != 0) {
rxF_ext[j]=rxF[rx_offset]; rxF_ext[j] = rxF[rx_offset];
dl_ch0_ext[j]=dl_ch0[i]; dl_ch0_ext[j] = dl_ch0[i];
#ifdef DEBUG_PSBCH #ifdef DEBUG_PSBCH
LOG_I(PHY,"rxF ext[%d] = (%d,%d) rxF [%u]= (%d,%d)\n", LOG_I(PHY,
(9*rb) + j,rxF_ext[j].r,rxF_ext[j].i, "rxF ext[%d] = (%d,%d) rxF [%u]= (%d,%d)\n",
rx_offset,rxF[rx_offset].r,rxF[rx_offset].i); (9 * rb) + j,
LOG_I(PHY,"dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n", rxF_ext[j].r,
(9*rb) + j,dl_ch0_ext[j].r,dl_ch0_ext[j].i, rxF_ext[j].i,
i, dl_ch0[i].r,dl_ch0[i].i); rx_offset,
rxF[rx_offset].r,
rxF[rx_offset].i);
LOG_I(PHY,
"dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n",
(9 * rb) + j,
dl_ch0_ext[j].r,
dl_ch0_ext[j].i,
i,
dl_ch0[i].r,
dl_ch0[i].i);
#endif #endif
j++; j++;
} }
rx_offset=(rx_offset+1)%(frame_params->ofdm_symbol_size); rx_offset = (rx_offset + 1) % (frame_params->ofdm_symbol_size);
} }
rxF_ext += SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_RB; rxF_ext += SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_RB;
...@@ -86,19 +95,17 @@ static void nr_psbch_extract(uint32_t rxdataF_sz, ...@@ -86,19 +95,17 @@ static void nr_psbch_extract(uint32_t rxdataF_sz,
} }
#ifdef DEBUG_PSBCH #ifdef DEBUG_PSBCH
char filename[40], varname[25]; char filename[40], varname[25];
sprintf(filename,"psbch_dlch_sym_%d.m", symbol); sprintf(filename, "psbch_dlch_sym_%d.m", symbol);
sprintf(varname,"psbch_dlch%d.m", symbol); sprintf(varname, "psbch_dlch%d.m", symbol);
LOG_M(filename, varname, (void*)dl_ch0, frame_params->ofdm_symbol_size, 1, 1); LOG_M(filename, varname, (void *)dl_ch0, frame_params->ofdm_symbol_size, 1, 1);
sprintf(filename,"psbch_dlchext_sym_%d.m", symbol); sprintf(filename, "psbch_dlchext_sym_%d.m", symbol);
sprintf(varname,"psbch_dlchext%d.m", symbol); sprintf(varname, "psbch_dlchext%d.m", symbol);
LOG_M(filename, varname, (void*)&dl_ch_estimates_ext[0][0], SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL , 1, 1); LOG_M(filename, varname, (void *)&dl_ch_estimates_ext[0][0], SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL, 1, 1);
#endif #endif
} }
return; return;
} }
int nr_rx_psbch(PHY_VARS_NR_UE *ue, int nr_rx_psbch(PHY_VARS_NR_UE *ue,
...@@ -110,29 +117,31 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue, ...@@ -110,29 +117,31 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue,
c16_t rxdataF[][frame_parms->samples_per_slot_wCP], c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
uint16_t slss_id) uint16_t slss_id)
{ {
uint32_t decoderState = 0;
uint32_t decoderState=0;
int psbch_e_rx_idx = 0; int psbch_e_rx_idx = 0;
//Extra 2 bits needed as polar decoder expects a multiple of 4 as encoder length // Extra 2 bits needed as polar decoder expects a multiple of 4 as encoder length
//If these 2 bits are not added, runs compiled with --sanitize will fail. // If these 2 bits are not added, runs compiled with --sanitize will fail.
int16_t psbch_e_rx[SL_NR_POLAR_PSBCH_E_NORMAL_CP+2]= {0}; int16_t psbch_e_rx[SL_NR_POLAR_PSBCH_E_NORMAL_CP + 2] = {0};
#ifdef DEBUG_PSBCH #ifdef DEBUG_PSBCH
write_output("psbch_rxdataF.m","psbchrxF", write_output("psbch_rxdataF.m",
&rxdataF[0][0],frame_parms->ofdm_symbol_size*SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP,1,1); "psbchrxF",
&rxdataF[0][0],
frame_parms->ofdm_symbol_size * SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP,
1,
1);
#endif #endif
// symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot // symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot
double log2_maxh = 0; double log2_maxh = 0;
// 0 for Normal Cyclic Prefix and 1 for EXT CyclicPrefix // 0 for Normal Cyclic Prefix and 1 for EXT CyclicPrefix
const int numsym = (frame_parms->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP const int numsym = (frame_parms->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
: SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
for (int symbol=0; symbol<numsym;) { for (int symbol = 0; symbol < numsym;) {
const uint16_t nb_re = SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL; const uint16_t nb_re = SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL;
__attribute__ ((aligned(32))) struct complex16 rxdataF_ext[frame_parms->nb_antennas_rx][nb_re+1]; __attribute__((aligned(32))) struct complex16 rxdataF_ext[frame_parms->nb_antennas_rx][nb_re + 1];
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][nb_re+1]; __attribute__((aligned(32))) struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][nb_re + 1];
//memset(dl_ch_estimates_ext,0, sizeof dl_ch_estimates_ext); // memset(dl_ch_estimates_ext,0, sizeof dl_ch_estimates_ext);
nr_psbch_extract(frame_parms->samples_per_slot_wCP, nr_psbch_extract(frame_parms->samples_per_slot_wCP,
rxdataF, rxdataF,
estimateSz, estimateSz,
...@@ -142,23 +151,20 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue, ...@@ -142,23 +151,20 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue,
symbol, symbol,
frame_parms); frame_parms);
#ifdef DEBUG_PSBCH #ifdef DEBUG_PSBCH
LOG_I(PHY,"PSBCH RX Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size ); LOG_I(PHY, "PSBCH RX Symbol %d ofdm size %d\n", symbol, frame_parms->ofdm_symbol_size);
#endif #endif
int max_h=0; int max_h = 0;
if (symbol == 0) { if (symbol == 0) {
max_h = nr_pbch_channel_level(dl_ch_estimates_ext, max_h = nr_pbch_channel_level(dl_ch_estimates_ext, frame_parms, nb_re);
frame_parms, // log2_maxh = 3+(log2_approx(max_h)/2);
nb_re); log2_maxh = 5 + (log2_approx(max_h) / 2); // LLR32 crc error. LLR 16 CRC works
//log2_maxh = 3+(log2_approx(max_h)/2);
log2_maxh = 5 +(log2_approx(max_h)/2);// LLR32 crc error. LLR 16 CRC works
} }
#ifdef DEBUG_PSBCH #ifdef DEBUG_PSBCH
LOG_I(PHY,"PSBCH RX log2_maxh = %f (%d)\n", log2_maxh, max_h); LOG_I(PHY, "PSBCH RX log2_maxh = %f (%d)\n", log2_maxh, max_h);
#endif #endif
__attribute__ ((aligned(32))) struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][nb_re+1]; __attribute__((aligned(32))) struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][nb_re + 1];
nr_pbch_channel_compensation(rxdataF_ext, nr_pbch_channel_compensation(rxdataF_ext,
dl_ch_estimates_ext, dl_ch_estimates_ext,
nb_re, nb_re,
...@@ -166,70 +172,68 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue, ...@@ -166,70 +172,68 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue,
frame_parms, frame_parms,
log2_maxh); // log2_maxh+I0_shift log2_maxh); // log2_maxh+I0_shift
nr_pbch_quantize(psbch_e_rx + psbch_e_rx_idx, nr_pbch_quantize(psbch_e_rx + psbch_e_rx_idx, (short *)rxdataF_comp[0], SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL);
(short *)rxdataF_comp[0],
SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL);
psbch_e_rx_idx += SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL; psbch_e_rx_idx += SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL;
//SKIP 2 SL-PSS AND 2 SL-SSS symbols // SKIP 2 SL-PSS AND 2 SL-SSS symbols
//Symbols carrying PSBCH 0, 5-12 // Symbols carrying PSBCH 0, 5-12
symbol = (symbol == 0) ? 5 : symbol + 1; symbol = (symbol == 0) ? 5 : symbol + 1;
} }
#if 0 // ENABLE SCOPE LATER
#if 0 //ENABLE SCOPE LATER
UEscopeCopy(ue, psbchRxdataF_comp, psbch_unClipped, sizeof(struct complex16), frame_parms->nb_antennas_rx, psbch_e_rx_idx/2); UEscopeCopy(ue, psbchRxdataF_comp, psbch_unClipped, sizeof(struct complex16), frame_parms->nb_antennas_rx, psbch_e_rx_idx/2);
UEscopeCopy(ue, psbchLlr, psbch_e_rx, sizeof(int16_t), frame_parms->nb_antennas_rx, psbch_e_rx_idx); UEscopeCopy(ue, psbchLlr, psbch_e_rx, sizeof(int16_t), frame_parms->nb_antennas_rx, psbch_e_rx_idx);
#endif #endif
#ifdef DEBUG_PSBCH #ifdef DEBUG_PSBCH
write_output("psbch_rxdataFcomp.m","psbch_rxFcomp",psbch_unClipped,SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS,1,1); write_output("psbch_rxdataFcomp.m", "psbch_rxFcomp", psbch_unClipped, SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS, 1, 1);
#endif #endif
//un-scrambling // un-scrambling
LOG_D(PHY, "PSBCH RX POLAR DECODING: total PSBCH bits:%d, rx_slss_id:%d\n", psbch_e_rx_idx, slss_id); LOG_D(PHY, "PSBCH RX POLAR DECODING: total PSBCH bits:%d, rx_slss_id:%d\n", psbch_e_rx_idx, slss_id);
nr_pbch_unscrambling(psbch_e_rx, slss_id, 0, 0, psbch_e_rx_idx, nr_pbch_unscrambling(psbch_e_rx, slss_id, 0, 0, psbch_e_rx_idx, 0, 0, 0, NULL);
0, 0, 0, NULL); // polar decoding de-rate matching
//polar decoding de-rate matching uint64_t tmp = 0;
uint64_t tmp=0; decoderState = polar_decoder_int16(psbch_e_rx,
decoderState = polar_decoder_int16(psbch_e_rx,(uint64_t *)&tmp,0, (uint64_t *)&tmp,
SL_NR_POLAR_PSBCH_MESSAGE_TYPE, SL_NR_POLAR_PSBCH_PAYLOAD_BITS, SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL); 0,
SL_NR_POLAR_PSBCH_MESSAGE_TYPE,
SL_NR_POLAR_PSBCH_PAYLOAD_BITS,
SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL);
uint32_t psbch_payload = tmp; uint32_t psbch_payload = tmp;
if(decoderState) { if (decoderState) {
LOG_D(PHY,"%d:%d PSBCH RX: NOK \n",proc->frame_rx, proc->nr_slot_rx); LOG_D(PHY, "%d:%d PSBCH RX: NOK \n", proc->frame_rx, proc->nr_slot_rx);
return(decoderState); return (decoderState);
} }
// Decoder reversal // Decoder reversal
uint32_t a_reversed=0; uint32_t a_reversed = 0;
for (int i=0; i<SL_NR_POLAR_PSBCH_PAYLOAD_BITS; i++) for (int i = 0; i < SL_NR_POLAR_PSBCH_PAYLOAD_BITS; i++)
a_reversed |= (((uint64_t)psbch_payload>>i)&1)<<(31-i); a_reversed |= (((uint64_t)psbch_payload >> i) & 1) << (31 - i);
psbch_payload = a_reversed; psbch_payload = a_reversed;
*((uint32_t *)decoded_output) = psbch_payload; *((uint32_t *)decoded_output) = psbch_payload;
#ifdef DEBUG_PSBCH #ifdef DEBUG_PSBCH
for (int i=0; i<4; i++) { for (int i = 0; i < 4; i++) {
LOG_I(PHY, "decoded_output[%d]:%x\n", i, decoded_output[i]); LOG_I(PHY, "decoded_output[%d]:%x\n", i, decoded_output[i]);
} }
#endif #endif
ue->symbol_offset = 0; ue->symbol_offset = 0;
//retrieve DFN and slot number from SL-MIB // retrieve DFN and slot number from SL-MIB
uint32_t DFN = 0, slot_offset = 0; uint32_t DFN = 0, slot_offset = 0;
DFN = (((psbch_payload & 0x0700) >> 1) | ((psbch_payload & 0xFE0000) >> 17)); DFN = (((psbch_payload & 0x0700) >> 1) | ((psbch_payload & 0xFE0000) >> 17));
slot_offset = (((psbch_payload & 0x010000) >> 10) | ((psbch_payload & 0xFC000000) >> 26)); slot_offset = (((psbch_payload & 0x010000) >> 10) | ((psbch_payload & 0xFC000000) >> 26));
LOG_D(PHY, "PSBCH RX SL-MIB:%x, decoded DFN:slot %d:%d, %x\n",psbch_payload, DFN, slot_offset, *(uint32_t *)decoded_output); LOG_D(PHY, "PSBCH RX SL-MIB:%x, decoded DFN:slot %d:%d, %x\n", psbch_payload, DFN, slot_offset, *(uint32_t *)decoded_output);
return 0; return 0;
} }
...@@ -26,17 +26,17 @@ ...@@ -26,17 +26,17 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h"
#include "PHY/MODULATION/nr_modulation.h" #include "PHY/MODULATION/nr_modulation.h"
//#define SL_DEBUG // #define SL_DEBUG
/** /**
*This function performs PSBCH SCrambling as described in 38.211. *This function performs PSBCH SCrambling as described in 38.211.
*Input parameter "output" is scrambled and the scrambled output is stored in this parameter. *Input parameter "output" is scrambled and the scrambled output is stored in this parameter.
*id - SLSS ID used for C_INIT *id - SLSS ID used for C_INIT
*length is the length of the buffer. *length is the length of the buffer.
*/ */
void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length) void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length)
{ {
uint32_t x1, x2, s=0; uint32_t x1, x2, s = 0;
// x1 is set in lte_gold_generic // x1 is set in lte_gold_generic
x2 = id; // C_INIT x2 = id; // C_INIT
...@@ -46,8 +46,8 @@ void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length) ...@@ -46,8 +46,8 @@ void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length)
#endif #endif
#ifdef SL_DEBUG #ifdef SL_DEBUG
for (int i=0; i<56;i++) { for (int i = 0; i < 56; i++) {
printf("\nBEFORE SCRAMBLING output[%d]:0x%x\n",i,output[i]); printf("\nBEFORE SCRAMBLING output[%d]:0x%x\n", i, output[i]);
} }
#endif #endif
...@@ -59,9 +59,8 @@ void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length) ...@@ -59,9 +59,8 @@ void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length)
// scramble in 32bit chunks // scramble in 32bit chunks
int i = 0; int i = 0;
while(i+32 <= length) { while (i + 32 <= length) {
output[i >> 5] ^= s;
output[i>>5] ^= s;
i += 32; i += 32;
s = lte_gold_generic(&x1, &x2, 0); s = lte_gold_generic(&x1, &x2, 0);
...@@ -72,59 +71,68 @@ void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length) ...@@ -72,59 +71,68 @@ void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length)
// scramble remaining bits // scramble remaining bits
for (; i < length; ++i) { for (; i < length; ++i) {
output[i>>5] ^= ((s>>(i&0x1f)&1)<<(i&0x1f)); output[i >> 5] ^= ((s >> (i & 0x1f) & 1) << (i & 0x1f));
} }
#ifdef SL_DEBUG #ifdef SL_DEBUG
for (int i=0; i<56;i++) { for (int i = 0; i < 56; i++) {
printf("\nAFTER SCRAMBLING output[%d]:0x%x\n",i,output[i]); printf("\nAFTER SCRAMBLING output[%d]:0x%x\n", i, output[i]);
} }
#endif #endif
} }
/** /**
*This function RE MAPS PSS, SSS sequences as described in 38.211. *This function RE MAPS PSS, SSS sequences as described in 38.211.
*txF is the data in frequency domain, sync_seq = PSS or SSS seq *txF is the data in frequency domain, sync_seq = PSS or SSS seq
*startsym = 1 for PSS, 3 for SSS *startsym = 1 for PSS, 3 for SSS
*re_offset = sample which points to first RE + SSB start RE *re_offset = sample which points to first RE + SSB start RE
*scaling factor = scaling factor used for PSS, SSS (determined according to PSBCH pwr) *scaling factor = scaling factor used for PSS, SSS (determined according to PSBCH pwr)
*symbol size = OFDM symbol size used for RE Mapping *symbol size = OFDM symbol size used for RE Mapping
*/ */
void sl_map_pss_or_sss(c16_t *txF, int16_t *sync_seq, uint16_t startsym, void sl_map_pss_or_sss(c16_t *txF,
uint16_t re_offset, uint16_t scaling_factor, int16_t *sync_seq,
uint16_t startsym,
uint16_t re_offset,
uint16_t scaling_factor,
uint16_t symbol_size) uint16_t symbol_size)
{ {
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("%s. DEBUG PSBCH TX: RE MAPPING of PSS/SSS \n", __func__); printf("%s. DEBUG PSBCH TX: RE MAPPING of PSS/SSS \n", __func__);
printf("Input Params - StartSYM:%d, NUMSYM:%d, RE_OFFSET:%d, num_REs:%d, scaling_factor:%d, symbol_size:%d\n", printf("Input Params - StartSYM:%d, NUMSYM:%d, RE_OFFSET:%d, num_REs:%d, scaling_factor:%d, symbol_size:%d\n",
startsym, SL_NR_NUM_PSS_OR_SSS_SYMBOLS,re_offset, SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL, scaling_factor, symbol_size); startsym,
SL_NR_NUM_PSS_OR_SSS_SYMBOLS,
re_offset,
SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL,
scaling_factor,
symbol_size);
#endif #endif
// RE Mapping of SL-PSS, SL-SSS // RE Mapping of SL-PSS, SL-SSS
for (int l = startsym;l < (startsym + SL_NR_NUM_PSS_OR_SSS_SYMBOLS);l++) { for (int l = startsym; l < (startsym + SL_NR_NUM_PSS_OR_SSS_SYMBOLS); l++) {
int k = re_offset % symbol_size; int k = re_offset % symbol_size;
int index = 0, offset = 0; int index = 0, offset = 0;
for (int m = 0;m < SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL;m++) { for (int m = 0; m < SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL; m++) {
offset = l * symbol_size + k;
offset = l*symbol_size + k;
if ((m < 2) || (m >= (SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL - 3))) { if ((m < 2) || (m >= (SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL - 3))) {
txF[offset].r = 0; //Set REs 0,1,129,130,131 = 0 txF[offset].r = 0; // Set REs 0,1,129,130,131 = 0
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("sym:%d, RE:%d, txF[%d]:%d.%d \n", l, m, offset, txF[offset].r,txF[offset].i); printf("sym:%d, RE:%d, txF[%d]:%d.%d \n", l, m, offset, txF[offset].r, txF[offset].i);
#endif #endif
} else { } else {
txF[offset].r = (sync_seq[index] * scaling_factor) >> 15; txF[offset].r = (sync_seq[index] * scaling_factor) >> 15;
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("sym:%d, RE:%d, txF[%d]:%d.%d, syncseq[%d]:%d \n", l, m, offset, txF[offset].r,txF[offset].i, index, sync_seq[index]); printf("sym:%d, RE:%d, txF[%d]:%d.%d, syncseq[%d]:%d \n",
l,
m,
offset,
txF[offset].r,
txF[offset].i,
index,
sync_seq[index]);
#endif #endif
index++; index++;
...@@ -133,95 +141,97 @@ void sl_map_pss_or_sss(c16_t *txF, int16_t *sync_seq, uint16_t startsym, ...@@ -133,95 +141,97 @@ void sl_map_pss_or_sss(c16_t *txF, int16_t *sync_seq, uint16_t startsym,
k = (k + 1) % symbol_size; k = (k + 1) % symbol_size;
} }
} }
} }
/** /**
* This function Generates the PSBCH DATA Modulation symbols and RE MAPS PSBCH Modulated symbols * This function Generates the PSBCH DATA Modulation symbols and RE MAPS PSBCH Modulated symbols
* and PSBCH DMRS sequences as described in 38.211. * and PSBCH DMRS sequences as described in 38.211.
* txF is the data in frequency domain * txF is the data in frequency domain
* payload is the PSBCH payload (SL-MIB given by higher layers) * payload is the PSBCH payload (SL-MIB given by higher layers)
* id - SLSS ID used for knowing which DMRS sequence to be used. * id - SLSS ID used for knowing which DMRS sequence to be used.
* Cp - NORMAL of extended Cyclic prefix * Cp - NORMAL of extended Cyclic prefix
* startsym = 0 and then PSBCH is mapped from symbols 5-13 if normal , 5-11 if extended * startsym = 0 and then PSBCH is mapped from symbols 5-13 if normal , 5-11 if extended
* re_offset = sample which points to first RE + SSB start RE * re_offset = sample which points to first RE + SSB start RE
* scaling factor = scaling factor used for PSS, SSS (determined according to PSBCH pwr) * scaling factor = scaling factor used for PSS, SSS (determined according to PSBCH pwr)
* symbol size = OFDM symbol size used for RE Mapping * symbol size = OFDM symbol size used for RE Mapping
*/ */
void sl_generate_and_map_psbch(c16_t *txF, uint32_t *payload, uint16_t id, void sl_generate_and_map_psbch(c16_t *txF,
uint16_t cp, uint16_t re_offset, uint32_t *payload,
uint16_t scaling_factor, uint16_t symbol_size, uint16_t id,
uint16_t cp,
uint16_t re_offset,
uint16_t scaling_factor,
uint16_t symbol_size,
c16_t *psbch_dmrs) c16_t *psbch_dmrs)
{ {
uint64_t psbch_a_reversed = 0; uint64_t psbch_a_reversed = 0;
uint16_t num_psbch_modsym = 0, numsym = 0; uint16_t num_psbch_modsym = 0, numsym = 0;
const int mod_order = 2;//QPSK const int mod_order = 2; // QPSK
uint32_t encoder_output[SL_NR_POLAR_PSBCH_E_DWORD]; uint32_t encoder_output[SL_NR_POLAR_PSBCH_E_DWORD];
struct complex16 psbch_modsym[SL_NR_NUM_PSBCH_MODULATED_SYMBOLS]; struct complex16 psbch_modsym[SL_NR_NUM_PSBCH_MODULATED_SYMBOLS];
LOG_D(PHY, "PSBCH TX: Generation accg to 38.212, 38.211. SLSS id:%d\n", id); LOG_D(PHY, "PSBCH TX: Generation accg to 38.212, 38.211. SLSS id:%d\n", id);
// Encoder reversal // Encoder reversal
for (int i=0; i<SL_NR_POLAR_PSBCH_PAYLOAD_BITS; i++) for (int i = 0; i < SL_NR_POLAR_PSBCH_PAYLOAD_BITS; i++)
psbch_a_reversed |= (((uint64_t)*payload>>i)&1)<<(31-i); psbch_a_reversed |= (((uint64_t)*payload >> i) & 1) << (31 - i);
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("DEBUG PSBCH TX: 38.212 PSBCH CRC + Channel coding (POLAR) + Rate Matching:\n"); printf("DEBUG PSBCH TX: 38.212 PSBCH CRC + Channel coding (POLAR) + Rate Matching:\n");
printf("PSBCH payload:%x, Reversed Payload:%016lx\n",*payload, psbch_a_reversed); printf("PSBCH payload:%x, Reversed Payload:%016lx\n", *payload, psbch_a_reversed);
#endif #endif
/// CRC, coding and rate matching /// CRC, coding and rate matching
polar_encoder_fast(&psbch_a_reversed, (void*)encoder_output, 0, 0, polar_encoder_fast(&psbch_a_reversed,
(void *)encoder_output,
0,
0,
SL_NR_POLAR_PSBCH_MESSAGE_TYPE, SL_NR_POLAR_PSBCH_MESSAGE_TYPE,
SL_NR_POLAR_PSBCH_PAYLOAD_BITS, SL_NR_POLAR_PSBCH_PAYLOAD_BITS,
SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL); SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL);
#ifdef SL_DEBUG #ifdef SL_DEBUG
for (int i=0; i<SL_NR_POLAR_PSBCH_E_DWORD; i++) for (int i = 0; i < SL_NR_POLAR_PSBCH_E_DWORD; i++)
printf("encoderoutput[%d]: 0x%08x\t", i, encoder_output[i]); printf("encoderoutput[%d]: 0x%08x\t", i, encoder_output[i]);
printf("\n"); printf("\n");
#endif #endif
/// 38.211 Scrambling /// 38.211 Scrambling
if (cp) { // EXT Cyclic prefix if (cp) { // EXT Cyclic prefix
sl_psbch_scrambling(encoder_output, id, SL_NR_POLAR_PSBCH_E_EXT_CP); //for Extended Cyclic prefix sl_psbch_scrambling(encoder_output, id, SL_NR_POLAR_PSBCH_E_EXT_CP); // for Extended Cyclic prefix
num_psbch_modsym = SL_NR_POLAR_PSBCH_E_EXT_CP/mod_order; num_psbch_modsym = SL_NR_POLAR_PSBCH_E_EXT_CP / mod_order;
numsym = SL_NR_NUM_SYMBOLS_SSB_EXT_CP; numsym = SL_NR_NUM_SYMBOLS_SSB_EXT_CP;
AssertFatal(1==0, "EXT CP is not yet supported\n"); AssertFatal(1 == 0, "EXT CP is not yet supported\n");
} } else { // Normal CP
else { // Normal CP sl_psbch_scrambling(encoder_output, id, SL_NR_POLAR_PSBCH_E_NORMAL_CP); // for Cyclic prefix
sl_psbch_scrambling(encoder_output, id, SL_NR_POLAR_PSBCH_E_NORMAL_CP); //for Cyclic prefix num_psbch_modsym = SL_NR_POLAR_PSBCH_E_NORMAL_CP / mod_order;
num_psbch_modsym = SL_NR_POLAR_PSBCH_E_NORMAL_CP/mod_order;
numsym = SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP; numsym = SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
} }
LOG_D(PHY,"PSBCH TX: 38.211 Scrambling done. Number of bits:%d \n", LOG_D(PHY, "PSBCH TX: 38.211 Scrambling done. Number of bits:%d \n", SL_NR_POLAR_PSBCH_E_NORMAL_CP);
SL_NR_POLAR_PSBCH_E_NORMAL_CP);
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("38211 STEP: PSBCH Scrambling \n"); printf("38211 STEP: PSBCH Scrambling \n");
for (int i=0; i<SL_NR_POLAR_PSBCH_E_NORMAL_CP/32; i++) for (int i = 0; i < SL_NR_POLAR_PSBCH_E_NORMAL_CP / 32; i++)
printf("Scrambleroutput[%d]: 0x%08x\t", i, encoder_output[i]); printf("Scrambleroutput[%d]: 0x%08x\t", i, encoder_output[i]);
printf("\n"); printf("\n");
#endif #endif
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("SIDELINK PSBCH TX: 38211 STEP: QPSK Modulation of PSBCH symbols:%d, symbols in PSBCH:%d\n", num_psbch_modsym, numsym); printf("SIDELINK PSBCH TX: 38211 STEP: QPSK Modulation of PSBCH symbols:%d, symbols in PSBCH:%d\n", num_psbch_modsym, numsym);
#endif #endif
/// 38.211 QPSK modulation /// 38.211 QPSK modulation
nr_modulation(encoder_output, num_psbch_modsym*mod_order,mod_order,(int16_t *)psbch_modsym); nr_modulation(encoder_output, num_psbch_modsym * mod_order, mod_order, (int16_t *)psbch_modsym);
// RE MApping of PSBCH and PSBCH DMRS // RE MApping of PSBCH and PSBCH DMRS
int index = 0, dmrs_index = 0; int index = 0, dmrs_index = 0;
const int numre=SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL; const int numre = SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL;
#ifdef SL_DEBUG #ifdef SL_DEBUG
LOG_M("sl_psbch_data_symbols.m", "psbch_sym", (void*)psbch_modsym, num_psbch_modsym, 1, 1); LOG_M("sl_psbch_data_symbols.m", "psbch_sym", (void *)psbch_modsym, num_psbch_modsym, 1, 1);
LOG_M("sl_psbch_dmrs_symbols.m", "psbch_dmrs", (void*)psbch_dmrs, SL_NR_NUM_PSBCH_DMRS_RE, 1, 1); LOG_M("sl_psbch_dmrs_symbols.m", "psbch_dmrs", (void *)psbch_dmrs, SL_NR_NUM_PSBCH_DMRS_RE, 1, 1);
#endif #endif
#ifdef SL_DEBUG #ifdef SL_DEBUG
...@@ -229,35 +239,42 @@ void sl_generate_and_map_psbch(c16_t *txF, uint32_t *payload, uint16_t id, ...@@ -229,35 +239,42 @@ void sl_generate_and_map_psbch(c16_t *txF, uint32_t *payload, uint16_t id,
#endif #endif
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("%s. DEBUG PSBCH TX: RE MAPPING of PSBCH DATA AND DMRS \n", __func__); printf("%s. DEBUG PSBCH TX: RE MAPPING of PSBCH DATA AND DMRS \n", __func__);
printf("Input Params - StartSYM:%d, NUMSYM:%d, RE_OFFSET:%d, num_REs:%d, scaling_factor:%d, symbol_size:%d\n", printf("Input Params - StartSYM:%d, NUMSYM:%d, RE_OFFSET:%d, num_REs:%d, scaling_factor:%d, symbol_size:%d\n",
0, numsym,re_offset, numre, scaling_factor, symbol_size); 0,
numsym,
re_offset,
numre,
scaling_factor,
symbol_size);
#endif #endif
for (int l=0;l < numsym;) { for (int l = 0; l < numsym;) {
int k = re_offset % symbol_size; int k = re_offset % symbol_size;
int symbol_offset = l*symbol_size; int symbol_offset = l * symbol_size;
int offset = 0; int offset = 0;
for (int m=0; m < numre;m++) { for (int m = 0; m < numre; m++) {
// Maps PSBCH DMRS in every 4th RE ex:0,4,....128 // Maps PSBCH DMRS in every 4th RE ex:0,4,....128
// Maps PSBCH in all other REs ex: 1,2,3,5,6,...127,129,130,131 // Maps PSBCH in all other REs ex: 1,2,3,5,6,...127,129,130,131
offset = symbol_offset + k; offset = symbol_offset + k;
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("symbol:%d, symbol_offset:%d, k:%d, re:%d, sampleoffset:%d ", l, symbol_offset, k, m, offset); printf("symbol:%d, symbol_offset:%d, k:%d, re:%d, sampleoffset:%d ", l, symbol_offset, k, m, offset);
#endif #endif
if (m % 4 == 0) { if (m % 4 == 0) {
txF[offset] = c16xmulConstShift(psbch_dmrs[dmrs_index], scaling_factor, 15); txF[offset] = c16xmulConstShift(psbch_dmrs[dmrs_index], scaling_factor, 15);
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("txF[%d]:%d,%d, psbch_dmrs[%d]:%d,%d ", offset, txF[offset].r, printf("txF[%d]:%d,%d, psbch_dmrs[%d]:%d,%d ",
txF[offset].i, dmrs_index, psbch_dmrs[dmrs_index].r, psbch_dmrs[dmrs_index].i); offset,
txF[offset].r,
txF[offset].i,
dmrs_index,
psbch_dmrs[dmrs_index].r,
psbch_dmrs[dmrs_index].i);
#endif #endif
dmrs_index++; dmrs_index++;
...@@ -266,8 +283,13 @@ void sl_generate_and_map_psbch(c16_t *txF, uint32_t *payload, uint16_t id, ...@@ -266,8 +283,13 @@ void sl_generate_and_map_psbch(c16_t *txF, uint32_t *payload, uint16_t id,
txF[offset] = c16xmulConstShift(psbch_modsym[index], scaling_factor, 15); txF[offset] = c16xmulConstShift(psbch_modsym[index], scaling_factor, 15);
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("txF[%d]:%d,%d, psbch_modsym[%d]:%d,%d\n", offset, txF[offset].r, printf("txF[%d]:%d,%d, psbch_modsym[%d]:%d,%d\n",
txF[offset].i, index ,psbch_modsym[index].r, psbch_modsym[index].i); offset,
txF[offset].r,
txF[offset].i,
index,
psbch_modsym[index].r,
psbch_modsym[index].i);
#endif #endif
index++; index++;
...@@ -276,53 +298,50 @@ void sl_generate_and_map_psbch(c16_t *txF, uint32_t *payload, uint16_t id, ...@@ -276,53 +298,50 @@ void sl_generate_and_map_psbch(c16_t *txF, uint32_t *payload, uint16_t id,
k = (k + 1) % symbol_size; k = (k + 1) % symbol_size;
} }
LOG_D(PHY, "PSBCH TX: 38211 STEP: RE MAPPING OF PSBCH, PSBCH DMRS DONE. symbol:%d, first RE offset:%d, Last RE offset:%d, Num PSBCH DATA REs:%d, Num PSBCH DMRS REs:%d\n", LOG_D(PHY,
l, symbol_offset+re_offset, offset, index, dmrs_index); "PSBCH TX: 38211 STEP: RE MAPPING OF PSBCH, PSBCH DMRS DONE. symbol:%d, first RE offset:%d, Last RE offset:%d, Num PSBCH "
"DATA REs:%d, Num PSBCH DMRS REs:%d\n",
l = (l == 0) ? 5: l+1; l,
symbol_offset + re_offset,
offset,
index,
dmrs_index);
l = (l == 0) ? 5 : l + 1;
} }
} }
/** /**
*This function prepares the PSBCH block and RE MAPS PSS, SSS, PSBCH DATA, PSBCH DMRS into buffer txF. *This function prepares the PSBCH block and RE MAPS PSS, SSS, PSBCH DATA, PSBCH DMRS into buffer txF.
*Called by the L1 Scheduler when MAC triggers PHY to send PSBCH *Called by the L1 Scheduler when MAC triggers PHY to send PSBCH
*UE is the UE context. *UE is the UE context.
*frame, slot points to the TTI in which PSBCH TX will be transmitted *frame, slot points to the TTI in which PSBCH TX will be transmitted
*/ */
void nr_tx_psbch(PHY_VARS_NR_UE *UE, uint32_t frame_tx, void nr_tx_psbch(PHY_VARS_NR_UE *UE, uint32_t frame_tx, uint32_t slot_tx, sl_nr_tx_config_psbch_pdu_t *psbch_vars, c16_t **txdataF)
uint32_t slot_tx,
sl_nr_tx_config_psbch_pdu_t *psbch_vars,
c16_t **txdataF)
{ {
sl_nr_ue_phy_params_t *sl_ue_phy_params = &UE->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_ue_phy_params = &UE->SL_UE_PHY_PARAMS;
uint16_t slss_id = psbch_vars->tx_slss_id; uint16_t slss_id = psbch_vars->tx_slss_id;
NR_DL_FRAME_PARMS *sl_fp = &sl_ue_phy_params->sl_frame_params; NR_DL_FRAME_PARMS *sl_fp = &sl_ue_phy_params->sl_frame_params;
uint32_t psbch_payload = *((uint32_t *)psbch_vars->psbch_payload); uint32_t psbch_payload = *((uint32_t *)psbch_vars->psbch_payload);
LOG_D(PHY,"PSBCH TX: slss-id %d, psbch payload %x \n", slss_id, psbch_payload); LOG_D(PHY, "PSBCH TX: slss-id %d, psbch payload %x \n", slss_id, psbch_payload);
// Insert FN and Slot number into SL-MIB // Insert FN and Slot number into SL-MIB
uint32_t mask = ~(0x700 | 0xFE0000 | 0x10000 | 0xFC000000); uint32_t mask = ~(0x700 | 0xFE0000 | 0x10000 | 0xFC000000);
psbch_payload &= mask; psbch_payload &= mask;
psbch_payload |= ((frame_tx%1024)<<1) & 0x700; psbch_payload |= ((frame_tx % 1024) << 1) & 0x700;
psbch_payload |= ((frame_tx%1024)<<17) & 0xFE0000; psbch_payload |= ((frame_tx % 1024) << 17) & 0xFE0000;
psbch_payload |= (slot_tx<<10) & 0x10000; psbch_payload |= (slot_tx << 10) & 0x10000;
psbch_payload |= (slot_tx<<26) & 0xFC000000; psbch_payload |= (slot_tx << 26) & 0xFC000000;
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("DEBUG PSBCH TX: DFN, SLOT included. psbch_a :0x%08x, frame:%d, slot:%d\n", printf("DEBUG PSBCH TX: DFN, SLOT included. psbch_a :0x%08x, frame:%d, slot:%d\n", psbch_payload, frame_tx, slot_tx);
psbch_payload, frame_tx, slot_tx);
#endif #endif
LOG_D(PHY,"PSBCH TX: Frame.Slot %d.%d. Payload::0x%08x, slssid:%d\n", LOG_D(PHY, "PSBCH TX: Frame.Slot %d.%d. Payload::0x%08x, slssid:%d\n", frame_tx, slot_tx, psbch_payload, slss_id);
frame_tx, slot_tx, psbch_payload, slss_id);
// GENERATE Sidelink PSS,SSS Sequences, PSBCH DMRS Symbols, PSBCH Symbols // GENERATE Sidelink PSS,SSS Sequences, PSBCH DMRS Symbols, PSBCH Symbols
int16_t *sl_pss = &sl_ue_phy_params->init_params.sl_pss[slss_id/336][0]; int16_t *sl_pss = &sl_ue_phy_params->init_params.sl_pss[slss_id / 336][0];
int16_t *sl_sss = &sl_ue_phy_params->init_params.sl_sss[slss_id][0]; int16_t *sl_sss = &sl_ue_phy_params->init_params.sl_sss[slss_id][0];
uint16_t re_offset = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier; uint16_t re_offset = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier;
...@@ -333,42 +352,33 @@ void nr_tx_psbch(PHY_VARS_NR_UE *UE, uint32_t frame_tx, ...@@ -333,42 +352,33 @@ void nr_tx_psbch(PHY_VARS_NR_UE *UE, uint32_t frame_tx,
struct complex16 *txF = &txdataF[0][0]; struct complex16 *txF = &txdataF[0][0];
uint16_t startsym = SL_NR_PSS_START_SYMBOL; uint16_t startsym = SL_NR_PSS_START_SYMBOL;
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("DEBUG PSBCH TX: MAP PSS. startsym:%d, PSS RE START:%d, scaling factor:%d\n", printf("DEBUG PSBCH TX: MAP PSS. startsym:%d, PSS RE START:%d, scaling factor:%d\n", startsym, re_offset, scaling_factor);
startsym, re_offset, scaling_factor);
#endif #endif
sl_map_pss_or_sss(txF, sl_pss, startsym, re_offset, scaling_factor, symbol_size); // PSS sl_map_pss_or_sss(txF, sl_pss, startsym, re_offset, scaling_factor, symbol_size); // PSS
startsym += SL_NR_NUM_PSS_SYMBOLS; startsym += SL_NR_NUM_PSS_SYMBOLS;
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("DEBUG PSBCH TX: MAP SSS. startsym:%d, SSS RE START:%d, scaling factor:%d\n", printf("DEBUG PSBCH TX: MAP SSS. startsym:%d, SSS RE START:%d, scaling factor:%d\n", startsym, re_offset, scaling_factor);
startsym, re_offset, scaling_factor);
#endif #endif
sl_map_pss_or_sss(txF, sl_sss, startsym, re_offset, scaling_factor, symbol_size); // SSS sl_map_pss_or_sss(txF, sl_sss, startsym, re_offset, scaling_factor, symbol_size); // SSS
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("DEBUG PSBCH TX: MAP PSBCH DATA AND DMRS. cyclicPrefix:%d, PSS RE START:%d, scaling factor:%d\n", printf("DEBUG PSBCH TX: MAP PSBCH DATA AND DMRS. cyclicPrefix:%d, PSS RE START:%d, scaling factor:%d\n",
sl_fp->Ncp, re_offset, scaling_factor); sl_fp->Ncp,
re_offset,
scaling_factor);
#endif #endif
struct complex16 *psbch_dmrs = &sl_ue_phy_params->init_params.psbch_dmrs_modsym[slss_id][0]; struct complex16 *psbch_dmrs = &sl_ue_phy_params->init_params.psbch_dmrs_modsym[slss_id][0];
sl_generate_and_map_psbch(txF, &psbch_payload, slss_id, sl_generate_and_map_psbch(txF, &psbch_payload, slss_id, sl_fp->Ncp, re_offset, scaling_factor, symbol_size, psbch_dmrs);
sl_fp->Ncp, re_offset, scaling_factor, symbol_size,
psbch_dmrs);
#ifdef SL_DEBUG #ifdef SL_DEBUG
printf("DEBUG PSBCH TX: txdataF Prepared\n"); printf("DEBUG PSBCH TX: txdataF Prepared\n");
#endif #endif
#ifdef SL_DEBUG #ifdef SL_DEBUG
LOG_M("sl_psbch_block.m", "sl_txF", (void*)txdataF[0], symbol_size*14, 1, 1); LOG_M("sl_psbch_block.m", "sl_txF", (void *)txdataF[0], symbol_size * 14, 1, 1);
#endif #endif
} }
...@@ -428,22 +428,20 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue, ...@@ -428,22 +428,20 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue,
c16_t rxdataF[][frame_parms->samples_per_slot_wCP], c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
uint16_t slss_id); uint16_t slss_id);
void nr_tx_psbch(PHY_VARS_NR_UE *UE, uint32_t frame_tx, uint32_t slot_tx, void nr_tx_psbch(PHY_VARS_NR_UE *UE, uint32_t frame_tx, uint32_t slot_tx, sl_nr_tx_config_psbch_pdu_t *psbch_vars, c16_t **txdataF);
sl_nr_tx_config_psbch_pdu_t *psbch_vars,
c16_t **txdataF);
nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, int num_frames); nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, int num_frames);
//Reuse already existing PBCH functions // Reuse already existing PBCH functions
int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL], int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
int nb_re); int nb_re);
void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL], void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL],
struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL], struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
int nb_re, int nb_re,
struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL], struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL],
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint8_t output_shift); uint8_t output_shift);
void nr_pbch_unscrambling(int16_t *demod_pbch_e, void nr_pbch_unscrambling(int16_t *demod_pbch_e,
uint16_t Nid, uint16_t Nid,
uint8_t nushift, uint8_t nushift,
......
...@@ -706,10 +706,9 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i ...@@ -706,10 +706,9 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i
void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling) void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling)
{ {
int i = 0, m = 0; int i = 0, m = 0;
int16_t x[SL_NR_PSS_SEQUENCE_LENGTH]; int16_t x[SL_NR_PSS_SEQUENCE_LENGTH];
const int x_initial[7] = {0, 1, 1 , 0, 1, 1, 1}; const int x_initial[7] = {0, 1, 1, 0, 1, 1, 1};
int16_t *sl_pss = sl_init_params->sl_pss[n_sl_id2]; int16_t *sl_pss = sl_init_params->sl_pss[n_sl_id2];
int16_t *sl_pss_for_sync = sl_init_params->sl_pss_for_sync[n_sl_id2]; int16_t *sl_pss_for_sync = sl_init_params->sl_pss_for_sync[n_sl_id2];
...@@ -720,37 +719,32 @@ void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, u ...@@ -720,37 +719,32 @@ void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, u
#endif #endif
/// Sequence generation /// Sequence generation
for (i=0; i < 7; i++) for (i = 0; i < 7; i++)
x[i] = x_initial[i]; x[i] = x_initial[i];
for (i=0; i < (SL_NR_PSS_SEQUENCE_LENGTH - 7); i++) { for (i = 0; i < (SL_NR_PSS_SEQUENCE_LENGTH - 7); i++) {
x[i+7] = (x[i + 4] + x[i]) %2; x[i + 7] = (x[i + 4] + x[i]) % 2;
} }
for (i=0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { for (i = 0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) {
m = (i + 22 + 43*n_sl_id2) % SL_NR_PSS_SEQUENCE_LENGTH; m = (i + 22 + 43 * n_sl_id2) % SL_NR_PSS_SEQUENCE_LENGTH;
sl_pss_for_sync[i] = (1 - 2*x[m]); sl_pss_for_sync[i] = (1 - 2 * x[m]);
sl_pss[i] = sl_pss_for_sync[i] * scaling; sl_pss[i] = sl_pss_for_sync[i] * scaling;
#ifdef SL_DEBUG_INIT_DATA #ifdef SL_DEBUG_INIT_DATA
printf("m:%d, sl_pss[%d]:%d\n", m, i, sl_pss[i]); printf("m:%d, sl_pss[%d]:%d\n", m, i, sl_pss[i]);
#endif #endif
} }
#ifdef SL_DUMP_INIT_SAMPLES #ifdef SL_DUMP_INIT_SAMPLES
LOG_M("sl_pss_seq.m", "sl_pss", (void*)sl_pss, SL_NR_PSS_SEQUENCE_LENGTH, 1, 0); LOG_M("sl_pss_seq.m", "sl_pss", (void *)sl_pss, SL_NR_PSS_SEQUENCE_LENGTH, 1, 0);
#endif #endif
} }
// This cannot be done at init time as ofdm symbol size, ssb start subcarrier depends on configuration // This cannot be done at init time as ofdm symbol size, ssb start subcarrier depends on configuration
// done at SLSS read time. // done at SLSS read time.
void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params) void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params)
{ {
uint8_t id2 = 0; uint8_t id2 = 0;
int16_t *sl_pss = NULL; int16_t *sl_pss = NULL;
NR_DL_FRAME_PARMS *sl_fp = &sl_ue_params->sl_frame_params; NR_DL_FRAME_PARMS *sl_fp = &sl_ue_params->sl_frame_params;
...@@ -765,9 +759,9 @@ void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_ ...@@ -765,9 +759,9 @@ void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_
LOG_I(PHY, "SIDELINK INIT: Generation of PSS time domain samples. scaling_factor:%d\n", scaling_factor); LOG_I(PHY, "SIDELINK INIT: Generation of PSS time domain samples. scaling_factor:%d\n", scaling_factor);
for (id2 = 0; id2 < SL_NR_NUM_IDs_IN_PSS; id2++) { for (id2 = 0; id2 < SL_NR_NUM_IDs_IN_PSS; id2++) {
k = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier + 2; // PSS in from REs 2-129 k = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier + 2; // PSS in from REs 2-129
if (k >= sl_fp->ofdm_symbol_size) k -= sl_fp->ofdm_symbol_size; if (k >= sl_fp->ofdm_symbol_size)
k -= sl_fp->ofdm_symbol_size;
pss_T = &sl_init_params->sl_pss_for_correlation[id2][0]; pss_T = &sl_init_params->sl_pss_for_correlation[id2][0];
sl_pss = sl_init_params->sl_pss[id2]; sl_pss = sl_init_params->sl_pss[id2];
...@@ -775,32 +769,28 @@ void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_ ...@@ -775,32 +769,28 @@ void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_
memset(pss_T, 0, sl_fp->ofdm_symbol_size * sizeof(pss_T[0])); memset(pss_T, 0, sl_fp->ofdm_symbol_size * sizeof(pss_T[0]));
memset(pss_F, 0, sl_fp->ofdm_symbol_size * sizeof(c16_t)); memset(pss_F, 0, sl_fp->ofdm_symbol_size * sizeof(c16_t));
for (int i=0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { for (int i = 0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) {
pss_F[k].r = (sl_pss[i] * scaling_factor) >> 15; pss_F[k].r = (sl_pss[i] * scaling_factor) >> 15;
//pss_F[2*k] = (sl_pss[i]/23170) * 4192; // pss_F[2*k] = (sl_pss[i]/23170) * 4192;
//pss_F[2*k+1] = 0; // pss_F[2*k+1] = 0;
#ifdef SL_DEBUG_INIT_DATA #ifdef SL_DEBUG_INIT_DATA
printf("id:%d, k:%d, pss_F[%d]:%d, sl_pss[%d]:%d\n", id2, k, 2*k, pss_F[2*k], i, sl_pss[i]); printf("id:%d, k:%d, pss_F[%d]:%d, sl_pss[%d]:%d\n", id2, k, 2 * k, pss_F[2 * k], i, sl_pss[i]);
#endif #endif
k++; k++;
if (k == sl_fp->ofdm_symbol_size) k=0; if (k == sl_fp->ofdm_symbol_size)
k = 0;
} }
idft((int16_t)get_idft(sl_fp->ofdm_symbol_size), idft((int16_t)get_idft(sl_fp->ofdm_symbol_size),
(int16_t *)&pss_F[0], /* complex input */ (int16_t *)&pss_F[0], /* complex input */
(int16_t *)&pss_T[0], /* complex output */ (int16_t *)&pss_T[0], /* complex output */
1); /* scaling factor */ 1); /* scaling factor */
} }
#ifdef SL_DUMP_PSBCH_TX_SAMPLES #ifdef SL_DUMP_PSBCH_TX_SAMPLES
LOG_M("sl_pss_TD_id0.m", "pss_TD_0", (void*)sl_init_params->sl_pss_for_correlation[0], sl_fp->ofdm_symbol_size, 1, 1); LOG_M("sl_pss_TD_id0.m", "pss_TD_0", (void *)sl_init_params->sl_pss_for_correlation[0], sl_fp->ofdm_symbol_size, 1, 1);
LOG_M("sl_pss_TD_id1.m", "pss_TD_1", (void*)sl_init_params->sl_pss_for_correlation[1], sl_fp->ofdm_symbol_size, 1, 1); LOG_M("sl_pss_TD_id1.m", "pss_TD_1", (void *)sl_init_params->sl_pss_for_correlation[1], sl_fp->ofdm_symbol_size, 1, 1);
#endif #endif
} }
...@@ -533,7 +533,6 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, ...@@ -533,7 +533,6 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling) void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling)
{ {
int i = 0; int i = 0;
int m0, m1; int m0, m1;
int n_sl_id1, n_sl_id2; int n_sl_id1, n_sl_id2;
...@@ -541,7 +540,7 @@ void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, u ...@@ -541,7 +540,7 @@ void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, u
int16_t *sl_sss_for_sync = sl_init_params->sl_sss_for_sync[slss_id]; int16_t *sl_sss_for_sync = sl_init_params->sl_sss_for_sync[slss_id];
int16_t x0[SL_NR_SSS_SEQUENCE_LENGTH], x1[SL_NR_SSS_SEQUENCE_LENGTH]; int16_t x0[SL_NR_SSS_SEQUENCE_LENGTH], x1[SL_NR_SSS_SEQUENCE_LENGTH];
const int x_initial[7] = { 1, 0, 0, 0, 0, 0, 0 }; const int x_initial[7] = {1, 0, 0, 0, 0, 0, 0};
n_sl_id1 = slss_id % 336; n_sl_id1 = slss_id % 336;
n_sl_id2 = slss_id / 336; n_sl_id2 = slss_id / 336;
...@@ -552,32 +551,30 @@ void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, u ...@@ -552,32 +551,30 @@ void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, u
printf("SIDELINK: SSS Generation with slss_id:%d, N_SL_id1:%d, N_SL_id2:%d\n", slss_id, n_sl_id1, n_sl_id2); printf("SIDELINK: SSS Generation with slss_id:%d, N_SL_id1:%d, N_SL_id2:%d\n", slss_id, n_sl_id1, n_sl_id2);
#endif #endif
for ( i=0 ; i < 7 ; i++) { for (i = 0; i < 7; i++) {
x0[i] = x_initial[i]; x0[i] = x_initial[i];
x1[i] = x_initial[i]; x1[i] = x_initial[i];
} }
for ( i=0 ; i < SL_NR_SSS_SEQUENCE_LENGTH - 7 ; i++) { for (i = 0; i < SL_NR_SSS_SEQUENCE_LENGTH - 7; i++) {
x0[i+7] = (x0[i + 4] + x0[i]) % 2; x0[i + 7] = (x0[i + 4] + x0[i]) % 2;
x1[i+7] = (x1[i + 1] + x1[i]) % 2; x1[i + 7] = (x1[i + 1] + x1[i]) % 2;
} }
m0 = 15*(n_sl_id1/112) + (5*n_sl_id2); m0 = 15 * (n_sl_id1 / 112) + (5 * n_sl_id2);
m1 = n_sl_id1 % 112; m1 = n_sl_id1 % 112;
for (i = 0; i < SL_NR_SSS_SEQUENCE_LENGTH ; i++) { for (i = 0; i < SL_NR_SSS_SEQUENCE_LENGTH; i++) {
sl_sss_for_sync[i] = (1 - 2*x0[(i + m0) % SL_NR_SSS_SEQUENCE_LENGTH] ) * (1 - 2*x1[(i + m1) % SL_NR_SSS_SEQUENCE_LENGTH] ); sl_sss_for_sync[i] = (1 - 2 * x0[(i + m0) % SL_NR_SSS_SEQUENCE_LENGTH]) * (1 - 2 * x1[(i + m1) % SL_NR_SSS_SEQUENCE_LENGTH]);
sl_sss[i] = sl_sss_for_sync[i] * scaling; sl_sss[i] = sl_sss_for_sync[i] * scaling;
#ifdef SL_DEBUG_INIT_DATA #ifdef SL_DEBUG_INIT_DATA
printf("m0:%d, m1:%d, sl_sss_for_sync[%d]:%d, sl_sss[%d]:%d\n", m0, m1, i, sl_sss_for_sync[i], i, sl_sss[i]); printf("m0:%d, m1:%d, sl_sss_for_sync[%d]:%d, sl_sss[%d]:%d\n", m0, m1, i, sl_sss_for_sync[i], i, sl_sss[i]);
#endif #endif
} }
#ifdef SL_DUMP_PSBCH_TX_SAMPLES #ifdef SL_DUMP_PSBCH_TX_SAMPLES
LOG_M("sl_sss_seq.m", "sl_sss", (void*)sl_sss, SL_NR_SSS_SEQUENCE_LENGTH, 1, 0); LOG_M("sl_sss_seq.m", "sl_sss", (void *)sl_sss, SL_NR_SSS_SEQUENCE_LENGTH, 1, 0);
LOG_M("sl_sss_forsync_seq.m", "sl_sss_for_sync", (void*)sl_sss_for_sync, SL_NR_SSS_SEQUENCE_LENGTH, 1, 0); LOG_M("sl_sss_forsync_seq.m", "sl_sss_for_sync", (void *)sl_sss_for_sync, SL_NR_SSS_SEQUENCE_LENGTH, 1, 0);
#endif #endif
} }
...@@ -242,11 +242,9 @@ extern "C" { ...@@ -242,11 +242,9 @@ extern "C" {
}; };
} }
__attribute__((always_inline)) inline c16_t c16xmulConstShift(const c16_t a, const int b, const int Shift) { __attribute__((always_inline)) inline c16_t c16xmulConstShift(const c16_t a, const int b, const int Shift)
return (c16_t) { {
.r = (int16_t)((a.r * b) >> Shift), return (c16_t){.r = (int16_t)((a.r * b) >> Shift), .i = (int16_t)((a.i * b) >> Shift)};
.i = (int16_t)((a.i * b) >> Shift)
};
} }
__attribute__((always_inline)) inline c32_t c32x16maddShift(const c16_t a, const c16_t b, const c32_t c, const int Shift) { __attribute__((always_inline)) inline c32_t c32x16maddShift(const c16_t a, const c16_t b, const c32_t c, const int Shift) {
......
...@@ -593,7 +593,7 @@ typedef struct PHY_VARS_NR_UE_s { ...@@ -593,7 +593,7 @@ typedef struct PHY_VARS_NR_UE_s {
notifiedFIFO_t tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME]; notifiedFIFO_t tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME];
//Sidelink parameters // Sidelink parameters
sl_nr_sidelink_mode_t sl_mode; sl_nr_sidelink_mode_t sl_mode;
sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS;
} PHY_VARS_NR_UE; } PHY_VARS_NR_UE;
...@@ -618,7 +618,7 @@ typedef struct nr_phy_data_tx_s { ...@@ -618,7 +618,7 @@ typedef struct nr_phy_data_tx_s {
NR_UE_ULSCH_t ulsch; NR_UE_ULSCH_t ulsch;
NR_UE_PUCCH pucch_vars; NR_UE_PUCCH pucch_vars;
//Sidelink Rx action decided by MAC // Sidelink Rx action decided by MAC
sl_nr_tx_config_type_enum_t sl_tx_action; sl_nr_tx_config_type_enum_t sl_tx_action;
sl_nr_tx_config_psbch_pdu_t psbch_vars; sl_nr_tx_config_psbch_pdu_t psbch_vars;
...@@ -628,7 +628,7 @@ typedef struct nr_phy_data_s { ...@@ -628,7 +628,7 @@ typedef struct nr_phy_data_s {
NR_UE_PDCCH_CONFIG phy_pdcch_config; NR_UE_PDCCH_CONFIG phy_pdcch_config;
NR_UE_DLSCH_t dlsch[2]; NR_UE_DLSCH_t dlsch[2];
//Sidelink Rx action decided by MAC // Sidelink Rx action decided by MAC
sl_nr_rx_config_type_enum_t sl_rx_action; sl_nr_rx_config_type_enum_t sl_rx_action;
} nr_phy_data_t; } nr_phy_data_t;
......
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
#define MAX_DELAY_COMP 20 #define MAX_DELAY_COMP 20
#define PBCH_MAX_RE_PER_SYMBOL (20*12) #define PBCH_MAX_RE_PER_SYMBOL (20 * 12)
typedef enum { typedef enum {
NR_MU_0=0, NR_MU_0=0,
......
...@@ -30,27 +30,24 @@ ...@@ -30,27 +30,24 @@
\warning \warning
*/ */
#ifndef _DEFS_NR_SL_UE_H_ #ifndef _DEFS_NR_SL_UE_H_
#define _DEFS_NR_SL_UE_H_ #define _DEFS_NR_SL_UE_H_
#include "PHY/types.h" #include "PHY/types.h"
#include "PHY/defs_nr_common.h" #include "PHY/defs_nr_common.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h" #include "nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h"
#include "common/utils/time_meas.h" #include "common/utils/time_meas.h"
// (33*(13-4)) // (33*(13-4))
// Normal CP - NUM_SSB_Symbols = 13. 4 symbols for PSS, SSS // Normal CP - NUM_SSB_Symbols = 13. 4 symbols for PSS, SSS
#define SL_NR_NUM_PSBCH_DMRS_RE 297 #define SL_NR_NUM_PSBCH_DMRS_RE 297
//ceil(2(QPSK)*SL_NR_NUM_PSBCH_DMRS_RE/32) // ceil(2(QPSK)*SL_NR_NUM_PSBCH_DMRS_RE/32)
#define SL_NR_NUM_PSBCH_DMRS_RE_DWORD 20 #define SL_NR_NUM_PSBCH_DMRS_RE_DWORD 20
//11 RBs for PSBCH in one symbol * 12 REs // 11 RBs for PSBCH in one symbol * 12 REs
#define SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL 132 #define SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL 132
//3 DMRS REs per RB * 11 RBS in one symbol // 3 DMRS REs per RB * 11 RBS in one symbol
#define SL_NR_NUM_PSBCH_DMRS_RE_IN_ONE_SYMBOL 33 #define SL_NR_NUM_PSBCH_DMRS_RE_IN_ONE_SYMBOL 33
//9 PSBCH DATA REs * 11 RBS in one symbol // 9 PSBCH DATA REs * 11 RBS in one symbol
#define SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL 99 #define SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL 99
#define SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL 11 #define SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL 11
// SL_NR_POLAR_PSBCH_E_NORMAL_CP/2 bits because QPSK used for PSBCH. // SL_NR_POLAR_PSBCH_E_NORMAL_CP/2 bits because QPSK used for PSBCH.
...@@ -61,8 +58,6 @@ ...@@ -61,8 +58,6 @@
// 11 * (12-3 DMRS REs) * 9 symbols for PSBCH // 11 * (12-3 DMRS REs) * 9 symbols for PSBCH
#define SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS 891 #define SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS 891
#define SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP 13 #define SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP 13
#define SL_NR_NUM_SYMBOLS_SSB_EXT_CP 11 #define SL_NR_NUM_SYMBOLS_SSB_EXT_CP 11
#define SL_NR_NUM_PSS_SYMBOLS 2 #define SL_NR_NUM_PSS_SYMBOLS 2
...@@ -76,21 +71,16 @@ ...@@ -76,21 +71,16 @@
#define SL_NR_NUM_IDs_IN_SSS 336 #define SL_NR_NUM_IDs_IN_SSS 336
#define SL_NR_NUM_SLSS_IDs 672 #define SL_NR_NUM_SLSS_IDs 672
typedef enum sl_nr_sidelink_mode { typedef enum sl_nr_sidelink_mode { SL_NOT_SUPPORTED = 0, SL_MODE1_SUPPORTED, SL_MODE2_SUPPORTED } sl_nr_sidelink_mode_t;
SL_NOT_SUPPORTED = 0,
SL_MODE1_SUPPORTED,
SL_MODE2_SUPPORTED
} sl_nr_sidelink_mode_t;
//(11*(12-3 DMRS REs) * 2 (QPSK used) //(11*(12-3 DMRS REs) * 2 (QPSK used)
#define SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL 198 #define SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL 198
typedef struct SL_NR_UE_INIT_PARAMS { typedef struct SL_NR_UE_INIT_PARAMS {
// gold sequences for PSBCH DMRS
//gold sequences for PSBCH DMRS
uint32_t psbch_dmrs_gold_sequences[SL_NR_NUM_SLSS_IDs][SL_NR_NUM_PSBCH_DMRS_RE_DWORD]; // Gold sequences for PSBCH DMRS uint32_t psbch_dmrs_gold_sequences[SL_NR_NUM_SLSS_IDs][SL_NR_NUM_PSBCH_DMRS_RE_DWORD]; // Gold sequences for PSBCH DMRS
//PSBCH DMRS QPSK modulated symbols for all possible SLSS Ids // PSBCH DMRS QPSK modulated symbols for all possible SLSS Ids
struct complex16 psbch_dmrs_modsym[SL_NR_NUM_SLSS_IDs][SL_NR_NUM_PSBCH_DMRS_RE]; struct complex16 psbch_dmrs_modsym[SL_NR_NUM_SLSS_IDs][SL_NR_NUM_PSBCH_DMRS_RE];
// Scaled values // Scaled values
...@@ -106,7 +96,6 @@ typedef struct SL_NR_UE_INIT_PARAMS { ...@@ -106,7 +96,6 @@ typedef struct SL_NR_UE_INIT_PARAMS {
} SL_NR_UE_INIT_PARAMS_t; } SL_NR_UE_INIT_PARAMS_t;
typedef struct SL_NR_SYNC_PARAMS { typedef struct SL_NR_SYNC_PARAMS {
// Indicating start of SSB block in the initial set of samples // Indicating start of SSB block in the initial set of samples
uint32_t ssb_offset; uint32_t ssb_offset;
// Freq Offset calculated // Freq Offset calculated
...@@ -115,16 +104,15 @@ typedef struct SL_NR_SYNC_PARAMS { ...@@ -115,16 +104,15 @@ typedef struct SL_NR_SYNC_PARAMS {
uint32_t remaining_frames; uint32_t remaining_frames;
uint32_t rx_offset; uint32_t rx_offset;
uint32_t slot_offset; uint32_t slot_offset;
uint16_t N_sl_id2; //id2 determined from PSS during sync ref UE selection uint16_t N_sl_id2; // id2 determined from PSS during sync ref UE selection
uint16_t N_sl_id1; //id2 determined from SSS during sync ref UE selection uint16_t N_sl_id1; // id2 determined from SSS during sync ref UE selection
uint16_t N_sl_id; //ID calculated from ID1 and ID2 uint16_t N_sl_id; // ID calculated from ID1 and ID2
int32_t psbch_rsrp; //rsrp of the decoded psbch during sync ref ue selection int32_t psbch_rsrp; // rsrp of the decoded psbch during sync ref ue selection
uint32_t DFN; // DFN calculated after sync ref UE search uint32_t DFN; // DFN calculated after sync ref UE search
} SL_NR_SYNC_PARAMS_t; } SL_NR_SYNC_PARAMS_t;
typedef struct SL_NR_UE_PSBCH { typedef struct SL_NR_UE_PSBCH {
// AVG POWER OF PSBCH DMRS in dB/RE // AVG POWER OF PSBCH DMRS in dB/RE
int16_t rsrp_dB_per_RE; int16_t rsrp_dB_per_RE;
// AVG POWER OF PSBCH DMRS in dBm/RE // AVG POWER OF PSBCH DMRS in dBm/RE
...@@ -142,7 +130,6 @@ typedef struct SL_NR_UE_PSBCH { ...@@ -142,7 +130,6 @@ typedef struct SL_NR_UE_PSBCH {
} SL_NR_UE_PSBCH_t; } SL_NR_UE_PSBCH_t;
typedef struct sl_nr_ue_phy_params { typedef struct sl_nr_ue_phy_params {
SL_NR_UE_INIT_PARAMS_t init_params; SL_NR_UE_INIT_PARAMS_t init_params;
SL_NR_SYNC_PARAMS_t sync_params; SL_NR_SYNC_PARAMS_t sync_params;
...@@ -150,7 +137,7 @@ typedef struct sl_nr_ue_phy_params { ...@@ -150,7 +137,7 @@ typedef struct sl_nr_ue_phy_params {
// Sidelink PHY PARAMETERS USED FOR PSBCH reception/Txn // Sidelink PHY PARAMETERS USED FOR PSBCH reception/Txn
SL_NR_UE_PSBCH_t psbch; SL_NR_UE_PSBCH_t psbch;
//Configuration parameters from MAC // Configuration parameters from MAC
sl_nr_phy_config_request_t sl_config; sl_nr_phy_config_request_t sl_config;
NR_DL_FRAME_PARMS sl_frame_params; NR_DL_FRAME_PARMS sl_frame_params;
...@@ -162,5 +149,4 @@ typedef struct sl_nr_ue_phy_params { ...@@ -162,5 +149,4 @@ typedef struct sl_nr_ue_phy_params {
} sl_nr_ue_phy_params_t; } sl_nr_ue_phy_params_t;
#endif #endif
\ No newline at end of file
...@@ -165,13 +165,8 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, ...@@ -165,13 +165,8 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
int psbch_pscch_processing(PHY_VARS_NR_UE *ue, int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data);
UE_nr_rxtx_proc_t *proc,
nr_phy_data_t *phy_data);
int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
nr_phy_data_tx_t *phy_data);
/*! \brief This function prepares the sl indication to pass to the MAC /*! \brief This function prepares the sl indication to pass to the MAC
*/ */
void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind, void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind,
......
...@@ -865,12 +865,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ ...@@ -865,12 +865,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[fp->nb_antennas_rx][fp->ofdm_symbol_size]; __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[fp->nb_antennas_rx][fp->ofdm_symbol_size];
for (int i=1; i<4; i++) { for (int i=1; i<4; i++) {
nr_slot_fep(ue, nr_slot_fep(ue, fp, proc, (ssb_start_symbol + i) % (fp->symbols_per_slot), rxdataF, link_type_dl);
fp,
proc,
(ssb_start_symbol+i)%(fp->symbols_per_slot),
rxdataF,
link_type_dl);
start_meas(&ue->dlsch_channel_estimation_stats); start_meas(&ue->dlsch_channel_estimation_stats);
nr_pbch_channel_estimation(ue, nr_pbch_channel_estimation(ue,
...@@ -879,9 +874,9 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ ...@@ -879,9 +874,9 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
dl_ch_estimates, dl_ch_estimates,
dl_ch_estimates_time, dl_ch_estimates_time,
proc, proc,
(ssb_start_symbol+i)%(fp->symbols_per_slot), (ssb_start_symbol + i) % (fp->symbols_per_slot),
i-1, i - 1,
ssb_index&7, ssb_index & 7,
ssb_slot_2 == nr_slot_rx, ssb_slot_2 == nr_slot_rx,
rxdataF, rxdataF,
false, false,
...@@ -926,12 +921,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ ...@@ -926,12 +921,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
{ {
for(int j = prs_config->SymbolStart; j < (prs_config->SymbolStart+prs_config->NumPRSSymbols); j++) for(int j = prs_config->SymbolStart; j < (prs_config->SymbolStart+prs_config->NumPRSSymbols); j++)
{ {
nr_slot_fep(ue, nr_slot_fep(ue, fp, proc, (j % fp->symbols_per_slot), rxdataF, link_type_dl);
fp,
proc,
(j%fp->symbols_per_slot),
rxdataF,
link_type_dl);
} }
nr_prs_channel_estimation(gNB_id, rsc_id, i, ue, proc, fp, rxdataF); nr_prs_channel_estimation(gNB_id, rsc_id, i, ue, proc, fp, rxdataF);
} }
...@@ -962,12 +952,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ ...@@ -962,12 +952,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
for (uint16_t l=0; l<nb_symb_pdcch; l++) { for (uint16_t l=0; l<nb_symb_pdcch; l++) {
start_meas(&ue->ofdm_demod_stats); start_meas(&ue->ofdm_demod_stats);
nr_slot_fep(ue, nr_slot_fep(ue, fp, proc, l, rxdataF, link_type_dl);
fp,
proc,
l,
rxdataF,
link_type_dl);
} }
// Hold the channel estimates in frequency domain. // Hold the channel estimates in frequency domain.
...@@ -1027,7 +1012,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ ...@@ -1027,7 +1012,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
nr_slot_fep(ue, nr_slot_fep(ue,
&ue->frame_parms, &ue->frame_parms,
proc, proc,
m, //to be updated from higher layer m, // to be updated from higher layer
rxdataF, rxdataF,
link_type_dl); link_type_dl);
} }
......
...@@ -39,21 +39,21 @@ void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind, ...@@ -39,21 +39,21 @@ void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind,
PHY_VARS_NR_UE *ue, PHY_VARS_NR_UE *ue,
void *phy_data) void *phy_data)
{ {
memset((void*)sl_ind, 0, sizeof(nr_sidelink_indication_t)); memset((void *)sl_ind, 0, sizeof(nr_sidelink_indication_t));
sl_ind->gNB_index = proc->gNB_id; sl_ind->gNB_index = proc->gNB_id;
sl_ind->module_id = ue->Mod_id; sl_ind->module_id = ue->Mod_id;
sl_ind->cc_id = ue->CC_id; sl_ind->cc_id = ue->CC_id;
sl_ind->frame_rx = proc->frame_rx; sl_ind->frame_rx = proc->frame_rx;
sl_ind->slot_rx = proc->nr_slot_rx; sl_ind->slot_rx = proc->nr_slot_rx;
sl_ind->frame_tx = proc->frame_tx; sl_ind->frame_tx = proc->frame_tx;
sl_ind->slot_tx = proc->nr_slot_tx; sl_ind->slot_tx = proc->nr_slot_tx;
sl_ind->phy_data = phy_data; sl_ind->phy_data = phy_data;
if (rx_ind) { if (rx_ind) {
sl_ind->rx_ind = rx_ind; // hang on rx_ind instance sl_ind->rx_ind = rx_ind; // hang on rx_ind instance
sl_ind->sci_ind = NULL; sl_ind->sci_ind = NULL;
} }
if (sci_ind) { if (sci_ind) {
sl_ind->rx_ind = NULL; sl_ind->rx_ind = NULL;
sl_ind->sci_ind = sci_ind; sl_ind->sci_ind = sci_ind;
...@@ -68,39 +68,37 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind, ...@@ -68,39 +68,37 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind,
void *typeSpecific, void *typeSpecific,
uint16_t rx_slss_id) uint16_t rx_slss_id)
{ {
if (n_pdus > 1) {
if (n_pdus > 1){
LOG_E(PHY, "In %s: multiple number of SL PDUs not supported yet...\n", __FUNCTION__); LOG_E(PHY, "In %s: multiple number of SL PDUs not supported yet...\n", __FUNCTION__);
} }
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
switch (pdu_type){ switch (pdu_type) {
case SL_NR_RX_PDU_TYPE_SLSCH: case SL_NR_RX_PDU_TYPE_SLSCH:
break; break;
case FAPI_NR_RX_PDU_TYPE_SSB: { case FAPI_NR_RX_PDU_TYPE_SSB: {
sl_nr_ssb_pdu_t *ssb_pdu = &rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu; sl_nr_ssb_pdu_t *ssb_pdu = &rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu;
if(typeSpecific) { if (typeSpecific) {
uint8_t *psbch_decoded_output = (uint8_t *)typeSpecific; uint8_t *psbch_decoded_output = (uint8_t *)typeSpecific;
memcpy(ssb_pdu->psbch_payload, psbch_decoded_output, sizeof(4));//4 bytes of PSBCH payload bytes memcpy(ssb_pdu->psbch_payload, psbch_decoded_output, sizeof(4)); // 4 bytes of PSBCH payload bytes
ssb_pdu->rsrp_dbm = sl_phy_params->psbch.rsrp_dBm_per_RE; ssb_pdu->rsrp_dbm = sl_phy_params->psbch.rsrp_dBm_per_RE;
ssb_pdu->rx_slss_id = rx_slss_id; ssb_pdu->rx_slss_id = rx_slss_id;
ssb_pdu->decode_status = true; ssb_pdu->decode_status = true;
LOG_D(PHY, "SL-IND: SSB to MAC. rsrp:%d, slssid:%d, payload:%x\n", LOG_D(PHY,
ssb_pdu->rsrp_dbm,ssb_pdu->rx_slss_id, "SL-IND: SSB to MAC. rsrp:%d, slssid:%d, payload:%x\n",
*((uint32_t *)(ssb_pdu->psbch_payload)) ); ssb_pdu->rsrp_dbm,
} ssb_pdu->rx_slss_id,
else *((uint32_t *)(ssb_pdu->psbch_payload)));
ssb_pdu->decode_status = false; } else
} ssb_pdu->decode_status = false;
break; } break;
default: default:
break; break;
} }
rx_ind->rx_indication_body[n_pdus -1].pdu_type = pdu_type; rx_ind->rx_indication_body[n_pdus - 1].pdu_type = pdu_type;
rx_ind->number_pdus = n_pdus; rx_ind->number_pdus = n_pdus;
} }
static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue,
...@@ -111,7 +109,6 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, ...@@ -111,7 +109,6 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue,
nr_phy_data_t *phy_data, nr_phy_data_t *phy_data,
c16_t rxdataF[][fp->samples_per_slot_wCP]) c16_t rxdataF[][fp->samples_per_slot_wCP])
{ {
int ret = 0; int ret = 0;
DevAssert(ue); DevAssert(ue);
...@@ -121,21 +118,24 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, ...@@ -121,21 +118,24 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue,
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
uint16_t rx_slss_id = sl_phy_params->sl_config.sl_sync_source.rx_slss_id; uint16_t rx_slss_id = sl_phy_params->sl_config.sl_sync_source.rx_slss_id;
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_IN); // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_IN);
LOG_D(PHY,"[UE %d] Frame %d Slot %d, Trying PSBCH (SLSS ID %d)\n", LOG_D(PHY,
ue->Mod_id,frame_rx,nr_slot_rx, "[UE %d] Frame %d Slot %d, Trying PSBCH (SLSS ID %d)\n",
sl_phy_params->sl_config.sl_sync_source.rx_slss_id); ue->Mod_id,
frame_rx,
nr_slot_rx,
sl_phy_params->sl_config.sl_sync_source.rx_slss_id);
uint8_t decoded_pdu[4] = {0}; uint8_t decoded_pdu[4] = {0};
ret = nr_rx_psbch(ue, ret = nr_rx_psbch(ue,
proc, proc,
estimateSz, estimateSz,
dl_ch_estimates, dl_ch_estimates,
fp, fp,
decoded_pdu, decoded_pdu,
rxdataF, rxdataF,
sl_phy_params->sl_config.sl_sync_source.rx_slss_id); sl_phy_params->sl_config.sl_sync_source.rx_slss_id);
nr_sidelink_indication_t sl_indication; nr_sidelink_indication_t sl_indication;
sl_nr_rx_indication_t rx_ind = {0}; sl_nr_rx_indication_t rx_ind = {0};
...@@ -143,12 +143,12 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, ...@@ -143,12 +143,12 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue,
uint8_t *result = NULL; uint8_t *result = NULL;
if (ret) { if (ret) {
sl_phy_params->psbch.rx_errors ++; sl_phy_params->psbch.rx_errors++;
LOG_E(PHY,"%d:%d PSBCH RX: NOK \n",proc->frame_rx, proc->nr_slot_rx); LOG_E(PHY, "%d:%d PSBCH RX: NOK \n", proc->frame_rx, proc->nr_slot_rx);
} else { } else {
result = decoded_pdu; result = decoded_pdu;
sl_phy_params->psbch.rx_ok ++; sl_phy_params->psbch.rx_ok++;
LOG_D(PHY,"%d:%d PSBCH RX: OK \n",proc->frame_rx, proc->nr_slot_rx); LOG_D(PHY, "%d:%d PSBCH RX: OK \n", proc->frame_rx, proc->nr_slot_rx);
} }
nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, ue, phy_data); nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, ue, phy_data);
...@@ -157,114 +157,98 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, ...@@ -157,114 +157,98 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue,
if (ue->if_inst && ue->if_inst->sl_indication) if (ue->if_inst && ue->if_inst->sl_indication)
ue->if_inst->sl_indication(&sl_indication); ue->if_inst->sl_indication(&sl_indication);
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_OUT); // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_OUT);
return ret; return ret;
} }
int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
int psbch_pscch_processing(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
nr_phy_data_t *phy_data)
{ {
int frame_rx = proc->frame_rx; int frame_rx = proc->frame_rx;
int nr_slot_rx = proc->nr_slot_rx; int nr_slot_rx = proc->nr_slot_rx;
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params; NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params;
int sampleShift = 0; int sampleShift = 0;
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX_SL, VCD_FUNCTION_IN); // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX_SL, VCD_FUNCTION_IN);
start_meas(&sl_phy_params->phy_proc_sl_rx); start_meas(&sl_phy_params->phy_proc_sl_rx);
LOG_D(PHY," ****** Sidelink RX-Chain for Frame.Slot %d.%d ****** \n", LOG_D(PHY, " ****** Sidelink RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx % 1024, nr_slot_rx);
frame_rx%1024, nr_slot_rx);
const uint32_t rxdataF_sz = fp->samples_per_slot_wCP; const uint32_t rxdataF_sz = fp->samples_per_slot_wCP;
__attribute__ ((aligned(32))) c16_t rxdataF[fp->nb_antennas_rx][rxdataF_sz]; __attribute__((aligned(32))) c16_t rxdataF[fp->nb_antennas_rx][rxdataF_sz];
if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSBCH){
if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSBCH) {
const int estimateSz = fp->symbols_per_slot * fp->ofdm_symbol_size; const int estimateSz = fp->symbols_per_slot * fp->ofdm_symbol_size;
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_IN); // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_IN);
LOG_D(PHY," ----- PSBCH RX TTI: frame.slot %d.%d ------ \n", LOG_D(PHY, " ----- PSBCH RX TTI: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);
frame_rx%1024, nr_slot_rx);
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[fp->nb_antennas_rx][estimateSz]; __attribute__((aligned(32))) struct complex16 dl_ch_estimates[fp->nb_antennas_rx][estimateSz];
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[fp->nb_antennas_rx][fp->ofdm_symbol_size]; __attribute__((aligned(32))) struct complex16 dl_ch_estimates_time[fp->nb_antennas_rx][fp->ofdm_symbol_size];
// 0 for Normal Cyclic Prefix and 1 for EXT CyclicPrefix // 0 for Normal Cyclic Prefix and 1 for EXT CyclicPrefix
const int numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP const int numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
: SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
for (int sym=0; sym<numsym;) { for (int sym = 0; sym < numsym;) {
nr_slot_fep(ue, nr_slot_fep(ue, fp, proc, sym, rxdataF, link_type_ul);
fp,
proc,
sym,
rxdataF,
link_type_ul);
start_meas(&sl_phy_params->channel_estimation_stats); start_meas(&sl_phy_params->channel_estimation_stats);
nr_pbch_channel_estimation(ue, nr_pbch_channel_estimation(ue,
fp, fp,
estimateSz, estimateSz,
dl_ch_estimates, dl_ch_estimates,
dl_ch_estimates_time, dl_ch_estimates_time,
proc, proc,
sym, sym,
sym, sym,
0, 0,
0, 0,
rxdataF, rxdataF,
true, true,
sl_phy_params->sl_config.sl_sync_source.rx_slss_id); sl_phy_params->sl_config.sl_sync_source.rx_slss_id);
stop_meas(&sl_phy_params->channel_estimation_stats); stop_meas(&sl_phy_params->channel_estimation_stats);
//PSBCH present in symbols 0, 5-12 for normal cp // PSBCH present in symbols 0, 5-12 for normal cp
sym = (sym == 0) ? 5 : sym + 1; sym = (sym == 0) ? 5 : sym + 1;
} }
nr_sl_psbch_rsrp_measurements(sl_phy_params,fp, rxdataF,false); nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false);
LOG_D(PHY," ------ Decode SL-MIB: frame.slot %d.%d ------ \n", LOG_D(PHY, " ------ Decode SL-MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);
frame_rx%1024, nr_slot_rx);
const int psbchSuccess = nr_ue_psbch_procedures(ue, fp, proc, estimateSz, const int psbchSuccess = nr_ue_psbch_procedures(ue, fp, proc, estimateSz, dl_ch_estimates, phy_data, rxdataF);
dl_ch_estimates, phy_data, rxdataF);
if (ue->no_timing_correction==0 && psbchSuccess == 0) { if (ue->no_timing_correction == 0 && psbchSuccess == 0) {
LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); LOG_D(PHY, "start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction);
sampleShift = nr_adjust_synch_ue(fp, ue, proc->gNB_id, fp->ofdm_symbol_size, sampleShift =
dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); nr_adjust_synch_ue(fp, ue, proc->gNB_id, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384);
} }
LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__); LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__);
// nr_ue_rrc_measurements(ue, proc, rxdataF); // nr_ue_rrc_measurements(ue, proc, rxdataF);
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_OUT); // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_OUT);
if (frame_rx%64 == 0) { if (frame_rx % 64 == 0) {
LOG_I(NR_PHY,"============================================\n"); LOG_I(NR_PHY, "============================================\n");
LOG_I(NR_PHY,"[UE%d] %d:%d PSBCH Stats: TX %d, RX ok %d, RX not ok %d\n", LOG_I(NR_PHY,
ue->Mod_id, frame_rx, nr_slot_rx, "[UE%d] %d:%d PSBCH Stats: TX %d, RX ok %d, RX not ok %d\n",
sl_phy_params->psbch.num_psbch_tx, ue->Mod_id,
sl_phy_params->psbch.rx_ok, frame_rx,
sl_phy_params->psbch.rx_errors); nr_slot_rx,
sl_phy_params->psbch.num_psbch_tx,
LOG_I(NR_PHY,"============================================\n"); sl_phy_params->psbch.rx_ok,
sl_phy_params->psbch.rx_errors);
LOG_I(NR_PHY, "============================================\n");
} }
} }
return sampleShift; return sampleShift;
} }
int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data)
UE_nr_rxtx_proc_t *proc,
nr_phy_data_tx_t *phy_data)
{ {
int slot_tx = proc->nr_slot_tx; int slot_tx = proc->nr_slot_tx;
int frame_tx = proc->frame_tx; int frame_tx = proc->frame_tx;
int tx_action = 0; int tx_action = 0;
...@@ -272,52 +256,49 @@ int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, ...@@ -272,52 +256,49 @@ int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue,
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params; NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params;
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL,VCD_FUNCTION_IN); // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL,VCD_FUNCTION_IN);
const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * fp->ofdm_symbol_size; const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * fp->ofdm_symbol_size;
c16_t txdataF_buf[fp->nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32))); c16_t txdataF_buf[fp->nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32)));
memset(txdataF_buf, 0, sizeof(txdataF_buf)); memset(txdataF_buf, 0, sizeof(txdataF_buf));
c16_t *txdataF[fp->nb_antennas_tx]; /* workaround to be compatible with current txdataF usage in all tx procedures. */ c16_t *txdataF[fp->nb_antennas_tx]; /* workaround to be compatible with current txdataF usage in all tx procedures. */
for(int i=0; i< fp->nb_antennas_tx; ++i) for (int i = 0; i < fp->nb_antennas_tx; ++i)
txdataF[i] = &txdataF_buf[i * samplesF_per_slot]; txdataF[i] = &txdataF_buf[i * samplesF_per_slot];
LOG_D(PHY,"****** start Sidelink TX-Chain for AbsSubframe %d.%d ******\n", LOG_D(PHY, "****** start Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
frame_tx, slot_tx);
start_meas(&sl_phy_params->phy_proc_sl_tx); start_meas(&sl_phy_params->phy_proc_sl_tx);
if (phy_data->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSBCH) { if (phy_data->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSBCH) {
sl_nr_tx_config_psbch_pdu_t *psbch_vars = &phy_data->psbch_vars; sl_nr_tx_config_psbch_pdu_t *psbch_vars = &phy_data->psbch_vars;
nr_tx_psbch(ue, frame_tx, slot_tx, psbch_vars, txdataF); nr_tx_psbch(ue, frame_tx, slot_tx, psbch_vars, txdataF);
sl_phy_params->psbch.num_psbch_tx ++; sl_phy_params->psbch.num_psbch_tx++;
if (frame_tx%64 == 0) { if (frame_tx % 64 == 0) {
LOG_I(NR_PHY,"============================================\n"); LOG_I(NR_PHY, "============================================\n");
LOG_I(NR_PHY,"[UE%d] %d:%d PSBCH Stats: TX %d, RX ok %d, RX not ok %d\n", LOG_I(NR_PHY,
ue->Mod_id, frame_tx, slot_tx, "[UE%d] %d:%d PSBCH Stats: TX %d, RX ok %d, RX not ok %d\n",
sl_phy_params->psbch.num_psbch_tx, ue->Mod_id,
sl_phy_params->psbch.rx_ok, frame_tx,
sl_phy_params->psbch.rx_errors); slot_tx,
sl_phy_params->psbch.num_psbch_tx,
sl_phy_params->psbch.rx_ok,
sl_phy_params->psbch.rx_errors);
LOG_I(NR_PHY,"============================================\n"); LOG_I(NR_PHY, "============================================\n");
} }
tx_action = 1; tx_action = 1;
} }
if (tx_action) { if (tx_action) {
LOG_D(PHY, "Sending Uplink data \n"); LOG_D(PHY, "Sending Uplink data \n");
nr_ue_pusch_common_procedures(ue, nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, fp, fp->nb_antennas_tx, txdataF);
proc->nr_slot_tx,
fp,
fp->nb_antennas_tx,
txdataF);
} }
LOG_D(PHY,"****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", LOG_D(PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
frame_tx, slot_tx);
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL, VCD_FUNCTION_OUT); // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL, VCD_FUNCTION_OUT);
stop_meas(&sl_phy_params->phy_proc_sl_tx); stop_meas(&sl_phy_params->phy_proc_sl_tx);
return tx_action; return tx_action;
......
...@@ -786,38 +786,45 @@ int main(int argc, char **argv) ...@@ -786,38 +786,45 @@ int main(int argc, char **argv)
int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1)); int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1));
proc.nr_slot_rx = ssb_slot; proc.nr_slot_rx = ssb_slot;
proc.gNB_id = 0; proc.gNB_id = 0;
for (int i=UE->symbol_offset+1; i<UE->symbol_offset+4; i++) { for (int i = UE->symbol_offset + 1; i < UE->symbol_offset + 4; i++) {
nr_slot_fep(UE, nr_slot_fep(UE, frame_parms, &proc, i % frame_parms->symbols_per_slot, rxdataF, link_type_dl);
frame_parms,
&proc, nr_pbch_channel_estimation(UE,
i%frame_parms->symbols_per_slot, &UE->frame_parms,
rxdataF, link_type_dl); estimateSz,
dl_ch_estimates,
nr_pbch_channel_estimation(UE,&UE->frame_parms, estimateSz, dl_ch_estimates, dl_ch_estimates_time, &proc, dl_ch_estimates_time,
i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1), &proc,
ssb_index%8,n_hf,rxdataF,false,frame_parms->Nid_cell); i % frame_parms->symbols_per_slot,
i - (UE->symbol_offset + 1),
ssb_index % 8,
n_hf,
rxdataF,
false,
frame_parms->Nid_cell);
} }
fapiPbch_t result; fapiPbch_t result;
ret = nr_rx_pbch(UE, &proc, estimateSz, dl_ch_estimates, frame_parms, ssb_index % 8, &result, rxdataF); ret = nr_rx_pbch(UE, &proc, estimateSz, dl_ch_estimates, frame_parms, ssb_index % 8, &result, rxdataF);
if (ret==0) { if (ret == 0) {
//UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically // UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically
//UE->rx_ind.rx_indication_body->mib_pdu.ssb_length; //Lmax, not yet detected automatically // UE->rx_ind.rx_indication_body->mib_pdu.ssb_length; //Lmax, not yet detected automatically
uint8_t gNB_xtra_byte=0; uint8_t gNB_xtra_byte = 0;
for (int i=0; i<8; i++) for (int i = 0; i < 8; i++)
gNB_xtra_byte |= ((gNB->pbch.pbch_a>>(31-i))&1)<<(7-i); gNB_xtra_byte |= ((gNB->pbch.pbch_a >> (31 - i)) & 1) << (7 - i);
payload_ret = (result.xtra_byte == gNB_xtra_byte); payload_ret = (result.xtra_byte == gNB_xtra_byte);
for (i=0;i<3;i++){ for (i = 0; i < 3; i++) {
payload_ret += (result.decoded_output[i] == ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff)); payload_ret +=
} (result.decoded_output[i] == ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload >> (8 * i)) & 0xff));
//printf("ret %d\n", payload_ret); }
if (payload_ret!=4) // printf("ret %d\n", payload_ret);
if (payload_ret != 4)
n_errors_payload++; n_errors_payload++;
} }
if (ret!=0) n_errors++; if (ret != 0)
n_errors++;
} }
} //noise trials } //noise trials
printf("SNR %f: trials %d, n_errors_crc = %d, n_errors_payload %d\n", SNR,n_trials,n_errors,n_errors_payload); printf("SNR %f: trials %d, n_errors_crc = %d, n_errors_payload %d\n", SNR,n_trials,n_errors,n_errors_payload);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "common/config/config_userapi.h" #include "common/config/config_userapi.h"
#include "common/ran_context.h" #include "common/ran_context.h"
#include "PHY/types.h" #include "PHY/types.h"
#include "PHY/defs_nr_common.h" #include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h" #include "PHY/defs_nr_UE.h"
...@@ -26,26 +26,39 @@ ...@@ -26,26 +26,39 @@
#include "PHY/MODULATION/nr_modulation.h" #include "PHY/MODULATION/nr_modulation.h"
#include "NR_SL-SSB-TimeAllocation-r16.h" #include "NR_SL-SSB-TimeAllocation-r16.h"
void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); } {
void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) { abort(); } abort();
void exit_function(const char* file, const char* function, const int line, const char* s, const int assert) { }
const char * msg= s==NULL ? "no comment": s; void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req)
{
abort();
}
void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd)
{
abort();
}
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
{
const char *msg = s == NULL ? "no comment" : s;
printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
exit(-1); exit(-1);
} }
int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 1; } int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index)
{
return 1;
}
// to solve link errors // to solve link errors
double cpuf; double cpuf;
//void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} // void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu, void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu, uint8_t *nb_dmrs_re_per_rb, uint16_t *number_dmrs_symbols)
uint8_t *nb_dmrs_re_per_rb, {
uint16_t *number_dmrs_symbols){} }
uint64_t downlink_frequency[1][1]; uint64_t downlink_frequency[1][1];
int32_t uplink_frequency_offset[1][1]; int32_t uplink_frequency_offset[1][1];
THREAD_STRUCT thread_struct; THREAD_STRUCT thread_struct;
instance_t DUuniqInstance=0; instance_t DUuniqInstance = 0;
instance_t CUuniqInstance=0; instance_t CUuniqInstance = 0;
openair0_config_t openair0_cfg[1]; openair0_config_t openair0_cfg[1];
RAN_CONTEXT_t RC; RAN_CONTEXT_t RC;
...@@ -58,21 +71,27 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB ...@@ -58,21 +71,27 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB
} }
int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
const int CC_id, const int CC_id,
const uint8_t gNB_id, const uint8_t gNB_id,
const frame_t frameP, const frame_t frameP,
const rb_id_t Srb_id, const rb_id_t Srb_id,
uint8_t *buffer_pP) uint8_t *buffer_pP)
{ {
return 0; return 0;
} }
nr_bler_struct nr_bler_data[NR_NUM_MCS]; nr_bler_struct nr_bler_data[NR_NUM_MCS];
void get_nrUE_params(void) { return;} void get_nrUE_params(void)
uint8_t check_if_ue_is_sl_syncsource() {return 0;} {
return;
}
uint8_t check_if_ue_is_sl_syncsource()
{
return 0;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
static void prepare_mib_bits(uint8_t *buf, uint32_t frame_tx, uint32_t slot_tx) { static void prepare_mib_bits(uint8_t *buf, uint32_t frame_tx, uint32_t slot_tx)
{
NR_MasterInformationBlockSidelink_t *sl_mib; NR_MasterInformationBlockSidelink_t *sl_mib;
asn_enc_rval_t enc_rval; asn_enc_rval_t enc_rval;
...@@ -80,67 +99,64 @@ static void prepare_mib_bits(uint8_t *buf, uint32_t frame_tx, uint32_t slot_tx) ...@@ -80,67 +99,64 @@ static void prepare_mib_bits(uint8_t *buf, uint32_t frame_tx, uint32_t slot_tx)
sl_mib = CALLOC(1, sizeof(NR_MasterInformationBlockSidelink_t)); sl_mib = CALLOC(1, sizeof(NR_MasterInformationBlockSidelink_t));
sl_mib->inCoverage_r16 = 0;//TRUE; sl_mib->inCoverage_r16 = 0; // TRUE;
// allocate buffer for 7 bits slotnumber // allocate buffer for 7 bits slotnumber
sl_mib->slotIndex_r16.size = 1; sl_mib->slotIndex_r16.size = 1;
sl_mib->slotIndex_r16.buf = CALLOC(1, sl_mib->slotIndex_r16.size); sl_mib->slotIndex_r16.buf = CALLOC(1, sl_mib->slotIndex_r16.size);
sl_mib->slotIndex_r16.bits_unused = sl_mib->slotIndex_r16.size*8 - 7; sl_mib->slotIndex_r16.bits_unused = sl_mib->slotIndex_r16.size * 8 - 7;
sl_mib->slotIndex_r16.buf[0] = slot_tx << sl_mib->slotIndex_r16.bits_unused; sl_mib->slotIndex_r16.buf[0] = slot_tx << sl_mib->slotIndex_r16.bits_unused;
sl_mib->directFrameNumber_r16.size = 2; sl_mib->directFrameNumber_r16.size = 2;
sl_mib->directFrameNumber_r16.buf = CALLOC(1, sl_mib->directFrameNumber_r16.size); sl_mib->directFrameNumber_r16.buf = CALLOC(1, sl_mib->directFrameNumber_r16.size);
sl_mib->directFrameNumber_r16.bits_unused = sl_mib->directFrameNumber_r16.size*8 - 10; sl_mib->directFrameNumber_r16.bits_unused = sl_mib->directFrameNumber_r16.size * 8 - 10;
sl_mib->directFrameNumber_r16.buf[0] = frame_tx >> (8 - sl_mib->directFrameNumber_r16.bits_unused); sl_mib->directFrameNumber_r16.buf[0] = frame_tx >> (8 - sl_mib->directFrameNumber_r16.bits_unused);
sl_mib->directFrameNumber_r16.buf[1] = frame_tx << sl_mib->directFrameNumber_r16.bits_unused; sl_mib->directFrameNumber_r16.buf[1] = frame_tx << sl_mib->directFrameNumber_r16.bits_unused;
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_MasterInformationBlockSidelink, enc_rval = uper_encode_to_buffer(&asn_DEF_NR_MasterInformationBlockSidelink, NULL, (void *)sl_mib, buffer, 100);
NULL,
(void *)sl_mib,
buffer,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
enc_rval.failed_type->name, enc_rval.encoded);
asn_DEF_NR_MasterInformationBlockSidelink.op->free_struct(&asn_DEF_NR_MasterInformationBlockSidelink, sl_mib, ASFM_FREE_EVERYTHING);
asn_DEF_NR_MasterInformationBlockSidelink.op->free_struct(&asn_DEF_NR_MasterInformationBlockSidelink,
sl_mib,
ASFM_FREE_EVERYTHING);
} }
static int test_rx_mib(uint8_t *decoded_output, uint16_t frame, uint16_t slot) { static int test_rx_mib(uint8_t *decoded_output, uint16_t frame, uint16_t slot)
{
uint32_t sl_mib = *(uint32_t *)decoded_output; uint32_t sl_mib = *(uint32_t *)decoded_output;
uint32_t fn = 0, sl = 0; uint32_t fn = 0, sl = 0;
fn = (((sl_mib & 0x0700) >> 1) | ((sl_mib & 0xFE0000) >> 17)); fn = (((sl_mib & 0x0700) >> 1) | ((sl_mib & 0xFE0000) >> 17));
sl = (((sl_mib & 0x010000) >> 10) | ((sl_mib & 0xFC000000) >> 26)); sl = (((sl_mib & 0x010000) >> 10) | ((sl_mib & 0xFC000000) >> 26));
printf("decoded output:%x, TX %d:%d, timing decoded from sl-MIB %d:%d\n", printf("decoded output:%x, TX %d:%d, timing decoded from sl-MIB %d:%d\n", *(uint32_t *)decoded_output, frame, slot, fn, sl);
*(uint32_t *)decoded_output, frame, slot, fn, sl);
if (frame == fn && slot == sl) if (frame == fn && slot == sl)
return 0; return 0;
return -1; return -1;
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
static void configure_NR_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB) { static void configure_NR_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB)
{
fapi_nr_config_request_t config; fapi_nr_config_request_t config;
NR_DL_FRAME_PARMS *fp = &UE->frame_parms; NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
config.ssb_config.scs_common = mu; config.ssb_config.scs_common = mu;
config.cell_config.frame_duplex_type = TDD; config.cell_config.frame_duplex_type = TDD;
config.carrier_config.dl_grid_size[mu] = N_RB; config.carrier_config.dl_grid_size[mu] = N_RB;
config.carrier_config.ul_grid_size[mu] = N_RB; config.carrier_config.ul_grid_size[mu] = N_RB;
config.carrier_config.dl_frequency = 0; config.carrier_config.dl_frequency = 0;
config.carrier_config.uplink_frequency = 0; config.carrier_config.uplink_frequency = 0;
int band; int band;
if (mu == 1) band = 78; if (mu == 1)
if (mu == 0) band = 34; band = 78;
if (mu == 0)
band = 34;
nr_init_frame_parms_ue(fp, &config, band); nr_init_frame_parms_ue(fp, &config, band);
fp->ofdm_offset_divisor = 8; fp->ofdm_offset_divisor = 8;
nr_dump_frame_parms(fp); nr_dump_frame_parms(fp);
...@@ -151,8 +167,8 @@ static void configure_NR_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB) { ...@@ -151,8 +167,8 @@ static void configure_NR_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB) {
} }
} }
static void sl_init_frame_parameters(PHY_VARS_NR_UE *UE) { static void sl_init_frame_parameters(PHY_VARS_NR_UE *UE)
{
NR_DL_FRAME_PARMS *nr_fp = &UE->frame_parms; NR_DL_FRAME_PARMS *nr_fp = &UE->frame_parms;
NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
...@@ -171,11 +187,10 @@ static void sl_init_frame_parameters(PHY_VARS_NR_UE *UE) { ...@@ -171,11 +187,10 @@ static void sl_init_frame_parameters(PHY_VARS_NR_UE *UE) {
LOG_I(PHY, "Dumping Sidelink Frame Parameters\n"); LOG_I(PHY, "Dumping Sidelink Frame Parameters\n");
nr_dump_frame_parms(sl_fp); nr_dump_frame_parms(sl_fp);
#endif #endif
} }
static void configure_SL_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB, int ssb_offset, int slss_id) { static void configure_SL_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB, int ssb_offset, int slss_id)
{
sl_nr_phy_config_request_t *config = &UE->SL_UE_PHY_PARAMS.sl_config; sl_nr_phy_config_request_t *config = &UE->SL_UE_PHY_PARAMS.sl_config;
NR_DL_FRAME_PARMS *fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; NR_DL_FRAME_PARMS *fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
...@@ -193,36 +208,36 @@ static void configure_SL_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB, int ssb_offset ...@@ -193,36 +208,36 @@ static void configure_SL_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB, int ssb_offset
nr_dump_frame_parms(fp); nr_dump_frame_parms(fp);
} }
static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx, static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx, int frame, int slot, nr_phy_data_tx_t *phy_data)
int frame, int slot, {
nr_phy_data_tx_t *phy_data) {
sl_nr_ue_phy_params_t *sl_ue1 = &UE_tx->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_ue1 = &UE_tx->SL_UE_PHY_PARAMS;
sl_nr_ue_phy_params_t *sl_ue2 = &UE_rx->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_ue2 = &UE_rx->SL_UE_PHY_PARAMS;
printf("\nPSBCH SIM -F: %d:%d slss id TX UE:%d, RX UE:%d\n", printf("\nPSBCH SIM -F: %d:%d slss id TX UE:%d, RX UE:%d\n",
frame, slot,phy_data->psbch_vars.tx_slss_id, frame,
sl_ue2->sl_config.sl_sync_source.rx_slss_id); slot,
phy_data->psbch_vars.tx_slss_id,
sl_ue2->sl_config.sl_sync_source.rx_slss_id);
NR_DL_FRAME_PARMS *fp = &sl_ue1->sl_frame_params; NR_DL_FRAME_PARMS *fp = &sl_ue1->sl_frame_params;
const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * fp->ofdm_symbol_size; const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * fp->ofdm_symbol_size;
c16_t txdataF_buf[fp->nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32))); c16_t txdataF_buf[fp->nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32)));
memset(txdataF_buf, 0, sizeof(txdataF_buf)); memset(txdataF_buf, 0, sizeof(txdataF_buf));
c16_t *txdataF[fp->nb_antennas_tx]; /* workaround to be compatible with current txdataF usage in all tx procedures. */ c16_t *txdataF[fp->nb_antennas_tx]; /* workaround to be compatible with current txdataF usage in all tx procedures. */
for(int i=0; i< fp->nb_antennas_tx; ++i) for (int i = 0; i < fp->nb_antennas_tx; ++i)
txdataF[i] = &txdataF_buf[i * samplesF_per_slot]; txdataF[i] = &txdataF_buf[i * samplesF_per_slot];
nr_tx_psbch(UE_tx,frame, slot, &phy_data->psbch_vars, txdataF); nr_tx_psbch(UE_tx, frame, slot, &phy_data->psbch_vars, txdataF);
int estimateSz = sl_ue2->sl_frame_params.samples_per_slot_wCP; int estimateSz = sl_ue2->sl_frame_params.samples_per_slot_wCP;
__attribute__ ((aligned(32))) struct complex16 rxdataF[1][estimateSz]; __attribute__((aligned(32))) struct complex16 rxdataF[1][estimateSz];
for (int i=0; i<sl_ue1->sl_frame_params.samples_per_slot_wCP; i++) { for (int i = 0; i < sl_ue1->sl_frame_params.samples_per_slot_wCP; i++) {
struct complex16 *txdataF_ptr = (struct complex16 *)&txdataF[0][i]; struct complex16 *txdataF_ptr = (struct complex16 *)&txdataF[0][i];
struct complex16 *rxdataF_ptr = (struct complex16 *)&rxdataF[0][i]; struct complex16 *rxdataF_ptr = (struct complex16 *)&rxdataF[0][i];
rxdataF_ptr->r = txdataF_ptr->r; rxdataF_ptr->r = txdataF_ptr->r;
rxdataF_ptr->i = txdataF_ptr->i; rxdataF_ptr->i = txdataF_ptr->i;
//printf("r,i TXDATAF[%d]- %d:%d, RXDATAF[%d]- %d:%d\n", // printf("r,i TXDATAF[%d]- %d:%d, RXDATAF[%d]- %d:%d\n",
// i, txdataF_ptr->r, txdataF_ptr->i, i, txdataF_ptr->r, txdataF_ptr->i); // i, txdataF_ptr->r, txdataF_ptr->i, i, txdataF_ptr->r, txdataF_ptr->i);
} }
uint8_t err_status = 0; uint8_t err_status = 0;
...@@ -234,10 +249,10 @@ static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx, ...@@ -234,10 +249,10 @@ static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx,
struct complex16 dl_ch_estimates[1][estimateSz]; struct complex16 dl_ch_estimates[1][estimateSz];
uint8_t decoded_output[4] = {0}; uint8_t decoded_output[4] = {0};
LOG_I(PHY,"DEBUG: HIJACKING DL CHANNEL ESTIMATES.\n"); LOG_I(PHY, "DEBUG: HIJACKING DL CHANNEL ESTIMATES.\n");
for (int s=0; s<14; s++) { for (int s = 0; s < 14; s++) {
for (int j=0; j<sl_ue2->sl_frame_params.ofdm_symbol_size; j++) { for (int j = 0; j < sl_ue2->sl_frame_params.ofdm_symbol_size; j++) {
struct complex16 *dlch = (struct complex16 *)(&dl_ch_estimates[0][s*sl_ue2->sl_frame_params.ofdm_symbol_size]); struct complex16 *dlch = (struct complex16 *)(&dl_ch_estimates[0][s * sl_ue2->sl_frame_params.ofdm_symbol_size]);
dlch[j].r = 128; dlch[j].r = 128;
dlch[j].i = 0; dlch[j].i = 0;
} }
...@@ -249,45 +264,43 @@ static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx, ...@@ -249,45 +264,43 @@ static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx,
dl_ch_estimates, dl_ch_estimates,
&sl_ue2->sl_frame_params, &sl_ue2->sl_frame_params,
decoded_output, decoded_output,
rxdataF, rxdataF,
sl_ue2->sl_config.sl_sync_source.rx_slss_id); sl_ue2->sl_config.sl_sync_source.rx_slss_id);
int error_payload = 0; int error_payload = 0;
error_payload = test_rx_mib(decoded_output, frame, slot); error_payload = test_rx_mib(decoded_output, frame, slot);
if (err_status == 0 || error_payload == 0) { if (err_status == 0 || error_payload == 0) {
LOG_I(PHY,"---------PSBCH -F TEST OK.\n"); LOG_I(PHY, "---------PSBCH -F TEST OK.\n");
return 0; return 0;
} }
LOG_E(PHY, "--------PSBCH -F TEST NOK. FAIL.\n"); LOG_E(PHY, "--------PSBCH -F TEST NOK. FAIL.\n");
return -1; return -1;
} }
PHY_VARS_NR_UE *UE_TX; // for tx PHY_VARS_NR_UE *UE_TX; // for tx
PHY_VARS_NR_UE *UE_RX; // for rx PHY_VARS_NR_UE *UE_RX; // for rx
double cpuf; double cpuf;
configmodule_interface_t *uniqCfg = NULL; configmodule_interface_t *uniqCfg = NULL;
int main(int argc, char **argv) { int main(int argc, char **argv)
{
char c; char c;
int test_freqdomain_loopback = 0,test_slss_search = 0; int test_freqdomain_loopback = 0, test_slss_search = 0;
int frame = 5, slot = 10, frame_tx = 0, slot_tx = 0; int frame = 5, slot = 10, frame_tx = 0, slot_tx = 0;
int loglvl = OAILOG_INFO; int loglvl = OAILOG_INFO;
uint16_t slss_id = 336, ssb_offset = 0; uint16_t slss_id = 336, ssb_offset = 0;
double snr1 = 2.0, snr0 = 2.0, SNR; double snr1 = 2.0, snr0 = 2.0, SNR;
double sigma2 = 0.0, sigma2_dB = 0.0; double sigma2 = 0.0, sigma2_dB = 0.0;
double cfo=0, ip =0.0; double cfo = 0, ip = 0.0;
SCM_t channel_model=AWGN;//Rayleigh1_anticorr; SCM_t channel_model = AWGN; // Rayleigh1_anticorr;
int N_RB_DL=106,mu=1; int N_RB_DL = 106, mu = 1;
uint16_t errors = 0, n_trials = 1; uint16_t errors = 0, n_trials = 1;
int frame_length_complex_samples; int frame_length_complex_samples;
//int frame_length_complex_samples_no_prefix; // int frame_length_complex_samples_no_prefix;
NR_DL_FRAME_PARMS *frame_parms; NR_DL_FRAME_PARMS *frame_parms;
int seed = 0; int seed = 0;
...@@ -301,48 +314,46 @@ int main(int argc, char **argv) { ...@@ -301,48 +314,46 @@ int main(int argc, char **argv) {
randominit(0); randominit(0);
while ((c = getopt(argc, argv, "c:hn:o:s:FIL:N:R:S:T:")) != -1) { while ((c = getopt(argc, argv, "c:hn:o:s:FIL:N:R:S:T:")) != -1) {
printf("SIDELINK PSBCH SIM: handling optarg %c\n", c);
printf("SIDELINK PSBCH SIM: handling optarg %c\n",c);
switch (c) { switch (c) {
case 'c': case 'c':
cfo = atof(optarg); cfo = atof(optarg);
printf("Setting CFO to %f Hz\n",cfo); printf("Setting CFO to %f Hz\n", cfo);
break; break;
case 'g': case 'g':
switch((char)*optarg) { switch ((char)*optarg) {
case 'A': case 'A':
channel_model=SCM_A; channel_model = SCM_A;
break; break;
case 'B': case 'B':
channel_model=SCM_B; channel_model = SCM_B;
break; break;
case 'C': case 'C':
channel_model=SCM_C; channel_model = SCM_C;
break; break;
case 'D': case 'D':
channel_model=SCM_D; channel_model = SCM_D;
break; break;
case 'E': case 'E':
channel_model=EPA; channel_model = EPA;
break; break;
case 'F': case 'F':
channel_model=EVA; channel_model = EVA;
break; break;
case 'G': case 'G':
channel_model=ETU; channel_model = ETU;
break; break;
default: default:
printf("Unsupported channel model! Exiting.\n"); printf("Unsupported channel model! Exiting.\n");
exit(-1); exit(-1);
} }
break; break;
...@@ -352,14 +363,14 @@ int main(int argc, char **argv) { ...@@ -352,14 +363,14 @@ int main(int argc, char **argv) {
case 'o': case 'o':
ssb_offset = atoi(optarg); ssb_offset = atoi(optarg);
printf("SIDELINK PSBCH SIM: ssb offset from pointA:%d\n",ssb_offset); printf("SIDELINK PSBCH SIM: ssb offset from pointA:%d\n", ssb_offset);
break; break;
case 's': case 's':
slss_id = atoi(optarg); slss_id = atoi(optarg);
printf("SIDELINK PSBCH SIM: slss_id from arg:%d\n",slss_id); printf("SIDELINK PSBCH SIM: slss_id from arg:%d\n", slss_id);
AssertFatal(slss_id >= 0 && slss_id <= 671,"SLSS ID not within Range 0-671\n"); AssertFatal(slss_id >= 0 && slss_id <= 671, "SLSS ID not within Range 0-671\n");
break; break;
case 'F': case 'F':
test_freqdomain_loopback = 1; test_freqdomain_loopback = 1;
...@@ -377,28 +388,28 @@ int main(int argc, char **argv) { ...@@ -377,28 +388,28 @@ int main(int argc, char **argv) {
case 'N': case 'N':
snr0 = atoi(optarg); snr0 = atoi(optarg);
snr1 = snr0; snr1 = snr0;
printf("Setting SNR0 to %f. Test uses this SNR as target SNR\n",snr0); printf("Setting SNR0 to %f. Test uses this SNR as target SNR\n", snr0);
break; break;
case 'R': case 'R':
N_RB_DL = atoi(optarg); N_RB_DL = atoi(optarg);
printf("SIDELINK PSBCH SIM: N_RB_DL:%d\n",N_RB_DL); printf("SIDELINK PSBCH SIM: N_RB_DL:%d\n", N_RB_DL);
break; break;
case 'S': case 'S':
snr1 = atof(optarg); snr1 = atof(optarg);
printf("Setting SNR1 to %f. Test will run until this SNR as target SNR\n",snr1); printf("Setting SNR1 to %f. Test will run until this SNR as target SNR\n", snr1);
AssertFatal(snr1 <= snr0, "Test runs SNR down, set snr1 to a lower value than %f\n", snr0); AssertFatal(snr1 <= snr0, "Test runs SNR down, set snr1 to a lower value than %f\n", snr0);
break; break;
case 'T': case 'T':
frame = atoi(optarg); frame = atoi(optarg);
slot = atoi(argv[optind]); slot = atoi(argv[optind]);
printf("PSBCH SIM: frame timing- %d:%d\n",frame, slot); printf("PSBCH SIM: frame timing- %d:%d\n", frame, slot);
break; break;
case 'h': case 'h':
default : default:
printf("\n\nSIDELINK PSBCH SIM OPTIONS LIST - hus:FL:T:\n"); printf("\n\nSIDELINK PSBCH SIM OPTIONS LIST - hus:FL:T:\n");
printf("-h: HELP\n"); printf("-h: HELP\n");
printf("-c Carrier frequency offset in Hz\n"); printf("-c Carrier frequency offset in Hz\n");
...@@ -413,7 +424,6 @@ int main(int argc, char **argv) { ...@@ -413,7 +424,6 @@ int main(int argc, char **argv) {
printf("-S Ending SNR, runs from SNR0 to SNR1\n"); printf("-S Ending SNR, runs from SNR0 to SNR1\n");
printf("-T: Frame,Slot to be sent in sl-MIB eg -T 4 2\n"); printf("-T: Frame,Slot to be sent in sl-MIB eg -T 4 2\n");
return 1; return 1;
} }
} }
...@@ -422,7 +432,7 @@ int main(int argc, char **argv) { ...@@ -422,7 +432,7 @@ int main(int argc, char **argv) {
logInit(); logInit();
set_glog(loglvl); set_glog(loglvl);
double fs=0, eps; double fs = 0, eps;
double scs = 30000; double scs = 30000;
double bw = 100e6; double bw = 100e6;
...@@ -432,63 +442,48 @@ int main(int argc, char **argv) { ...@@ -432,63 +442,48 @@ int main(int argc, char **argv) {
if (N_RB_DL == 217) { if (N_RB_DL == 217) {
fs = 122.88e6; fs = 122.88e6;
bw = 80e6; bw = 80e6;
} } else if (N_RB_DL == 245) {
else if (N_RB_DL == 245) {
fs = 122.88e6; fs = 122.88e6;
bw = 90e6; bw = 90e6;
} } else if (N_RB_DL == 273) {
else if (N_RB_DL == 273) {
fs = 122.88e6; fs = 122.88e6;
bw = 100e6; bw = 100e6;
} } else if (N_RB_DL == 106) {
else if (N_RB_DL == 106) {
fs = 61.44e6; fs = 61.44e6;
bw = 40e6; bw = 40e6;
} } else
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); AssertFatal(1 == 0, "Unsupported numerology for mu %d, N_RB %d\n", mu, N_RB_DL);
break; break;
case 3: case 3:
scs = 120000; scs = 120000;
if (N_RB_DL == 66) { if (N_RB_DL == 66) {
fs = 122.88e6; fs = 122.88e6;
bw = 100e6; bw = 100e6;
} } else
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); AssertFatal(1 == 0, "Unsupported numerology for mu %d, N_RB %d\n", mu, N_RB_DL);
break; break;
} }
// cfo with respect to sub-carrier spacing // cfo with respect to sub-carrier spacing
eps = cfo/scs; eps = cfo / scs;
// computation of integer and fractional FO to compare with estimation results // computation of integer and fractional FO to compare with estimation results
int IFO; int IFO;
if(eps!=0.0){ if (eps != 0.0) {
printf("Introducing a CFO of %lf relative to SCS of %d kHz\n",eps,(int)(scs/1000)); printf("Introducing a CFO of %lf relative to SCS of %d kHz\n", eps, (int)(scs / 1000));
if (eps>0) if (eps > 0)
IFO=(int)(eps+0.5); IFO = (int)(eps + 0.5);
else else
IFO=(int)(eps-0.5); IFO = (int)(eps - 0.5);
printf("FFO = %lf; IFO = %d\n",eps-IFO,IFO); printf("FFO = %lf; IFO = %d\n", eps - IFO, IFO);
} }
channel_desc_t *UE2UE; channel_desc_t *UE2UE;
int n_tx = 1, n_rx = 1; int n_tx = 1, n_rx = 1;
UE2UE = new_channel_desc_scm(n_tx, UE2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, 0, bw, 300e-9, 0.0, CORR_LEVEL_LOW, 0, 0, 0, 0);
n_rx,
channel_model, if (UE2UE == NULL) {
fs, printf("Problem generating channel model. Exiting.\n");
0,
bw,
300e-9,
0.0,
CORR_LEVEL_LOW,
0,
0,
0,
0);
if (UE2UE==NULL) {
printf("Problem generating channel model. Exiting.\n");
exit(-1); exit(-1);
} }
...@@ -497,12 +492,12 @@ int main(int argc, char **argv) { ...@@ -497,12 +492,12 @@ int main(int argc, char **argv) {
UE_RX = calloc(1, sizeof(PHY_VARS_NR_UE)); UE_RX = calloc(1, sizeof(PHY_VARS_NR_UE));
LOG_I(PHY, "Configure UE-TX and sidelink UE-TX.\n"); LOG_I(PHY, "Configure UE-TX and sidelink UE-TX.\n");
configure_NR_UE(UE_TX, mu, N_RB_DL); configure_NR_UE(UE_TX, mu, N_RB_DL);
configure_SL_UE(UE_TX, mu, N_RB_DL,ssb_offset, 0xFFFF); configure_SL_UE(UE_TX, mu, N_RB_DL, ssb_offset, 0xFFFF);
LOG_I(PHY, "Configure UE-RX and sidelink UE-RX.\n"); LOG_I(PHY, "Configure UE-RX and sidelink UE-RX.\n");
configure_NR_UE(UE_RX, mu, N_RB_DL); configure_NR_UE(UE_RX, mu, N_RB_DL);
UE_RX->is_synchronized = (test_slss_search) ? 0 : 1; UE_RX->is_synchronized = (test_slss_search) ? 0 : 1;
configure_SL_UE(UE_RX, mu, N_RB_DL,ssb_offset, slss_id); configure_SL_UE(UE_RX, mu, N_RB_DL, ssb_offset, slss_id);
/*****************************************/ /*****************************************/
sl_nr_ue_phy_params_t *sl_uetx = &UE_TX->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_uetx = &UE_TX->SL_UE_PHY_PARAMS;
sl_nr_ue_phy_params_t *sl_uerx = &UE_RX->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_uerx = &UE_RX->SL_UE_PHY_PARAMS;
...@@ -510,21 +505,21 @@ int main(int argc, char **argv) { ...@@ -510,21 +505,21 @@ int main(int argc, char **argv) {
frame_tx = frame % 1024; frame_tx = frame % 1024;
slot_tx = slot % frame_parms->slots_per_frame; slot_tx = slot % frame_parms->slots_per_frame;
frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; frame_length_complex_samples = frame_parms->samples_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
//frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; // frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP;
double **s_re,**s_im,**r_re,**r_im; double **s_re, **s_im, **r_re, **r_im;
s_re = malloc(2*sizeof(double*)); s_re = malloc(2 * sizeof(double *));
s_im = malloc(2*sizeof(double*)); s_im = malloc(2 * sizeof(double *));
r_re = malloc(2*sizeof(double*)); r_re = malloc(2 * sizeof(double *));
r_im = malloc(2*sizeof(double*)); r_im = malloc(2 * sizeof(double *));
s_re[0] = malloc16_clear(frame_length_complex_samples*sizeof(double)); s_re[0] = malloc16_clear(frame_length_complex_samples * sizeof(double));
s_im[0] = malloc16_clear(frame_length_complex_samples*sizeof(double)); s_im[0] = malloc16_clear(frame_length_complex_samples * sizeof(double));
r_re[0] = malloc16_clear(frame_length_complex_samples*sizeof(double)); r_re[0] = malloc16_clear(frame_length_complex_samples * sizeof(double));
r_im[0] = malloc16_clear(frame_length_complex_samples*sizeof(double)); r_im[0] = malloc16_clear(frame_length_complex_samples * sizeof(double));
if(eps!=0.0) if (eps != 0.0)
UE_RX->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation UE_RX->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation
UE_nr_rxtx_proc_t proc; UE_nr_rxtx_proc_t proc;
...@@ -534,8 +529,8 @@ int main(int argc, char **argv) { ...@@ -534,8 +529,8 @@ int main(int argc, char **argv) {
phy_data_tx.psbch_vars.tx_slss_id = slss_id; phy_data_tx.psbch_vars.tx_slss_id = slss_id;
uint8_t sl_mib[4] = {0}; uint8_t sl_mib[4] = {0};
prepare_mib_bits(sl_mib,frame, slot); prepare_mib_bits(sl_mib, frame, slot);
memcpy(phy_data_tx.psbch_vars.psbch_payload,sl_mib, 4); memcpy(phy_data_tx.psbch_vars.psbch_payload, sl_mib, 4);
phy_data_tx.sl_tx_action = SL_NR_CONFIG_TYPE_TX_PSBCH; phy_data_tx.sl_tx_action = SL_NR_CONFIG_TYPE_TX_PSBCH;
proc.frame_rx = frame; proc.frame_rx = frame;
...@@ -547,81 +542,85 @@ int main(int argc, char **argv) { ...@@ -547,81 +542,85 @@ int main(int argc, char **argv) {
errors += freq_domain_loopback(UE_TX, UE_RX, frame_tx, slot_tx, &phy_data_tx); errors += freq_domain_loopback(UE_TX, UE_RX, frame_tx, slot_tx, &phy_data_tx);
} }
printf("\nSidelink TX UE - Frame.Slot %d.%d SLSS id:%d\n", printf("\nSidelink TX UE - Frame.Slot %d.%d SLSS id:%d\n", frame, slot, phy_data_tx.psbch_vars.tx_slss_id);
frame, slot,phy_data_tx.psbch_vars.tx_slss_id);
printf("Sidelink RX UE - Frame.Slot %d.%d SLSS id:%d\n", printf("Sidelink RX UE - Frame.Slot %d.%d SLSS id:%d\n",
proc.frame_rx, proc.nr_slot_rx, proc.frame_rx,
sl_uerx->sl_config.sl_sync_source.rx_slss_id); proc.nr_slot_rx,
sl_uerx->sl_config.sl_sync_source.rx_slss_id);
phy_procedures_nrUE_SL_TX(UE_TX, &proc, &phy_data_tx); phy_procedures_nrUE_SL_TX(UE_TX, &proc, &phy_data_tx);
for (SNR=snr0; SNR>=snr1; SNR-=1) { for (SNR = snr0; SNR >= snr1; SNR -= 1) {
for (int trial = 0; trial < n_trials; trial++) {
for (int trial=0; trial<n_trials; trial++) { for (int i = 0; i < frame_length_complex_samples; i++) {
for (int aa = 0; aa < frame_parms->nb_antennas_tx; aa++) {
for (int i=0; i<frame_length_complex_samples; i++) {
for (int aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
struct complex16 *txdata_ptr = (struct complex16 *)&UE_TX->common_vars.txData[aa][i]; struct complex16 *txdata_ptr = (struct complex16 *)&UE_TX->common_vars.txData[aa][i];
r_re[aa][i] = (double)txdata_ptr->r; r_re[aa][i] = (double)txdata_ptr->r;
r_im[aa][i] = (double)txdata_ptr->i; r_im[aa][i] = (double)txdata_ptr->i;
} }
} }
LOG_M("txData0.m","txd0", UE_TX->common_vars.txData[0],frame_parms->samples_per_frame,1,1); LOG_M("txData0.m", "txd0", UE_TX->common_vars.txData[0], frame_parms->samples_per_frame, 1, 1);
//AWGN // AWGN
sigma2_dB = 20*log10((double)AMP/4)-SNR; sigma2_dB = 20 * log10((double)AMP / 4) - SNR;
sigma2 = pow(10,sigma2_dB/10); sigma2 = pow(10, sigma2_dB / 10);
//printf("sigma2 %f (%f dB), tx_lev %f (%f dB)\n",sigma2,sigma2_dB,txlev,10*log10((double)txlev)); // printf("sigma2 %f (%f dB), tx_lev %f (%f dB)\n",sigma2,sigma2_dB,txlev,10*log10((double)txlev));
if(eps!=0.0) { if (eps != 0.0) {
rf_rx(r_re, // real part of txdata rf_rx(r_re, // real part of txdata
r_im, // imag part of txdata r_im, // imag part of txdata
NULL, // interference real part NULL, // interference real part
NULL, // interference imag part NULL, // interference imag part
0, // interference power 0, // interference power
frame_parms->nb_antennas_rx, // number of rx antennas frame_parms->nb_antennas_rx, // number of rx antennas
frame_length_complex_samples, // number of samples in frame frame_length_complex_samples, // number of samples in frame
1.0e9/fs, //sampling time (ns) 1.0e9 / fs, // sampling time (ns)
cfo, // frequency offset in Hz cfo, // frequency offset in Hz
0.0, // drift (not implemented) 0.0, // drift (not implemented)
0.0, // noise figure (not implemented) 0.0, // noise figure (not implemented)
0.0, // rx gain in dB ? 0.0, // rx gain in dB ?
200, // 3rd order non-linearity in dB ? 200, // 3rd order non-linearity in dB ?
&ip, // initial phase &ip, // initial phase
30.0e3, // phase noise cutoff in kHz 30.0e3, // phase noise cutoff in kHz
-500.0, // phase noise amplitude in dBc -500.0, // phase noise amplitude in dBc
0.0, // IQ imbalance (dB), 0.0, // IQ imbalance (dB),
0.0); // IQ phase imbalance (rad) 0.0); // IQ phase imbalance (rad)
} }
for (int i=0; i<frame_length_complex_samples; i++) { for (int i = 0; i < frame_length_complex_samples; i++) {
for (int aa=0; aa<frame_parms->nb_antennas_rx; aa++) { for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
UE_RX->common_vars.rxdata[aa][i].r = (short)(r_re[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0)); UE_RX->common_vars.rxdata[aa][i].r = (short)(r_re[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0));
UE_RX->common_vars.rxdata[aa][i].i = (short)(r_im[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0)); UE_RX->common_vars.rxdata[aa][i].i = (short)(r_im[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0));
}
} }
}
if (UE_RX->is_synchronized == 0) { if (UE_RX->is_synchronized == 0) {
nr_initial_sync_t ret = {false, 0}; nr_initial_sync_t ret = {false, 0};
UE_nr_rxtx_proc_t proc={0}; UE_nr_rxtx_proc_t proc = {0};
//Should not have SLSS id configured. Search should find SLSS id from TX UE // Should not have SLSS id configured. Search should find SLSS id from TX UE
UE_RX->SL_UE_PHY_PARAMS.sl_config.sl_sync_source.rx_slss_id = 0xFFFF; UE_RX->SL_UE_PHY_PARAMS.sl_config.sl_sync_source.rx_slss_id = 0xFFFF;
ret = sl_nr_slss_search(UE_RX, &proc, 1); ret = sl_nr_slss_search(UE_RX, &proc, 1);
printf("Sidelink SLSS search returns status:%d, rx_offset:%d\n",ret.cell_detected, ret.rx_offset); printf("Sidelink SLSS search returns status:%d, rx_offset:%d\n", ret.cell_detected, ret.rx_offset);
if (!ret.cell_detected) sl_uerx->psbch.rx_errors = 1; if (!ret.cell_detected)
sl_uerx->psbch.rx_errors = 1;
else { else {
AssertFatal(UE_RX->SL_UE_PHY_PARAMS.sync_params.N_sl_id == slss_id, AssertFatal(UE_RX->SL_UE_PHY_PARAMS.sync_params.N_sl_id == slss_id,
"DETECTED INCORRECT SLSS ID in SEARCH.CHECK id:%d\n", UE_RX->SL_UE_PHY_PARAMS.sync_params.N_sl_id); "DETECTED INCORRECT SLSS ID in SEARCH.CHECK id:%d\n",
UE_RX->SL_UE_PHY_PARAMS.sync_params.N_sl_id);
sl_uerx->psbch.rx_ok = 1; sl_uerx->psbch.rx_ok = 1;
} }
} else psbch_pscch_processing(UE_RX,&proc,&phy_data_rx); } else
psbch_pscch_processing(UE_RX, &proc, &phy_data_rx);
} //noise trials } // noise trials
printf("Runs:%d SNR %f: SLSS Search:%d crc ERRORs = %d, OK = %d\n", printf("Runs:%d SNR %f: SLSS Search:%d crc ERRORs = %d, OK = %d\n",
n_trials, SNR, !UE_RX->is_synchronized, n_trials,
sl_uerx->psbch.rx_errors, sl_uerx->psbch.rx_ok); SNR,
!UE_RX->is_synchronized,
sl_uerx->psbch.rx_errors,
sl_uerx->psbch.rx_ok);
errors += sl_uerx->psbch.rx_errors; errors += sl_uerx->psbch.rx_errors;
sl_uerx->psbch.rx_errors = 0; sl_uerx->psbch.rx_errors = 0;
sl_uerx->psbch.rx_ok = 0; sl_uerx->psbch.rx_ok = 0;
...@@ -629,9 +628,9 @@ int main(int argc, char **argv) { ...@@ -629,9 +628,9 @@ int main(int argc, char **argv) {
} // NSR } // NSR
if (errors == 0) if (errors == 0)
LOG_I(PHY,"PSBCH test OK\n"); LOG_I(PHY, "PSBCH test OK\n");
else else
LOG_E(PHY,"PSBCH test NOT OK\n"); LOG_E(PHY, "PSBCH test NOT OK\n");
free_channel_desc_scm(UE2UE); free_channel_desc_scm(UE2UE);
...@@ -654,5 +653,3 @@ int main(int argc, char **argv) { ...@@ -654,5 +653,3 @@ int main(int argc, char **argv) {
return errors; return errors;
} }
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