Commit 47df7e51 authored by Florian Kaltenberger's avatar Florian Kaltenberger

Merge branch 'nr_pbchsim' of https://gitlab.eurecom.fr/oai/openairinterface5g into nr_pbchsim

parents f841174f 6f38c94d
...@@ -1296,7 +1296,7 @@ set(PHY_SRC_UE ...@@ -1296,7 +1296,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c ${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c #${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c ${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c ${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c ${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c
...@@ -1334,7 +1334,7 @@ set(PHY_SRC_UE ...@@ -1334,7 +1334,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c ${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c # ${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c ${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c ${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c ${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c
......
...@@ -1069,9 +1069,17 @@ int8_t polar_decoder_int16(int16_t *input, ...@@ -1069,9 +1069,17 @@ int8_t polar_decoder_int16(int16_t *input,
nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K); nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
//Remove the CRC (â) //Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j]; //for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j];
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out); // Check the CRC
for (int j=0;j<polarParams->crcParityBits;j++) {
int crcbit=0;
for (int i=0;i<polarParams->payloadBits;i++)
crcbit = crcbit ^ (polarParams->crc_generator_matrix[i][j] & polarParams->nr_polar_B[i]);
if (crcbit != polarParams->nr_polar_B[polarParams->payloadBits+j]) return(-1);
}
// pack into ceil(payloadBits/32) 32 bit words, lowest index in MSB
// nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
nr_byte2bit_uint8_32_t(polarParams->nr_polar_B, polarParams->payloadBits, out);
return(0); return(0);
} }
...@@ -443,7 +443,7 @@ void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) { ...@@ -443,7 +443,7 @@ void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) {
} }
else else
#endif #endif
{// equvalent scalar code to above, activated only on non x86/ARM architectures {// equvalent scalar code to above, activated only on non x86/ARM architectures or Nv=1,2
for (int i=0;i<node->Nv/2;i++) { for (int i=0;i<node->Nv/2;i++) {
alpha_r[i] = alpha_v[i+(node->Nv/2)] - (betal[i]*alpha_v[i]); alpha_r[i] = alpha_v[i+(node->Nv/2)] - (betal[i]*alpha_v[i]);
} }
......
...@@ -361,11 +361,13 @@ static inline void nr_polar_interleaver(uint8_t *input, ...@@ -361,11 +361,13 @@ static inline void nr_polar_interleaver(uint8_t *input,
} }
static inline void nr_polar_deinterleaver(uint8_t *input, static inline void nr_polar_deinterleaver(uint8_t *input,
uint8_t *output, uint8_t *output,
uint16_t *pattern, uint16_t *pattern,
uint16_t size) uint16_t size)
{ {
for (int i=0; i<size; i++) output[pattern[i]]=input[i]; for (int i=0; i<size; i++) {
output[pattern[i]]=input[i];
}
} }
#endif #endif
...@@ -54,7 +54,7 @@ void polar_encoder(uint32_t *in, ...@@ -54,7 +54,7 @@ void polar_encoder(uint32_t *in,
polarParams->nr_polar_crc, polarParams->nr_polar_crc,
polarParams->payloadBits, polarParams->payloadBits,
polarParams->crcParityBits); polarParams->crcParityBits);
for (uint8_t i = 0; i < polarParams->crcParityBits; i++) for (uint8_t i = 0; i < polarParams->crcParityBits; i++)
polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2); polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
//Attach CRC to the Transport Block. (a to b) //Attach CRC to the Transport Block. (a to b)
......
...@@ -185,9 +185,9 @@ void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams) ...@@ -185,9 +185,9 @@ void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams)
} }
t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams, t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams,
int8_t messageType, int8_t messageType,
uint16_t messageLength, uint16_t messageLength,
uint8_t aggregation_level) uint8_t aggregation_level)
{ {
t_nrPolar_paramsPtr currentPtr = NULL; t_nrPolar_paramsPtr currentPtr = NULL;
......
...@@ -100,6 +100,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, ...@@ -100,6 +100,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
gNB->check_for_MUMIMO_transmissions=0; gNB->check_for_MUMIMO_transmissions=0;
while(gNB->configured == 0) usleep(10000); while(gNB->configured == 0) usleep(10000);
init_dfts();
/* /*
LOG_I(PHY,"[gNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d nb_antennas_tx:%u nb_antennas_rx:%u PRACH[rootSequenceIndex:%u prach_Config_enabled:%u configIndex:%u highSpeed:%u zeroCorrelationZoneConfig:%u freqOffset:%u]\n", LOG_I(PHY,"[gNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d nb_antennas_tx:%u nb_antennas_rx:%u PRACH[rootSequenceIndex:%u prach_Config_enabled:%u configIndex:%u highSpeed:%u zeroCorrelationZoneConfig:%u freqOffset:%u]\n",
gNB->Mod_id, gNB->Mod_id,
...@@ -367,7 +369,7 @@ void install_schedule_handlers(IF_Module_t *if_inst) ...@@ -367,7 +369,7 @@ void install_schedule_handlers(IF_Module_t *if_inst)
/// this function is a temporary addition for NR configuration /// this function is a temporary addition for NR configuration
void nr_phy_config_request_sim(PHY_VARS_gNB *gNB) void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu)
{ {
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config; nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config;
...@@ -375,14 +377,14 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB) ...@@ -375,14 +377,14 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB)
//overwrite for new NR parameters //overwrite for new NR parameters
gNB_config->nfapi_config.rf_bands.rf_band[0] = 22; gNB_config->nfapi_config.rf_bands.rf_band[0] = 22;
gNB_config->nfapi_config.earfcn.value = 6600; gNB_config->nfapi_config.earfcn.value = 6600;
gNB_config->subframe_config.numerology_index_mu.value = 1; gNB_config->subframe_config.numerology_index_mu.value = mu;
gNB_config->subframe_config.duplex_mode.value = FDD; gNB_config->subframe_config.duplex_mode.value = TDD;
gNB_config->rf_config.tx_antenna_ports.value = 1; gNB_config->rf_config.tx_antenna_ports.value = 1;
gNB_config->rf_config.dl_carrier_bandwidth.value = 106; gNB_config->rf_config.dl_carrier_bandwidth.value = N_RB_DL;
gNB_config->rf_config.ul_carrier_bandwidth.value = 106; gNB_config->rf_config.ul_carrier_bandwidth.value = N_RB_UL;
gNB_config->sch_config.half_frame_index.value = 0; gNB_config->sch_config.half_frame_index.value = 0;
gNB_config->sch_config.ssb_subcarrier_offset.value = 0; gNB_config->sch_config.ssb_subcarrier_offset.value = 0;
gNB_config->sch_config.n_ssb_crb.value = 86; gNB_config->sch_config.n_ssb_crb.value = (N_RB_DL-20)>>1;
gNB_config->sch_config.ssb_subcarrier_offset.value = 0; gNB_config->sch_config.ssb_subcarrier_offset.value = 0;
......
...@@ -655,15 +655,16 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, ...@@ -655,15 +655,16 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
int i,j,k,l; int i,j,k,l;
int eNB_id; int eNB_id;
int th_id; int th_id;
int n_ssb_crb=(fp->N_RB_DL-20)>>1;
abstraction_flag = 0; abstraction_flag = 0;
fp->nb_antennas_tx = 1; fp->nb_antennas_tx = 1;
fp->nb_antennas_rx=1; fp->nb_antennas_rx=1;
printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx); printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx);
//LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST); //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST);
nr_init_frame_parms_ue(&ue->frame_parms); nr_init_frame_parms_ue(&ue->frame_parms,NR_MU_1,NORMAL,n_ssb_crb,0);
phy_init_nr_top(ue); phy_init_nr_top(ue);
// many memory allocation sizes are hard coded // many memory allocation sizes are hard coded
...@@ -941,43 +942,25 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag) { ...@@ -941,43 +942,25 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag) {
void phy_init_nr_top(PHY_VARS_NR_UE *ue) void phy_init_nr_top(PHY_VARS_NR_UE *ue)
{ {
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_UE_DLSCH_t *dlsch0 = ue->dlsch[0][0][0]; NR_UE_DLSCH_t *dlsch0 = ue->dlsch[0][0][0];
dlsch0 =(NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t)); dlsch0 =(NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t));
crcTableInit(); crcTableInit();
init_dfts(); init_dfts();
ccodedot11_init();
ccodedot11_init_inv();
ccodelte_init();
ccodelte_init_inv();
//treillis_table_init();
phy_generate_viterbi_tables();
phy_generate_viterbi_tables_lte();
//init_td8();
//init_td16();
#ifdef __AVX2__
//init_td16avx2();
#endif
init_context_synchro_nr(frame_parms); init_context_synchro_nr(frame_parms);
generate_ul_reference_signal_sequences(SHRT_MAX); generate_ul_reference_signal_sequences(SHRT_MAX);
// Polar encoder init for PBCH // Polar encoder init for PBCH
//nr_polar_init(&frame_parms->pbch_polar_params, 1);
/*t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL;
nr_polar_init(&ue->nrPolar_params,
NR_POLAR_PBCH_MESSAGE_TYPE,
NR_POLAR_PBCH_PAYLOAD_BITS,
NR_POLAR_PBCH_AGGREGATION_LEVEL);*/
ue->nrPolar_params = NULL;
nr_polar_init(&ue->nrPolar_params,
NR_POLAR_PBCH_MESSAGE_TYPE,
NR_POLAR_PBCH_PAYLOAD_BITS,
NR_POLAR_PBCH_AGGREGATION_LEVEL);
//lte_sync_time_init(frame_parms); //lte_sync_time_init(frame_parms);
//generate_ul_ref_sigs(); //generate_ul_ref_sigs();
......
...@@ -26,18 +26,20 @@ ...@@ -26,18 +26,20 @@
uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3}; uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 16, 32}; uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 16, 32};
int nr_init_frame_parms(nfapi_nr_config_request_t* config,
NR_DL_FRAME_PARMS *frame_parms) int nr_init_frame_parms0(
NR_DL_FRAME_PARMS *fp,
int mu,
int Ncp)
{ {
int N_RB = config->rf_config.dl_carrier_bandwidth.value;
int Ncp = config->subframe_config.dl_cyclic_prefix_type.value;
int mu = config->subframe_config.numerology_index_mu.value;
#if DISABLE_LOG_X #if DISABLE_LOG_X
printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp); printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, fp->N_RB_DL, Ncp);
#else #else
LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp); LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, fp->N_RB_DL, Ncp);
#endif #endif
if (Ncp == NFAPI_CP_EXTENDED) if (Ncp == NFAPI_CP_EXTENDED)
...@@ -46,15 +48,15 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config, ...@@ -46,15 +48,15 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
switch(mu) { switch(mu) {
case NR_MU_0: //15kHz scs case NR_MU_0: //15kHz scs
frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0]; fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0];
frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_0]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_0];
break; break;
case NR_MU_1: //30kHz scs case NR_MU_1: //30kHz scs
frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1]; fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1];
frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_1]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_1];
switch(N_RB){ switch(fp->N_RB_DL){
case 11: case 11:
case 24: case 24:
case 38: case 38:
...@@ -63,17 +65,17 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config, ...@@ -63,17 +65,17 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
case 65: case 65:
case 106: //40 MHz case 106: //40 MHz
if (frame_parms->threequarter_fs) { if (fp->threequarter_fs) {
frame_parms->ofdm_symbol_size = 1536; fp->ofdm_symbol_size = 1536;
frame_parms->first_carrier_offset = 900; //1536 - 636 fp->first_carrier_offset = 900; //1536 - 636
frame_parms->nb_prefix_samples0 = 132; fp->nb_prefix_samples0 = 132;
frame_parms->nb_prefix_samples = 108; fp->nb_prefix_samples = 108;
} }
else { else {
frame_parms->ofdm_symbol_size = 2048; fp->ofdm_symbol_size = 2048;
frame_parms->first_carrier_offset = 1412; //2048 - 636 fp->first_carrier_offset = 1412; //2048 - 636
frame_parms->nb_prefix_samples0 = 176; fp->nb_prefix_samples0 = 176;
frame_parms->nb_prefix_samples = 144; fp->nb_prefix_samples = 144;
} }
break; break;
...@@ -82,32 +84,44 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config, ...@@ -82,32 +84,44 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
case 189: case 189:
case 217: //80 MHz case 217: //80 MHz
if (frame_parms->threequarter_fs) { if (fp->threequarter_fs) {
frame_parms->ofdm_symbol_size = 3072; fp->ofdm_symbol_size = 3072;
frame_parms->first_carrier_offset = 1770; //3072 - 1302 fp->first_carrier_offset = 1770; //3072 - 1302
frame_parms->nb_prefix_samples0 = 264; fp->nb_prefix_samples0 = 264;
frame_parms->nb_prefix_samples = 216; fp->nb_prefix_samples = 216;
}
else {
frame_parms->ofdm_symbol_size = 4096;
frame_parms->first_carrier_offset = 2794; //4096 - 1302
frame_parms->nb_prefix_samples0 = 352;
frame_parms->nb_prefix_samples = 288;
} }
else {
fp->ofdm_symbol_size = 4096;
fp->first_carrier_offset = 2794; //4096 - 1302
fp->nb_prefix_samples0 = 352;
fp->nb_prefix_samples = 288;
}
break; break;
case 245: case 245:
AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",fp->N_RB_DL,mu);
fp->ofdm_symbol_size = 4096;
fp->first_carrier_offset = 2626; //4096 - 1478
fp->nb_prefix_samples0 = 352;
fp->nb_prefix_samples = 288;
break;
case 273: case 273:
AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",fp->N_RB_DL,mu);
fp->ofdm_symbol_size = 4096;
fp->first_carrier_offset = 2458; //4096 - 1638
fp->nb_prefix_samples0 = 352;
fp->nb_prefix_samples = 288;
break;
default: default:
AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB, mu, frame_parms); AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", fp->N_RB_DL, mu, fp);
} }
break; break;
case NR_MU_2: //60kHz scs case NR_MU_2: //60kHz scs
frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2]; fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2];
frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_2]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_2];
switch(N_RB){ //FR1 bands only switch(fp->N_RB_DL){ //FR1 bands only
case 11: case 11:
case 18: case 18:
case 38: case 38:
...@@ -121,196 +135,80 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config, ...@@ -121,196 +135,80 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
case 121: case 121:
case 135: case 135:
default: default:
AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB, mu, frame_parms); AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", fp->N_RB_DL, mu, fp);
} }
break; break;
case NR_MU_3: case NR_MU_3:
frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3]; fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_3]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
break; break;
case NR_MU_4: case NR_MU_4:
frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4]; fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4];
frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_4]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_4];
break; break;
default: default:
AssertFatal(1==0,"Invalid numerology index %d", mu); AssertFatal(1==0,"Invalid numerology index %d", mu);
} }
frame_parms->slots_per_frame = 10* frame_parms->slots_per_subframe; fp->slots_per_frame = 10* fp->slots_per_subframe;
frame_parms->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
frame_parms->samples_per_subframe_wCP = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot * frame_parms->slots_per_subframe; fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP; fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
frame_parms->samples_per_subframe = (frame_parms->samples_per_subframe_wCP + (frame_parms->nb_prefix_samples0 * frame_parms->slots_per_subframe) + fp->samples_per_subframe = (fp->samples_per_subframe_wCP + (fp->nb_prefix_samples0 * fp->slots_per_subframe) +
(frame_parms->nb_prefix_samples * frame_parms->slots_per_subframe * (frame_parms->symbols_per_slot - 1))); (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1)));
frame_parms->samples_per_frame = 10 * frame_parms->samples_per_subframe; fp->samples_per_frame = 10 * fp->samples_per_subframe;
frame_parms->freq_range = (frame_parms->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
// Initial bandwidth part configuration -- full carrier bandwidth // Initial bandwidth part configuration -- full carrier bandwidth
frame_parms->initial_bwp_dl.bwp_id = 0; fp->initial_bwp_dl.bwp_id = 0;
frame_parms->initial_bwp_dl.scs = frame_parms->subcarrier_spacing; fp->initial_bwp_dl.scs = fp->subcarrier_spacing;
frame_parms->initial_bwp_dl.location = 0; fp->initial_bwp_dl.location = 0;
frame_parms->initial_bwp_dl.N_RB = N_RB; fp->initial_bwp_dl.N_RB = fp->N_RB_DL;
frame_parms->initial_bwp_dl.cyclic_prefix = Ncp; fp->initial_bwp_dl.cyclic_prefix = Ncp;
frame_parms->initial_bwp_dl.ofdm_symbol_size = frame_parms->ofdm_symbol_size; fp->initial_bwp_dl.ofdm_symbol_size = fp->ofdm_symbol_size;
return 0; return 0;
} }
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms) int nr_init_frame_parms(nfapi_nr_config_request_t* config,
{ NR_DL_FRAME_PARMS *fp) {
int N_RB = 106;
int Ncp = 0;
int mu = 1;
#if DISABLE_LOG_X
printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp);
#else
LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp);
#endif
if (Ncp == EXTENDED)
AssertFatal(mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, mu);
switch(mu) {
case NR_MU_0: //15kHz scs
frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0];
frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_0];
break;
case NR_MU_1: //30kHz scs
frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1];
frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_1];
switch(N_RB){
case 11:
case 24:
case 38:
case 78:
case 51:
case 65:
case 106: //40 MHz
if (frame_parms->threequarter_fs) {
frame_parms->ofdm_symbol_size = 1536;
frame_parms->first_carrier_offset = 900; //1536 - 636
frame_parms->nb_prefix_samples0 = 132;
frame_parms->nb_prefix_samples = 108;
}
else {
frame_parms->ofdm_symbol_size = 2048;
frame_parms->first_carrier_offset = 1412; //2048 - 636
frame_parms->nb_prefix_samples0 = 176;
frame_parms->nb_prefix_samples = 144;
}
break;
case 133:
case 162:
case 189:
case 217: //80 MHz
if (frame_parms->threequarter_fs) {
frame_parms->ofdm_symbol_size = 3072;
frame_parms->first_carrier_offset = 1770; //3072 - 1302
frame_parms->nb_prefix_samples0 = 264;
frame_parms->nb_prefix_samples = 216;
}
else {
frame_parms->ofdm_symbol_size = 4096;
frame_parms->first_carrier_offset = 2794; //4096 - 1302
frame_parms->nb_prefix_samples0 = 352;
frame_parms->nb_prefix_samples = 288;
}
break;
case 245:
case 273:
default:
AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB, mu, frame_parms);
}
break;
case NR_MU_2: //60kHz scs
frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2];
frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_2];
switch(N_RB){ //FR1 bands only
case 11:
case 18:
case 38:
case 24:
case 31:
case 51:
case 65:
case 79:
case 93:
case 107:
case 121:
case 135:
default:
AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB, mu, frame_parms);
}
break;
case NR_MU_3:
frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
break;
case NR_MU_4:
frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4];
frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_4];
break;
default:
AssertFatal(1==0,"Invalid numerology index %d", mu);
}
frame_parms->nb_prefix_samples0 = 160;
frame_parms->nb_prefix_samples = 144;
frame_parms->symbols_per_tti = 14;
frame_parms->numerology_index = 0;
frame_parms->ttis_per_subframe = 1;
frame_parms->slots_per_tti = 2; //only slot config 1 is supported
frame_parms->ofdm_symbol_size = 2048; nr_init_frame_parms0(fp,
frame_parms->samples_per_tti = 30720; config->subframe_config.numerology_index_mu.value,
frame_parms->samples_per_subframe = 30720 * frame_parms->ttis_per_subframe; config->subframe_config.dl_cyclic_prefix_type.value);
//frame_parms->first_carrier_offset = 2048-600; }
frame_parms->slots_per_frame = 10* frame_parms->slots_per_subframe; int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
frame_parms->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats int mu,
frame_parms->samples_per_subframe_wCP = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot * frame_parms->slots_per_subframe; int Ncp,
frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP; int n_ssb_crb,
//frame_parms->samples_per_subframe = (frame_parms->samples_per_subframe_wCP + (frame_parms->nb_prefix_samples0 * frame_parms->slots_per_subframe) + int ssb_subcarrier_offset)
// (frame_parms->nb_prefix_samples * frame_parms->slots_per_subframe * (frame_parms->symbols_per_slot - 1))); {
frame_parms->samples_per_frame = 10 * frame_parms->samples_per_subframe;
frame_parms->freq_range = (frame_parms->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
nr_init_frame_parms0(fp,mu,Ncp);
int start_rb = n_ssb_crb / (1<<mu);
fp->ssb_start_subcarrier = 12 * start_rb + ssb_subcarrier_offset;
return 0; return 0;
} }
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms) void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
{ {
LOG_I(PHY,"frame_parms->scs=%d\n",frame_parms->subcarrier_spacing); LOG_I(PHY,"fp->scs=%d\n",fp->subcarrier_spacing);
LOG_I(PHY,"frame_parms->ofdm_symbol_size=%d\n",frame_parms->ofdm_symbol_size); LOG_I(PHY,"fp->ofdm_symbol_size=%d\n",fp->ofdm_symbol_size);
LOG_I(PHY,"frame_parms->nb_prefix_samples0=%d\n",frame_parms->nb_prefix_samples0); LOG_I(PHY,"fp->nb_prefix_samples0=%d\n",fp->nb_prefix_samples0);
LOG_I(PHY,"frame_parms->nb_prefix_samples=%d\n",frame_parms->nb_prefix_samples); LOG_I(PHY,"fp->nb_prefix_samples=%d\n",fp->nb_prefix_samples);
LOG_I(PHY,"frame_parms->slots_per_subframe=%d\n",frame_parms->slots_per_subframe); LOG_I(PHY,"fp->slots_per_subframe=%d\n",fp->slots_per_subframe);
LOG_I(PHY,"frame_parms->samples_per_subframe_wCP=%d\n",frame_parms->samples_per_subframe_wCP); LOG_I(PHY,"fp->samples_per_subframe_wCP=%d\n",fp->samples_per_subframe_wCP);
LOG_I(PHY,"frame_parms->samples_per_frame_wCP=%d\n",frame_parms->samples_per_frame_wCP); LOG_I(PHY,"fp->samples_per_frame_wCP=%d\n",fp->samples_per_frame_wCP);
LOG_I(PHY,"frame_parms->samples_per_subframe=%d\n",frame_parms->samples_per_subframe); LOG_I(PHY,"fp->samples_per_subframe=%d\n",fp->samples_per_subframe);
LOG_I(PHY,"frame_parms->samples_per_frame=%d\n",frame_parms->samples_per_frame); LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame);
LOG_I(PHY,"frame_parms->initial_bwp_dl.bwp_id=%d\n",frame_parms->initial_bwp_dl.bwp_id); LOG_I(PHY,"fp->initial_bwp_dl.bwp_id=%d\n",fp->initial_bwp_dl.bwp_id);
LOG_I(PHY,"frame_parms->initial_bwp_dl.scs=%d\n",frame_parms->initial_bwp_dl.scs); LOG_I(PHY,"fp->initial_bwp_dl.scs=%d\n",fp->initial_bwp_dl.scs);
LOG_I(PHY,"frame_parms->initial_bwp_dl.N_RB=%d\n",frame_parms->initial_bwp_dl.N_RB); LOG_I(PHY,"fp->initial_bwp_dl.N_RB=%d\n",fp->initial_bwp_dl.N_RB);
LOG_I(PHY,"frame_parms->initial_bwp_dl.cyclic_prefix=%d\n",frame_parms->initial_bwp_dl.cyclic_prefix); LOG_I(PHY,"fp->initial_bwp_dl.cyclic_prefix=%d\n",fp->initial_bwp_dl.cyclic_prefix);
LOG_I(PHY,"frame_parms->initial_bwp_dl.location=%d\n",frame_parms->initial_bwp_dl.location); LOG_I(PHY,"fp->initial_bwp_dl.location=%d\n",fp->initial_bwp_dl.location);
LOG_I(PHY,"frame_parms->initial_bwp_dl.ofdm_symbol_size=%d\n",frame_parms->initial_bwp_dl.ofdm_symbol_size); LOG_I(PHY,"fp->initial_bwp_dl.ofdm_symbol_size=%d\n",fp->initial_bwp_dl.ofdm_symbol_size);
} }
...@@ -377,11 +377,12 @@ void phy_config_request(PHY_Config_t *phy_config); ...@@ -377,11 +377,12 @@ void phy_config_request(PHY_Config_t *phy_config);
int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf); int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms); void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms(nfapi_nr_config_request_t* config, NR_DL_FRAME_PARMS *frame_parms); int nr_init_frame_parms(nfapi_nr_config_request_t* config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms); int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,int mu,int Ncp,int n_ssb_crb,int ssb_subcarrier_offset);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag); int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms); void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms);
int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char is_secondary_gNB, unsigned char abstraction_flag); int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char is_secondary_gNB, unsigned char abstraction_flag);
void nr_phy_config_request(NR_PHY_Config_t *gNB); void nr_phy_config_request(NR_PHY_Config_t *gNB);
void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu);
void phy_free_nr_gNB(PHY_VARS_gNB *gNB); void phy_free_nr_gNB(PHY_VARS_gNB *gNB);
int l1_north_init_gNB(void); int l1_north_init_gNB(void);
......
...@@ -285,6 +285,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) ...@@ -285,6 +285,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
init_frame_parms(frame_parms,1); init_frame_parms(frame_parms,1);
/* /*
LOG_M("rxdata0.m","rxd0",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1); LOG_M("rxdata0.m","rxd0",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
exit(-1); exit(-1);
*/ */
sync_pos = lte_sync_time(ue->common_vars.rxdata, sync_pos = lte_sync_time(ue->common_vars.rxdata,
......
...@@ -122,10 +122,10 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input ...@@ -122,10 +122,10 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
case 3072: case 3072:
idft = idft3072; idft = idft3072;
break;
case 4096: case 4096:
idft = idft4096; idft = idft4096;
break;
default: default:
idft = idft512; idft = idft512;
break; break;
......
...@@ -30,12 +30,12 @@ ...@@ -30,12 +30,12 @@
#define SOFFSET 0 #define SOFFSET 0
int nr_slot_fep(PHY_VARS_NR_UE *ue, int nr_slot_fep(PHY_VARS_NR_UE *ue,
unsigned char l, unsigned char l,
unsigned char Ns, unsigned char Ns,
int sample_offset, int sample_offset,
int no_prefix, int no_prefix,
int reset_freq_est, int reset_freq_est,
NR_CHANNEL_EST_t channel) NR_CHANNEL_EST_t channel)
{ {
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_UE_COMMON *common_vars = &ue->common_vars; NR_UE_COMMON *common_vars = &ue->common_vars;
...@@ -61,7 +61,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -61,7 +61,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
int uespec_pilot[9][1200];*/ int uespec_pilot[9][1200];*/
void (*dft)(int16_t *,int16_t *, int); void (*dft)(int16_t *,int16_t *, int);
int tmp_dft_in[2048] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
switch (frame_parms->ofdm_symbol_size) { switch (frame_parms->ofdm_symbol_size) {
case 128: case 128:
...@@ -88,6 +88,14 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -88,6 +88,14 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
dft = dft2048; dft = dft2048;
break; break;
case 4096:
dft = dft4096;
break;
case 8192:
dft = dft8192;
break;
default: default:
dft = dft512; dft = dft512;
break; break;
...@@ -143,7 +151,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -143,7 +151,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats); stop_meas(&ue->rx_dft_stats);
#endif #endif
} }
} else { } else {
rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// + rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// +
...@@ -191,20 +198,17 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -191,20 +198,17 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
switch(channel){ switch(channel){
case NR_PBCH_EST: case NR_PBCH_EST:
//if ((l>4) && (l<8)) {
for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
//#ifdef DEBUG_FEP #ifdef DEBUG_FEP
printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l); printf("Channel estimation eNB %d, slot %d, symbol %d\n",eNB_id,Ns,l);
//#endif #endif
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats); start_meas(&ue->dlsch_channel_estimation_stats);
#endif #endif
nr_pbch_channel_estimation(ue,eNB_id,0, nr_pbch_channel_estimation(ue,eNB_id,0,
Ns, Ns,
aa, l,
l, symbol);
symbol);
//} //}
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
stop_meas(&ue->dlsch_channel_estimation_stats); stop_meas(&ue->dlsch_channel_estimation_stats);
...@@ -232,53 +236,48 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -232,53 +236,48 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
#endif #endif
} }
}
break; break;
case NR_PDCCH_EST: case NR_PDCCH_EST:
for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
#ifdef DEBUG_FEP #ifdef DEBUG_FEP
printf("PDCCH Channel estimation eNB %d, aatx %d, slot %d, symbol %d start_sc %d\n",eNB_id,aa,Ns,l,coreset_start_subcarrier); printf("PDCCH Channel estimation eNB %d, aatx %d, slot %d, symbol %d start_sc %d\n",eNB_id,aa,Ns,l,coreset_start_subcarrier);
#endif #endif
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats); start_meas(&ue->dlsch_channel_estimation_stats);
#endif #endif
nr_pdcch_channel_estimation(ue,eNB_id,0, nr_pdcch_channel_estimation(ue,eNB_id,0,
Ns, Ns,
aa, l,
l, symbol,
symbol, coreset_start_subcarrier,
coreset_start_subcarrier, nb_rb_coreset);
nb_rb_coreset);
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
stop_meas(&ue->dlsch_channel_estimation_stats); stop_meas(&ue->dlsch_channel_estimation_stats);
#endif #endif
}
break; break;
case NR_PDSCH_EST: case NR_PDSCH_EST:
for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
#ifdef DEBUG_FEP #ifdef DEBUG_FEP
printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l); printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l);
#endif #endif
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats); start_meas(&ue->dlsch_channel_estimation_stats);
#endif #endif
nr_pdsch_channel_estimation(ue,eNB_id,0, nr_pdsch_channel_estimation(ue,eNB_id,0,
Ns, Ns,
aa, l,
l, symbol,
symbol, bwp_start_subcarrier,
bwp_start_subcarrier, nb_rb_pdsch);
nb_rb_pdsch);
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
stop_meas(&ue->dlsch_channel_estimation_stats); stop_meas(&ue->dlsch_channel_estimation_stats);
#endif #endif
}
break; break;
case NR_SSS_EST: case NR_SSS_EST:
break; break;
......
...@@ -106,13 +106,13 @@ short nr_rx_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,23170,-23170,-23170,23170, ...@@ -106,13 +106,13 @@ short nr_rx_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,23170,-23170,-23170,23170,
}*/ }*/
int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
uint8_t eNB_offset, uint8_t eNB_offset,
unsigned int Ns, unsigned int Ns,
unsigned int nr_gold_pdsch[2][20][2][21], unsigned int nr_gold_pdsch[2][20][2][21],
int32_t *output, int32_t *output,
unsigned short p, unsigned short p,
int length_dmrs, int length_dmrs,
unsigned short nb_rb_pdsch) unsigned short nb_rb_pdsch)
{ {
int32_t qpsk[4],nqpsk[4],*qpsk_p, n; int32_t qpsk[4],nqpsk[4],*qpsk_p, n;
//int w,mprime,ind,l,ind_dword,ind_qpsk_symb,kp,lp, config_type, k; //int w,mprime,ind,l,ind_dword,ind_qpsk_symb,kp,lp, config_type, k;
...@@ -216,26 +216,38 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, ...@@ -216,26 +216,38 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
return(0); return(0);
} }
int nr_pbch_dmrs_rx(unsigned int *nr_gold_pbch, int nr_pbch_dmrs_rx(int symbol,unsigned int *nr_gold_pbch,int32_t *output )
int32_t *output )
{ {
int m; int m,m0,m1;
uint8_t idx=0; uint8_t idx=0;
AssertFatal(symbol>=0 && symbol <3,"illegal symbol %d\n",symbol);
/// QPSK modulation if (symbol == 0) {
for (m=0; m<NR_PBCH_DMRS_LENGTH>>1; m++) { m0=0;
idx = ((((nr_gold_pbch[(m<<1)>>5])>>((m<<1)&0x1f))&1)<<1) ^ (((nr_gold_pbch[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1); m1=60;
((int16_t*)output)[m<<1] = nr_rx_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; }
((int16_t*)output)[(m<<1)+1] = nr_rx_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; else if (symbol == 1) {
m0=60;
m1=84;
}
else {
m0=84;
m1=144;
}
// printf("Generating pilots symbol %d, m0 %d, m1 %d\n",symbol,m0,m1);
/// QPSK modulation
for (m=m0; m<m1; m++) {
idx = ((((nr_gold_pbch[(m<<1)>>5])>>((m<<1)&0x1f))&1)<<1) ^ (((nr_gold_pbch[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1);
((int16_t*)output)[(m-m0)<<1] = nr_rx_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
((int16_t*)output)[((m-m0)<<1)+1] = nr_rx_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
if (m<16) if (m<16)
{printf("nr_gold_pbch[(m<<1)>>5] %x\n",nr_gold_pbch[(m<<1)>>5]); {printf("nr_gold_pbch[(m<<1)>>5] %x\n",nr_gold_pbch[(m<<1)>>5]);
printf("m %d output %d %d addr %p\n", m, ((int16_t*)output)[m<<1], ((int16_t*)output)[(m<<1)+1],&output[0]); printf("m %d output %d %d addr %p\n", m, ((int16_t*)output)[m<<1], ((int16_t*)output)[(m<<1)+1],&output[0]);
} }
#endif #endif
} }
return(0); return(0);
} }
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
/* PSS configuration */ /* PSS configuration */
#define SYNCHRO_FFT_SIZE_MAX (2048) /* maximum size of fft for synchronisation */ #define SYNCHRO_FFT_SIZE_MAX (8192) /* maximum size of fft for synchronisation */
#define NO_RATE_CHANGE (1) #define NO_RATE_CHANGE (1)
...@@ -102,13 +102,18 @@ EXTERN int16_t *primary_synchro_nr[NUMBER_PSS_SEQUENCE] ...@@ -102,13 +102,18 @@ EXTERN int16_t *primary_synchro_nr[NUMBER_PSS_SEQUENCE]
= { NULL, NULL, NULL} = { NULL, NULL, NULL}
#endif #endif
; ;
EXTERN int16_t *primary_synchro_nr2[NUMBER_PSS_SEQUENCE]
#ifdef INIT_VARIABLES_PSS_NR_H
= { NULL, NULL, NULL}
#endif
;
EXTERN int16_t *primary_synchro_time_nr[NUMBER_PSS_SEQUENCE] EXTERN int16_t *primary_synchro_time_nr[NUMBER_PSS_SEQUENCE]
#ifdef INIT_VARIABLES_PSS_NR_H #ifdef INIT_VARIABLES_PSS_NR_H
= { NULL, NULL, NULL} = { NULL, NULL, NULL}
#endif #endif
; ;
EXTERN int *pss_corr_ue[NUMBER_PSS_SEQUENCE] EXTERN int64_t *pss_corr_ue[NUMBER_PSS_SEQUENCE]
#ifdef INIT_VARIABLES_PSS_NR_H #ifdef INIT_VARIABLES_PSS_NR_H
= { NULL, NULL, NULL} = { NULL, NULL, NULL}
#endif #endif
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS. /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
*/ */
int nr_pbch_dmrs_rx(unsigned int *nr_gold_pbch, int32_t *output ); int nr_pbch_dmrs_rx(int dmrss,unsigned int *nr_gold_pbch, int32_t *output );
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS. /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
#define NUMBER_SSS_SEQUENCE (336) #define NUMBER_SSS_SEQUENCE (336)
#define INVALID_SSS_SEQUENCE (NUMBER_SSS_SEQUENCE) #define INVALID_SSS_SEQUENCE (NUMBER_SSS_SEQUENCE)
#define LENGTH_SSS_NR (127) #define LENGTH_SSS_NR (127)
#define SCALING_METRIC_SSS_NR (19) #define SCALING_METRIC_SSS_NR (15)//(19)
#define N_ID_2_NUMBER (NUMBER_PSS_SEQUENCE) #define N_ID_2_NUMBER (NUMBER_PSS_SEQUENCE)
#define N_ID_1_NUMBER (NUMBER_SSS_SEQUENCE) #define N_ID_1_NUMBER (NUMBER_SSS_SEQUENCE)
......
...@@ -55,7 +55,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -55,7 +55,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
uint8_t idx=0; uint8_t idx=0;
uint8_t nushift = config->sch_config.physical_cell_id.value &3; uint8_t nushift = config->sch_config.physical_cell_id.value &3;
LOG_I(PHY, "PBCH DMRS mapping started at symbol %d shift %d\n", ssb_start_symbol+1, nushift); LOG_D(PHY, "PBCH DMRS mapping started at symbol %d shift %d\n", ssb_start_symbol+1, nushift);
/// QPSK modulation /// QPSK modulation
for (int m=0; m<NR_PBCH_DMRS_LENGTH; m++) { for (int m=0; m<NR_PBCH_DMRS_LENGTH; m++) {
...@@ -85,6 +85,11 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -85,6 +85,11 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
#endif #endif
((int16_t*)txdataF[aa])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (a * mod_dmrs[m<<1]) >> 15; ((int16_t*)txdataF[aa])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (a * mod_dmrs[m<<1]) >> 15;
((int16_t*)txdataF[aa])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[(m<<1) + 1]) >> 15; ((int16_t*)txdataF[aa])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[(m<<1) + 1]) >> 15;
#ifdef DEBUG_PBCH_DMRS
printf("(%d,%d)\n",
((int16_t*)txdataF[aa])[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t*)txdataF[aa])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif
k+=4; k+=4;
if (k >= frame_parms->ofdm_symbol_size) if (k >= frame_parms->ofdm_symbol_size)
...@@ -101,6 +106,11 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -101,6 +106,11 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
#endif #endif
((int16_t*)txdataF[aa])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (a * mod_dmrs[m<<1]) >> 15; ((int16_t*)txdataF[aa])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (a * mod_dmrs[m<<1]) >> 15;
((int16_t*)txdataF[aa])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[(m<<1) + 1]) >> 15; ((int16_t*)txdataF[aa])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[(m<<1) + 1]) >> 15;
#ifdef DEBUG_PBCH_DMRS
printf("(%d,%d)\n",
((int16_t*)txdataF[aa])[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t*)txdataF[aa])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif
k+=(m==71)?148:4; // Jump from 44+nu to 192+nu k+=(m==71)?148:4; // Jump from 44+nu to 192+nu
if (k >= frame_parms->ofdm_symbol_size) if (k >= frame_parms->ofdm_symbol_size)
...@@ -117,6 +127,11 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -117,6 +127,11 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
#endif #endif
((int16_t*)txdataF[aa])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (a * mod_dmrs[m<<1]) >> 15; ((int16_t*)txdataF[aa])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (a * mod_dmrs[m<<1]) >> 15;
((int16_t*)txdataF[aa])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[(m<<1) + 1]) >> 15; ((int16_t*)txdataF[aa])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[(m<<1) + 1]) >> 15;
#ifdef DEBUG_PBCH_DMRS
printf("(%d,%d)\n",
((int16_t*)txdataF[aa])[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t*)txdataF[aa])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif
k+=4; k+=4;
if (k >= frame_parms->ofdm_symbol_size) if (k >= frame_parms->ofdm_symbol_size)
...@@ -218,7 +233,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -218,7 +233,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
memset((void*) xbyte, 0, 1); memset((void*) xbyte, 0, 1);
//uint8_t pbch_a_b[32]; //uint8_t pbch_a_b[32];
LOG_I(PHY, "PBCH generation started\n"); // LOG_D(PHY, "PBCH generation started\n");
memset((void*)pbch, 0, sizeof(NR_gNB_PBCH)); memset((void*)pbch, 0, sizeof(NR_gNB_PBCH));
///Payload generation ///Payload generation
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "PHY/NR_TRANSPORT/nr_transport.h" #include "PHY/NR_TRANSPORT/nr_transport.h"
#define NR_PSS_DEBUG //#define NR_PSS_DEBUG
int nr_generate_pss( int16_t *d_pss, int nr_generate_pss( int16_t *d_pss,
int32_t **txdataF, int32_t **txdataF,
...@@ -53,6 +53,7 @@ int nr_generate_pss( int16_t *d_pss, ...@@ -53,6 +53,7 @@ int nr_generate_pss( int16_t *d_pss,
#ifdef NR_PSS_DEBUG #ifdef NR_PSS_DEBUG
write_output("d_pss.m", "d_pss", (void*)d_pss, NR_PSS_LENGTH, 1, 0); write_output("d_pss.m", "d_pss", (void*)d_pss, NR_PSS_LENGTH, 1, 0);
printf("PSS: ofdm_symbol_size %d, first_carrier_offset %d\n",frame_parms->ofdm_symbol_size,frame_parms->first_carrier_offset);
#endif #endif
/// Resource mapping /// Resource mapping
...@@ -63,9 +64,12 @@ int nr_generate_pss( int16_t *d_pss, ...@@ -63,9 +64,12 @@ int nr_generate_pss( int16_t *d_pss,
// PSS occupies a predefined position (subcarriers 56-182, symbol 0) within the SSB block starting from // PSS occupies a predefined position (subcarriers 56-182, symbol 0) within the SSB block starting from
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; //and k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; //and
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
l = ssb_start_symbol; l = ssb_start_symbol;
for (m = 0; m < NR_PSS_LENGTH; m++) { for (m = 0; m < NR_PSS_LENGTH; m++) {
// printf("pss: writing position k %d / %d\n",k,frame_parms->ofdm_symbol_size);
((int16_t*)txdataF[aa])[2*(l*frame_parms->ofdm_symbol_size + k)] = (a * d_pss[m]) >> 15; ((int16_t*)txdataF[aa])[2*(l*frame_parms->ofdm_symbol_size + k)] = (a * d_pss[m]) >> 15;
k++; k++;
...@@ -75,7 +79,9 @@ int nr_generate_pss( int16_t *d_pss, ...@@ -75,7 +79,9 @@ int nr_generate_pss( int16_t *d_pss,
} }
#ifdef NR_PSS_DEBUG #ifdef NR_PSS_DEBUG
write_output("pss_0.m", "pss_0", (void*)&txdataF[0][2*l*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1); LOG_M("pss_0.m", "pss_0",
(void*)&txdataF[0][ssb_start_symbol*frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size, 1, 1);
#endif #endif
return 0; return 0;
......
...@@ -83,7 +83,7 @@ int nr_generate_sss( int16_t *d_sss, ...@@ -83,7 +83,7 @@ int nr_generate_sss( int16_t *d_sss,
} }
} }
#ifdef NR_SSS_DEBUG #ifdef NR_SSS_DEBUG
write_output("sss_0.m", "sss_0", (void*)txdataF[0][2*l*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1); // write_output("sss_0.m", "sss_0", (void*)txdataF[0][l*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1);
#endif #endif
return 0; return 0;
......
...@@ -19,78 +19,92 @@ ...@@ -19,78 +19,92 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
#ifdef USER_MODE
#include <string.h> #include <string.h>
#endif
//#include "defs.h" //#include "defs.h"
//#include "SCHED/defs.h" //#include "SCHED/defs.h"
#include "PHY/defs_nr_UE.h" #include "PHY/defs_nr_UE.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "filt16a_32.h" #include "filt16a_32.h"
#include "T.h" #include "T.h"
//#define DEBUG_CH //#define DEBUG_CH
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_id, uint8_t eNB_id,
uint8_t eNB_offset, uint8_t eNB_offset,
unsigned char Ns, unsigned char Ns,
unsigned char p, unsigned char l,
unsigned char l, unsigned char symbol)
unsigned char symbol)
{ {
int pilot[2][200] __attribute__((aligned(16))); int pilot[200] __attribute__((aligned(16)));
unsigned char aarx; unsigned char aarx;
unsigned short k; unsigned short k;
unsigned int pilot_cnt; unsigned int pilot_cnt;
int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr; int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
int ch_offset,symbol_offset; int ch_offset,symbol_offset;
int dmrss;
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
uint8_t nushift, ssb_index=0, n_hf=0; uint8_t nushift,ssb_index=0, n_hf=0;
int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset]; int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset];
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF; int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
nushift = ue->frame_parms.Nid_cell%4; nushift = ue->frame_parms.Nid_cell%4;
ue->frame_parms.nushift = nushift; ue->frame_parms.nushift = nushift;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
if (ue->is_synchronized ==0 ) dmrss = symbol-1;
else dmrss = symbol-5;
if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
ch_offset = ue->frame_parms.ofdm_symbol_size ; ch_offset = ue->frame_parms.ofdm_symbol_size ;
else else
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
AssertFatal((symbol > 0 && symbol < 4 && ue->is_synchronized == 0) ||
(symbol > 4 && symbol < 8 && ue->is_synchronized == 1),
"symbol %d is illegal for PBCH DM-RS (is_synchronized %d)\n",
symbol,ue->is_synchronized);
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol; symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
k = nushift; k = nushift;
#ifdef DEBUG_CH #ifdef DEBUG_CH
printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,Nid_cell,ch_offset,ue->frame_parms.ofdm_symbol_size, printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,l,Ns,k, symbol); ue->frame_parms.Ncp,l,Ns,k, symbol);
#endif #endif
switch (k) { switch (k) {
case 0: case 0:
fl = filt16a_l0; fl = filt16a_l0;
fm = filt16a_m0; fm = filt16a_m0;
fr = filt16a_r0; fr = filt16a_r0;
break; break;
case 1: case 1:
fl = filt16a_l1; fl = filt16a_l1;
fm = filt16a_m1; fm = filt16a_m1;
fr = filt16a_r1; fr = filt16a_r1;
break; break;
case 2: case 2:
fl = filt16a_l2; fl = filt16a_l2;
fm = filt16a_m2; fm = filt16a_m2;
fr = filt16a_r2; fr = filt16a_r2;
break; break;
case 3: case 3:
fl = filt16a_l3; fl = filt16a_l3;
fm = filt16a_m3; fm = filt16a_m3;
fr = filt16a_r3; fr = filt16a_r3;
break; break;
default: default:
msg("pbch_channel_estimation: k=%d -> ERROR\n",k); msg("pbch_channel_estimation: k=%d -> ERROR\n",k);
...@@ -99,119 +113,136 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -99,119 +113,136 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
} }
// generate pilot // generate pilot
nr_pbch_dmrs_rx(ue->nr_gold_pbch[n_hf][ssb_index], &pilot[p][0]); nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
int re_offset = ssb_offset;
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
pil = (int16_t *)&pilot[p][0]; pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+(ue->frame_parms.ofdm_symbol_size-10*12))]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]; dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1), multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1), ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
1,ue->frame_parms.ofdm_symbol_size); 1,ue->frame_parms.ofdm_symbol_size);
#ifdef DEBUG_CH #ifdef DEBUG_CH
printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[p][0], ue->frame_parms.N_RB_DL); printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset); printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
printf("rxF addr %p\n", rxF); printf("rxF addr %p\n", rxF);
printf("dl_ch addr %p\n",dl_ch); printf("dl_ch addr %p\n",dl_ch);
#endif #endif
//if ((ue->frame_parms.N_RB_DL&1)==0) { //if ((ue->frame_parms.N_RB_DL&1)==0) {
// Treat first 2 pilots specially (left edge) // Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fl,
ch,
dl_ch,
16);
pil+=2;
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
//for (int i= 0; i<8; i++)
//printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fm,
ch,
dl_ch,
16);
pil+=2;
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fr,
ch,
dl_ch,
16);
pil+=2;
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch+=24;
for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt+=3) {
// if (pilot_cnt == 30)
// rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)];
// in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS)
if (dmrss == 1 && pilot_cnt == 12) {
pilot_cnt=48;
re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch += 288;
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH #ifdef DEBUG_CH
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif #endif
multadd_real_vector_complex_scalar(fl, multadd_real_vector_complex_scalar(fl,
ch, ch,
dl_ch, dl_ch,
16); 16);
pil+=2;
rxF+=8;
//for (int i= 0; i<8; i++) //for (int i= 0; i<8; i++)
//printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); // printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i));
pil+=2;
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH #ifdef DEBUG_CH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif #endif
multadd_real_vector_complex_scalar(fm, multadd_real_vector_complex_scalar(fm,
ch, ch,
dl_ch, dl_ch,
16); 16);
pil+=2; pil+=2;
rxF+=8; re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH #ifdef DEBUG_CH
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif #endif
multadd_real_vector_complex_scalar(fr, multadd_real_vector_complex_scalar(fr,
ch, ch,
dl_ch, dl_ch,
16); 16);
pil+=2; pil+=2;
rxF+=8; re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch+=24; dl_ch+=24;
for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt+=3) { }
if (pilot_cnt == 30)
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fl,
ch,
dl_ch,
16);
//for (int i= 0; i<8; i++)
// printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i));
pil+=2;
rxF+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fm,
ch,
dl_ch,
16);
pil+=2;
rxF+=8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fr,
ch,
dl_ch,
16);
pil+=2;
rxF+=8;
dl_ch+=24;
}
//} //}
...@@ -222,16 +253,15 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -222,16 +253,15 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
} }
int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_id, uint8_t eNB_id,
uint8_t eNB_offset, uint8_t eNB_offset,
unsigned char Ns, unsigned char Ns,
unsigned char p, unsigned char l,
unsigned char l, unsigned char symbol,
unsigned char symbol, unsigned short coreset_start_subcarrier,
unsigned short coreset_start_subcarrier, unsigned short nb_rb_coreset)
unsigned short nb_rb_coreset)
{ {
int pilot[2][200] __attribute__((aligned(16))); int pilot[200] __attribute__((aligned(16)));
unsigned char aarx; unsigned char aarx;
unsigned short k; unsigned short k;
unsigned int pilot_cnt; unsigned int pilot_cnt;
...@@ -266,25 +296,25 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -266,25 +296,25 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
fr = filt16a_r1; fr = filt16a_r1;
// generate pilot // generate pilot
nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[p][0],2000,nb_rb_coreset); nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset);
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
pil = (int16_t *)&pilot[p][0]; pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]; dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1), multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1), ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
1,ue->frame_parms.ofdm_symbol_size); 1,ue->frame_parms.ofdm_symbol_size);
//#ifdef DEBUG_CH //#ifdef DEBUG_CH
printf("pdcch ch est pilot addr %p RB_DL %d\n",&pilot[p][0], ue->frame_parms.N_RB_DL); printf("pdcch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset); printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
printf("rxF addr %p\n", rxF); printf("rxF addr %p\n", rxF);
printf("dl_ch addr %p\n",dl_ch); printf("dl_ch addr %p\n",dl_ch);
//#endif //#endif
if ((ue->frame_parms.N_RB_DL&1)==0) { if ((ue->frame_parms.N_RB_DL&1)==0) {
// Treat first 2 pilots specially (left edge) // Treat first 2 pilots specially (left edge)
...@@ -329,7 +359,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -329,7 +359,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
#ifdef DEBUG_CH #ifdef DEBUG_CH
for (int m =0; m<12; m++) for (int m =0; m<12; m++)
printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]); printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]);
#endif #endif
pil+=2; pil+=2;
rxF+=8; rxF+=8;
...@@ -341,8 +371,8 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -341,8 +371,8 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt+=3) { for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt+=3) {
if (k >= ue->frame_parms.ofdm_symbol_size){ if (k >= ue->frame_parms.ofdm_symbol_size){
k-=ue->frame_parms.ofdm_symbol_size; k-=ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];} rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
...@@ -399,30 +429,28 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -399,30 +429,28 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
} }
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_id, uint8_t eNB_id,
uint8_t eNB_offset, uint8_t eNB_offset,
unsigned char Ns, unsigned char Ns,
unsigned char p, unsigned char l,
unsigned char l, unsigned char symbol,
unsigned char symbol, unsigned short bwp_start_subcarrier,
unsigned short bwp_start_subcarrier, unsigned short nb_rb_pdsch)
unsigned short nb_rb_pdsch)
{ {
int pilot[2][200] __attribute__((aligned(16))); int pilot[200] __attribute__((aligned(16)));
unsigned char aarx; unsigned char aarx;
unsigned short k; unsigned short k;
unsigned int pilot_cnt; unsigned int pilot_cnt;
int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr,*fml,*fmr; int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr,*fml,*fmr;
int ch_offset,symbol_offset; int ch_offset,symbol_offset;
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
uint8_t nushift; uint8_t nushift=0;
int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset]; int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset];
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF; int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
nushift = (p>>1)&1;
ue->frame_parms.nushift = nushift;
if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
ch_offset = ue->frame_parms.ofdm_symbol_size ; ch_offset = ue->frame_parms.ofdm_symbol_size ;
...@@ -434,42 +462,42 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -434,42 +462,42 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
k = bwp_start_subcarrier; k = bwp_start_subcarrier;
#ifdef DEBUG_CH #ifdef DEBUG_CH
printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,Nid_cell,ch_offset,ue->frame_parms.ofdm_symbol_size, printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,l,Ns,k, symbol); ue->frame_parms.Ncp,l,Ns,k, symbol);
#endif #endif
switch (nushift) { switch (nushift) {
case 0: case 0:
fl = filt8_l0; fl = filt8_l0;
fm = filt8_m0; fm = filt8_m0;
fr = filt8_r0; fr = filt8_r0;
fml = filt8_m0; fml = filt8_m0;
fmr = filt8_mr0; fmr = filt8_mr0;
break; break;
case 1: case 1:
fl = filt8_l1; fl = filt8_l1;
fm = filt8_m1; fm = filt8_m1;
fr = filt8_r1; fr = filt8_r1;
fml = filt8_ml1; fml = filt8_ml1;
fmr = filt8_m1; fmr = filt8_m1;
break; break;
default: default:
msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift); msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift);
return(-1); return(-1);
break; break;
} }
// generate pilot // generate pilot
nr_pdsch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol], &pilot[p][0],1000,1,nb_rb_pdsch); nr_pdsch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol], &pilot[0],1000,1,nb_rb_pdsch);
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
pil = (int16_t *)&pilot[p][0]; pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]; dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
...@@ -477,7 +505,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -477,7 +505,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1), ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
1,ue->frame_parms.ofdm_symbol_size); 1,ue->frame_parms.ofdm_symbol_size);
#ifdef DEBUG_CH #ifdef DEBUG_CH
printf("ch est pilot addr %p RB_DL %d\n",&pilot[p][0], ue->frame_parms.N_RB_DL); printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset); printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
printf("rxF addr %p\n", rxF); printf("rxF addr %p\n", rxF);
printf("dl_ch addr %p\n",dl_ch); printf("dl_ch addr %p\n",dl_ch);
...@@ -516,11 +544,11 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -516,11 +544,11 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
for (pilot_cnt=2; pilot_cnt<(6*(nb_rb_pdsch-1)+4); pilot_cnt+=2) { for (pilot_cnt=2; pilot_cnt<(6*(nb_rb_pdsch-1)+4); pilot_cnt+=2) {
if ((pilot_cnt%6)==0) if ((pilot_cnt%6)==0)
dl_ch+=4; dl_ch+=4;
if (k >= ue->frame_parms.ofdm_symbol_size){ if (k >= ue->frame_parms.ofdm_symbol_size){
k-=ue->frame_parms.ofdm_symbol_size; k-=ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];} rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
......
...@@ -46,7 +46,6 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -46,7 +46,6 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_id, uint8_t eNB_id,
uint8_t eNB_offset, uint8_t eNB_offset,
unsigned char Ns, unsigned char Ns,
unsigned char p,
unsigned char l, unsigned char l,
unsigned char symbol, unsigned char symbol,
unsigned short coreset_start_subcarrier, unsigned short coreset_start_subcarrier,
...@@ -56,7 +55,6 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -56,7 +55,6 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_id, uint8_t eNB_id,
uint8_t eNB_offset, uint8_t eNB_offset,
unsigned char Ns, unsigned char Ns,
unsigned char p,
unsigned char l, unsigned char l,
unsigned char symbol); unsigned char symbol);
...@@ -64,7 +62,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -64,7 +62,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_id, uint8_t eNB_id,
uint8_t eNB_offset, uint8_t eNB_offset,
unsigned char Ns, unsigned char Ns,
unsigned char p,
unsigned char l, unsigned char l,
unsigned char symbol, unsigned char symbol,
unsigned short bwp_start_subcarrier, unsigned short bwp_start_subcarrier,
......
...@@ -58,233 +58,13 @@ ...@@ -58,233 +58,13 @@
#define NR_NBR_SEARCHSPACE_ACT_BWP 10 // The number of SearSpaces per BWP is limited to 10 (including initial SEARCHSPACE: SearchSpaceId 0) #define NR_NBR_SEARCHSPACE_ACT_BWP 10 // The number of SearSpaces per BWP is limited to 10 (including initial SEARCHSPACE: SearchSpaceId 0)
#define PDCCH_TEST_POLAR_TEMP_FIX #define PDCCH_TEST_POLAR_TEMP_FIX
//#undef ALL_AGGREGATION
//extern uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3];
//extern uint16_t pcfich_reg[4];
uint16_t extract_crc(uint8_t *dci,uint8_t dci_len)
{
uint16_t crc16;
// uint8_t i;
/*
uint8_t crc;
crc = ((uint16_t *)dci)[DCI_LENGTH>>4];
printf("crc1: %x, shift %d (DCI_LENGTH %d)\n",crc,DCI_LENGTH&0xf,DCI_LENGTH);
crc = (crc>>(DCI_LENGTH&0xf));
// clear crc bits
((uint16_t *)dci)[DCI_LENGTH>>4] &= (0xffff>>(16-(DCI_LENGTH&0xf)));
printf("crc2: %x, dci0 %x\n",crc,((int16_t *)dci)[DCI_LENGTH>>4]);
crc |= (((uint16_t *)dci)[1+(DCI_LENGTH>>4)])<<(16-(DCI_LENGTH&0xf));
// clear crc bits
(((uint16_t *)dci)[1+(DCI_LENGTH>>4)]) = 0;
printf("extract_crc: crc %x\n",crc);
*/
#ifdef DEBUG_DCI_DECODING
LOG_I(PHY,"dci_crc (%x,%x,%x), dci_len&0x7=%d\n",dci[dci_len>>3],dci[1+(dci_len>>3)],dci[2+(dci_len>>3)],
dci_len&0x7);
#endif
if ((dci_len&0x7) > 0) {
((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)]<<(dci_len&0x7) | dci[2+(dci_len>>3)]>>(8-(dci_len&0x7));
((uint8_t *)&crc16)[1] = dci[(dci_len>>3)]<<(dci_len&0x7) | dci[1+(dci_len>>3)]>>(8-(dci_len&0x7));
} else {
((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)];
((uint8_t *)&crc16)[1] = dci[(dci_len>>3)];
}
#ifdef DEBUG_DCI_DECODING
LOG_I(PHY,"dci_crc =>%x\n",crc16);
#endif
// dci[(dci_len>>3)]&=(0xffff<<(dci_len&0xf));
// dci[(dci_len>>3)+1] = 0;
// dci[(dci_len>>3)+2] = 0;
return((uint16_t)crc16);
}
static uint8_t d[3*(MAX_DCI_SIZE_BITS + 16) + 96];
static uint8_t w[3*3*(MAX_DCI_SIZE_BITS+16)];
void dci_encoding(uint8_t *a,
uint8_t A,
uint16_t E,
uint8_t *e,
uint16_t rnti)
{
uint8_t D = (A + 16);
uint32_t RCC;
#ifdef DEBUG_DCI_ENCODING
int32_t i;
#endif
// encode dci
#ifdef DEBUG_DCI_ENCODING
printf("Doing DCI encoding for %d bits, e %p, rnti %x\n",A,e,rnti);
#endif
memset((void *)d,LTE_NULL,96);
ccodelte_encode(A,2,a,d+96,rnti);
#ifdef DEBUG_DCI_ENCODING
for (i=0; i<16+A; i++)
printf("%d : (%d,%d,%d)\n",i,*(d+96+(3*i)),*(d+97+(3*i)),*(d+98+(3*i)));
#endif
#ifdef DEBUG_DCI_ENCODING
printf("Doing DCI interleaving for %d coded bits, e %p\n",D*3,e);
#endif
RCC = sub_block_interleaving_cc(D,d+96,w);
#ifdef DEBUG_DCI_ENCODING
printf("Doing DCI rate matching for %d channel bits, RCC %d, e %p\n",E,RCC,e);
#endif
lte_rate_matching_cc(RCC,E,w,e);
}
uint8_t *generate_dci0(uint8_t *dci,
uint8_t *e,
uint8_t DCI_LENGTH,
uint8_t aggregation_level,
uint16_t rnti)
{
uint16_t coded_bits;
uint8_t dci_flip[8];
if (aggregation_level>3) {
printf("dci.c: generate_dci FATAL, illegal aggregation_level %d\n",aggregation_level);
return NULL;
}
coded_bits = 72 * (1<<aggregation_level);
/*
#ifdef DEBUG_DCI_ENCODING
for (i=0;i<1+((DCI_LENGTH+16)/8);i++)
printf("i %d : %x\n",i,dci[i]);
#endif
*/
if (DCI_LENGTH<=32) {
dci_flip[0] = dci[3];
dci_flip[1] = dci[2];
dci_flip[2] = dci[1];
dci_flip[3] = dci[0];
} else {
dci_flip[0] = dci[7];
dci_flip[1] = dci[6];
dci_flip[2] = dci[5];
dci_flip[3] = dci[4];
dci_flip[4] = dci[3];
dci_flip[5] = dci[2];
dci_flip[6] = dci[1];
dci_flip[7] = dci[0];
#ifdef DEBUG_DCI_ENCODING
printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3],
dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]);
#endif
}
dci_encoding(dci_flip,DCI_LENGTH,coded_bits,e,rnti);
return(e+coded_bits);
}
uint32_t Y;
#define CCEBITS 72
#define CCEPERSYMBOL 33 // This is for 1200 RE
#define CCEPERSYMBOL0 22 // This is for 1200 RE
#define DCI_BITS_MAX ((2*CCEPERSYMBOL+CCEPERSYMBOL0)*CCEBITS)
#define Msymb (DCI_BITS_MAX/2)
//#define Mquad (Msymb/4)
static int32_t wtemp[2][Msymb];
void pdcch_interleaving(NR_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi)
{
int32_t *wptr,*wptr2,*zptr;
uint32_t Mquad = get_nquad(n_symbols_pdcch,frame_parms,mi);
uint32_t RCC = (Mquad>>5), ND;
uint32_t row,col,Kpi,index;
int32_t i,k,a;
#ifdef RM_DEBUG
int32_t nulled=0;
#endif
// printf("[PHY] PDCCH Interleaving Mquad %d (Nsymb %d)\n",Mquad,n_symbols_pdcch);
if ((Mquad&0x1f) > 0)
RCC++;
Kpi = (RCC<<5);
ND = Kpi - Mquad;
k=0;
for (col=0; col<32; col++) {
index = bitrev_cc_dci[col];
for (row=0; row<RCC; row++) {
//printf("col %d, index %d, row %d\n",col,index,row);
if (index>=ND) {
for (a=0; a<frame_parms->nb_antenna_ports_eNB; a++) {
//printf("a %d k %d\n",a,k);
wptr = &wtemp[a][k<<2];
zptr = &z[a][(index-ND)<<2];
//printf("wptr=%p, zptr=%p\n",wptr,zptr);
wptr[0] = zptr[0];
wptr[1] = zptr[1];
wptr[2] = zptr[2];
wptr[3] = zptr[3];
}
k++;
}
index+=32;
}
}
// permutation
for (i=0; i<Mquad; i++) {
for (a=0; a<frame_parms->nb_antenna_ports_eNB; a++) {
//wptr = &wtemp[a][i<<2];
//wptr2 = &wbar[a][((i+frame_parms->Nid_cell)%Mquad)<<2];
wptr = &wtemp[a][((i+frame_parms->Nid_cell)%Mquad)<<2];
wptr2 = &wbar[a][i<<2];
wptr2[0] = wptr[0];
wptr2[1] = wptr[1];
wptr2[2] = wptr[2];
wptr2[3] = wptr[3];
}
}
}
#ifdef NR_PDCCH_DCI_RUN
static const uint16_t conjugate[8]__attribute__((aligned(32))) = {-1,1,-1,1,-1,1,-1,1};
#ifdef NR_PDCCH_DCI_RUN
void nr_pdcch_demapping_deinterleaving(uint16_t *llr, void nr_pdcch_demapping_deinterleaving(uint16_t *llr,
uint16_t *z, uint16_t *z,
...@@ -866,480 +646,6 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, ...@@ -866,480 +646,6 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
#endif #endif
void pdcch_extract_rbs_single(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint8_t symbol,
uint32_t high_speed_flag,
NR_DL_FRAME_PARMS *frame_parms)
{
uint16_t rb,nb_rb=0;
uint8_t i,j,aarx;
int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
int nushiftmod3 = frame_parms->nushift%3;
uint8_t symbol_mod;
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
#ifdef DEBUG_DCI_DECODING
LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod);
#endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
if (high_speed_flag == 1)
dl_ch0 = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
else
dl_ch0 = &dl_ch_estimates[aarx][5];
dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))];
if ((frame_parms->N_RB_DL&1) == 0) { // even number of RBs
for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
// For second half of RBs skip DC carrier
if (rb==(frame_parms->N_RB_DL>>1)) {
rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))];
//dl_ch0++;
}
if (symbol_mod>0) {
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
for (i=0; i<12; i++) {
rxF_ext[i]=rxF[i];
}
nb_rb++;
dl_ch0_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
rxF+=12;
} else {
j=0;
for (i=0; i<12; i++) {
if ((i!=nushiftmod3) &&
(i!=(nushiftmod3+3)) &&
(i!=(nushiftmod3+6)) &&
(i!=(nushiftmod3+9))) {
rxF_ext[j]=rxF[i];
// printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
dl_ch0_ext[j++]=dl_ch0[i];
// printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
}
}
nb_rb++;
dl_ch0_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
rxF+=12;
}
}
} else { // Odd number of RBs
for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {
if (symbol_mod>0) {
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
for (i=0; i<12; i++)
rxF_ext[i]=rxF[i];
nb_rb++;
dl_ch0_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
rxF+=12;
} else {
j=0;
for (i=0; i<12; i++) {
if ((i!=nushiftmod3) &&
(i!=(nushiftmod3+3)) &&
(i!=(nushiftmod3+6)) &&
(i!=(nushiftmod3+9))) {
rxF_ext[j]=rxF[i];
// printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
dl_ch0_ext[j++]=dl_ch0[i];
// printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
}
}
nb_rb++;
dl_ch0_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
rxF+=12;
}
}
// Do middle RB (around DC)
// printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
if (symbol_mod==0) {
j=0;
for (i=0; i<6; i++) {
if ((i!=nushiftmod3) &&
(i!=(nushiftmod3+3))) {
dl_ch0_ext[j]=dl_ch0[i];
rxF_ext[j++]=rxF[i];
// printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
}
}
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
for (; i<12; i++) {
if ((i!=(nushiftmod3+6)) &&
(i!=(nushiftmod3+9))) {
dl_ch0_ext[j]=dl_ch0[i];
rxF_ext[j++]=rxF[(1+i-6)];
// printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
}
}
nb_rb++;
dl_ch0_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
rxF+=7;
rb++;
} else {
for (i=0; i<6; i++) {
dl_ch0_ext[i]=dl_ch0[i];
rxF_ext[i]=rxF[i];
}
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
for (; i<12; i++) {
dl_ch0_ext[i]=dl_ch0[i];
rxF_ext[i]=rxF[(1+i-6)];
}
nb_rb++;
dl_ch0_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
rxF+=7;
rb++;
}
for (; rb<frame_parms->N_RB_DL; rb++) {
if (symbol_mod > 0) {
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
for (i=0; i<12; i++)
rxF_ext[i]=rxF[i];
nb_rb++;
dl_ch0_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
rxF+=12;
} else {
j=0;
for (i=0; i<12; i++) {
if ((i!=(nushiftmod3)) &&
(i!=(nushiftmod3+3)) &&
(i!=(nushiftmod3+6)) &&
(i!=(nushiftmod3+9))) {
rxF_ext[j]=rxF[i];
// printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
dl_ch0_ext[j++]=dl_ch0[i];
}
}
nb_rb++;
dl_ch0_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
rxF+=12;
}
}
}
}
}
void pdcch_extract_rbs_dual(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint8_t symbol,
uint32_t high_speed_flag,
NR_DL_FRAME_PARMS *frame_parms)
{
uint16_t rb,nb_rb=0;
uint8_t i,aarx,j;
int32_t *dl_ch0,*dl_ch0_ext,*dl_ch1,*dl_ch1_ext,*rxF,*rxF_ext;
uint8_t symbol_mod;
int nushiftmod3 = frame_parms->nushift%3;
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
#ifdef DEBUG_DCI_DECODING
LOG_I(PHY, "extract_rbs_dual: symbol_mod %d\n",symbol_mod);
#endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
if (high_speed_flag==1) {
dl_ch0 = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
dl_ch1 = &dl_ch_estimates[2+aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
} else {
dl_ch0 = &dl_ch_estimates[aarx][5];
dl_ch1 = &dl_ch_estimates[2+aarx][5];
}
dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(frame_parms->N_RB_DL*12)];
// printf("pdcch extract_rbs: rxF_ext pos %d\n",symbol*(frame_parms->N_RB_DL*12));
rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))];
if ((frame_parms->N_RB_DL&1) == 0) // even number of RBs
for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
// For second half of RBs skip DC carrier
if (rb==(frame_parms->N_RB_DL>>1)) {
rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))];
// dl_ch0++;
//dl_ch1++;
}
if (symbol_mod>0) {
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t));
/*
printf("rb %d\n",rb);
for (i=0;i<12;i++)
printf("(%d %d)",((int16_t *)dl_ch0)[i<<1],((int16_t*)dl_ch0)[1+(i<<1)]);
printf("\n");
*/
for (i=0; i<12; i++) {
rxF_ext[i]=rxF[i];
// printf("%d : (%d,%d)\n",(rxF+(2*i)-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))*2])/2,
// ((int16_t*)&rxF[i<<1])[0],((int16_t*)&rxF[i<<1])[0]);
}
nb_rb++;
dl_ch0_ext+=12;
dl_ch1_ext+=12;
rxF_ext+=12;
} else {
j=0;
for (i=0; i<12; i++) {
if ((i!=nushiftmod3) &&
(i!=nushiftmod3+3) &&
(i!=nushiftmod3+6) &&
(i!=nushiftmod3+9)) {
rxF_ext[j]=rxF[i];
// printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
dl_ch0_ext[j] =dl_ch0[i];
dl_ch1_ext[j++]=dl_ch1[i];
}
}
nb_rb++;
dl_ch0_ext+=8;
dl_ch1_ext+=8;
rxF_ext+=8;
}
dl_ch0+=12;
dl_ch1+=12;
rxF+=12;
}
else { // Odd number of RBs
for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {
// printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
if (symbol_mod>0) {
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t));
for (i=0; i<12; i++)
rxF_ext[i]=rxF[i];
nb_rb++;
dl_ch0_ext+=12;
dl_ch1_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
dl_ch1+=12;
rxF+=12;
} else {
j=0;
for (i=0; i<12; i++) {
if ((i!=nushiftmod3) &&
(i!=nushiftmod3+3) &&
(i!=nushiftmod3+6) &&
(i!=nushiftmod3+9)) {
rxF_ext[j]=rxF[i];
// printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
dl_ch0_ext[j]=dl_ch0[i];
dl_ch1_ext[j++]=dl_ch1[i];
// printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
}
}
nb_rb++;
dl_ch0_ext+=8;
dl_ch1_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
dl_ch1+=12;
rxF+=12;
}
}
// Do middle RB (around DC)
if (symbol_mod > 0) {
for (i=0; i<6; i++) {
dl_ch0_ext[i]=dl_ch0[i];
dl_ch1_ext[i]=dl_ch1[i];
rxF_ext[i]=rxF[i];
}
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
for (; i<12; i++) {
dl_ch0_ext[i]=dl_ch0[i];
dl_ch1_ext[i]=dl_ch1[i];
rxF_ext[i]=rxF[(1+i)];
}
nb_rb++;
dl_ch0_ext+=12;
dl_ch1_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
dl_ch1+=12;
rxF+=7;
rb++;
} else {
j=0;
for (i=0; i<6; i++) {
if ((i!=nushiftmod3) &&
(i!=nushiftmod3+3)) {
dl_ch0_ext[j]=dl_ch0[i];
dl_ch1_ext[j]=dl_ch1[i];
rxF_ext[j++]=rxF[i];
// printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
}
}
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
for (; i<12; i++) {
if ((i!=nushiftmod3+6) &&
(i!=nushiftmod3+9)) {
dl_ch0_ext[j]=dl_ch0[i];
dl_ch1_ext[j]=dl_ch1[i];
rxF_ext[j++]=rxF[(1+i-6)];
// printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
}
}
nb_rb++;
dl_ch0_ext+=8;
dl_ch1_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
dl_ch1+=12;
rxF+=7;
rb++;
}
for (; rb<frame_parms->N_RB_DL; rb++) {
if (symbol_mod>0) {
// printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t));
for (i=0; i<12; i++)
rxF_ext[i]=rxF[i];
nb_rb++;
dl_ch0_ext+=12;
dl_ch1_ext+=12;
rxF_ext+=12;
dl_ch0+=12;
dl_ch1+=12;
rxF+=12;
} else {
j=0;
for (i=0; i<12; i++) {
if ((i!=nushiftmod3) &&
(i!=nushiftmod3+3) &&
(i!=nushiftmod3+6) &&
(i!=nushiftmod3+9)) {
rxF_ext[j]=rxF[i];
// printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
dl_ch0_ext[j]=dl_ch0[i];
dl_ch1_ext[j++]=dl_ch1[i];
}
}
nb_rb++;
dl_ch0_ext+=8;
dl_ch1_ext+=8;
rxF_ext+=8;
dl_ch0+=12;
dl_ch1+=12;
rxF+=12;
}
}
}
}
}
#if defined(__x86_64__) || defined(__i386__)
__m128i mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#elif defined(__arm__)
int16x8_t mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#endif
void nr_pdcch_channel_compensation(int32_t **rxdataF_ext, void nr_pdcch_channel_compensation(int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext, int32_t **dl_ch_estimates_ext,
...@@ -1353,6 +659,13 @@ void nr_pdcch_channel_compensation(int32_t **rxdataF_ext, ...@@ -1353,6 +659,13 @@ void nr_pdcch_channel_compensation(int32_t **rxdataF_ext,
uint16_t rb; //,nb_rb=20; uint16_t rb; //,nb_rb=20;
uint8_t aatx,aarx; uint8_t aatx,aarx;
#if defined(__x86_64__) || defined(__i386__)
__m128i mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#elif defined(__arm__)
int16x8_t mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#endif
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
__m128i *dl_ch128,*rxdataF128,*rxdataF_comp128; __m128i *dl_ch128,*rxdataF128,*rxdataF_comp128;
#elif defined(__arm__) #elif defined(__arm__)
...@@ -1522,39 +835,6 @@ void pdcch_siso(NR_DL_FRAME_PARMS *frame_parms, ...@@ -1522,39 +835,6 @@ void pdcch_siso(NR_DL_FRAME_PARMS *frame_parms,
} }
void pdcch_alamouti(NR_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint8_t symbol)
{
int16_t *rxF0,*rxF1;
uint8_t rb,re;
int32_t jj=(symbol*frame_parms->N_RB_DL*12);
rxF0 = (int16_t*)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y
rxF1 = (int16_t*)&rxdataF_comp[2][jj]; //tx antenna 1 h1*y
for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
for (re=0; re<12; re+=2) {
// Alamouti RX combining
rxF0[0] = rxF0[0] + rxF1[2];
rxF0[1] = rxF0[1] - rxF1[3];
rxF0[2] = rxF0[2] - rxF1[0];
rxF0[3] = rxF0[3] + rxF1[1];
rxF0+=4;
rxF1+=4;
}
}
}
int32_t avgP[4]; int32_t avgP[4];
...@@ -1952,259 +1232,6 @@ printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> (c_init=%d, n_id=%d, ...@@ -1952,259 +1232,6 @@ printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> (c_init=%d, n_id=%d,
#endif #endif
#ifdef PHY_ABSTRACTION
uint8_t generate_dci_top_emul(PHY_VARS_eNB *phy_vars_eNB,
int num_dci,
DCI_ALLOC_t *dci_alloc,
uint8_t subframe)
{
int n_dci, n_dci_dl;
uint8_t ue_id;
LTE_eNB_DLSCH_t *dlsch_eNB;
int num_ue_spec_dci;
int num_common_dci;
int i;
uint8_t num_pdcch_symbols = get_num_pdcch_symbols(num_dci,
dci_alloc,
&phy_vars_eNB->frame_parms,
subframe);
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].cntl.cfi=num_pdcch_symbols;
num_ue_spec_dci = 0;
num_common_dci = 0;
for (i = 0; i < num_dci; i++) {
/* TODO: maybe useless test, to remove? */
if (!(dci_alloc[i].firstCCE>=0)) abort();
if (dci_alloc[i].search_space == DCI_COMMON_SPACE)
num_common_dci++;
else
num_ue_spec_dci++;
}
memcpy(phy_vars_eNB->dci_alloc[subframe&1],dci_alloc,sizeof(DCI_ALLOC_t)*(num_dci));
phy_vars_eNB->num_ue_spec_dci[subframe&1]=num_ue_spec_dci;
phy_vars_eNB->num_common_dci[subframe&1]=num_common_dci;
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_ue_spec_dci = num_ue_spec_dci;
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_common_dci = num_common_dci;
LOG_D(PHY,"[eNB %d][DCI][EMUL] CC id %d: num spec dci %d num comm dci %d num PMCH %d \n",
phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, num_ue_spec_dci,num_common_dci,
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_pmch);
if (eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].cntl.pmch_flag == 1 )
n_dci_dl = eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_pmch;
else
n_dci_dl = 0;
for (n_dci =0 ;
n_dci < (eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_ue_spec_dci+ eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_common_dci);
n_dci++) {
if (dci_alloc[n_dci].format > 0) { // exclude the uplink dci
if (dci_alloc[n_dci].rnti == SI_RNTI) {
dlsch_eNB = PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]->dlsch_SI;
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dlsch_type[n_dci_dl] = 0;//SI;
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl] = 0;
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl] = dlsch_eNB->harq_processes[0]->TBS>>3;
LOG_D(PHY,"[DCI][EMUL]SI tbs is %d and dci index %d harq pid is %d \n",eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl],n_dci_dl,
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl]);
} else if (dci_alloc[n_dci_dl].ra_flag == 1) {
dlsch_eNB = PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]->dlsch_ra;
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dlsch_type[n_dci_dl] = 1;//RA;
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl] = 0;
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl] = dlsch_eNB->harq_processes[0]->TBS>>3;
LOG_D(PHY,"[DCI][EMUL] RA tbs is %d and dci index %d harq pid is %d \n",eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl],n_dci_dl,
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl]);
} else {
ue_id = find_ue(dci_alloc[n_dci_dl].rnti,PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]);
DevAssert( ue_id != (uint8_t)-1 );
dlsch_eNB = PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]->dlsch[ue_id][0];
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dlsch_type[n_dci_dl] = 2;//TB0;
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl] = dlsch_eNB->current_harq_pid;
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].ue_id[n_dci_dl] = ue_id;
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl] = dlsch_eNB->harq_processes[dlsch_eNB->current_harq_pid]->TBS>>3;
LOG_D(PHY,"[DCI][EMUL] TB1 tbs is %d and dci index %d harq pid is %d \n",eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl],n_dci_dl,
eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl]);
// check for TB1 later
}
}
n_dci_dl++;
}
memcpy((void *)&eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dci_alloc,
(void *)dci_alloc,
n_dci*sizeof(DCI_ALLOC_t));
return(num_pdcch_symbols);
}
#endif
//static uint8_t dci_decoded_output[RX_NB_TH][(MAX_DCI_SIZE_BITS+64)/8];
/*uint16_t get_nCCE(uint8_t num_pdcch_symbols,NR_DL_FRAME_PARMS *frame_parms,uint8_t mi)
{
return(get_nquad(num_pdcch_symbols,frame_parms,mi)/9);
}
uint16_t get_nquad(uint8_t num_pdcch_symbols,NR_DL_FRAME_PARMS *frame_parms,uint8_t mi)
{
uint16_t Nreg=0;
uint8_t Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48;
if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0)
Ngroup_PHICH++;
if (frame_parms->Ncp == 1) {
Ngroup_PHICH<<=1;
}
Ngroup_PHICH*=mi;
if ((num_pdcch_symbols>0) && (num_pdcch_symbols<4))
switch (frame_parms->N_RB_DL) {
case 6:
Nreg=12+(num_pdcch_symbols-1)*18;
break;
case 25:
Nreg=50+(num_pdcch_symbols-1)*75;
break;
case 50:
Nreg=100+(num_pdcch_symbols-1)*150;
break;
case 100:
Nreg=200+(num_pdcch_symbols-1)*300;
break;
default:
return(0);
}
// printf("Nreg %d (%d)\n",Nreg,Nreg - 4 - (3*Ngroup_PHICH));
return(Nreg - 4 - (3*Ngroup_PHICH));
}
uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int nr_tti_rx)
{
// check for eNB only !
return(get_nCCE(num_pdcch_symbols,
&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,
get_mi(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,nr_tti_rx)));
}
*/
int get_nCCE_offset_l1(int *CCE_table,
const unsigned char L,
const int nCCE,
const int common_dci,
const unsigned short rnti,
const unsigned char nr_tti_rx)
{
int search_space_free,m,nb_candidates = 0,l,i;
unsigned int Yk;
/*
printf("CCE Allocation: ");
for (i=0;i<nCCE;i++)
printf("%d.",CCE_table[i]);
printf("\n");
*/
if (common_dci == 1) {
// check CCE(0 ... L-1)
nb_candidates = (L==4) ? 4 : 2;
nb_candidates = min(nb_candidates,nCCE/L);
// printf("Common DCI nb_candidates %d, L %d\n",nb_candidates,L);
for (m = nb_candidates-1 ; m >=0 ; m--) {
search_space_free = 1;
for (l=0; l<L; l++) {
// printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]);
if (CCE_table[(m*L) + l] == 1) {
search_space_free = 0;
break;
}
}
if (search_space_free == 1) {
// printf("returning %d\n",m*L);
for (l=0; l<L; l++)
CCE_table[(m*L)+l]=1;
return(m*L);
}
}
return(-1);
} else { // Find first available in ue specific search space
// according to procedure in Section 9.1.1 of 36.213 (v. 8.6)
// compute Yk
Yk = (unsigned int)rnti;
for (i=0; i<=nr_tti_rx; i++)
Yk = (Yk*39827)%65537;
Yk = Yk % (nCCE/L);
switch (L) {
case 1:
case 2:
nb_candidates = 6;
break;
case 4:
case 8:
nb_candidates = 2;
break;
default:
DevParam(L, nCCE, rnti);
break;
}
LOG_D(MAC,"rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n",rnti,Yk,nCCE,nCCE/L,nb_candidates);
for (m = 0 ; m < nb_candidates ; m++) {
search_space_free = 1;
for (l=0; l<L; l++) {
int cce = (((Yk+m)%(nCCE/L))*L) + l;
if (cce >= nCCE || CCE_table[cce] == 1) {
search_space_free = 0;
break;
}
}
if (search_space_free == 1) {
for (l=0; l<L; l++)
CCE_table[(((Yk+m)%(nCCE/L))*L)+l]=1;
return(((Yk+m)%(nCCE/L))*L);
}
}
return(-1);
}
}
#ifdef NR_PDCCH_DCI_RUN #ifdef NR_PDCCH_DCI_RUN
void nr_dci_decoding_procedure0(int s, void nr_dci_decoding_procedure0(int s,
int p, int p,
...@@ -4022,32 +3049,4 @@ uint8_t nr_dci_decoding_procedure(int s, ...@@ -4022,32 +3049,4 @@ uint8_t nr_dci_decoding_procedure(int s,
#endif #endif
#ifdef PHY_ABSTRACTION
uint16_t dci_decoding_procedure_emul(NR_UE_PDCCH **pdcch_vars,
uint8_t num_ue_spec_dci,
uint8_t num_common_dci,
DCI_ALLOC_t *dci_alloc_tx,
DCI_ALLOC_t *dci_alloc_rx,
int16_t eNB_id)
{
uint8_t dci_cnt=0,i;
memcpy(dci_alloc_rx,dci_alloc_tx,num_common_dci*sizeof(DCI_ALLOC_t));
dci_cnt = num_common_dci;
LOG_D(PHY,"[DCI][EMUL] : num_common_dci %d\n",num_common_dci);
for (i=num_common_dci; i<(num_ue_spec_dci+num_common_dci); i++) {
LOG_D(PHY,"[DCI][EMUL] Checking dci %d => %x format %d (bit 0 %d)\n",i,pdcch_vars[eNB_id]->crnti,dci_alloc_tx[i].format,
dci_alloc_tx[i].dci_pdu[0]&0x80);
if (dci_alloc_tx[i].rnti == pdcch_vars[eNB_id]->crnti) {
memcpy(dci_alloc_rx+dci_cnt,dci_alloc_tx+i,sizeof(DCI_ALLOC_t));
dci_cnt++;
}
}
return(dci_cnt);
}
#endif
...@@ -53,7 +53,6 @@ int cnt=0; ...@@ -53,7 +53,6 @@ int cnt=0;
int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode) int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode)
{ {
printf("nr pbch detec RB_DL %d\n", ue->frame_parms.N_RB_DL);
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
int ret =-1; int ret =-1;
...@@ -62,53 +61,54 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -62,53 +61,54 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode)
ue->rx_offset); ue->rx_offset);
#endif #endif
// save the nb_prefix_samples0 since we are not synchronized to subframes yet and the SSB has all symbols with nb_prefix_samples
int nb_prefix_samples0 = frame_parms->nb_prefix_samples0; int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
frame_parms->nb_prefix_samples0 = 0; frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples;
//symbol 1 //symbol 1
nr_slot_fep(ue, nr_slot_fep(ue,
5, 1,
0, 0,
ue->rx_offset, ue->ssb_offset,
0, 0,
1, 1,
NR_PBCH_EST); NR_PBCH_EST);
//symbol 2 //symbol 2
nr_slot_fep(ue, nr_slot_fep(ue,
6, 2,
0, 0,
ue->rx_offset, ue->ssb_offset,
0, 0,
1, 1,
NR_PBCH_EST); NR_PBCH_EST);
//symbol 3 //symbol 3
nr_slot_fep(ue, nr_slot_fep(ue,
7, 3,
0, 0,
ue->rx_offset, ue->ssb_offset,
0, 0,
1, 1,
NR_PBCH_EST); NR_PBCH_EST);
//put back nb_prefix_samples0
frame_parms->nb_prefix_samples0 = nb_prefix_samples0; frame_parms->nb_prefix_samples0 = nb_prefix_samples0;
printf("pbch_detection nid_cell %d\n",frame_parms->Nid_cell);
ret = nr_rx_pbch(ue,
&ue->proc.proc_rxtx[0], ret = nr_rx_pbch(ue,
ue->pbch_vars[0], &ue->proc.proc_rxtx[0],
frame_parms, ue->pbch_vars[0],
0, frame_parms,
SISO, 0,
ue->high_speed_flag); SISO,
ue->high_speed_flag);
if (ret==0) { if (ret==0) {
frame_parms->nb_antenna_ports_eNB = 1; //pbch_tx_ant; frame_parms->nb_antenna_ports_eNB = 1; //pbch_tx_ant;
// set initial transmission mode to 1 or 2 depending on number of detected TX antennas // set initial transmission mode to 1 or 2 depending on number of detected TX antennas
//frame_parms->mode1_flag = (pbch_tx_ant==1); //frame_parms->mode1_flag = (pbch_tx_ant==1);
// openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1; // openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1;
...@@ -145,29 +145,22 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -145,29 +145,22 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
{ {
int32_t sync_pos, sync_pos2, sync_pos_slot; // k_ssb, N_ssb_crb, int32_t sync_pos, sync_pos2, sync_pos_slot; // k_ssb, N_ssb_crb,
int32_t metric_fdd_ncp=0; int32_t metric_tdd_ncp=0;
uint8_t phase_fdd_ncp; uint8_t phase_tdd_ncp;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
int ret=-1; int ret=-1;
int rx_power=0; //aarx, int rx_power=0; //aarx,
//nfapi_nr_config_request_t* config; //nfapi_nr_config_request_t* config;
/*offset parameters to be updated from higher layer */ int n_ssb_crb=(fp->N_RB_DL-20)>>1;
//k_ssb =0; // First try TDD normal prefix, mu 1
//N_ssb_crb = 0; fp->Ncp=NORMAL;
fp->frame_type=TDD;
/*#ifdef OAI_USRP nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0);
__m128i *rxdata128; LOG_D(PHY,"nr_initial sync ue RB_DL %d\n", fp->N_RB_DL);
#endif*/
// LOG_I(PHY,"**************************************************************\n");
// First try FDD normal prefix
frame_parms->Ncp=NORMAL;
frame_parms->frame_type=TDD;
nr_init_frame_parms_ue(frame_parms);
LOG_D(PHY,"nr_initial sync ue RB_DL %d\n", ue->frame_parms.N_RB_DL);
/* /*
write_output("rxdata0.m","rxd0",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1); write_output("rxdata0.m","rxd0",ue->common_vars.rxdata[0],10*fp->samples_per_tti,1,1);
exit(-1); exit(-1);
*/ */
...@@ -183,56 +176,51 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -183,56 +176,51 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
* -------------------------- * --------------------------
* sync_pos SS/PBCH block * sync_pos SS/PBCH block
*/ */
cnt++; cnt++;
if (1){ if (1){ // (cnt>100)
cnt =0; cnt =0;
/* process pss search on received buffer */ /* process pss search on received buffer */
sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE); sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE);
sync_pos_slot = (frame_parms->samples_per_tti>>1) - 3*(frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
if (sync_pos >= fp->nb_prefix_samples)
sync_pos = sync_pos_slot+frame_parms->nb_prefix_samples; ue->ssb_offset = sync_pos - fp->nb_prefix_samples;
else
if (sync_pos >= frame_parms->nb_prefix_samples) ue->ssb_offset = sync_pos + (fp->samples_per_tti * 10) - fp->nb_prefix_samples;
sync_pos2 = sync_pos - frame_parms->nb_prefix_samples;
else LOG_D(PHY,"sync_pos %d ssb_offset %d\n",sync_pos,ue->ssb_offset);
sync_pos2 = sync_pos + FRAME_LENGTH_COMPLEX_SAMPLES - frame_parms->nb_prefix_samples;
/* offset is used by sss serach as it is returned from pss search */
if (sync_pos2 >= sync_pos_slot)
ue->rx_offset = sync_pos2 - sync_pos_slot;
else
ue->rx_offset = FRAME_LENGTH_COMPLEX_SAMPLES + sync_pos2 - sync_pos_slot;
LOG_D(PHY,"sync_pos %d sync_pos_slot %d rx_offset %d\n",sync_pos,sync_pos_slot, ue->rx_offset);
// write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1); // write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*fp->samples_per_tti,1,1);
#ifdef DEBUG_INITIAL_SYNCH #ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos,ue->common_vars.eNb_id); LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos,ue->common_vars.eNb_id);
#endif #endif
/* check that SSS/PBCH block is continuous inside the received buffer */ /* check that SSS/PBCH block is continuous inside the received buffer */
if (sync_pos < (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->ttis_per_subframe*frame_parms->samples_per_tti - (NB_SYMBOLS_PBCH * frame_parms->ofdm_symbol_size))) { if (sync_pos < (10*fp->ttis_per_subframe*fp->samples_per_tti - (NB_SYMBOLS_PBCH * fp->ofdm_symbol_size))) {
#ifdef DEBUG_INITIAL_SYNCH #ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"Calling sss detection (normal CP)\n"); LOG_I(PHY,"Calling sss detection (normal CP)\n");
#endif #endif
rx_sss_nr(ue,&metric_fdd_ncp,&phase_fdd_ncp); rx_sss_nr(ue,&metric_tdd_ncp,&phase_tdd_ncp);
nr_init_frame_parms_ue(&ue->frame_parms); nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0);
nr_gold_pbch(ue); nr_gold_pbch(ue);
ret = nr_pbch_detection(ue,mode); ret = nr_pbch_detection(ue,mode);
nr_gold_pdcch(ue,0, 2); nr_gold_pdcch(ue,0, 2);
/*
int nb_prefix_samples0 = frame_parms->nb_prefix_samples0; int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
frame_parms->nb_prefix_samples0 = 0; frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples.
nr_slot_fep(ue,0, 0, ue->rx_offset, 0, 1, NR_PDCCH_EST); nr_slot_fep(ue,0, 0, ue->ssb_offset, 0, 1, NR_PDCCH_EST);
nr_slot_fep(ue,1, 0, ue->rx_offset, 0, 1, NR_PDCCH_EST); nr_slot_fep(ue,1, 0, ue->ssb_offset, 0, 1, NR_PDCCH_EST);
frame_parms->nb_prefix_samples0 = nb_prefix_samples0; frame_parms->nb_prefix_samples0 = nb_prefix_samples0;
LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n", LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
...@@ -240,18 +228,16 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -240,18 +228,16 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
ue->proc.proc_rxtx[0].frame_rx, ue->proc.proc_rxtx[0].frame_rx,
ue->rx_offset, ue->rx_offset,
ue->common_vars.freq_offset ); ue->common_vars.freq_offset );
*/
//ret = -1; //to be deleted
// write_output("rxdata2.m","rxd2",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
#ifdef DEBUG_INITIAL_SYNCH #ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"FDD Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n", LOG_I(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
frame_parms->Nid_cell,metric_fdd_ncp,phase_fdd_ncp,flip_fdd_ncp,ret); frame_parms->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,flip_tdd_ncp,ret);
#endif #endif
} }
else { else {
#ifdef DEBUG_INITIAL_SYNCH #ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"FDD Normal prefix: SSS error condition: sync_pos %d, sync_pos_slot %d\n", sync_pos, sync_pos_slot); LOG_I(PHY,"TDD Normal prefix: SSS error condition: sync_pos %d, sync_pos_slot %d\n", sync_pos, sync_pos_slot);
#endif #endif
} }
} }
...@@ -291,17 +277,6 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -291,17 +277,6 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
#endif #endif
// send sync status to higher layers later when timing offset converge to target timing // send sync status to higher layers later when timing offset converge to target timing
#if OAISIM
if (ue->mac_enabled==1) {
LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
//mac_resynch();
mac_xface->dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id);
ue->UE_mode[0] = PRACH;
}
else {
ue->UE_mode[0] = PUSCH;
}
#endif
ue->pbch_vars[0]->pdu_errors_conseq=0; ue->pbch_vars[0]->pdu_errors_conseq=0;
...@@ -321,13 +296,13 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -321,13 +296,13 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
printf("[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n", printf("[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n",
ue->Mod_id, ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx, ue->proc.proc_rxtx[0].frame_rx,
duplex_string[ue->frame_parms.frame_type], duplex_string[fp->frame_type],
prefix_string[ue->frame_parms.Ncp], prefix_string[fp->Ncp],
ue->frame_parms.Nid_cell, fp->Nid_cell,
ue->frame_parms.N_RB_DL, fp->N_RB_DL,
ue->frame_parms.phich_config_common.phich_duration, fp->phich_config_common.phich_duration,
phich_string[ue->frame_parms.phich_config_common.phich_resource], phich_string[fp->phich_config_common.phich_resource],
ue->frame_parms.nb_antenna_ports_eNB); fp->nb_antenna_ports_eNB);
#else #else
LOG_I(PHY, "[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id, LOG_I(PHY, "[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx, ue->proc.proc_rxtx[0].frame_rx,
...@@ -341,13 +316,13 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -341,13 +316,13 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
/* LOG_I(PHY, "[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n", /* LOG_I(PHY, "[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n",
ue->Mod_id, ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx, ue->proc.proc_rxtx[0].frame_rx,
duplex_string[ue->frame_parms.frame_type], duplex_string[fp->frame_type],
prefix_string[ue->frame_parms.Ncp], prefix_string[fp->Ncp],
ue->frame_parms.Nid_cell, fp->Nid_cell,
ue->frame_parms.N_RB_DL, fp->N_RB_DL,
ue->frame_parms.phich_config_common.phich_duration, fp->phich_config_common.phich_duration,
phich_string[ue->frame_parms.phich_config_common.phich_resource], phich_string[fp->phich_config_common.phich_resource],
ue->frame_parms.nb_antenna_ports_eNB);*/ fp->nb_antenna_ports_eNB);*/
#endif #endif
#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) #if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
...@@ -369,12 +344,6 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -369,12 +344,6 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
#ifdef DEBUG_INITIAL_SYNC #ifdef DEBUG_INITIAL_SYNC
LOG_I(PHY,"[UE%d] Initial sync : PBCH not ok\n",ue->Mod_id); LOG_I(PHY,"[UE%d] Initial sync : PBCH not ok\n",ue->Mod_id);
LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n",ue->Mod_id,sync_pos,ue->common_vars.eNb_id); LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n",ue->Mod_id,sync_pos,ue->common_vars.eNb_id);
/* LOG_I(PHY,"[UE%d] Initial sync: (metric fdd_ncp %d (%d), metric fdd_ecp %d (%d), metric_tdd_ncp %d (%d), metric_tdd_ecp %d (%d))\n",
ue->Mod_id,
metric_fdd_ncp,Nid_cell_fdd_ncp,
metric_fdd_ecp,Nid_cell_fdd_ecp,
metric_tdd_ncp,Nid_cell_tdd_ncp,
metric_tdd_ecp,Nid_cell_tdd_ecp);*/
LOG_I(PHY,"[UE%d] Initial sync : Estimated Nid_cell %d, Frame_type %d\n",ue->Mod_id, LOG_I(PHY,"[UE%d] Initial sync : Estimated Nid_cell %d, Frame_type %d\n",ue->Mod_id,
frame_parms->Nid_cell,frame_parms->frame_type); frame_parms->Nid_cell,frame_parms->frame_type);
#endif #endif
...@@ -403,7 +372,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -403,7 +372,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
*/ */
// we might add a low-pass filter here later // we might add a low-pass filter here later
ue->measurements.rx_power_avg[0] = rx_power/frame_parms->nb_antennas_rx; ue->measurements.rx_power_avg[0] = rx_power/fp->nb_antennas_rx;
ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]); ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]);
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include "PHY/sse_intrin.h" #include "PHY/sse_intrin.h"
#include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/LTE_REFSIG/lte_refsig.h"
#define DEBUG_PBCH 1 //#define DEBUG_PBCH 1
//#define DEBUG_PBCH_ENCODING //#define DEBUG_PBCH_ENCODING
#ifdef OPENAIR2 #ifdef OPENAIR2
...@@ -44,31 +44,42 @@ ...@@ -44,31 +44,42 @@
#define PBCH_A 24 #define PBCH_A 24
#define print_shorts(s,x) printf("%s : %d,%d,%d,%d,%d,%d,%d,%d\n",s,((int16_t*)x)[0],((int16_t*)x)[1],((int16_t*)x)[2],((int16_t*)x)[3],((int16_t*)x)[4],((int16_t*)x)[5],((int16_t*)x)[6],((int16_t*)x)[7])
uint16_t nr_pbch_extract(int **rxdataF, uint16_t nr_pbch_extract(int **rxdataF,
int **dl_ch_estimates, int **dl_ch_estimates,
int **rxdataF_ext, int **rxdataF_ext,
int **dl_ch_estimates_ext, int **dl_ch_estimates_ext,
uint32_t symbol, uint32_t symbol,
uint32_t high_speed_flag, uint32_t high_speed_flag,
NR_DL_FRAME_PARMS *frame_parms) int is_synchronized,
NR_DL_FRAME_PARMS *frame_parms)
{ {
uint16_t rb; uint16_t rb;
uint8_t i,j,aarx,aatx; uint8_t i,j,aarx;
int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
int rx_offset = frame_parms->ofdm_symbol_size-10*12;
int nushiftmod4 = frame_parms->nushift; int nushiftmod4 = frame_parms->nushift;
unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; //and
if (rx_offset>= frame_parms->ofdm_symbol_size) rx_offset-=frame_parms->ofdm_symbol_size;
int s_offset=0;
AssertFatal(symbol>=1 && symbol<5,
"symbol %d illegal for PBCH extraction\n",
symbol);
if (is_synchronized==1) s_offset=4;
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
rxF = &rxdataF[aarx][(rx_offset + (symbol*(frame_parms->ofdm_symbol_size)))]; rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size];
rxF_ext = &rxdataF_ext[aarx][symbol*(20*12)]; rxF_ext = &rxdataF_ext[aarx][(symbol+s_offset)*(20*12)];
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
printf("extract_rbs (nushift %d): rx_offset=%d, symbol %d\n",frame_parms->nushift, printf("extract_rbs (nushift %d): rx_offset=%d, symbol %d\n",frame_parms->nushift,
(rx_offset + (symbol*(frame_parms->ofdm_symbol_size))),symbol); (rx_offset + ((symbol+s_offset)*(frame_parms->ofdm_symbol_size))),symbol);
int16_t *p = (int16_t *)rxF; int16_t *p = (int16_t *)rxF;
for (int i =0; i<8;i++){ for (int i =0; i<8;i++){
printf("rxF [%d]= %d\n",i,rxF[i]); printf("rxF [%d]= %d\n",i,rxF[i]);
...@@ -78,89 +89,109 @@ uint16_t nr_pbch_extract(int **rxdataF, ...@@ -78,89 +89,109 @@ uint16_t nr_pbch_extract(int **rxdataF,
#endif #endif
for (rb=0; rb<20; rb++) { for (rb=0; rb<20; rb++) {
if (rb==10) {
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
}
j=0; j=0;
if ((symbol==5) || (symbol==7)) {
if (symbol==1 || symbol==7) {
for (i=0; i<12; i++) { for (i=0; i<12; i++) {
if ((i!=nushiftmod4) && if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) && (i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) { (i!=(nushiftmod4+8))) {
rxF_ext[j]=rxF[i]; rxF_ext[j]=rxF[rx_offset];
//printf("rxF ext[%d] = %d rxF [%d]= %d\n",j,rxF_ext[j],i,rxF[i]); #ifdef DEBUG_PBCH
printf("rxF ext[%d] = (%d,%d) rxF [%d]= (%d,%d)\n",(9*rb) + j,
((int16_t*)&rxF_ext[j])[0],
((int16_t*)&rxF_ext[j])[1],
rx_offset,
((int16_t*)&rxF[rx_offset])[0],
((int16_t*)&rxF[rx_offset])[1]);
#endif
j++; j++;
} }
rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1);
} }
rxF+=12;
rxF_ext+=9; rxF_ext+=9;
} else { //symbol 2 } else { //symbol 2
if ((rb < 4) || (rb >15)){ if ((rb < 4) || (rb >15)){
for (i=0; i<12; i++) { for (i=0; i<12; i++) {
if ((i!=nushiftmod4) && if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) && (i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) { (i!=(nushiftmod4+8))) {
rxF_ext[j]=rxF[i]; rxF_ext[j]=rxF[rx_offset];
//printf("symbol2 rxF ext[%d] = %d at %p\n",j,rxF_ext[j],&rxF[i]); #ifdef DEBUG_PBCH
j++; printf("rxF ext[%d] = (%d,%d) rxF [%d]= (%d,%d)\n",(rb<4) ? (9*rb) + j : (9*(rb-12))+j,
} ((int16_t*)&rxF_ext[j])[0],
((int16_t*)&rxF_ext[j])[1],
rx_offset,
((int16_t*)&rxF[rx_offset])[0],
((int16_t*)&rxF[rx_offset])[1]);
#endif
j++;
}
rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1);
} }
rxF_ext+=9;
} }
else rx_offset = (rx_offset+12)&(frame_parms->ofdm_symbol_size-1);
rxF+=12;
rxF_ext+=9;
} }
} }
for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB;aatx++) { if (high_speed_flag == 1)
if (high_speed_flag == 1) dl_ch0 = &dl_ch_estimates[aarx][((symbol+s_offset)*(frame_parms->ofdm_symbol_size))];
dl_ch0 = &dl_ch_estimates[(aatx<<1)+aarx][(symbol*(frame_parms->ofdm_symbol_size))]; else
else dl_ch0 = &dl_ch_estimates[aarx][0];
dl_ch0 = &dl_ch_estimates[(aatx<<1)+aarx][0];
//printf("dl_ch0 addr %p\n",dl_ch0);
//printf("dl_ch0 addr %p\n",dl_ch0);
dl_ch0_ext = &dl_ch_estimates_ext[aarx][(symbol+s_offset)*(20*12)];
dl_ch0_ext = &dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*(20*12)];
for (rb=0; rb<20; rb++) {
for (rb=0; rb<20; rb++) { j=0;
j=0; if (symbol==1 || symbol==7) {
if ((symbol==5) || (symbol==7)) { for (i=0; i<12; i++) {
for (i=0; i<12; i++) { if ((i!=nushiftmod4) &&
if ((i!=nushiftmod4) && (i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+4)) && (i!=(nushiftmod4+8))) {
(i!=(nushiftmod4+8))) { dl_ch0_ext[j]=dl_ch0[i];
dl_ch0_ext[j]=dl_ch0[i]; #ifdef DEBUG_PBCH
if ((rb==0) && (i<2)) if ((rb==0) && (i<2))
printf("dl ch0 ext[%d] = %d dl_ch0 [%d]= %d\n",j,dl_ch0_ext[j],i,dl_ch0[i]); printf("dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n",j,
j++; ((int16_t*)&dl_ch0_ext[j])[0],
} ((int16_t*)&dl_ch0_ext[j])[1],
} i,
((int16_t*)&dl_ch0[i])[0],
dl_ch0+=12; ((int16_t*)&dl_ch0[i])[1]);
dl_ch0_ext+=9; #endif
} j++;
else { }
if ((rb < 4) || (rb >15)){ }
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) && dl_ch0+=12;
(i!=(nushiftmod4+4)) && dl_ch0_ext+=9;
(i!=(nushiftmod4+8))) {
dl_ch0_ext[j]=dl_ch0[i];
//printf("symbol2 dl ch0 ext[%d] = %d dl_ch0 [%d]= %d\n",j,dl_ch0_ext[j],i,dl_ch0[i]);
j++;
}
}
}
dl_ch0+=12;
dl_ch0_ext+=9;
}
} }
} //tx antenna loop else {
if ((rb < 4) || (rb >15)){
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) {
dl_ch0_ext[j]=dl_ch0[i];
#ifdef DEBUG_PBCH
printf("dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n",j,
((int16_t*)&dl_ch0_ext[j])[0],
((int16_t*)&dl_ch0_ext[j])[1],
i,
((int16_t*)&dl_ch0[i])[0],
((int16_t*)&dl_ch0[i])[1]);
#endif
j++;
}
}
dl_ch0_ext+=9;
}
dl_ch0+=12;
}
}
} }
return(0); return(0);
...@@ -170,12 +201,12 @@ uint16_t nr_pbch_extract(int **rxdataF, ...@@ -170,12 +201,12 @@ uint16_t nr_pbch_extract(int **rxdataF,
//compute average channel_level on each (TX,RX) antenna pair //compute average channel_level on each (TX,RX) antenna pair
int nr_pbch_channel_level(int **dl_ch_estimates_ext, int nr_pbch_channel_level(int **dl_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint32_t symbol) uint32_t symbol)
{ {
int16_t rb, nb_rb=20; int16_t rb, nb_rb=20;
uint8_t aatx,aarx; uint8_t aarx;
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
__m128i avg128; __m128i avg128;
...@@ -186,46 +217,45 @@ int nr_pbch_channel_level(int **dl_ch_estimates_ext, ...@@ -186,46 +217,45 @@ int nr_pbch_channel_level(int **dl_ch_estimates_ext,
#endif #endif
int avg1=0,avg2=0; int avg1=0,avg2=0;
for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB;aatx++) for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { //clear average level
//clear average level
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_setzero_si128(); avg128 = _mm_setzero_si128();
dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*20*12]; dl_ch128=(__m128i *)&dl_ch_estimates_ext[aarx][symbol*20*12];
#elif defined(__arm__) #elif defined(__arm__)
avg128 = vdupq_n_s32(0); avg128 = vdupq_n_s32(0);
dl_ch128=(int16x8_t *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*20*12]; dl_ch128=(int16x8_t *)&dl_ch_estimates_ext[aarx][symbol*20*12];
#endif #endif
for (rb=0; rb<nb_rb; rb++) { for (rb=0; rb<nb_rb; rb++) {
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[1],dl_ch128[1])); avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[1],dl_ch128[1]));
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[2],dl_ch128[2])); avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
#elif defined(__arm__) #elif defined(__arm__)
// to be filled in // to be filled in
#endif #endif
dl_ch128+=3; dl_ch128+=3;
/* /*
if (rb==0) { if (rb==0) {
print_shorts("dl_ch128",&dl_ch128[0]); print_shorts("dl_ch128",&dl_ch128[0]);
print_shorts("dl_ch128",&dl_ch128[1]); print_shorts("dl_ch128",&dl_ch128[1]);
print_shorts("dl_ch128",&dl_ch128[2]); print_shorts("dl_ch128",&dl_ch128[2]);
} }*/
*/
}
avg1 = (((int*)&avg128)[0] +
((int*)&avg128)[1] +
((int*)&avg128)[2] +
((int*)&avg128)[3])/(nb_rb*12);
if (avg1>avg2)
avg2 = avg1;
//msg("Channel level : %d, %d\n",avg1, avg2);
} }
avg1 = (((int*)&avg128)[0] +
((int*)&avg128)[1] +
((int*)&avg128)[2] +
((int*)&avg128)[3])/(nb_rb*12);
if (avg1>avg2)
avg2 = avg1;
//LOG_I(PHY,"Channel level : %d, %d\n",avg1, avg2);
}
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
_mm_empty(); _mm_empty();
_m_empty(); _m_empty();
...@@ -234,114 +264,127 @@ int nr_pbch_channel_level(int **dl_ch_estimates_ext, ...@@ -234,114 +264,127 @@ int nr_pbch_channel_level(int **dl_ch_estimates_ext,
} }
#if defined(__x86_64__) || defined(__i386__)
__m128i mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#elif defined(__arm__)
int16x8_t mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#endif
void nr_pbch_channel_compensation(int **rxdataF_ext, void nr_pbch_channel_compensation(int **rxdataF_ext,
int **dl_ch_estimates_ext, int **dl_ch_estimates_ext,
int **rxdataF_comp, int **rxdataF_comp,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint8_t symbol, uint8_t symbol,
uint8_t output_shift) int is_synchronized,
uint8_t output_shift)
{ {
short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1}; short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1}; short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
#if defined(__x86_64__) || defined(__i386__)
__m128i mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#elif defined(__arm__)
int16x8_t mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#endif
uint16_t rb,nb_rb=20; uint16_t nb_re=180;
uint8_t aatx,aarx; uint8_t aarx;
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
__m128i *dl_ch128,*rxdataF128,*rxdataF_comp128; __m128i *dl_ch128,*rxdataF128,*rxdataF_comp128;
#elif defined(__arm__) #elif defined(__arm__)
#endif #endif
for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB;aatx++) AssertFatal((symbol > 0 && symbol < 4 && is_synchronized == 0) ||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { (symbol > 4 && symbol < 8 && is_synchronized == 1),
"symbol %d is illegal for PBCH DM-RS (is_synchronized %d)\n",
symbol,is_synchronized);
#if defined(__x86_64__) || defined(__i386__)
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*20*12];
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*20*12];
rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*20*12];
//printf("ch compensation dl_ch ext addr %p \n", &dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*20*12]);
//printf("rxdataf ext addr %p symbol %d\n", &rxdataF_ext[aarx][symbol*20*12], symbol);
//printf("rxdataf_comp addr %p\n",&rxdataF_comp[(aatx<<1)+aarx][symbol*20*12]);
if (symbol == 2 || symbol == 6) nb_re = 72;
// printf("comp: symbol %d : nb_re %d\n",symbol,nb_re);
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
#if defined(__x86_64__) || defined(__i386__)
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*20*12];
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*20*12];
rxdataF_comp128 = (__m128i *)&rxdataF_comp[aarx][symbol*20*12];
/*
printf("ch compensation dl_ch ext addr %p \n", &dl_ch_estimates_ext[aarx][symbol*20*12]);
printf("rxdataf ext addr %p symbol %d\n", &rxdataF_ext[aarx][symbol*20*12], symbol);
printf("rxdataf_comp addr %p\n",&rxdataF_comp[aarx][symbol*20*12]);
*/
#elif defined(__arm__) #elif defined(__arm__)
// to be filled in // to be filled in
#endif #endif
for (rb=0; rb<nb_rb; rb++) { for (int re=0; re<nb_re; re+=12) {
//printf("rb %d\n",rb); // printf("******re %d\n",re);
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
// multiply by conjugated channel // multiply by conjugated channel
mmtmpP0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); mmtmpP0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]);
// print_ints("re",&mmtmpP0); // print_ints("re",&mmtmpP0);
// mmtmpP0 contains real part of 4 consecutive outputs (32-bit) // mmtmpP0 contains real part of 4 consecutive outputs (32-bit)
mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1)); mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]); mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]);
// print_ints("im",&mmtmpP1); // print_ints("im",&mmtmpP1);
mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[0]); mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[0]);
// mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift); mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift);
// print_ints("re(shift)",&mmtmpP0); // print_ints("re(shift)",&mmtmpP0);
mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift); mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift);
// print_ints("im(shift)",&mmtmpP1); // print_ints("im(shift)",&mmtmpP1);
mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1); mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1);
mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1); mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1);
// print_ints("c0",&mmtmpP2); // print_ints("c0",&mmtmpP2);
// print_ints("c1",&mmtmpP3); // print_ints("c1",&mmtmpP3);
rxdataF_comp128[0] = _mm_packs_epi32(mmtmpP2,mmtmpP3); rxdataF_comp128[0] = _mm_packs_epi32(mmtmpP2,mmtmpP3);
// print_shorts("rx:",rxdataF128); /*
// print_shorts("ch:",dl_ch128); print_shorts("rx:",rxdataF128);
// print_shorts("pack:",rxdataF_comp128); print_shorts("ch:",dl_ch128);
print_shorts("pack:",rxdataF_comp128);
// multiply by conjugated channel */
mmtmpP0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); // multiply by conjugated channel
// mmtmpP0 contains real part of 4 consecutive outputs (32-bit) mmtmpP0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]);
mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); // mmtmpP0 contains real part of 4 consecutive outputs (32-bit)
mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1)); mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]); mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[1]); mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]);
// mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[1]);
mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift); // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift); mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift);
mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1); mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift);
mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1); mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1);
rxdataF_comp128[1] = _mm_packs_epi32(mmtmpP2,mmtmpP3); mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1);
// print_shorts("rx:",rxdataF128+1); rxdataF_comp128[1] = _mm_packs_epi32(mmtmpP2,mmtmpP3);
// print_shorts("ch:",dl_ch128+1); // print_shorts("rx:",rxdataF128+1);
// print_shorts("pack:",rxdataF_comp128+1); // print_shorts("ch:",dl_ch128+1);
// print_shorts("pack:",rxdataF_comp128+1);
// multiply by conjugated channel
mmtmpP0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); // multiply by conjugated channel
// mmtmpP0 contains real part of 4 consecutive outputs (32-bit) mmtmpP0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); // mmtmpP0 contains real part of 4 consecutive outputs (32-bit)
mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1)); mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]); mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[2]); mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]);
// mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[2]);
mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift); // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift); mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift);
mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1); mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift);
mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1); mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1);
rxdataF_comp128[2] = _mm_packs_epi32(mmtmpP2,mmtmpP3); mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1);
// print_shorts("rx:",rxdataF128+2); rxdataF_comp128[2] = _mm_packs_epi32(mmtmpP2,mmtmpP3);
// print_shorts("ch:",dl_ch128+2); // print_shorts("rx:",rxdataF128+2);
// print_shorts("pack:",rxdataF_comp128+2); // print_shorts("ch:",dl_ch128+2);
// print_shorts("pack:",rxdataF_comp128+2);
dl_ch128+=3;
rxdataF128+=3; dl_ch128+=3;
rxdataF_comp128+=3; rxdataF128+=3;
rxdataF_comp128+=3;
#elif defined(__arm__) #elif defined(__arm__)
// to be filled in // to be filled in
#endif #endif
}
} }
}
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
_mm_empty(); _mm_empty();
_m_empty(); _m_empty();
...@@ -353,7 +396,7 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, ...@@ -353,7 +396,7 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
uint8_t symbol) uint8_t symbol)
{ {
uint8_t aatx, symbol_mod; uint8_t symbol_mod;
int i, nb_rb=6; int i, nb_rb=6;
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
__m128i *rxdataF_comp128_0,*rxdataF_comp128_1; __m128i *rxdataF_comp128_0,*rxdataF_comp128_1;
...@@ -363,13 +406,12 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, ...@@ -363,13 +406,12 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
if (frame_parms->nb_antennas_rx>1) { if (frame_parms->nb_antennas_rx>1) {
for (aatx=0; aatx<4; aatx++) { //frame_parms->nb_antenna_ports_eNB;aatx++) {
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol_mod*6*12]; rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol_mod*6*12];
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol_mod*6*12]; rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[1][symbol_mod*6*12];
#elif defined(__arm__) #elif defined(__arm__)
rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol_mod*6*12]; rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol_mod*6*12];
rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol_mod*6*12]; rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol_mod*6*12];
#endif #endif
// MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
...@@ -382,7 +424,7 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, ...@@ -382,7 +424,7 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
#endif #endif
} }
} }
}
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
_mm_empty(); _mm_empty();
_m_empty(); _m_empty();
...@@ -390,18 +432,20 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, ...@@ -390,18 +432,20 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
} }
void nr_pbch_unscrambling(NR_UE_PBCH *pbch, void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
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)
{ {
uint8_t reset, offset; uint8_t reset, offset;
uint32_t x1, x2, s=0; uint32_t x1, x2, s=0;
double *demod_pbch_e = pbch->demod_pbch_e; int16_t *demod_pbch_e = pbch->llr;
uint32_t *pbch_a_prime = (uint32_t*)pbch->pbch_a_prime;
uint32_t *pbch_a_interleaved = (uint32_t*)pbch->pbch_a_interleaved;
uint32_t unscrambling_mask = 0x100006D; uint32_t unscrambling_mask = 0x100006D;
printf("unscramb nid_cell %d\n",Nid);
reset = 1; reset = 1;
// x1 is set in first call to lte_gold_generic // x1 is set in first call to lte_gold_generic
...@@ -420,11 +464,11 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch, ...@@ -420,11 +464,11 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
s = lte_gold_generic(&x1, &x2, reset); s = lte_gold_generic(&x1, &x2, reset);
reset = 0; reset = 0;
} }
#ifdef DEBUG_PBCH_ENCODING #ifdef DEBUG_PBCH_ENCODING
if (i<8) if (i<8)
printf("s: %04x\t", s); printf("s: %04x\t", s);
printf("pbch_a_interleaved 0x%08x\n", pbch->pbch_a_interleaved); printf("pbch_a_interleaved 0x%08x\n", pbch->pbch_a_interleaved);
#endif #endif
if (bitwise) { if (bitwise) {
(pbch->pbch_a_interleaved) ^= ((unscrambling_mask>>i)&1)? ((pbch->pbch_a_prime>>i)&1)<<i : (((pbch->pbch_a_prime>>i)&1) ^ ((s>>((i+offset)&0x1f))&1))<<i; (pbch->pbch_a_interleaved) ^= ((unscrambling_mask>>i)&1)? ((pbch->pbch_a_prime>>i)&1)<<i : (((pbch->pbch_a_prime>>i)&1) ^ ((s>>((i+offset)&0x1f))&1))<<i;
...@@ -442,44 +486,6 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch, ...@@ -442,44 +486,6 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
} }
void nr_pbch_alamouti(NR_DL_FRAME_PARMS *frame_parms,
int **rxdataF_comp,
uint8_t symbol)
{
int16_t *rxF0,*rxF1;
// __m128i *ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b;
uint8_t rb,re,symbol_mod;
int jj;
// printf("Doing alamouti\n");
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
jj = (symbol_mod*6*12);
rxF0 = (int16_t*)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y
rxF1 = (int16_t*)&rxdataF_comp[2][jj]; //tx antenna 1 h1*y
for (rb=0; rb<6; rb++) {
for (re=0; re<12; re+=2) {
// Alamouti RX combining
rxF0[0] = rxF0[0] + rxF1[2];
rxF0[1] = rxF0[1] - rxF1[3];
rxF0[2] = rxF0[2] - rxF1[0];
rxF0[3] = rxF0[3] + rxF1[1];
rxF0+=4;
rxF1+=4;
}
}
}
void nr_pbch_quantize(int16_t *pbch_llr8, void nr_pbch_quantize(int16_t *pbch_llr8,
int16_t *pbch_llr, int16_t *pbch_llr,
uint16_t len) uint16_t len)
...@@ -488,10 +494,10 @@ void nr_pbch_quantize(int16_t *pbch_llr8, ...@@ -488,10 +494,10 @@ void nr_pbch_quantize(int16_t *pbch_llr8,
uint16_t i; uint16_t i;
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (pbch_llr[i]>127) if (pbch_llr[i]>31)
pbch_llr8[i]=127; pbch_llr8[i]=32;
else if (pbch_llr[i]<-128) else if (pbch_llr[i]<-31)
pbch_llr8[i]=-128; pbch_llr8[i]=-32;
else else
pbch_llr8[i] = (char)(pbch_llr[i]); pbch_llr8[i] = (char)(pbch_llr[i]);
...@@ -506,33 +512,29 @@ unsigned char sign(int8_t x) { ...@@ -506,33 +512,29 @@ unsigned char sign(int8_t x) {
uint8_t pbch_deinterleaving_pattern[32] = {28,0,31,30,1,29,25,27,22,2,24,3,4,5,6,7,18,21,20,8,9,10,11,19,26,12,13,14,15,16,23,17}; uint8_t pbch_deinterleaving_pattern[32] = {28,0,31,30,1,29,25,27,22,2,24,3,4,5,6,7,18,21,20,8,9,10,11,19,26,12,13,14,15,16,23,17};
int nr_rx_pbch( PHY_VARS_NR_UE *ue, int nr_rx_pbch( PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc, UE_nr_rxtx_proc_t *proc,
NR_UE_PBCH *nr_ue_pbch_vars, NR_UE_PBCH *nr_ue_pbch_vars,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id, uint8_t eNB_id,
MIMO_mode_t mimo_mode, MIMO_mode_t mimo_mode,
uint32_t high_speed_flag) uint32_t high_speed_flag)
{ {
NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars; NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
uint8_t log2_maxh;
int max_h=0; int max_h=0;
int symbol,i; int symbol,i;
//uint8_t pbch_a[64]; //uint8_t pbch_a[64];
uint8_t *pbch_a = malloc(sizeof(uint8_t) * 32); uint8_t *pbch_a = malloc(sizeof(uint8_t) * 32);
uint32_t pbch_a_prime; uint32_t pbch_a_prime;
int8_t *pbch_e_rx; int16_t *pbch_e_rx;
uint8_t *decoded_output = nr_ue_pbch_vars->decoded_output; uint8_t *decoded_output = nr_ue_pbch_vars->decoded_output;
uint8_t nushift; uint8_t nushift;
uint16_t M; uint16_t M;
uint8_t Lmax=8; //to update uint8_t Lmax=8; //to update
uint8_t ssb_index=0; uint8_t ssb_index=0;
//uint16_t crc; //uint16_t crc;
//short nr_demod_table[8] = {0,0,0,1,1,0,1,1};
//double nr_demod_table[8] = {0.707,0.707,-0.707,0.707,0.707,-0.707,-0.707,-0.707};
//int16_t *demod_pbch_e; // = malloc (sizeof(int16_t) * 864);
unsigned short idx_demod =0; unsigned short idx_demod =0;
int8_t decoderState=0; int8_t decoderState=0;
uint8_t decoderListSize = 8, pathMetricAppr = 0; uint8_t decoderListSize = 8, pathMetricAppr = 0;
...@@ -546,52 +548,55 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -546,52 +548,55 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
int subframe_rx = proc->subframe_rx; int subframe_rx = proc->subframe_rx;
printf("ue->current_thread_id[subframe_rx] %d subframe_rx %d\n",ue->current_thread_id[subframe_rx], subframe_rx);
pbch_e_rx = &nr_ue_pbch_vars->llr[0]; pbch_e_rx = &nr_ue_pbch_vars->llr[0];
// clear LLR buffer // clear LLR buffer
memset(nr_ue_pbch_vars->llr,0,NR_POLAR_PBCH_E); memset(nr_ue_pbch_vars->llr,0,NR_POLAR_PBCH_E);
for (symbol=5; symbol<8; symbol++) { int first_symbol=1;
if (ue->is_synchronized > 0) first_symbol+=4;
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
//printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF); //printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF);
write_output("rxdataF0_pbch.m","rxF0pbch",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF,frame_parms->ofdm_symbol_size*4,2,1); write_output("rxdataF0_pbch.m","rxF0pbch",
&nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][first_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1);
#endif #endif
for (symbol=first_symbol; symbol<(first_symbol+3); symbol++) {
nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF, nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF,
nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[eNB_id], nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[eNB_id],
nr_ue_pbch_vars->rxdataF_ext, nr_ue_pbch_vars->rxdataF_ext,
nr_ue_pbch_vars->dl_ch_estimates_ext, nr_ue_pbch_vars->dl_ch_estimates_ext,
symbol, symbol-first_symbol+1,
high_speed_flag, high_speed_flag,
frame_parms); ue->is_synchronized,
frame_parms);
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
msg("[PHY] PBCH Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size ); LOG_I(PHY,"[PHY] PBCH Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size );
msg("[PHY] PBCH starting channel_level\n"); LOG_I(PHY,"[PHY] PBCH starting channel_level\n");
#endif #endif
max_h = nr_pbch_channel_level(nr_ue_pbch_vars->dl_ch_estimates_ext, if (symbol == 1 || symbol == 5) {
frame_parms, max_h = nr_pbch_channel_level(nr_ue_pbch_vars->dl_ch_estimates_ext,
symbol); frame_parms,
log2_maxh = 3+(log2_approx(max_h)/2); symbol);
nr_ue_pbch_vars->log2_maxh = 3+(log2_approx(max_h)/2);
}
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
msg("[PHY] PBCH log2_maxh = %d (%d)\n",log2_maxh,max_h); LOG_I(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n",nr_ue_pbch_vars->log2_maxh,max_h);
#endif #endif
nr_pbch_channel_compensation(nr_ue_pbch_vars->rxdataF_ext, nr_pbch_channel_compensation(nr_ue_pbch_vars->rxdataF_ext,
nr_ue_pbch_vars->dl_ch_estimates_ext, nr_ue_pbch_vars->dl_ch_estimates_ext,
nr_ue_pbch_vars->rxdataF_comp, nr_ue_pbch_vars->rxdataF_comp,
frame_parms, frame_parms,
symbol, symbol,
log2_maxh); // log2_maxh+I0_shift ue->is_synchronized,
nr_ue_pbch_vars->log2_maxh); // log2_maxh+I0_shift
#ifdef DEBUG_PBCH
write_output("rxdataF_comp.m","rxFcomp",nr_ue_pbch_vars->rxdataF_comp,180,2,1);
#endif
/*if (frame_parms->nb_antennas_rx > 1) /*if (frame_parms->nb_antennas_rx > 1)
pbch_detection_mrc(frame_parms, pbch_detection_mrc(frame_parms,
nr_ue_pbch_vars->rxdataF_comp, nr_ue_pbch_vars->rxdataF_comp,
...@@ -601,11 +606,11 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -601,11 +606,11 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
if (mimo_mode == ALAMOUTI) { if (mimo_mode == ALAMOUTI) {
nr_pbch_alamouti(frame_parms,nr_ue_pbch_vars->rxdataF_comp,symbol); nr_pbch_alamouti(frame_parms,nr_ue_pbch_vars->rxdataF_comp,symbol);
} else if (mimo_mode != SISO) { } else if (mimo_mode != SISO) {
msg("[PBCH][RX] Unsupported MIMO mode\n"); LOG_I(PHY,"[PBCH][RX] Unsupported MIMO mode\n");
return(-1); return(-1);
} }
*/ */
if (symbol==6) { if (symbol==(first_symbol+1)) {
nr_pbch_quantize(pbch_e_rx, nr_pbch_quantize(pbch_e_rx,
(short*)&(nr_ue_pbch_vars->rxdataF_comp[0][symbol*240]), (short*)&(nr_ue_pbch_vars->rxdataF_comp[0][symbol*240]),
144); 144);
...@@ -622,6 +627,11 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -622,6 +627,11 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
} }
#ifdef DEBUG_PBCH
write_output("rxdataF_comp.m","rxFcomp",&nr_ue_pbch_vars->rxdataF_comp[0][240*first_symbol],240*3,1,1);
#endif
pbch_e_rx = nr_ue_pbch_vars->llr; pbch_e_rx = nr_ue_pbch_vars->llr;
//demod_pbch_e = nr_ue_pbch_vars->demod_pbch_e; //demod_pbch_e = nr_ue_pbch_vars->demod_pbch_e;
pbch_a = nr_ue_pbch_vars->pbch_a; pbch_a = nr_ue_pbch_vars->pbch_a;
...@@ -629,46 +639,30 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -629,46 +639,30 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
//pbch_e_rx = &nr_ue_pbch_vars->llr[0]; //pbch_e_rx = &nr_ue_pbch_vars->llr[0];
short *p = (short *)&(nr_ue_pbch_vars->rxdataF_comp[0][5*20*12]); short *p = (short *)&(nr_ue_pbch_vars->rxdataF_comp[0][first_symbol*20*12]);
for (int cnt = 0; cnt < 32 ; cnt++) for (int cnt = 0; cnt < 864 ; cnt++)
printf("pbch rx llr %d rxdata_comp %d addr %p\n",*(pbch_e_rx+cnt), p[cnt], &p[0]); printf("pbch rx llr %d\n",*(pbch_e_rx+cnt));
#endif
/*
for (i=0; i<NR_POLAR_PBCH_E/2; i++){
idx_demod = (sign(pbch_e_rx[i<<1])&1) ^ ((sign(pbch_e_rx[(i<<1)+1])&1)<<1);
demod_pbch_e[i<<1] = nr_demod_table[(idx_demod)<<1];
demod_pbch_e[(i<<1)+1] = nr_demod_table[((idx_demod)<<1)+1];
#ifdef DEBUG_PBCH
if (i<16){
printf("idx[%d]= %d\n", i , idx_demod);
printf("sign[%d]= %d sign[%d]= %d\n", i<<1 , sign(pbch_e_rx[i<<1]), (i<<1)+1 , sign(pbch_e_rx[(i<<1)+1]));
printf("demod_pbch_e[%d] r = %2.3f i = %2.3f\n", i<<1 , demod_pbch_e[i<<1], demod_pbch_e[(i<<1)+1]);}
#endif #endif
}
*/
//un-scrambling //un-scrambling
M = NR_POLAR_PBCH_E; M = NR_POLAR_PBCH_E;
nushift = (Lmax==4)? ssb_index&3 : ssb_index&7; nushift = (Lmax==4)? ssb_index&3 : ssb_index&7;
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_E,0); nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_E,0);
/*
//#ifdef DEBUG_PBCH
for (i=0; i<16; i++){
printf("unscrambling demod_pbch_e[%d] r = %2.3f i = %2.3f\n", i<<1 , demod_pbch_e[i<<1], demod_pbch_e[(i<<1)+1]);}
//#endif
*/
// uint32_t pbch_out;
//polar decoding de-rate matching //polar decoding de-rate matching
t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL;
nr_polar_init(&nrPolar_params,
NR_POLAR_PBCH_MESSAGE_TYPE, AssertFatal(ue->nrPolar_params != NULL,"ue->nrPolar_params is null\n");
NR_POLAR_PBCH_PAYLOAD_BITS,
NR_POLAR_PBCH_AGGREGATION_LEVEL); t_nrPolar_params *currentPtr = nr_polar_params(ue->nrPolar_params, NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);
currentPtr = nr_polar_params(nrPolar_params, NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);
double aPrioriArray[currentPtr->payloadBits]; decoderState = polar_decoder_int16(pbch_e_rx,&nr_ue_pbch_vars->pbch_a_prime,currentPtr);
for (int i=0; i<currentPtr->payloadBits; i++) aPrioriArray[i] = NAN;
decoderState = polar_decoder_aPriori(demod_pbch_e,&nr_ue_pbch_vars->pbch_a_prime, currentPtr, decoderListSize, pathMetricAppr,aPrioriArray);
printf("polar decoder state %d\n", decoderState);
if(decoderState == -1) if(decoderState == -1)
return(decoderState); return(decoderState);
...@@ -678,7 +672,6 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -678,7 +672,6 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
memset(&nr_ue_pbch_vars->pbch_a_interleaved, 0, sizeof(uint32_t) ); memset(&nr_ue_pbch_vars->pbch_a_interleaved, 0, sizeof(uint32_t) );
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3); M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
nushift = ((nr_ue_pbch_vars->pbch_a_prime>>6)&1) ^ (((nr_ue_pbch_vars->pbch_a_prime>>24)&1)<<1); nushift = ((nr_ue_pbch_vars->pbch_a_prime>>6)&1) ^ (((nr_ue_pbch_vars->pbch_a_prime>>24)&1)<<1);
printf("payload unscrambling nushift %d sfn3 %d sfn2 %d M %d\n",nushift, ((nr_ue_pbch_vars->pbch_a_prime>>6)&1),((nr_ue_pbch_vars->pbch_a_prime>>24)&1),M);
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_PAYLOAD_BITS,1); nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_PAYLOAD_BITS,1);
//payload deinterleaving //payload deinterleaving
...@@ -688,35 +681,37 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -688,35 +681,37 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
for (int i=0; i<32; i++) { for (int i=0; i<32; i++) {
out |= ((nr_ue_pbch_vars->pbch_a_interleaved>>i)&1)<<(pbch_deinterleaving_pattern[i]); out |= ((nr_ue_pbch_vars->pbch_a_interleaved>>i)&1)<<(pbch_deinterleaving_pattern[i]);
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
printf("i %d in 0x%08x out 0x%08x ilv %d (in>>i)&1) 0x%08x\n", i, nr_ue_pbch_vars->pbch_a_interleaved, out, pbch_deinterleaving_pattern[i], (in>>i)&1); printf("i %d in 0x%08x out 0x%08x ilv %d (in>>i)&1) 0x%08x\n", i, nr_ue_pbch_vars->pbch_a_interleaved, out, pbch_deinterleaving_pattern[i], (nr_ue_pbch_vars->pbch_a_interleaved>>i)&1);
#endif #endif
} }
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS>>3; i++) for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS>>3; i++)
pbch_a[i] = (uint8_t)((out>>(i<<3))&0xff); decoded_output[i] = (uint8_t)((out>>(i<<3))&0xff);
// Fix byte endian // Fix byte endian
for (i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++) // for (i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++)
decoded_output[(NR_POLAR_PBCH_PAYLOAD_BITS>>3)-i-1] = pbch_a[i]; // decoded_output[(NR_POLAR_PBCH_PAYLOAD_BITS>>3)-i-1] = pbch_a[i];
//#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
for (i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++){ for (i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++){
//printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]); // printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]);
printf("[PBCH] decoder payload[%d] = %x\n",i,decoded_output[i]); printf("[PBCH] decoder payload[%d] = %x\n",i,decoded_output[i]);
} }
//#endif #endif
ue->dl_indication.rx_ind = &ue->rx_ind; // hang on rx_ind instance ue->dl_indication.rx_ind = &ue->rx_ind; // hang on rx_ind instance
//ue->rx_ind.sfn_slot = 0; //should be set by higher-1-layer, i.e. clean_and_set_if_instance() //ue->rx_ind.sfn_slot = 0; //should be set by higher-1-layer, i.e. clean_and_set_if_instance()
ue->rx_ind.number_pdus = ue->rx_ind.number_pdus + 1; ue->rx_ind.number_pdus = ue->rx_ind.number_pdus + 1;
ue->rx_ind.rx_indication_body = (fapi_nr_rx_indication_body_t *)malloc(sizeof(fapi_nr_rx_indication_body_t)); ue->rx_ind.rx_indication_body = (fapi_nr_rx_indication_body_t *)malloc(sizeof(fapi_nr_rx_indication_body_t));
ue->rx_ind.rx_indication_body->pdu_type = FAPI_NR_RX_PDU_TYPE_MIB; ue->rx_ind.rx_indication_body->pdu_type = FAPI_NR_RX_PDU_TYPE_MIB;
ue->rx_ind.rx_indication_body->mib_pdu.pdu = &decoded_output[1]; ue->rx_ind.rx_indication_body->mib_pdu.pdu = &decoded_output[0];
ue->rx_ind.rx_indication_body->mib_pdu.additional_bits = decoded_output[0]; ue->rx_ind.rx_indication_body->mib_pdu.additional_bits = decoded_output[3];
ue->rx_ind.rx_indication_body->mib_pdu.ssb_index = ssb_index; // confirm with TCL ue->rx_ind.rx_indication_body->mib_pdu.ssb_index = ssb_index; // confirm with TCL
ue->rx_ind.rx_indication_body->mib_pdu.ssb_length = Lmax; // confirm with TCL ue->rx_ind.rx_indication_body->mib_pdu.ssb_length = Lmax; // confirm with TCL
ue->rx_ind.rx_indication_body->mib_pdu.cell_id = frame_parms->Nid_cell; // confirm with TCL ue->rx_ind.rx_indication_body->mib_pdu.cell_id = frame_parms->Nid_cell; // confirm with TCL
ue->if_inst->dl_indication(&ue->dl_indication); if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&ue->dl_indication);
return 0; return 0;
} }
...@@ -1362,6 +1362,7 @@ void generate_RIV_tables(void); ...@@ -1362,6 +1362,7 @@ void generate_RIV_tables(void);
N_RB_DL, PHICH_CONFIG and Nid_cell) and the UE can begin decoding PDCCH and DLSCH SI to retrieve the rest. Once these N_RB_DL, PHICH_CONFIG and Nid_cell) and the UE can begin decoding PDCCH and DLSCH SI to retrieve the rest. Once these
parameters are know, the routine calls some basic initialization routines (cell-specific reference signals, etc.) parameters are know, the routine calls some basic initialization routines (cell-specific reference signals, etc.)
@param phy_vars_ue Pointer to UE variables @param phy_vars_ue Pointer to UE variables
@param mode current running mode
*/ */
int nr_initial_sync(PHY_VARS_NR_UE *phy_vars_ue, runmode_t mode); int nr_initial_sync(PHY_VARS_NR_UE *phy_vars_ue, runmode_t mode);
......
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
* *
*********************************************************************/ *********************************************************************/
#define DBG_PSS_NR //#define DBG_PSS_NR
void *get_idft(int ofdm_symbol_size) void *get_idft(int ofdm_symbol_size)
{ {
...@@ -88,6 +88,14 @@ void *get_idft(int ofdm_symbol_size) ...@@ -88,6 +88,14 @@ void *get_idft(int ofdm_symbol_size)
idft = idft2048; idft = idft2048;
break; break;
case 4096:
idft = idft4096;
break;
case 8192:
idft = idft8192;
break;
default: default:
printf("function get_idft : unsupported ofdm symbol size \n"); printf("function get_idft : unsupported ofdm symbol size \n");
assert(0); assert(0);
...@@ -137,6 +145,14 @@ void *get_dft(int ofdm_symbol_size) ...@@ -137,6 +145,14 @@ void *get_dft(int ofdm_symbol_size)
dft = dft2048; dft = dft2048;
break; break;
case 4096:
dft = dft4096;
break;
case 8192:
dft = dft8192;
break;
default: default:
printf("function get_dft : unsupported ofdm symbol size \n"); printf("function get_dft : unsupported ofdm symbol size \n");
assert(0); assert(0);
...@@ -159,14 +175,17 @@ void *get_dft(int ofdm_symbol_size) ...@@ -159,14 +175,17 @@ void *get_dft(int ofdm_symbol_size)
* *
*********************************************************************/ *********************************************************************/
void generate_pss_nr(int N_ID_2, int ofdm_symbol_size) void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2)
{ {
AssertFatal(fp->ofdm_symbol_size > 127,"Illegal ofdm_symbol_size %d\n",fp->ofdm_symbol_size);
AssertFatal(N_ID_2>=0 && N_ID_2 <=2,"Illegal N_ID_2 %d\n",N_ID_2);
int16_t d_pss[LENGTH_PSS_NR]; int16_t d_pss[LENGTH_PSS_NR];
int16_t x[LENGTH_PSS_NR]; int16_t x[LENGTH_PSS_NR];
int16_t *primary_synchro_time = primary_synchro_time_nr[N_ID_2]; int16_t *primary_synchro_time = primary_synchro_time_nr[N_ID_2];
unsigned int length = ofdm_symbol_size; unsigned int length = fp->ofdm_symbol_size;
unsigned int size = length * IQ_SIZE; /* i & q */ unsigned int size = length * IQ_SIZE; /* i & q */
int16_t *primary_synchro = primary_synchro_nr[N_ID_2]; /* pss in complex with alternatively i then q */ int16_t *primary_synchro = primary_synchro_nr[N_ID_2]; /* pss in complex with alternatively i then q */
int16_t *primary_synchro2 = primary_synchro_nr2[N_ID_2]; /* pss in complex with alternatively i then q */
void (*idft)(int16_t *,int16_t *, int); void (*idft)(int16_t *,int16_t *, int);
#define INITIAL_PSS_NR (7) #define INITIAL_PSS_NR (7)
...@@ -197,9 +216,11 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size) ...@@ -197,9 +216,11 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
#if 1 #if 1
primary_synchro[2*i] = (d_pss[i] * SHRT_MAX)>>SCALING_PSS_NR; /* Maximum value for type short int ie int16_t */ primary_synchro[2*i] = (d_pss[i] * SHRT_MAX)>>SCALING_PSS_NR; /* Maximum value for type short int ie int16_t */
primary_synchro[2*i+1] = 0; primary_synchro[2*i+1] = 0;
primary_synchro2[i] = d_pss[i];
#else #else
primary_synchro[2*i] = d_pss[i] * AMP; primary_synchro[2*i] = d_pss[i] * AMP;
primary_synchro[2*i+1] = 0; primary_synchro[2*i+1] = 0;
primary_synchro2[i] = d_pss[i];
#endif #endif
} }
...@@ -212,7 +233,7 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size) ...@@ -212,7 +233,7 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
sprintf(sequence_name, "pss_seq_%d_%d", N_ID_2, length); sprintf(sequence_name, "pss_seq_%d_%d", N_ID_2, length);
printf("file %s sequence %s\n", output_file, sequence_name); printf("file %s sequence %s\n", output_file, sequence_name);
write_output(output_file, sequence_name, primary_synchro, LENGTH_PSS_NR, 1, 1); LOG_M(output_file, sequence_name, primary_synchro, LENGTH_PSS_NR, 1, 1);
} }
#endif #endif
...@@ -239,7 +260,10 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size) ...@@ -239,7 +260,10 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
* sample 0 is for continuous frequency which is used here * sample 0 is for continuous frequency which is used here
*/ */
unsigned int k = length - (LENGTH_PSS_NR/2+1); unsigned int k = fp->first_carrier_offset + fp->ssb_start_subcarrier + 56; //and
if (k>= fp->ofdm_symbol_size) k-=fp->ofdm_symbol_size;
for (int i=0; i < LENGTH_PSS_NR; i++) { for (int i=0; i < LENGTH_PSS_NR; i++) {
synchroF_tmp[2*k] = primary_synchro[2*i]; synchroF_tmp[2*k] = primary_synchro[2*i];
...@@ -247,10 +271,8 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size) ...@@ -247,10 +271,8 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
k++; k++;
if (k >= length) { if (k == length) k=0;
k++;
k-=length;
}
} }
/* IFFT will give temporal signal of Pss */ /* IFFT will give temporal signal of Pss */
...@@ -276,7 +298,10 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size) ...@@ -276,7 +298,10 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
printf("file %s sequence %s\n", output_file, sequence_name); printf("file %s sequence %s\n", output_file, sequence_name);
write_output(output_file, sequence_name, primary_synchro_time, length, 1, 1); LOG_M(output_file, sequence_name, primary_synchro_time, length, 1, 1);
sprintf(output_file, "%s%d_%d%s","pss_seq_f_", N_ID_2, length, ".m");
sprintf(sequence_name, "%s%d_%d","pss_seq_f_", N_ID_2, length);
LOG_M(output_file, sequence_name, synchroF_tmp, length, 1, 1);
} }
#endif #endif
...@@ -288,7 +313,7 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size) ...@@ -288,7 +313,7 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
if ((N_ID_2 == 0) && (length == 256)) { if ((N_ID_2 == 0) && (length == 256)) {
write_output("pss_f00.m","pss_f00",synchro_tmp,length,1,1); LOG_M("pss_f00.m","pss_f00",synchro_tmp,length,1,1);
bzero(synchroF_tmp, size); bzero(synchroF_tmp, size);
...@@ -301,7 +326,7 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size) ...@@ -301,7 +326,7 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
1); /* scaling factor */ 1); /* scaling factor */
if ((N_ID_2 == 0) && (length == 256)) { if ((N_ID_2 == 0) && (length == 256)) {
write_output("pss_f_0.m","pss_f_0",synchroF_tmp,length,1,1); LOG_M("pss_f_0.m","pss_f_0",synchroF_tmp,length,1,1);
} }
/* check Pss */ /* check Pss */
...@@ -347,8 +372,9 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue) ...@@ -347,8 +372,9 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
int sizePss = LENGTH_PSS_NR * IQ_SIZE; /* complex value i & q signed 16 bits */ int sizePss = LENGTH_PSS_NR * IQ_SIZE; /* complex value i & q signed 16 bits */
int size = ofdm_symbol_size * IQ_SIZE; /* i and q samples signed 16 bits */ int size = ofdm_symbol_size * IQ_SIZE; /* i and q samples signed 16 bits */
int16_t *p = NULL; int16_t *p = NULL;
int *q = NULL; int64_t *q = NULL;
AssertFatal(ofdm_symbol_size > 127, "illegal ofdm_symbol_size %d\n",ofdm_symbol_size);
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) { for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
p = malloc16(sizePss); /* pss in complex with alternatively i then q */ p = malloc16(sizePss); /* pss in complex with alternatively i then q */
...@@ -360,7 +386,11 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue) ...@@ -360,7 +386,11 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
msg("Fatal memory allocation problem \n"); msg("Fatal memory allocation problem \n");
assert(0); assert(0);
} }
p = malloc(LENGTH_PSS_NR*2);
if (p != NULL) {
primary_synchro_nr2[i] = p;
bzero( primary_synchro_nr2[i],LENGTH_PSS_NR*2);
}
p = malloc16(size); p = malloc16(size);
if (p != NULL) { if (p != NULL) {
primary_synchro_time_nr[i] = p; primary_synchro_time_nr[i] = p;
...@@ -371,8 +401,8 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue) ...@@ -371,8 +401,8 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
assert(0); assert(0);
} }
size = NR_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms_ue->samples_per_subframe; size = NR_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int64_t)*frame_parms_ue->samples_per_subframe;
q = malloc16(size); q = (int64_t*)malloc16(size);
if (q != NULL) { if (q != NULL) {
pss_corr_ue[i] = q; pss_corr_ue[i] = q;
bzero( pss_corr_ue[i], size); bzero( pss_corr_ue[i], size);
...@@ -382,7 +412,7 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue) ...@@ -382,7 +412,7 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
assert(0); assert(0);
} }
generate_pss_nr(i, ofdm_symbol_size); generate_pss_nr(frame_parms_ue,i);
} }
} }
...@@ -582,6 +612,8 @@ void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **r ...@@ -582,6 +612,8 @@ void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **r
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
int samples_for_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti; int samples_for_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti;
AssertFatal(frame_parms->samples_per_tti > 3839,"Illegal samples_per_tti %d\n",frame_parms->samples_per_tti);
#if TEST_SYNCHRO_TIMING_PSS #if TEST_SYNCHRO_TIMING_PSS
opp_enabled = 1; opp_enabled = 1;
...@@ -635,7 +667,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) ...@@ -635,7 +667,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
int samples_for_frame = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; int samples_for_frame = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
write_output("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], samples_for_frame, 1, 1); LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], samples_for_frame, 1, 1);
#endif #endif
...@@ -644,7 +676,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) ...@@ -644,7 +676,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*)); rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
for (int aa=0; aa < frame_parms->nb_antennas_rx; aa++) { for (int aa=0; aa < frame_parms->nb_antennas_rx; aa++) {
rxdata[aa] = (int32_t*) malloc16_clear( (frame_parms->samples_per_subframe*10+2048)*sizeof(int32_t)); rxdata[aa] = (int32_t*) malloc16_clear( (frame_parms->samples_per_subframe*10+8192)*sizeof(int32_t));
} }
#ifdef SYNCHRO_DECIMAT #ifdef SYNCHRO_DECIMAT
...@@ -659,7 +691,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) ...@@ -659,7 +691,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
#ifdef DBG_PSS_NR #ifdef DBG_PSS_NR
write_output("rxdata0_des.m","rxd0_des", &rxdata[0][0], samples_for_frame,1,1); LOG_M("rxdata0_des.m","rxd0_des", &rxdata[0][0], samples_for_frame,1,1);
#endif #endif
...@@ -714,6 +746,11 @@ static inline int abs32(int x) ...@@ -714,6 +746,11 @@ static inline int abs32(int x)
return (((int)((short*)&x)[0])*((int)((short*)&x)[0]) + ((int)((short*)&x)[1])*((int)((short*)&x)[1])); return (((int)((short*)&x)[0])*((int)((short*)&x)[0]) + ((int)((short*)&x)[1])*((int)((short*)&x)[1]));
} }
static inline int64_t abs64(int64_t x)
{
return (((int64_t)((int32_t*)&x)[0])*((int64_t)((int32_t*)&x)[0]) + ((int64_t)((int32_t*)&x)[1])*((int64_t)((int32_t*)&x)[1]));
}
/******************************************************************* /*******************************************************************
* *
* NAME : pss_search_time_nr * NAME : pss_search_time_nr
...@@ -770,75 +807,91 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain ...@@ -770,75 +807,91 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
int *eNB_id) int *eNB_id)
{ {
unsigned int n, ar, peak_position, peak_value, pss_source; unsigned int n, ar, peak_position, pss_source;
int result; int64_t peak_value;
int synchro_out; int64_t result;
unsigned int tmp[NUMBER_PSS_SEQUENCE]; int64_t avg[NUMBER_PSS_SEQUENCE];
unsigned int length = (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->ttis_per_subframe*frame_parms->samples_per_tti); /* 1 frame for now, it should be 2 TODO_NR */
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
tmp[i] = 0;
if (pss_corr_ue[i] == NULL) {
msg("[SYNC TIME] pss_corr_ue[%d] not yet allocated! Exiting.\n", i);
return(-1);
}
}
unsigned int length = (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe); /* 1 frame for now, it should be 2 TODO_NR */
AssertFatal(length>0,"illegal length %d\n",length);
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) AssertFatal(pss_corr_ue[i] != NULL,"pss_corr_ue[%d] not yet allocated! Exiting.\n", i);
peak_value = 0; peak_value = 0;
peak_position = 0; peak_position = 0;
pss_source = 0; pss_source = 0;
int maxval=0;
for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) {
maxval = max(maxval,primary_synchro_time_nr[0][i]);
maxval = max(maxval,-primary_synchro_time_nr[0][i]);
maxval = max(maxval,primary_synchro_time_nr[1][i]);
maxval = max(maxval,-primary_synchro_time_nr[1][i]);
maxval = max(maxval,primary_synchro_time_nr[2][i]);
maxval = max(maxval,-primary_synchro_time_nr[2][i]);
}
int shift = log2_approx(maxval);//*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*2);
/* Search pss in the received buffer each 4 samples which ensures a memory alignment on 128 bits (32 bits x 4 ) */ /* Search pss in the received buffer each 4 samples which ensures a memory alignment on 128 bits (32 bits x 4 ) */
/* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors. */ /* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors. */
/* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */ /* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) avg[pss_index]=0;
for (n=0; n < length; n+=4) { for (n=0; n < length; n+=4) {
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) { for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) {
pss_corr_ue[pss_index][n] = 0; /* clean correlation for position n */ pss_corr_ue[pss_index][n] = 0; /* clean correlation for position n */
synchro_out = 0;
if ( n < (length - frame_parms->ofdm_symbol_size)) { if ( n < (length - frame_parms->ofdm_symbol_size)) {
/* 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 (ar=0; ar<frame_parms->nb_antennas_rx; ar++) { for (ar=0; ar<frame_parms->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 */
result = dot_product((short*)primary_synchro_time_nr[pss_index], (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, DOT_PRODUCT_SCALING_SHIFT); result = dot_product64((short*)primary_synchro_time_nr[pss_index],
(short*) &(rxdata[ar][n]),
frame_parms->ofdm_symbol_size,
shift);
pss_corr_ue[pss_index][n] += abs64(result);
//((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0]; /* real part */
//((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
//((short*)&synchro_out)[0] += ((short*) &result)[0]; /* real part */
//((short*)&synchro_out)[1] += ((short*) &result)[1]; /* imaginary part */
((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0]; /* real part */
((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
((short*)&synchro_out)[0] += ((short*) &result)[0]; /* real part */
((short*)&synchro_out)[1] += ((short*) &result)[1]; /* imaginary part */
} }
} }
pss_corr_ue[pss_index][n] = abs32(pss_corr_ue[pss_index][n]);
/* calculate the absolute value of sync_corr[n] */ /* calculate the absolute value of sync_corr[n] */
tmp[pss_index] = (abs32(synchro_out)) ; avg[pss_index]+=pss_corr_ue[pss_index][n];
if (pss_corr_ue[pss_index][n] > peak_value) {
if (tmp[pss_index] > peak_value) { peak_value = pss_corr_ue[pss_index][n];
peak_value = tmp[pss_index];
peak_position = n; peak_position = n;
pss_source = pss_index; pss_source = pss_index;
//printf("pss_index %d: n %6d peak_value %10d, synchro_out (% 6d,% 6d) \n", pss_index, n, abs32(synchro_out),((int16_t*)&synchro_out)[0],((int16_t*)&synchro_out)[1]); #ifdef DEBUG_PSS_NR
printf("pss_index %d: n %6d peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_ue[pss_index][n]);
#endif
} }
} }
} }
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) avg[pss_index]/=(length/4);
*eNB_id = pss_source; *eNB_id = pss_source;
LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n", pss_source, peak_position, peak_value, dB_fixed(peak_value)/2); LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB\n", pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]));
//#ifdef DEBUG_PSS_NR //#ifdef DEBUG_PSS_NR
#define PSS_DETECTION_FLOOR_NR (31) #define PSS_DETECTION_FLOOR_NR (31)
if ((dB_fixed(peak_value)/2) > PSS_DETECTION_FLOOR_NR) { if (peak_value < 5*avg[pss_source]) { //PSS_DETECTION_FLOOR_NR)
printf("[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n", pss_source, peak_position, peak_value,dB_fixed(peak_value)/2); return(-1);
} }
//#endif //#endif
...@@ -847,10 +900,10 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain ...@@ -847,10 +900,10 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
static debug_cnt = 0; static debug_cnt = 0;
if (debug_cnt == 0) { if (debug_cnt == 0) {
write_output("pss_corr_ue0.m","pss_corr_ue0",pss_corr_ue[0],length,1,2); /* LOG_M("pss_corr_ue0.m","pss_corr_ue0",pss_corr_ue[0],length,1,6);
write_output("pss_corr_ue1.m","pss_corr_ue1",pss_corr_ue[1],length,1,2); LOG_M("pss_corr_ue1.m","pss_corr_ue1",pss_corr_ue[1],length,1,6);
write_output("pss_corr_ue2.m","pss_corr_ue2",pss_corr_ue[2],length,1,2); LOG_M("pss_corr_ue2.m","pss_corr_ue2",pss_corr_ue[2],length,1,6);
write_output("rxdata0.m","rxd0",rxdata[0],length,1,1); LOG_M("rxdata0.m","rxd0",rxdata[0],length,1,1); */
} else { } else {
debug_cnt++; debug_cnt++;
} }
......
...@@ -96,7 +96,8 @@ void init_context_sss_nr(int amp) ...@@ -96,7 +96,8 @@ void init_context_sss_nr(int amp)
/* Modulation of SSS is a BPSK TS 36.211 chapter 5.1.2 BPSK */ /* Modulation of SSS is a BPSK TS 36.211 chapter 5.1.2 BPSK */
#if 1 #if 1
d_sss[N_ID_2][N_ID_1][n] = dss_current * amp; d_sss[N_ID_2][N_ID_1][n] = dss_current;// * amp;
(void) amp;
#else #else
(void) amp; (void) amp;
d_sss[N_ID_2][N_ID_1][n] = (dss_current * SHRT_MAX)>>SCALING_PSS_NR; d_sss[N_ID_2][N_ID_1][n] = (dss_current * SHRT_MAX)>>SCALING_PSS_NR;
...@@ -126,6 +127,8 @@ void init_context_sss_nr(int amp) ...@@ -126,6 +127,8 @@ void init_context_sss_nr(int amp)
* *
*********************************************************************/ *********************************************************************/
//#define DEBUG_SSS_NR
//#define DEBUG_PLOT_SSS
void insert_sss_nr(int16_t *sss_time, void insert_sss_nr(int16_t *sss_time,
NR_DL_FRAME_PARMS *frame_parms) NR_DL_FRAME_PARMS *frame_parms)
{ {
...@@ -210,10 +213,14 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue, ...@@ -210,10 +213,14 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
uint8_t aarx,i; uint8_t aarx,i;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
pss = primary_synchro_nr[ue->common_vars.eNb_id]; pss = primary_synchro_nr2[ue->common_vars.eNb_id];
sss_ext3 = (int16_t*)&sss_ext[0][0]; sss_ext3 = (int16_t*)&sss_ext[0][0];
#if 0
int16_t chest[2*LENGTH_PSS_NR];
#endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
sss_ext2 = (int16_t*)&sss_ext[aarx][0]; sss_ext2 = (int16_t*)&sss_ext[aarx][0];
...@@ -240,18 +247,28 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue, ...@@ -240,18 +247,28 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
#endif #endif
int32_t amp;
int shift;
for (i = 0; i < LENGTH_PSS_NR; i++) { for (i = 0; i < LENGTH_PSS_NR; i++) {
// This is H*(PSS) = R* \cdot PSS // This is H*(PSS) = R* \cdot PSS
tmp_re = (int16_t)(((pss_ext2[i*2] * (int32_t)pss[i*2])>>SCALING_CE_PSS_NR) + ((pss_ext2[i*2+1] * (int32_t)pss[i*2+1])>>SCALING_CE_PSS_NR)); tmp_re = pss_ext2[i*2] * pss[i];
tmp_im = (int16_t)(((pss_ext2[i*2] * (int32_t)pss[i*2+1])>>SCALING_CE_PSS_NR) - ((pss_ext2[i*2+1] * (int32_t)pss[i*2])>>SCALING_CE_PSS_NR)); tmp_im = -pss_ext2[i*2+1] * pss[i];
//printf("H*(%d,%d) : (%d,%d)\n",aarx,i,tmp_re,tmp_im);
//printf("pss(%d,%d) : (%d,%d)\n",aarx,i,pss[2*i],pss[2*i+1]); amp = (((int32_t)tmp_re)*tmp_re) + ((int32_t)tmp_im)*tmp_im;
//printf("pss_ext(%d,%d) : (%d,%d)\n",aarx,i,pss_ext2[2*i],pss_ext2[2*i+1]); shift = log2_approx(amp)/2;
#if 0
printf("H*(%d,%d) : (%d,%d)\n",aarx,i,tmp_re,tmp_im);
printf("pss(%d,%d) : (%d,%d)\n",aarx,i,pss[2*i],pss[2*i+1]);
printf("pss_ext(%d,%d) : (%d,%d)\n",aarx,i,pss_ext2[2*i],pss_ext2[2*i+1]);
if (aarx==0) {
chest[i<<1]=tmp_re;
chest[1+(i<<1)]=tmp_im;
}
#endif
// This is R(SSS) \cdot H*(PSS) // This is R(SSS) \cdot H*(PSS)
tmp_re2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i*2])>>SCALING_CE_PSS_NR) - ((tmp_im * (int32_t)sss_ext2[i*2+1]>>SCALING_CE_PSS_NR))); tmp_re2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i*2])>>shift) - ((tmp_im * (int32_t)sss_ext2[i*2+1]>>shift)));
tmp_im2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i*2+1])>>SCALING_CE_PSS_NR) + ((tmp_im * (int32_t)sss_ext2[i*2]>>SCALING_CE_PSS_NR))); tmp_im2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i*2+1])>>shift) + ((tmp_im * (int32_t)sss_ext2[i*2]>>shift)));
// printf("SSSi(%d,%d) : (%d,%d)\n",aarx,i,sss_ext2[i<<1],sss_ext2[1+(i<<1)]); // printf("SSSi(%d,%d) : (%d,%d)\n",aarx,i,sss_ext2[i<<1],sss_ext2[1+(i<<1)]);
// printf("SSSo(%d,%d) : (%d,%d)\n",aarx,i,tmp_re2,tmp_im2); // printf("SSSo(%d,%d) : (%d,%d)\n",aarx,i,tmp_re2,tmp_im2);
...@@ -265,7 +282,11 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue, ...@@ -265,7 +282,11 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
} }
} }
} }
#if 0
LOG_M("pssrx.m","pssrx",pss,LENGTH_PSS_NR,1,1);
LOG_M("pss_ext.m","pssext",pss_ext2,LENGTH_PSS_NR,1,1);
LOG_M("psschest.m","pssch",chest,LENGTH_PSS_NR,1,1);
#endif
#if 0 #if 0
for (int i = 0; i < LENGTH_PSS_NR; i++) { for (int i = 0; i < LENGTH_PSS_NR; i++) {
...@@ -307,8 +328,8 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, ...@@ -307,8 +328,8 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
pss_symbol = PSS_SYMBOL_NB; /* symbol position */ pss_symbol = 0;
sss_symbol = SSS_SYMBOL_NB; sss_symbol = SSS_SYMBOL_NB-PSS_SYMBOL_NB;
rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
...@@ -320,7 +341,8 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, ...@@ -320,7 +341,8 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue,
pss_rxF_ext = &pss_ext[aarx][0]; pss_rxF_ext = &pss_ext[aarx][0];
sss_rxF_ext = &sss_ext[aarx][0]; sss_rxF_ext = &sss_ext[aarx][0];
unsigned int k = ofdm_symbol_size - ((LENGTH_PSS_NR/2)+1); unsigned int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56;
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
for (int i=0; i < LENGTH_PSS_NR; i++) { for (int i=0; i < LENGTH_PSS_NR; i++) {
if (doPss) { if (doPss) {
...@@ -333,10 +355,8 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, ...@@ -333,10 +355,8 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue,
k++; k++;
if (k >= ofdm_symbol_size) { if (k == ofdm_symbol_size) k=0;
k++;
k-=ofdm_symbol_size;
}
} }
} }
...@@ -420,26 +440,27 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) ...@@ -420,26 +440,27 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
/* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */ /* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */
int nb_prefix_samples0 = frame_parms->nb_prefix_samples0; int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
frame_parms->nb_prefix_samples0 = 0; // For now, symbol 0 = PSS/PBCH and it is never in symbol 0 or 7*2^mu (i.e. always shorter prefix)
frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples;
// Do FFTs for SSS/PSS // Do FFTs for SSS/PSS
// SSS // SSS
nr_slot_fep(ue, nr_slot_fep(ue,
SSS_SYMBOL_NB, // symbol number SSS_SYMBOL_NB-PSS_SYMBOL_NB, // symbol number w.r.t. PSS
0, // Ns slot number 0, // Ns slot number
ue->rx_offset, // sample_offset of int16_t ue->ssb_offset, // sample_offset of int16_t
0, // no_prefix 0, // no_prefix
1, // reset frequency estimation 1, // reset frequency estimation
NR_SSS_EST); NR_SSS_EST);
// PSS // PSS
nr_slot_fep(ue, nr_slot_fep(ue,
PSS_SYMBOL_NB, 0,
0, 0,
ue->rx_offset, ue->ssb_offset,
0, 0,
1, 1,
NR_SSS_EST); NR_SSS_EST);
frame_parms->nb_prefix_samples0 = nb_prefix_samples0; frame_parms->nb_prefix_samples0 = nb_prefix_samples0;
...@@ -451,19 +472,13 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) ...@@ -451,19 +472,13 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
#ifdef DEBUG_PLOT_SSS #ifdef DEBUG_PLOT_SSS
write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_tti,1,1); write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_subframe,1,1);
write_output("rxdataF0.m","rxF0",&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[0]].rxdataF[0],frame_parms->ofdm_symbol_size,2,1); write_output("rxdataF0_pss.m","rxF0_pss",&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[0]].rxdataF[0][0],frame_parms->ofdm_symbol_size,1,1);
write_output("rxdataF0_sss.m","rxF0_sss",&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[0]].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); write_output("pss_ext.m","pss_ext",pss_ext,LENGTH_PSS_NR,1,1);
#endif #endif
#if 0
write_output("sss_ext.m","sss_ext",sss_ext,LENGTH_SSS_NR,1,1);
write_output("sss_ref.m","sss_ref", d_sss,LENGTH_SSS_NR,1,1);
#endif
#if 0 #if 0
int16_t *p = (int16_t *)sss_ext[0]; int16_t *p = (int16_t *)sss_ext[0];
int16_t *p2 = (int16_t *)pss_ext[0]; int16_t *p2 = (int16_t *)pss_ext[0];
...@@ -472,7 +487,7 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) ...@@ -472,7 +487,7 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
printf("sss ref [%i] : %d %d \n", i, d_sss[0][0][i], d_sss[0][0][i]); printf("sss ref [%i] : %d %d \n", i, d_sss[0][0][i], d_sss[0][0][i]);
printf("sss ext [%i] : %d %d \n", i, p[2*i], p[2*i+1]); printf("sss ext [%i] : %d %d \n", i, p[2*i], p[2*i+1]);
printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr[0][2*i], primary_synchro_nr[0][2*i+1]); printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr2[0][2*i], primary_synchro_nr2[0][2*i+1]);
printf("pss ext [%i] : %d %d \n", i, p2[2*i], p2[2*i+1]); printf("pss ext [%i] : %d %d \n", i, p2[2*i], p2[2*i+1]);
} }
#endif #endif
...@@ -489,6 +504,14 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) ...@@ -489,6 +504,14 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
sss = (int16_t*)&sss_ext[0][0]; sss = (int16_t*)&sss_ext[0][0];
#ifdef DEBUG_PLOT_SSS
write_output("sss_ext.m","sss_ext",sss_ext[0],LENGTH_SSS_NR,1,1);
write_output("sss_ref.m","sss_ref", d_sss,LENGTH_SSS_NR,1,1);
#endif
#if 0 #if 0
/* simulate of a phase shift on the signal */ /* simulate of a phase shift on the signal */
...@@ -503,10 +526,10 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) ...@@ -503,10 +526,10 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
int16_t *ps = (int16_t *)pss_ext; int16_t *ps = (int16_t *)pss_ext;
for (int i = 0; i < LENGTH_SSS_NR; i++) { for (int i = 0; i < LENGTH_SSS_NR; i++) {
printf("sss ref [%i] : %d %d \n", i, d_sss[0][0][i], d_sss[0][0][i]); printf("sss ref [%i] : %d \n", i, d_sss[0][0][i]);
printf("sss ext [%i] : %d %d \n", i, sss[2*i], sss[2*i+1]); printf("sss ext [%i] : %d %d \n", i, sss[2*i], sss[2*i+1]);
printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr[0][2*i], primary_synchro_nr[0][2*i+1]); printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr2[0][2*i], primary_synchro_nr2[0][2*i+1]);
printf("pss ext [%i] : %d %d \n", i, ps[2*i], ps[2*i+1]); printf("pss ext [%i] : %d %d \n", i, ps[2*i], ps[2*i+1]);
} }
#endif #endif
...@@ -517,8 +540,9 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) ...@@ -517,8 +540,9 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
/* cosinus cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */ /* cosinus cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */
/* sinus sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */ /* sinus sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */
for (phase=0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS for (Nid1 = 0 ; Nid1 < N_ID_1_NUMBER; Nid1++) { // all possible Nid1 values
for (Nid1 = 0 ; Nid1 < N_ID_1_NUMBER; Nid1++) { // all possible Nid1 values for (phase=0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS
metric = 0; metric = 0;
metric_re = 0; metric_re = 0;
...@@ -528,8 +552,12 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) ...@@ -528,8 +552,12 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
// 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 (i=0; i < LENGTH_SSS_NR; i++) { for (i=0; i < LENGTH_SSS_NR; i++) {
metric_re += d[i]*(((phase_re_nr[phase]*sss[2*i])>>SCALING_METRIC_SSS_NR) - ((phase_im_nr[phase]*sss[2*i+1])>>SCALING_METRIC_SSS_NR))
+ d[i]*(((phase_im_nr[phase]*sss[2*i])>>SCALING_METRIC_SSS_NR) + ((phase_re_nr[phase]*sss[2*i+1])>>SCALING_METRIC_SSS_NR)); metric_re += d[i]*(((phase_re_nr[phase]*sss[2*i])>>SCALING_METRIC_SSS_NR) - ((phase_im_nr[phase]*sss[2*i+1])>>SCALING_METRIC_SSS_NR));
#if 0
printf("i %d, phase %d/%d: metric %d, phase (%d,%d) sss (%d,%d) d %d\n",i,phase,PHASE_HYPOTHESIS_NUMBER,metric_re,phase_re_nr[phase],phase_im_nr[phase],sss[2*i],sss[1+(2*i)],d[i]);
#endif
} }
metric = metric_re; metric = metric_re;
...@@ -550,14 +578,14 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) ...@@ -550,14 +578,14 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
} }
//#ifdef DEBUG_SSS_NR //#ifdef DEBUG_SSS_NR
#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 = GET_NID2(frame_parms->Nid_cell); Nid2 = GET_NID2(frame_parms->Nid_cell);
Nid1 = GET_NID1(frame_parms->Nid_cell); Nid1 = GET_NID1(frame_parms->Nid_cell);
printf("Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max); printf("Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
} }
//#endif //#endif
return(0); return(0);
} }
...@@ -158,6 +158,128 @@ int32_t dot_product(int16_t *x, ...@@ -158,6 +158,128 @@ int32_t dot_product(int16_t *x,
#endif #endif
} }
int64_t dot_product64(int16_t *x,
int16_t *y,
uint32_t N, //must be a multiple of 8
uint8_t output_shift)
{
uint32_t n;
#if defined(__x86_64__) || defined(__i386__)
__m128i *x128,*y128,mmtmp1,mmtmp2,mmtmp3,mmcumul,mmcumul_re,mmcumul_im;
__m128i minus_i = _mm_set_epi16(-1,1,-1,1,-1,1,-1,1);
int32_t result;
x128 = (__m128i*) x;
y128 = (__m128i*) y;
mmcumul_re = _mm_setzero_si128();
mmcumul_im = _mm_setzero_si128();
for (n=0; n<(N>>2); n++) {
// printf("n=%d, x128=%p, y128=%p\n",n,x128,y128);
// print_shorts("x",&x128[0]);
// print_shorts("y",&y128[0]);
// this computes Re(z) = Re(x)*Re(y) + Im(x)*Im(y)
mmtmp1 = _mm_madd_epi16(x128[0],y128[0]);
// print_ints("retmp",&mmtmp1);
// mmtmp1 contains real part of 4 consecutive outputs (32-bit)
// shift and accumulate results
mmtmp1 = _mm_srai_epi32(mmtmp1,output_shift);
mmcumul_re = _mm_add_epi32(mmcumul_re,mmtmp1);
//print_ints("re",&mmcumul_re);
// this computes Im(z) = Re(x)*Im(y) - Re(y)*Im(x)
mmtmp2 = _mm_shufflelo_epi16(y128[0],_MM_SHUFFLE(2,3,0,1));
//print_shorts("y",&mmtmp2);
mmtmp2 = _mm_shufflehi_epi16(mmtmp2,_MM_SHUFFLE(2,3,0,1));
//print_shorts("y",&mmtmp2);
mmtmp2 = _mm_sign_epi16(mmtmp2,minus_i);
// print_shorts("y",&mmtmp2);
mmtmp3 = _mm_madd_epi16(x128[0],mmtmp2);
//print_ints("imtmp",&mmtmp3);
// mmtmp3 contains imag part of 4 consecutive outputs (32-bit)
// shift and accumulate results
mmtmp3 = _mm_srai_epi32(mmtmp3,output_shift);
mmcumul_im = _mm_add_epi32(mmcumul_im,mmtmp3);
//print_ints("im",&mmcumul_im);
x128++;
y128++;
}
// this gives Re Re Im Im
mmcumul = _mm_hadd_epi32(mmcumul_re,mmcumul_im);
//print_ints("cumul1",&mmcumul);
// this gives Re Im Re Im
mmcumul = _mm_hadd_epi32(mmcumul,mmcumul);
//print_ints("cumul2",&mmcumul);
//mmcumul = _mm_srai_epi32(mmcumul,output_shift);
// extract the lower half
result = _mm_extract_epi64(mmcumul,0);
//printf("result: (%d,%d)\n",((int32_t*)&result)[0],((int32_t*)&result)[1]);
_mm_empty();
_m_empty();
return(result);
#elif defined(__arm__)
int16x4_t *x_128=(int16x4_t*)x;
int16x4_t *y_128=(int16x4_t*)y;
int32x4_t tmp_re,tmp_im;
int32x4_t tmp_re1,tmp_im1;
int32x4_t re_cumul,im_cumul;
int32x2_t re_cumul2,im_cumul2;
int32x4_t shift = vdupq_n_s32(-output_shift);
int32x2x2_t result2;
int16_t conjug[4]__attribute__((aligned(16))) = {-1,1,-1,1} ;
re_cumul = vdupq_n_s32(0);
im_cumul = vdupq_n_s32(0);
for (n=0; n<(N>>2); n++) {
tmp_re = vmull_s16(*x_128++, *y_128++);
//tmp_re = [Re(x[0])Re(y[0]) Im(x[0])Im(y[0]) Re(x[1])Re(y[1]) Im(x[1])Im(y[1])]
tmp_re1 = vmull_s16(*x_128++, *y_128++);
//tmp_re1 = [Re(x1[1])Re(x2[1]) Im(x1[1])Im(x2[1]) Re(x1[1])Re(x2[2]) Im(x1[1])Im(x2[2])]
tmp_re = vcombine_s32(vpadd_s32(vget_low_s32(tmp_re),vget_high_s32(tmp_re)),
vpadd_s32(vget_low_s32(tmp_re1),vget_high_s32(tmp_re1)));
//tmp_re = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2]) Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])]
tmp_im = vmull_s16(vrev32_s16(vmul_s16(*x_128++,*(int16x4_t*)conjug)),*y_128++);
//tmp_im = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
tmp_im1 = vmull_s16(vrev32_s16(vmul_s16(*x_128++,*(int16x4_t*)conjug)),*y_128++);
//tmp_im1 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
tmp_im = vcombine_s32(vpadd_s32(vget_low_s32(tmp_im),vget_high_s32(tmp_im)),
vpadd_s32(vget_low_s32(tmp_im1),vget_high_s32(tmp_im1)));
//tmp_im = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
re_cumul = vqaddq_s32(re_cumul,vqshlq_s32(tmp_re,shift));
im_cumul = vqaddq_s32(im_cumul,vqshlq_s32(tmp_im,shift));
}
re_cumul2 = vpadd_s32(vget_low_s32(re_cumul),vget_high_s32(re_cumul));
im_cumul2 = vpadd_s32(vget_low_s32(im_cumul),vget_high_s32(im_cumul));
re_cumul2 = vpadd_s32(re_cumul2,re_cumul2);
im_cumul2 = vpadd_s32(im_cumul2,im_cumul2);
result2 = vzip_s32(re_cumul2,im_cumul2);
return(vget_lane_s32(result2.val[0],0));
#endif
}
#ifdef MAIN #ifdef MAIN
void print_bytes(char *s,__m128i *x) void print_bytes(char *s,__m128i *x)
......
...@@ -624,6 +624,14 @@ int8_t dB_fixed(uint32_t x) ...@@ -624,6 +624,14 @@ int8_t dB_fixed(uint32_t x)
return dB_power; return dB_power;
} }
uint8_t dB_fixed64(uint64_t x)
{
if (x<(((uint64_t)1)<<32)) return(dB_fixed((uint32_t)x));
else return(4*dB_table[255] + dB_fixed(x>>32));
}
int8_t dB_fixed2(uint32_t x, uint32_t y) int8_t dB_fixed2(uint32_t x, uint32_t y)
{ {
......
...@@ -74,7 +74,7 @@ static inline void cmac(__m128i a,__m128i b, __m128i *re32, __m128i *im32) ...@@ -74,7 +74,7 @@ static inline void cmac(__m128i a,__m128i b, __m128i *re32, __m128i *im32)
cmac_tmp = _mm_sign_epi16(b,*(__m128i*)reflip); cmac_tmp = _mm_sign_epi16(b,*(__m128i*)reflip);
cmac_tmp_re32 = _mm_madd_epi16(a,cmac_tmp); cmac_tmp_re32 = _mm_madd_epi16(a,cmac_tmp);
// cmac_tmp = _mm_shufflelo_epi16(b,_MM_SHUFFLE(2,3,0,1)); // cmac_tmp = _mm_shufflelo_epi16(b,_MM_SHUFFLE(2,3,0,1));
// cmac_tmp = _mm_shufflehi_epi16(cmac_tmp,_MM_SHUFFLE(2,3,0,1)); // cmac_tmp = _mm_shufflehi_epi16(cmac_tmp,_MM_SHUFFLE(2,3,0,1));
cmac_tmp = _mm_shuffle_epi8(b,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2)); cmac_tmp = _mm_shuffle_epi8(b,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
...@@ -4464,6 +4464,7 @@ void dft2048(int16_t *x,int16_t *y,int scale) ...@@ -4464,6 +4464,7 @@ void dft2048(int16_t *x,int16_t *y,int scale)
_mm_empty(); _mm_empty();
_m_empty(); _m_empty();
} }
void idft2048(int16_t *x,int16_t *y,int scale) void idft2048(int16_t *x,int16_t *y,int scale)
...@@ -4567,6 +4568,7 @@ void dft2048(int16_t *x,int16_t *y,int scale) ...@@ -4567,6 +4568,7 @@ void dft2048(int16_t *x,int16_t *y,int scale)
int i; int i;
simd256_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16_simd256(ONE_OVER_SQRT2_Q15); simd256_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
xtmpp = xtmp; xtmpp = xtmp;
for (i=0; i<4; i++) { for (i=0; i<4; i++) {
...@@ -4658,7 +4660,7 @@ void idft2048(int16_t *x,int16_t *y,int scale) ...@@ -4658,7 +4660,7 @@ void idft2048(int16_t *x,int16_t *y,int scale)
simd256_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16_simd256(ONE_OVER_SQRT2_Q15); simd256_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
xtmpp = xtmp; xtmpp = xtmp;
for (i=0; i<4; i++) { for (i=0; i<4; i++) {
transpose4_ooff_simd256(x256 ,xtmpp,128); transpose4_ooff_simd256(x256 ,xtmpp,128);
transpose4_ooff_simd256(x256+2,xtmpp+1,128); transpose4_ooff_simd256(x256+2,xtmpp+1,128);
...@@ -4801,7 +4803,7 @@ void dft4096(int16_t *x,int16_t *y,int scale) ...@@ -4801,7 +4803,7 @@ void dft4096(int16_t *x,int16_t *y,int scale)
} }
void idft4096(int16_t *x,int16_t *y,int scale) void idft4096(int16_t *x,int16_t *y,int scale)
{ {
...@@ -4851,7 +4853,7 @@ void idft4096(int16_t *x,int16_t *y,int scale) ...@@ -4851,7 +4853,7 @@ void idft4096(int16_t *x,int16_t *y,int scale)
y128+=16; y128+=16;
} }
} }
_mm_empty(); _mm_empty();
......
...@@ -350,6 +350,11 @@ int32_t dot_product(int16_t *x, ...@@ -350,6 +350,11 @@ int32_t dot_product(int16_t *x,
uint32_t N, //must be a multiple of 8 uint32_t N, //must be a multiple of 8
uint8_t output_shift); uint8_t output_shift);
int64_t dot_product64(int16_t *x,
int16_t *y,
uint32_t N, //must be a multiple of 8
uint8_t output_shift);
void dft12(int16_t *x,int16_t *y); void dft12(int16_t *x,int16_t *y);
void dft24(int16_t *x,int16_t *y,uint8_t scale_flag); void dft24(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft36(int16_t *x,int16_t *y,uint8_t scale_flag); void dft36(int16_t *x,int16_t *y,uint8_t scale_flag);
......
...@@ -920,6 +920,7 @@ typedef struct { ...@@ -920,6 +920,7 @@ typedef struct {
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - second index: ? [0..287] (hard coded) /// - second index: ? [0..287] (hard coded)
int32_t **dl_ch_estimates_ext; int32_t **dl_ch_estimates_ext;
int log2_maxh;
uint8_t pbch_a[NR_POLAR_PBCH_PAYLOAD_BITS>>3]; uint8_t pbch_a[NR_POLAR_PBCH_PAYLOAD_BITS>>3];
uint32_t pbch_a_interleaved; uint32_t pbch_a_interleaved;
uint32_t pbch_a_prime; uint32_t pbch_a_prime;
...@@ -1061,7 +1062,7 @@ typedef struct { ...@@ -1061,7 +1062,7 @@ typedef struct {
uint32_t dmrs_pbch_bitmap_nr[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE]; uint32_t dmrs_pbch_bitmap_nr[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE];
#endif #endif
t_nrPolar_paramsPtr nrPolar_params; t_nrPolar_params *nrPolar_params;
/// PBCH DMRS sequence /// PBCH DMRS sequence
uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD]; uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
...@@ -1129,6 +1130,8 @@ typedef struct { ...@@ -1129,6 +1130,8 @@ typedef struct {
// uint8_t prach_timer; // uint8_t prach_timer;
uint8_t decode_SIB; uint8_t decode_SIB;
uint8_t decode_MIB; uint8_t decode_MIB;
/// temporary offset during cell search prior to MIB decoding
int ssb_offset;
int rx_offset; /// Timing offset int rx_offset; /// Timing offset
int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP
int time_sync_cell; int time_sync_cell;
......
...@@ -160,10 +160,14 @@ typedef struct { ...@@ -160,10 +160,14 @@ typedef struct {
typedef struct NR_DL_FRAME_PARMS { typedef struct NR_DL_FRAME_PARMS {
/// frequency range /// frequency range
nr_frequency_range_e freq_range; nr_frequency_range_e freq_range;
/// Placeholder to replace overlapping fields below
nfapi_nr_rf_config_t rf_config;
/// Placeholder to replace SSB overlapping fields below
nfapi_nr_sch_config_t sch_config;
/// Number of resource blocks (RB) in DL /// Number of resource blocks (RB) in DL
uint8_t N_RB_DL; int N_RB_DL;
/// Number of resource blocks (RB) in UL /// Number of resource blocks (RB) in UL
uint8_t N_RB_UL; int N_RB_UL;
/// total Number of Resource Block Groups: this is ceil(N_PRB/P) /// total Number of Resource Block Groups: this is ceil(N_PRB/P)
uint8_t N_RBG; uint8_t N_RBG;
/// Total Number of Resource Block Groups SubSets: this is P /// Total Number of Resource Block Groups SubSets: this is P
......
...@@ -111,9 +111,9 @@ int nr_get_ssb_start_symbol(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *f ...@@ -111,9 +111,9 @@ int nr_get_ssb_start_symbol(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *f
void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp) void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp)
{ {
int start_rb = cfg->sch_config.n_ssb_crb.value / pow(2,cfg->subframe_config.numerology_index_mu.value); int start_rb = cfg->sch_config.n_ssb_crb.value / (1<<cfg->subframe_config.numerology_index_mu.value);
fp->ssb_start_subcarrier = 12 * start_rb + cfg->sch_config.ssb_subcarrier_offset.value; fp->ssb_start_subcarrier = 12 * start_rb + cfg->sch_config.ssb_subcarrier_offset.value;
LOG_D(PHY, "SSB first subcarrier %d\n", fp->ssb_start_subcarrier); LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,start_rb,cfg->sch_config.ssb_subcarrier_offset.value);
} }
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) { void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) {
...@@ -135,12 +135,13 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) { ...@@ -135,12 +135,13 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) {
if (subframe == ss_subframe) if (subframe == ss_subframe)
{ {
// Current implementation is based on SSB in first half frame, first candidate // Current implementation is based on SSB in first half frame, first candidate
LOG_I(PHY,"SS TX: frame %d, subframe %d, start_symbol %d\n",frame,subframe, ssb_start_symbol); LOG_D(PHY,"SS TX: frame %d, subframe %d, start_symbol %d\n",frame,subframe, ssb_start_symbol);
nr_generate_pss(gNB->d_pss, txdataF, AMP, ssb_start_symbol, cfg, fp); nr_generate_pss(gNB->d_pss, txdataF, AMP, ssb_start_symbol, cfg, fp);
nr_generate_sss(gNB->d_sss, txdataF, AMP_OVER_2, ssb_start_symbol, cfg, fp); nr_generate_sss(gNB->d_sss, txdataF, AMP_OVER_2, ssb_start_symbol, cfg, fp);
if (!(frame&7)){ if (!(frame&7)){
LOG_D(PHY,"%d.%d : pbch_configured %d\n",frame,subframe,gNB->pbch_configured);
if (gNB->pbch_configured != 1)return; if (gNB->pbch_configured != 1)return;
gNB->pbch_configured = 0; gNB->pbch_configured = 0;
} }
...@@ -182,7 +183,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -182,7 +183,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
num_dci = gNB->pdcch_vars.num_dci; num_dci = gNB->pdcch_vars.num_dci;
if (num_dci) { if (num_dci) {
LOG_I(PHY, "[gNB %d] Frame %d subframe %d \ LOG_D(PHY, "[gNB %d] Frame %d subframe %d \
Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, subframe, num_dci); Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, subframe, num_dci);
uint8_t slot_idx = gNB->pdcch_vars.dci_alloc[0].pdcch_params.first_slot; uint8_t slot_idx = gNB->pdcch_vars.dci_alloc[0].pdcch_params.first_slot;
......
...@@ -101,13 +101,12 @@ int main(int argc, char **argv) ...@@ -101,13 +101,12 @@ int main(int argc, char **argv)
char input_val_str[50],input_val_str2[50]; char input_val_str[50],input_val_str2[50];
uint8_t frame_mod4,num_pdcch_symbols = 0; uint8_t frame_mod4,num_pdcch_symbols = 0;
uint16_t NB_RB=25;
SCM_t channel_model=AWGN;//Rayleigh1_anticorr; SCM_t channel_model=AWGN;//Rayleigh1_anticorr;
double pbch_sinr; double pbch_sinr;
int pbch_tx_ant; int pbch_tx_ant;
uint8_t N_RB_DL=106,mu=1; int N_RB_DL=273,mu=1;
unsigned char frame_type = 0; unsigned char frame_type = 0;
unsigned char pbch_phase = 0; unsigned char pbch_phase = 0;
...@@ -119,7 +118,8 @@ int main(int argc, char **argv) ...@@ -119,7 +118,8 @@ int main(int argc, char **argv)
nfapi_nr_config_request_t *gNB_config; nfapi_nr_config_request_t *gNB_config;
int ret; int ret;
int run_initial_sync=0;
cpuf = get_cpu_freq_GHz(); cpuf = get_cpu_freq_GHz();
if ( load_configmodule(argc,argv) == 0) { if ( load_configmodule(argc,argv) == 0) {
...@@ -129,7 +129,7 @@ int main(int argc, char **argv) ...@@ -129,7 +129,7 @@ int main(int argc, char **argv)
logInit(); logInit();
randominit(0); randominit(0);
while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:N:F:GR:dP:")) != -1) { while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:N:F:GR:dP:I")) != -1) {
switch (c) { switch (c) {
case 'f': case 'f':
write_output_file=1; write_output_file=1;
...@@ -281,7 +281,10 @@ int main(int argc, char **argv) ...@@ -281,7 +281,10 @@ int main(int argc, char **argv)
printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase);
break; break;
case 'I':
run_initial_sync=1;
break;
default: default:
case 'h': case 'h':
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n",
...@@ -314,19 +317,8 @@ int main(int argc, char **argv) ...@@ -314,19 +317,8 @@ int main(int argc, char **argv)
if (snr1set==0) if (snr1set==0)
snr1 = snr0+10; snr1 = snr0+10;
gNB2UE = new_channel_desc_scm(n_tx,
n_rx,
channel_model,
61.44e6, //N_RB2sampling_rate(N_RB_DL),
40e6, //N_RB2channel_bandwidth(N_RB_DL),
0,
0,
0);
if (gNB2UE==NULL) { printf("Initializing gNodeB for mu %d, N_RB_DL %d\n",mu,N_RB_DL);
msg("Problem generating channel model. Exiting.\n");
exit(-1);
}
RC.gNB = (PHY_VARS_gNB***) malloc(sizeof(PHY_VARS_gNB **)); RC.gNB = (PHY_VARS_gNB***) malloc(sizeof(PHY_VARS_gNB **));
RC.gNB[0] = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *)); RC.gNB[0] = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *));
...@@ -337,10 +329,45 @@ int main(int argc, char **argv) ...@@ -337,10 +329,45 @@ int main(int argc, char **argv)
frame_parms->nb_antennas_tx = n_tx; frame_parms->nb_antennas_tx = n_tx;
frame_parms->nb_antennas_rx = n_rx; frame_parms->nb_antennas_rx = n_rx;
frame_parms->N_RB_DL = N_RB_DL; frame_parms->N_RB_DL = N_RB_DL;
frame_parms->N_RB_UL = N_RB_DL;
nr_phy_config_request_sim(gNB); nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu);
phy_init_nr_gNB(gNB,0,0); phy_init_nr_gNB(gNB,0,0);
double fs,bw;
if (mu == 1 && N_RB_DL == 217) {
fs = 122.88e6;
bw = 80e6;
}
else if (mu == 1 && N_RB_DL == 245) {
fs = 122.88e6;
bw = 90e6;
}
else if (mu == 1 && N_RB_DL == 273) {
fs = 122.88e6;
bw = 100e6;
}
else if (mu == 1 && N_RB_DL == 106) {
fs = 61.44e6;
bw = 40e6;
}
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
gNB2UE = new_channel_desc_scm(n_tx,
n_rx,
channel_model,
fs,
bw,
0,
0,
0);
if (gNB2UE==NULL) {
msg("Problem generating channel model. Exiting.\n");
exit(-1);
}
frame_length_complex_samples = frame_parms->samples_per_subframe; frame_length_complex_samples = frame_parms->samples_per_subframe;
frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP;
...@@ -362,6 +389,7 @@ int main(int argc, char **argv) ...@@ -362,6 +389,7 @@ int main(int argc, char **argv)
r_im[i] = malloc(frame_length_complex_samples*sizeof(double)); r_im[i] = malloc(frame_length_complex_samples*sizeof(double));
bzero(r_im[i],frame_length_complex_samples*sizeof(double)); bzero(r_im[i],frame_length_complex_samples*sizeof(double));
printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
txdata[i] = malloc(frame_length_complex_samples*sizeof(int)); txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
bzero(r_re[i],frame_length_complex_samples*sizeof(int)); bzero(r_re[i],frame_length_complex_samples*sizeof(int));
...@@ -375,23 +403,31 @@ int main(int argc, char **argv) ...@@ -375,23 +403,31 @@ int main(int argc, char **argv)
//configure UE //configure UE
UE = malloc(sizeof(PHY_VARS_NR_UE)); UE = malloc(sizeof(PHY_VARS_NR_UE));
memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
phy_init_nr_top(frame_parms); phy_init_nr_top(UE);
if (run_initial_sync==1) UE->is_synchronized = 0;
else UE->is_synchronized = 1;
UE->perfect_ce = 0;
if (init_nr_ue_signal(UE, 1, 0) != 0) if (init_nr_ue_signal(UE, 1, 0) != 0)
{ {
printf("Error at UE NR initialisation\n"); printf("Error at UE NR initialisation\n");
exit(-1); exit(-1);
} }
nr_gold_pbch(UE);
// generate signal // generate signal
if (input_fd==NULL) { if (input_fd==NULL) {
gNB->pbch_configured = 1;
for (int i=0;i<4;i++) gNB->pbch_pdu[i]=i+1;
nr_common_signal_procedures (gNB,frame,subframe); nr_common_signal_procedures (gNB,frame,subframe);
} }
/*
LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
if (gNB->frame_parms.nb_antennas_tx>1) if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1); LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);
*/
//TODO: loop over slots //TODO: loop over slots
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) { for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) { if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) {
...@@ -408,18 +444,22 @@ int main(int argc, char **argv) ...@@ -408,18 +444,22 @@ int main(int argc, char **argv)
frame_parms); frame_parms);
} }
} }
/*
LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1); LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1);
if (gNB->frame_parms.nb_antennas_tx>1) if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1); LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1);
*/
int txlev = signal_energy(&txdata[0][5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
// printf("txlev %d (%f)\n",txlev,10*log10(txlev));
for (i=0; i<frame_length_complex_samples; i++) { for (i=0; i<frame_length_complex_samples; i++) {
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) { for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
}
} }
}
for (SNR=snr0; SNR<snr1; SNR+=.2) { for (SNR=snr0; SNR<snr1; SNR+=.2) {
...@@ -433,13 +473,15 @@ int main(int argc, char **argv) ...@@ -433,13 +473,15 @@ int main(int argc, char **argv)
//multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0); //multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0);
//AWGN //AWGN
sigma2_dB = SNR; sigma2_dB = 10*log10((double)txlev)-SNR;
sigma2 = pow(10,sigma2_dB/10); sigma2 = pow(10,sigma2_dB/10);
// printf("sigma2 %f (%f dB)\n",sigma2,sigma2_dB);
for (i=0; i<frame_length_complex_samples; i++) { for (i=0; i<frame_length_complex_samples; i++) {
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
} }
} }
...@@ -448,13 +490,53 @@ int main(int argc, char **argv) ...@@ -448,13 +490,53 @@ int main(int argc, char **argv)
if (gNB->frame_parms.nb_antennas_tx>1) if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_length_complex_samples,1,1); LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_length_complex_samples,1,1);
} }
if (UE->is_synchronized == 0) {
ret = nr_initial_sync(UE, normal_txrx); ret = nr_initial_sync(UE, normal_txrx);
printf("nr_initial_sync1 returns %d\n",ret); printf("nr_initial_sync1 returns %d\n",ret);
if (ret<0) n_errors++;
}
else {
UE->rx_offset=0;
//symbol 1
nr_slot_fep(UE,
5,
0,
0,
0,
1,
NR_PBCH_EST);
//symbol 2
nr_slot_fep(UE,
6,
0,
0,
0,
1,
NR_PBCH_EST);
//symbol 3
nr_slot_fep(UE,
7,
0,
0,
0,
1,
NR_PBCH_EST);
ret = nr_rx_pbch(UE,
&UE->proc.proc_rxtx[0],
UE->pbch_vars[0],
frame_parms,
0,
SISO,
UE->high_speed_flag);
if (ret<0) n_errors++;
}
} //noise trials } //noise trials
printf("SNR %f : n_errors = %d/%d\n", SNR,n_errors,n_trials); printf("SNR %f : n_errors (negative CRC) = %d/%d\n", SNR,n_errors,n_trials);
if (n_trials==1) if (n_trials==1)
break; break;
......
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