From 34f260769ba31a2ee1afc84ba3b0272916565999 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 8 Mar 2024 11:35:06 +0100 Subject: [PATCH 1/9] make better log text for ue synchronization, make better sync code, no functional change --- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 100 ++++-------------- openair1/PHY/NR_UE_TRANSPORT/pss_nr.c | 10 +- openair1/PHY/NR_UE_TRANSPORT/sss_nr.c | 15 +-- openair1/PHY/defs_nr_UE.h | 1 - 4 files changed, 35 insertions(+), 91 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 09ea85fbd4..6276766c65 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -45,7 +45,6 @@ #include "PHY/NR_REFSIG/sss_nr.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" -extern openair0_config_t openair0_cfg[]; //static nfapi_nr_config_request_t config_t; //static nfapi_nr_config_request_t* config =&config_t; int cnt=0; @@ -53,94 +52,36 @@ int cnt=0; // #define DEBUG_INITIAL_SYNCH #define DUMP_PBCH_CH_ESTIMATES 0 -// create a new node of SSB structure -NR_UE_SSB* create_ssb_node(uint8_t i, uint8_t h) { - NR_UE_SSB *new_node = (NR_UE_SSB*)malloc(sizeof(NR_UE_SSB)); - new_node->i_ssb = i; - new_node->n_hf = h; - new_node->c_re = 0; - new_node->c_im = 0; - new_node->metric = 0; - new_node->next_ssb = NULL; - - return new_node; -} - - -// insertion of the structure in the ordered list (highest metric first) -NR_UE_SSB* insert_into_list(NR_UE_SSB *head, NR_UE_SSB *node) { - - if (node->metric > head->metric) { - node->next_ssb = head; - head = node; - return head; - } - - NR_UE_SSB *current = head; - while (current->next_ssb !=NULL) { - NR_UE_SSB *temp=current->next_ssb; - if(node->metric > temp->metric) { - node->next_ssb = temp; - current->next_ssb = node; - return head; - } - else - current = temp; - } - current->next_ssb = node; - - return head; -} - - -void free_list(NR_UE_SSB *node) { - if (node->next_ssb != NULL) - free_list(node->next_ssb); - free(node); -} - -static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, - PHY_VARS_NR_UE *ue, - int pbch_initial_symbol, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) +int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, + PHY_VARS_NR_UE *ue, + int pbch_initial_symbol, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - NR_UE_SSB *best_ssb = NULL; - NR_UE_SSB *current_ssb; - - uint8_t N_L = (frame_parms->Lmax == 4)? 4:8; - uint8_t N_hf = (frame_parms->Lmax == 4)? 2:1; - + const int N_L = (frame_parms->Lmax == 4) ? 4 : 8; + const int N_hf = (frame_parms->Lmax == 4) ? 2 : 1; + NR_UE_SSB best_ssb[N_L * N_hf]; + NR_UE_SSB *current_ssb = best_ssb; // loops over possible pbch dmrs cases to retrive best estimated i_ssb (and n_hf for Lmax=4) for multiple ssb detection for (int hf = 0; hf < N_hf; hf++) { for (int l = 0; l < N_L ; l++) { - // initialization of structure - current_ssb = create_ssb_node(l,hf); - + *current_ssb = (NR_UE_SSB){.i_ssb = l, .n_hf = hf}; start_meas(&ue->dlsch_channel_estimation_stats); // computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf for(int i=pbch_initial_symbol; idlsch_channel_estimation_stats); - - current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im; - - // generate a list of SSB structures - if (best_ssb == NULL) - best_ssb = current_ssb; - else - best_ssb = insert_into_list(best_ssb,current_ssb); + current_ssb->metric = current_ssb->c_re * current_ssb->c_re + current_ssb->c_im * current_ssb->c_im; + current_ssb++; } } - NR_UE_SSB *temp_ptr = best_ssb; - bool ret = false; - while (!ret && temp_ptr != NULL) { - + NR_UE_SSB *temp_ptr=best_ssb; + while (ret!=0 && temp_ptr != NULL) { start_meas(&ue->dlsch_channel_estimation_stats); // computing channel estimation for selected best ssb const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; @@ -167,14 +108,13 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, 1); } - temp_ptr=temp_ptr->next_ssb; + temp_ptr++; } - free_list(best_ssb); - - if (ret) { - frame_parms->nb_antenna_ports_gNB = 1; // pbch_tx_ant; + if (ret == 0) { LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); + } else { + LOG_W(PHY, "[UE%d] Initial sync: pbch not decoded, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); } return ret; } @@ -394,11 +334,7 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, i // send sync status to higher layers later when timing offset converge to target timing } - LOG_I(PHY, - "[UE %d] Measured Carrier Frequency %.0f Hz (offset %d Hz)\n", - ue->Mod_id, - openair0_cfg[0].rx_freq[0] + ue->common_vars.freq_offset, - ue->common_vars.freq_offset); + LOG_I(PHY, "[UE %d] Measured Carrier Frequency offset %d Hz\n", ue->Mod_id, ue->common_vars.freq_offset); } else { #ifdef DEBUG_INITIAL_SYNC LOG_I(PHY,"[UE%d] Initial sync : PBCH not ok\n",ue->Mod_id); diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index 7323d27dbb..b2c0a6242b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -672,7 +672,15 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i *nid2 = pss_source; - LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf\n", pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]),ffo_est); + LOG_I(PHY, + "[UE] nr_synchro_time: Sync source (nid2) = %d, Peak found at pos %d, val = %ld (%d dB power over signal avg %d dB), ffo " + "%lf\n", + pss_source, + peak_position, + peak_value, + dB_fixed64(peak_value), + dB_fixed64(avg[pss_source]), + ffo_est); if (peak_value < 5*avg[pss_source]) return(-1); diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index ac2ae3ac5e..0ec5f23b40 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -503,15 +503,15 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, Nid1 = GET_NID1(frame_parms->Nid_cell); LOG_D(PHY,"Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max); } - //#endif - - if (Nid1==N_ID_1_NUMBER) - return false; - + // #endif int re = 0; int im = 0; if (Nid1 == N_ID_1_NUMBER) { - LOG_I(PHY,"Failed to detect SSS after PSS\n"); + LOG_W(PHY, + "Failed to detect SSS after PSS, metric of SSS %d, threshold to consider SSS valid %d, detected PCI: %d\n", + *tot_metric, + SSS_METRIC_FLOOR_NR, + frame_parms->Nid_cell); return false; } d = (int16_t *)&d_sss[Nid2][Nid1]; @@ -524,7 +524,8 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, double ffo_pss = ((double)ue->common_vars.freq_offset)/frame_parms->subcarrier_spacing; LOG_W(NR_PHY, - "ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n", + "SSS detected, PCI: %d, ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n", + frame_parms->Nid_cell, ffo_pss, (int)(ffo_pss * frame_parms->subcarrier_spacing), ffo_sss, diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index ef3be45717..0e46beb0e3 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -314,7 +314,6 @@ typedef struct NR_UE_SSB { uint32_t metric; // metric to order SSB hypothesis uint32_t c_re; uint32_t c_im; - struct NR_UE_SSB *next_ssb; } NR_UE_SSB; typedef struct UE_NR_SCAN_INFO_s { From 39400a458ef23ea553ae60f1c281884578414a6a Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 8 Mar 2024 15:17:09 +0100 Subject: [PATCH 2/9] change partially pbch detection to c16_t instead of hidden complex in int16_t and int32_t --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 4 +- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 92 +++-- openair1/PHY/NR_REFSIG/nr_refsig.h | 22 +- openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 9 +- openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c | 5 +- openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h | 28 +- .../nr_dl_channel_estimation.c | 367 ++++++------------ .../PHY/NR_UE_ESTIMATION/nr_ue_measurements.c | 8 +- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 7 +- openair1/PHY/TOOLS/tools_defs.h | 19 + openair1/PHY/defs_nr_UE.h | 4 +- 11 files changed, 235 insertions(+), 330 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 3d8c375072..2cbab9d9d3 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -114,7 +114,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], - (int32_t *)pilot, + pilot, (1000 + p), 0, nb_rb_pusch, @@ -129,7 +129,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index); AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); - nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, (int32_t *)pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); + nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); #ifdef DEBUG_PUSCH printf ("NR_UL_CHANNEL_EST: index %d, u %d,v %d\n", index, u, v); LOG_M("gNb_DMRS_SEQ.m","gNb_DMRS_SEQ", dmrs_seq,6*nb_rb_pusch,1,1); diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 17655b581a..c96d4e7c47 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -51,10 +51,10 @@ static const int wt2[12][2] = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}}; // complex conjugate of mod table -static const short nr_rx_mod_table[14] = - {0, 0, 23170, -23170, -23170, 23170, 23170, -23170, 23170, 23170, -23170, -23170, -23170, 23170}; -static const short nr_rx_nmod_table[14] = - {0, 0, -23170, 23170, 23170, -23170, -23170, 23170, -23170, -23170, 23170, 23170, 23170, -23170}; +static const c16_t nr_rx_mod_table[7] = + {{0, 0}, {23170, -23170}, {-23170, 23170}, {23170, -23170}, {23170, 23170}, {-23170, -23170}, {-23170, 23170}}; +static const c16_t nr_rx_nmod_table[7] = + {{0, 0}, {-23170, 23170}, {23170, -23170}, {-23170, 23170}, {-23170, -23170}, {23170, 23170}, {23170, -23170}}; int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p) { if (dmrs_config_type == pusch_dmrs_type1) { @@ -67,7 +67,7 @@ int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p) { int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, unsigned int Ns, unsigned int *nr_gold_pusch, - int32_t *output, + c16_t *output, unsigned short p, unsigned char lp, unsigned short nb_pusch_rb, @@ -92,16 +92,21 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, for (int i=dmrs_offset; i>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); - ((int16_t*)output)[k<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; - ((int16_t*)output)[(k<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; + output[k] = mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx]; #ifdef DEBUG_PUSCH printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", dmrs_type, p, nb_pusch_rb); printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]); - printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1), - (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[k<<1], ((int16_t*)output)[(k<<1)+1]); + printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", + i, + idx, + nr_gold_pusch[(i << 1) >> 5], + (((nr_gold_pusch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1), + (((nr_gold_pusch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1), + output[k].r, + output[k].i); #endif } @@ -115,11 +120,10 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, return(0); } - int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, unsigned int Ns, unsigned int *nr_gold_pdsch, - int32_t *output, + c16_t *output, unsigned short p, unsigned char lp, unsigned short nb_pdsch_rb, @@ -139,11 +143,10 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, if (ue->frame_parms.Ncp == NORMAL) { for (int i = 0; i < nb_pdsch_rb * ((config_type == NFAPI_NR_DMRS_TYPE1) ? 6 : 4); i++) { w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]); - const short *mod_table = (w == 1) ? nr_rx_mod_table : nr_rx_nmod_table; + const c16_t *mod_table = (w == 1) ? nr_rx_mod_table : nr_rx_nmod_table; idx = ((((nr_gold_pdsch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1) << 1) ^ (((nr_gold_pdsch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1); - ((int16_t *)output)[i << 1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx) << 1]; - ((int16_t *)output)[(i << 1) + 1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx) << 1) + 1]; + output[i] = mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx]; #ifdef DEBUG_PDSCH printf("nr_pdsch_dmrs_rx dmrs config type %d port %d nb_pdsch_rb %d\n", config_type, p, nb_pdsch_rb); printf("wf[%d] = %d wt[%d]= %d\n", i & 1, wf[p - 1000][i & 1], lp, wt[p - 1000][lp]); @@ -153,8 +156,8 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, nr_gold_pdsch[(i << 1) >> 5], (((nr_gold_pdsch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1), (((nr_gold_pdsch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1), - ((int16_t *)output)[i << 1], - ((int16_t *)output)[(i << 1) + 1]); + output[i].r, + output[i].i); #endif } } else { @@ -167,11 +170,10 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, return(0); } - int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, unsigned int Ns, unsigned int *nr_gold_pdcch, - int32_t *output, + c16_t *output, unsigned short p, unsigned short nb_rb_coreset) { @@ -182,12 +184,17 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, if (p==2000) { for (int i=0; i<((nb_rb_coreset*6)>>1); i++) { idx = ((((nr_gold_pdcch[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pdcch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); - ((int16_t*)output)[i<<1] = nr_rx_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; - ((int16_t*)output)[(i<<1)+1] = nr_rx_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; + output[i] = nr_rx_mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx]; #ifdef DEBUG_PDCCH if (i<8) - printf("i %d idx %d pdcch gold %u b0-b1 %d-%d mod_dmrs %d %d addr %p\n", i, idx, nr_gold_pdcch[(i<<1)>>5], (((nr_gold_pdcch[(i<<1)>>5])>>((i<<1)&0x1f))&1), - (((nr_gold_pdcch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1],&output[0]); + printf("i %d idx %d pdcch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", + i, + idx, + nr_gold_pdcch[(i << 1) >> 5], + (((nr_gold_pdcch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1), + (((nr_gold_pdcch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1), + output[i].r, + output[i].i); #endif } } @@ -195,8 +202,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, return(0); } - -int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, int32_t *output) +int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, c16_t *output) { int m,m0,m1; uint8_t idx=0; @@ -217,13 +223,12 @@ int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, int32_t *output) /// QPSK modulation for (m=m0; m>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]; - + output[m - m0] = nr_rx_mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx]; + #ifdef DEBUG_PBCH if (m<16) {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\n", m, output[m].r, output[m].i); } #endif } @@ -237,7 +242,7 @@ int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, int32_t *output) \param length is number of RE in a OFDM symbol \param *output pointer to all ptrs RE in a OFDM symbol */ -void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order) +void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, c16_t *output, uint16_t offset, int mod_order) { uint8_t idx, b_idx; for (int i=0; i>b_idx)&1)<<(mod_order-j-1); } - output[i<<1] = nr_rx_mod_table[(offset+idx)<<1]; - output[(i<<1)+1] = nr_rx_mod_table[((offset+idx)<<1)+1]; + output[i] = nr_rx_mod_table[offset + idx]; } } int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB, unsigned int Ns, int16_t *dmrs_seq, - int32_t *output, + c16_t *output, unsigned short p, unsigned char lp, unsigned short nb_pusch_rb, @@ -278,19 +282,21 @@ int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB, nb_dmrs = NR_NB_SC_PER_RB/2; // for DMRS TYPE 1 - 6 DMRS REs present per RB for (int i=dmrs_offset; iframe_parms.samples_per_slot_wCP]) { - int pilot[200] __attribute__((aligned(16))); + c16_t pilot[200] __attribute__((aligned(16))); unsigned int pilot_cnt; - int16_t ch[2],*pil,*rxF; int symbol_offset; uint8_t ssb_index=current_ssb->i_ssb; @@ -656,128 +656,71 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, unsigned int k = ue->frame_parms.Nid_cell % 4; -#ifdef DEBUG_PBCH - printf("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol); -#endif + DEBUG_PBCH("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, k=%d symbol %d\n", + proc->gNB_id, + ue->frame_parms.ofdm_symbol_size, + ue->frame_parms.Ncp, + k, + symbol); // generate pilot // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]); + nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], pilot); for (int aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { int re_offset = ssb_offset; - pil = (int16_t *)&pilot[0]; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + c16_t *pil = pilot; + c16_t *rxF = &rxdataF[aarx][symbol_offset + k]; -#ifdef DEBUG_PBCH - 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("rxF addr %p\n", rxF); -#endif + DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", ue->frame_parms.N_RB_DL); + DEBUG_PBCH("k %d, first_carrier %d\n", k, ue->frame_parms.first_carrier_offset); //if ((ue->frame_parms.N_RB_DL&1)==0) { // Treat first 2 pilots specially (left edge) - 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); + current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); - current_ssb->c_re += ch[0]; - current_ssb->c_im += ch[1]; + DEBUG_PBCH("ch 0 %d\n", pil->r * rxF[re_offset].r - pil->i * rxF[re_offset].i); + DEBUG_PBCH("pilot 0 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); -#ifdef DEBUG_PBCH - 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 - - pil += 2; + pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); + DEBUG_PBCH("pilot 1 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->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); - - current_ssb->c_re += ch[0]; - current_ssb->c_im += ch[1]; - -#ifdef DEBUG_PBCH - 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 - - pil += 2; + pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); - current_ssb->c_re += ch[0]; - current_ssb->c_im += ch[1]; + DEBUG_PBCH("pilot 2 : rxF - > (%d,%d), pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); -#ifdef DEBUG_PBCH - 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 - - pil += 2; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - - for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt += 3) { - - // if (pilot_cnt == 30) - // rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)]; + pil++; + re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; + for (pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) { // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; - re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size; } - 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); - - current_ssb->c_re += ch[0]; - current_ssb->c_im += ch[1]; + current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); -#ifdef DEBUG_PBCH - printf("pilot %u : 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 + DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); - pil += 2; + pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - 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); + current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); - current_ssb->c_re += ch[0]; - current_ssb->c_im += ch[1]; - -#ifdef DEBUG_PBCH - printf("pilot %u : 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 - pil += 2; + DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 1, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); + pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - 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); - - current_ssb->c_re += ch[0]; - current_ssb->c_im += ch[1]; - -#ifdef DEBUG_PBCH - printf("pilot %u : 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 - - pil += 2; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); + DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 2, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); + pil++; + re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; } - - - //} - } return(0); } @@ -794,33 +737,31 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { int Ns = proc->nr_slot_rx; - int pilot[200] __attribute__((aligned(16))); - unsigned short k; - unsigned int pilot_cnt; - int16_t *pil, *rxF, *dl_ch; - const int16_t *fl, *fm, *fr; - int ch_offset,symbol_offset; + c16_t pilot[200] __attribute__((aligned(16))); //int slot_pbch; - uint8_t nushift; - nushift = ue->frame_parms.Nid_cell % 4; + const int nushift = ue->frame_parms.Nid_cell % 4; 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; - ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; + const int ch_offset = ue->frame_parms.ofdm_symbol_size * symbol; AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss); - symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol; + const int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol; - - k = nushift; - -#ifdef DEBUG_PBCH - printf("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ch_offset, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol); -#endif + const int k = nushift; + const c16_t *fl, *fm, *fr; + DEBUG_PBCH("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", + proc->gNB_id, + ch_offset, + ue->frame_parms.ofdm_symbol_size, + ue->frame_parms.Ncp, + Ns, + k, + symbol); switch (k) { case 0: @@ -903,136 +844,91 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]); + nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], pilot); for (int aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { int re_offset = ssb_offset; - pil = (int16_t *)&pilot[0]; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + c16_t *pil = pilot; + c16_t *rxF = &rxdataF[aarx][symbol_offset + k]; + c16_t *dl_ch = &dl_ch_estimates[aarx][ch_offset]; - memset(dl_ch,0,sizeof(struct complex16)*(ue->frame_parms.ofdm_symbol_size)); + memset(dl_ch, 0, sizeof(c16_t) * ue->frame_parms.ofdm_symbol_size); -#ifdef DEBUG_PBCH - 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("rxF addr %p\n", rxF); - printf("dl_ch addr %p\n",dl_ch); -#endif + DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", ue->frame_parms.N_RB_DL); + DEBUG_PBCH("k %d, first_carrier %d\n", k, ue->frame_parms.first_carrier_offset); // Treat first 2 pilots specially (left edge) - int16_t ch[2]; - 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); + c16_t ch; + ch = c16mulShift(*pil, rxF[re_offset], 15); + DEBUG_PBCH("pilot 0: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i); + multaddRealVectorComplexScalar(fl, ch, dl_ch, 16); + pil++; + re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; -#ifdef DEBUG_PBCH - 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; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + ch = c16mulShift(*pil, rxF[re_offset], 15); - //for (int i= 0; i<8; i++) - //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); + DEBUG_PBCH("pilot 1: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i); + multaddRealVectorComplexScalar(fm, ch, dl_ch, 16); + pil++; + re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; - 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 = c16mulShift(*pil, rxF[re_offset], 15); - -#ifdef DEBUG_PBCH - 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; - 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_PBCH - 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; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + DEBUG_PBCH("pilot 2: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i); + multaddRealVectorComplexScalar(fr, ch, dl_ch, 16); + pil++; + re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; dl_ch += 24; - for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt += 3) { - + for (int 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; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size; dl_ch += 288; } - 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 = c16mulShift(*pil, rxF[re_offset], 15); + DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", + pilot_cnt, + rxF[re_offset].r, + rxF[re_offset].i, + ch.r, + ch.i, + pil->r, + pil->i); + multaddRealVectorComplexScalar(fl, ch, dl_ch, 16); -#ifdef DEBUG_PBCH - printf("pilot %u : 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; + pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - 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_PBCH - printf("pilot %u : 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; + ch = c16mulShift(*pil, rxF[re_offset], 15); + DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", + pilot_cnt + 1, + rxF[re_offset].r, + rxF[re_offset].i, + ch.r, + ch.i, + pil->r, + pil->i); + multaddRealVectorComplexScalar(fm, ch, dl_ch, 16); + pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - 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_PBCH - printf("pilot %u : 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 - - multadd_real_vector_complex_scalar(fr, - ch, - dl_ch, - 16); - pil += 2; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - dl_ch += 24; - + ch = c16mulShift(*pil, rxF[re_offset], 15); + DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", + pilot_cnt + 2, + rxF[re_offset].r, + rxF[re_offset].i, + ch.r, + ch.i, + pil->r, + pil->i); + multaddRealVectorComplexScalar(fr, ch, dl_ch, 16); + pil++; + re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; + dl_ch += 12; } if( dmrss == 2) // update time statistics for last PBCH symbol @@ -1117,7 +1013,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot int pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16))); // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pdcch_dmrs_rx(ue, Ns, ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0], 2000, (nb_rb_coreset + dmrs_ref)); + nr_pdcch_dmrs_rx(ue, Ns, ue->nr_gold_pdcch[gNB_id][Ns][symbol], (c16_t *)pilot, 2000, (nb_rb_coreset + dmrs_ref)); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { @@ -1655,14 +1551,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, c16_t pilot[3280] __attribute__((aligned(16))); // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pdsch_dmrs_rx(ue, - Ns, - ue->nr_gold_pdsch[gNB_id][Ns][symbol][nscid], - (int32_t *)pilot, - 1000 + p, - 0, - nb_rb_pdsch + rb_offset, - config_type); + nr_pdsch_dmrs_rx(ue, Ns, ue->nr_gold_pdsch[gNB_id][Ns][symbol][nscid], pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type); uint8_t nushift = 0; if (config_type == NFAPI_NR_DMRS_TYPE1) { diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 840577d296..35e17531e3 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -92,15 +92,15 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, int, ue->measurements.rx_spatial_power, NUMBER_OF_CONNECTED_gNB_MAX, - frame_parms->nb_antenna_ports_gNB, - frame_parms->nb_antennas_rx, + cmax(frame_parms->nb_antenna_ports_gNB,1), + cmax(frame_parms->nb_antennas_rx,1), false); allocCast3D(rx_spatial_power_dB, unsigned short, ue->measurements.rx_spatial_power_dB, NUMBER_OF_CONNECTED_gNB_MAX, - frame_parms->nb_antenna_ports_gNB, - frame_parms->nb_antennas_rx, + cmax(frame_parms->nb_antenna_ports_gNB,1), + cmax(frame_parms->nb_antennas_rx,1), false); // signal measurements diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 6276766c65..8d1253274a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -74,14 +74,11 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, for(int i=pbch_initial_symbol; idlsch_channel_estimation_stats); - - current_ssb->metric = current_ssb->c_re * current_ssb->c_re + current_ssb->c_im * current_ssb->c_im; current_ssb++; } } - NR_UE_SSB *temp_ptr=best_ssb; - while (ret!=0 && temp_ptr != NULL) { + for (NR_UE_SSB *temp_ptr = best_ssb; ret != 0 && temp_ptr < best_ssb + N_L * N_hf; temp_ptr++) { start_meas(&ue->dlsch_channel_estimation_stats); // computing channel estimation for selected best ssb const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; @@ -107,8 +104,6 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, 1, 1); } - - temp_ptr++; } if (ret == 0) { diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index cd99eb497e..9c860553a7 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -309,6 +309,25 @@ The function implemented is : \f$\mathbf{y} = y + \alpha\mathbf{x}\f$ */ void multadd_real_vector_complex_scalar(const int16_t *x, const int16_t *alpha, int16_t *y, uint32_t N); + // Same with correct types + static inline void multaddRealVectorComplexScalar(const c16_t *in, const c16_t alpha, c16_t *out, uint32_t N) + { + // do 8 multiplications at a time + simd_q15_t *x_128 = (simd_q15_t *)in, *y_128 = (simd_q15_t *)out; + + // printf("alpha = %d,%d\n",alpha[0],alpha[1]); + const simd_q15_t alpha_r_128 = set1_int16(alpha.r); + const simd_q15_t alpha_i_128 = set1_int16(alpha.i); + for (unsigned int i = 0; i < N >> 3; i++) { + const simd_q15_t yr = mulhi_s1_int16(alpha_r_128, x_128[i]); + const simd_q15_t yi = mulhi_s1_int16(alpha_i_128, x_128[i]); + const simd_q15_t tmp = simde_mm_loadu_si128(y_128); + simde_mm_storeu_si128(y_128++, simde_mm_adds_epi16(tmp, simde_mm_unpacklo_epi16(yr, yi))); + const simd_q15_t tmp2 = simde_mm_loadu_si128(y_128); + simde_mm_storeu_si128(y_128++, simde_mm_adds_epi16(tmp2, simde_mm_unpackhi_epi16(yr, yi))); + } + } + static __attribute__((always_inline)) inline void multadd_real_four_symbols_vector_complex_scalar(const int16_t *x, c16_t *alpha, c16_t *y) diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 0e46beb0e3..5059ccd107 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -311,9 +311,7 @@ typedef struct { typedef struct NR_UE_SSB { uint8_t i_ssb; // i_ssb between 0 and 7 (it corresponds to ssb_index only for Lmax=4,8) uint8_t n_hf; // n_hf = 0,1 for Lmax =4 or n_hf = 0 for Lmax =8,64 - uint32_t metric; // metric to order SSB hypothesis - uint32_t c_re; - uint32_t c_im; + c32_t c; } NR_UE_SSB; typedef struct UE_NR_SCAN_INFO_s { From 99e1bb1a001d23118ec8fdc22a5b0dba5ee38bbe Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 8 Mar 2024 18:26:23 +0100 Subject: [PATCH 3/9] fix ug on pilot 2 in nr_pbch_dmrs_correlation() that is lacking signal processing, make the code in pbch simpler and faster --- openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 35e17531e3..c21a6a709f 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -92,15 +92,15 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, int, ue->measurements.rx_spatial_power, NUMBER_OF_CONNECTED_gNB_MAX, - cmax(frame_parms->nb_antenna_ports_gNB,1), - cmax(frame_parms->nb_antennas_rx,1), + cmax(frame_parms->nb_antenna_ports_gNB, 1), + cmax(frame_parms->nb_antennas_rx, 1), false); allocCast3D(rx_spatial_power_dB, unsigned short, ue->measurements.rx_spatial_power_dB, NUMBER_OF_CONNECTED_gNB_MAX, - cmax(frame_parms->nb_antenna_ports_gNB,1), - cmax(frame_parms->nb_antennas_rx,1), + cmax(frame_parms->nb_antenna_ports_gNB, 1), + cmax(frame_parms->nb_antennas_rx, 1), false); // signal measurements From 88fb3c359844bc862b015ae235779ef8ab83dffc Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 14 Mar 2024 16:27:33 +0100 Subject: [PATCH 4/9] change type to c16_t around dmrs computation pieces of code --- ci-scripts/cls_oaicitest.py | 4 +- openair1/PHY/INIT/nr_init.c | 5 +- openair1/PHY/MODULATION/nr_modulation.c | 39 ++-- openair1/PHY/MODULATION/nr_modulation.h | 12 +- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 37 ++-- openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h | 26 +-- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 10 +- openair1/PHY/NR_REFSIG/nr_refsig.h | 2 +- openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c | 124 +++++------- openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h | 8 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 190 ++++++++---------- .../PHY/NR_UE_TRANSPORT/srs_modulation_nr.c | 36 ++-- .../PHY/NR_UE_TRANSPORT/srs_modulation_nr.h | 2 +- openair1/PHY/TOOLS/tools_defs.h | 5 + openair1/PHY/defs_nr_common.h | 2 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- openair1/SIMULATION/NR_PHY/ulsim.c | 2 +- .../NR_UE_PHY/unit_tests/src/srs_test.c | 8 +- 18 files changed, 225 insertions(+), 289 deletions(-) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index d7fecf8397..ed121739b7 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -1127,10 +1127,10 @@ class OaiCiTest(): mib_found = True except Exception as e: logging.error(f'\033[91m MIB marker was not found \033[0m') - result = re.search("Measured Carrier Frequency (?P\d{1,15}) Hz", str(line)) + result = re.search("Initial sync: pbch decoded sucessfully", str(line)) if result is not None and (not frequency_found): try: - mibMsg = f"Measured Carrier Frequency = {result.group('measured_carrier_frequency')} Hz" + mibMsg = f"UE decoded PBCH successfully" HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' logging.debug(f'\033[94m{mibMsg}\033[0m') frequency_found = True diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 2f4fad4257..6d08b72c6d 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -254,9 +254,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) gNB->nr_srs_info = (nr_srs_info_t **)malloc16_clear(gNB->max_nb_srs * sizeof(nr_srs_info_t*)); for (int id = 0; id < gNB->max_nb_srs; id++) { gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); - gNB->nr_srs_info[id]->srs_generated_signal = (int32_t**)malloc16_clear(MAX_NUM_NR_SRS_AP*sizeof(int32_t*)); + gNB->nr_srs_info[id]->srs_generated_signal = malloc16_clear(MAX_NUM_NR_SRS_AP * sizeof(c16_t *)); for(int ap=0; apnr_srs_info[id]->srs_generated_signal[ap] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); + gNB->nr_srs_info[id]->srs_generated_signal[ap] = + malloc16_clear(fp->ofdm_symbol_size * MAX_NUM_NR_SRS_SYMBOLS * sizeof(c16_t)); } } diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index e5f28d1c50..f696b12b42 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -318,24 +318,19 @@ void nr_layer_mapping(int nbCodes, } } -void nr_ue_layer_mapping(int16_t *mod_symbs, - uint8_t n_layers, - uint32_t n_symbs, - int16_t **tx_layers) { - +void nr_ue_layer_mapping(const c16_t *mod_symbs, const int n_layers, const int n_symbs, c16_t **tx_layers) +{ for (int i=0; i>15; - tx_layers[l][(i<<1)+1] = (mod_symbs[((n_layers*i+l)<<1)+1]*AMP)>>15; + tx_layers[l][i] = c16mulRealShift(mod_symbs[n_layers * i + l], AMP, 15); } } } - -void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) +void nr_dft(c16_t *z, c16_t *d, uint32_t Msc_PUSCH) { - simde__m128i dft_in128[1][3240], dft_out128[1][3240]; - uint32_t *dft_in0 = (uint32_t*)dft_in128[0], *dft_out0 = (uint32_t*)dft_out128[0]; + simde__m128i dft_in128[3240], dft_out128[3240]; + c16_t *dft_in0 = (c16_t *)dft_in128, *dft_out0 = (c16_t *)dft_out128; uint32_t i, ip; @@ -659,36 +654,32 @@ void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp) } } -int nr_layer_precoder(int16_t **datatx_F_precoding, const char *prec_matrix, uint8_t n_layers, int32_t re_offset) +c16_t nr_layer_precoder(c16_t **datatx_F_precoding, const char *prec_matrix, uint8_t n_layers, int32_t re_offset) { - int32_t precodatatx_F = 0; + c16_t precodatatx_F = {0}; for (int al = 0; aldmrs_config_type); } else { // if transform precoding or SC-FDMA is enabled in Uplink // NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible - const uint16_t index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB/2)); + const int index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB / 2)); const uint8_t u = pusch_pdu->dfts_ofdm.low_papr_group_number; const uint8_t v = pusch_pdu->dfts_ofdm.low_papr_sequence_number; - int16_t *dmrs_seq = gNB_dmrs_lowpaprtype1_sequence[u][v][index]; + c16_t *dmrs_seq = gNB_dmrs_lowpaprtype1_sequence[u][v][index]; LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index); AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); @@ -611,19 +611,21 @@ uint32_t calc_power(const int16_t *x, const uint32_t size) { return sum_x2/size - (sum_x/size)*(sum_x/size); } -int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, - const int frame, - const int slot, - const nfapi_nr_srs_pdu_t *srs_pdu, - const nr_srs_info_t *nr_srs_info, - const int32_t **srs_generated_signal, - int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_estimated_channel_freq[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_estimated_channel_time[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - int32_t srs_estimated_channel_time_shifted[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - int8_t *snr_per_rb, - int8_t *snr) { - +int nr_srs_channel_estimation( + const PHY_VARS_gNB *gNB, + const int frame, + const int slot, + const nfapi_nr_srs_pdu_t *srs_pdu, + const nr_srs_info_t *nr_srs_info, + const c16_t **srs_generated_signal, + int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], + int32_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports] + [gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], + int32_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], + int32_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], + int8_t *snr_per_rb, + int8_t *snr) +{ #ifdef SRS_DEBUG LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__); #endif @@ -694,9 +696,8 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, uint16_t subcarrier_cdm = subcarrier; for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) { - - int16_t generated_real = ((c16_t*)srs_generated_signal[p_index])[subcarrier_cdm].r; - int16_t generated_imag = ((c16_t*)srs_generated_signal[p_index])[subcarrier_cdm].i; + int16_t generated_real = srs_generated_signal[p_index][subcarrier_cdm].r; + int16_t generated_imag = srs_generated_signal[p_index][subcarrier_cdm].i; int16_t received_real = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].r; int16_t received_imag = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].i; diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index e3210552fc..609fa6c0b3 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -72,18 +72,20 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, unsigned char symbol, uint32_t nb_re_pusch); -int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, - const int frame, - const int slot, - const nfapi_nr_srs_pdu_t *srs_pdu, - const nr_srs_info_t *nr_srs_info, - const int32_t **srs_generated_signal, - int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_estimated_channel_freq[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_estimated_channel_time[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - int32_t srs_estimated_channel_time_shifted[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - int8_t *snr_per_rb, - int8_t *snr); +int nr_srs_channel_estimation( + const PHY_VARS_gNB *gNB, + const int frame, + const int slot, + const nfapi_nr_srs_pdu_t *srs_pdu, + const nr_srs_info_t *nr_srs_info, + const c16_t **srs_generated_signal, + int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], + int32_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports] + [gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], + int32_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], + int32_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], + int8_t *snr_per_rb, + int8_t *snr); void nr_freq_equalization(NR_DL_FRAME_PARMS *frame_parms, int *rxdataF_comp, diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index c96d4e7c47..72da87cbdf 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -261,7 +261,7 @@ void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, c16_t *output, uint1 int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB, unsigned int Ns, - int16_t *dmrs_seq, + c16_t *dmrs_seq, c16_t *output, unsigned short p, unsigned char lp, @@ -284,8 +284,8 @@ int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB, k = i-dmrs_offset; w = (wf1[p - 1000][i & 1]) * (wt1[p - 1000][lp]); - output[k].r = w * dmrs_seq[2 * i]; - output[k].i = -(w * dmrs_seq[(2 * i) + 1]); // conjugate + output[k].r = w * dmrs_seq[i].r; + output[k].i = -w * dmrs_seq[i].i; // conjugate #ifdef DEBUG_PUSCH printf("NR_DMRS_RX: nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d nb_dmrs %d\n", @@ -294,8 +294,8 @@ int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB, nb_pusch_rb, nb_dmrs); printf("NR_DMRS_RX: wf[%d] = %d wt[%d]= %d\n", i & 1, wf1[p - 1000][i & 1], lp, wt1[p - 1000][lp]); - printf("NR_DMRS_RX: i %d dmrs_offset %d k %d pusch dmrsseq[i<<1] %d, dmrsseq[(i<<1)+1] %d pilots[k<<1] %d pilots[(k<<1)+1] %d\n", i, dmrs_offset, k, - dmrs_seq[i<<1], dmrs_seq[(i<<1)+1], output[k].r, output[(k].i); + printf("NR_DMRS_RX: i %d dmrs_offset %d k %d pusch dmrsseq[i<<1] %d, dmrsseq[(i<<1)+1] %d pilots[k<<1] %d pilots[(k<<1)+1] %d\n", i, dmrs_offset, k, + dmrs_seq[i].r, dmrs_seq[i].i, output[k].r, output[(k].i); #endif } } else { diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index b702c752ba..c8afffa7d3 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -70,7 +70,7 @@ extern simde__m128i byte2m128i[256]; int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB, unsigned int Ns, - int16_t *dmrs_seq, + c16_t *dmrs_seq, c16_t *output, unsigned short p, unsigned char lp, diff --git a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c index ea2971e79f..22fe1b0d13 100644 --- a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c +++ b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c @@ -52,53 +52,44 @@ * *********************************************************************/ -static int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling) +static c16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling) { - char *phi_table; - int16_t *rv_overbar; - double x; - unsigned int n; - + const char *phi_table; switch(M_ZC) { case 6: - phi_table = (char *)phi_M_ZC_6; + phi_table = phi_M_ZC_6; break; case 12: - phi_table = (char *)phi_M_ZC_12; + phi_table = phi_M_ZC_12; break; case 18: - phi_table = (char *)phi_M_ZC_18; + phi_table = phi_M_ZC_18; break; case 24: - phi_table = (char *)phi_M_ZC_24; + phi_table = phi_M_ZC_24; break; case 30: break; default: - printf("function base_sequence_less_than 36_: unsupported base sequence size : %u \n", M_ZC); - assert(0); + AssertFatal(false, "function base_sequence_less_than 36_: unsupported base sequence size : %u \n", M_ZC); break; } - rv_overbar = malloc16(IQ_SIZE*M_ZC); - - if (rv_overbar == NULL) { - msg("Fatal memory allocation problem \n"); - assert(0); - } + c16_t *rv_overbar = malloc16(IQ_SIZE * M_ZC); + AssertFatal(rv_overbar, "Fatal memory allocation problem \n"); if (M_ZC == 30) { - for (n=0; n= MAX_INDEX_DMRS_UL_ALLOCATED_REs) index = MAX_INDEX_DMRS_UL_ALLOCATED_REs-1; @@ -149,55 +140,40 @@ int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res) { * *********************************************************************/ -static int16_t *base_sequence_36_or_larger(unsigned int Msc_RS, - unsigned int u, - unsigned int v, - unsigned int scaling, - unsigned int if_dmrs_seq) +static c16_t *base_sequence_36_or_larger(unsigned int Msc_RS, + unsigned int u, + unsigned int v, + unsigned int scaling, + unsigned int if_dmrs_seq) { - int16_t *rv_overbar; - unsigned int N_ZC, M_ZC; - double q_overbar, x; - unsigned int q,m,n; - + const unsigned int M_ZC = if_dmrs_seq ? dmrs_ul_allocated_res[Msc_RS] : ul_allocated_re[Msc_RS]; - if (if_dmrs_seq) - M_ZC = dmrs_ul_allocated_res[Msc_RS]; - else - M_ZC = ul_allocated_re[Msc_RS]; - + c16_t *rv_overbar = malloc16(IQ_SIZE * M_ZC); + AssertFatal(rv_overbar, "Fatal memory allocation problem \n"); - rv_overbar = malloc16(IQ_SIZE*M_ZC); - if (rv_overbar == NULL) { - msg("Fatal memory allocation problem \n"); - assert(0); - } + /* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */ + const unsigned int N_ZC = if_dmrs_seq ? dmrs_ref_ul_primes[Msc_RS] : ref_ul_primes[Msc_RS]; - if (if_dmrs_seq) - N_ZC = dmrs_ref_ul_primes[Msc_RS]; - else - N_ZC = ref_ul_primes[Msc_RS]; /* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */ - - - q_overbar = N_ZC * (u+1)/(double)31; + const double q_overbar = N_ZC * (u + 1) / (double)31; /* q = (q_overbar + 1/2) + v.(-1)^(2q_overbar) */ + double q; if ((((int)floor(2*q_overbar))&1) == 0) - q = (int)(floor(q_overbar+.5)) - v; + q = floor(q_overbar + .5) - v; else - q = (int)(floor(q_overbar+.5)) + v; + q = floor(q_overbar + .5) + v; - for (n = 0; n < M_ZC; n++) { - m=n%N_ZC; - x = (double)q * m * (m+1)/N_ZC; - rv_overbar[2*n] = (int16_t)(floor(scaling*cos(M_PI*x))); /* cos(-x) = cos(x) */ - rv_overbar[2*n+1] = -(int16_t)(floor(scaling*sin(M_PI*x))); /* sin(-x) = -sin(x) */ + for (int n = 0; n < M_ZC; n++) { + const int m = n % N_ZC; + const double x = q * m * (m + 1) / N_ZC; + rv_overbar[n].r = (int16_t)(floor(scaling * cos(M_PI * x))); /* cos(-x) = cos(x) */ + rv_overbar[n].i = -(int16_t)(floor(scaling * sin(M_PI * x))); /* sin(-x) = -sin(x) */ } return rv_overbar; } -int16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF]; -int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; +c16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF]; +c16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling) { /* prevent multiple calls, relevant when both UE & gNB initialize this */ @@ -205,24 +181,22 @@ void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling) if (already_called) return; already_called = true; - - unsigned int u, Msc_RS; unsigned int v = 0; // sequence hopping and group hopping are not supported yet - for (Msc_RS=0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) { - for (u=0; u < U_GROUP_NUMBER; u++) { + for (unsigned int Msc_RS = 0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) { + for (unsigned int u = 0; u < U_GROUP_NUMBER; u++) { gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling); } } - for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) { - for (u=0; u < U_GROUP_NUMBER; u++) { - gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 1); - } - } + for (unsigned int Msc_RS = INDEX_SB_LESS_32 + 1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) { + for (unsigned int u = 0; u < U_GROUP_NUMBER; u++) { + gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 1); + } + } } -int16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; +c16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; void generate_ul_reference_signal_sequences(unsigned int scaling) { /* prevent multiple calls, relevant when both UE & gNB initialize this */ diff --git a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h index 3ef9b30c28..9ed101f247 100644 --- a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h +++ b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h @@ -228,7 +228,7 @@ static const uint16_t ref_ul_primes[SRS_SB_CONF] = { }; /* Low-PAPR base sequence; see TS 38.211 clause 5.2.2 */ -extern int16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF]; +extern c16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF]; /* 38.211 table Table 5.2.2.2-1: Definition of phi(n) for M_ZC = 6 */ static const char phi_M_ZC_6[6 * U_GROUP_NUMBER] = { @@ -524,9 +524,9 @@ static const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs] = { }; /// PUSCH DMRS for transform precoding -extern int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; -extern int16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; -int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res); +extern c16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; +extern c16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; +int get_index_for_dmrs_lowpapr_seq(int num_dmrs_res); void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling); void free_gnb_lowpapr_sequences(void); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 885fcd403a..392172a6bc 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -224,7 +224,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////// int max_num_re = Nl*number_of_symbols*nb_rb*NR_NB_SC_PER_RB; - int32_t d_mod[max_num_re] __attribute__ ((aligned(16))); + c16_t d_mod[max_num_re] __attribute__((aligned(16))); nr_modulation(scrambled_output, // assume one codeword for the moment available_bits, @@ -245,7 +245,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot]; uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4); - int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16))); + c16_t mod_dmrs[n_dmrs] __attribute((aligned(16))); /////////// //////////////////////////////////////////////////////////////////////// @@ -254,14 +254,11 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH layer mapping///////////////////////// /////////// - int16_t **tx_layers = (int16_t **)malloc16_clear(Nl*sizeof(int16_t *)); + c16_t **tx_layers = (c16_t **)malloc16_clear(Nl * sizeof(c16_t *)); for (int nl=0; nltransform_precoding == transformPrecoder_enabled) { @@ -287,7 +282,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint16_t num_dmrs_res_per_symbol = nb_rb*(NR_NB_SC_PER_RB/2); // Calculate index to dmrs seq array based on number of DMRS Subcarriers on this symbol - index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol); + int index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol); u = pusch_pdu->dfts_ofdm.low_papr_group_number; v = pusch_pdu->dfts_ofdm.low_papr_sequence_number; dmrs_seq = dmrs_lowpaprtype1_ul_ref_sig[u][v][index]; @@ -303,7 +298,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /* In the symbol with DMRS no data would be transmitted CDM groups is 2*/ continue; - nr_dft(&y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch); + nr_dft(&y[y_offset], &tx_layers[0][y_offset], nb_re_pusch); y_offset = y_offset + nb_re_pusch; @@ -321,7 +316,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, printf("NR_ULSCH_UE: available_bits: %u, mod_order: %d", available_bits,mod_order); for (int ll = 0; ll < (available_bits/mod_order); ll++) { - debug_symbols[ll] = ulsch_ue->y[ll]; + debug_symbols[ll] = ulsch_ue->y[ll]; } printf("NR_ULSCH_UE: numSym: %d, num_dmrs_sym: %d", number_of_symbols,number_dmrs_symbols); @@ -346,9 +341,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////// int encoded_length = frame_parms->N_RB_UL*14*NR_NB_SC_PER_RB*mod_order*Nl; - int16_t **tx_precoding = (int16_t **)malloc16_clear(Nl*sizeof(int16_t *)); + c16_t **tx_precoding = malloc16_clear(Nl * sizeof(c16_t *)); for (int nl=0; nl> l) & 0x01) { is_dmrs_sym = 1; @@ -387,7 +382,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part // Perform this on gold sequence, not required when SC FDMA operation is done, LOG_D(PHY,"DMRS in symbol %d\n",l); - nr_modulation(pusch_dmrs[l][pusch_pdu->scid], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated + nr_modulation(pusch_dmrs[l][pusch_pdu->scid], + n_dmrs * 2, + DMRS_MOD_ORDER, + (int16_t *)mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated } else { dmrs_idx = 0; } @@ -397,7 +395,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) { is_ptrs_sym = 1; - nr_modulation(pusch_dmrs[l][pusch_pdu->scid], nb_rb, DMRS_MOD_ORDER, mod_ptrs); + nr_modulation(pusch_dmrs[l][pusch_pdu->scid], nb_rb, DMRS_MOD_ORDER, (int16_t *)mod_ptrs); } } @@ -422,156 +420,140 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if (is_dmrs == 1) { // if transform precoding is enabled - if (pusch_pdu->transform_precoding == transformPrecoder_enabled) { - ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; - } else { - ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; - } + const int tmp = Wt[l_prime[0]] * Wf[k_prime] * AMP; + if (pusch_pdu->transform_precoding == transformPrecoder_enabled) + tx_precoding[nl][sample_offsetF] = c16mulRealShift(dmrs_seq[dmrs_idx], tmp, 15); + else + tx_precoding[nl][sample_offsetF] = c16mulRealShift(mod_dmrs[dmrs_idx], tmp, 15); #ifdef DEBUG_PUSCH_MAPPING printf("DMRS: Layer: %d\t, dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", - nl, dmrs_idx, l, k, k_prime, n, ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1], - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1]); + nl, dmrs_idx, l, k, k_prime, n, tx_precoding[nl])[sample_offsetF].r,tx_precoding[nl])[sample_offsetF].i); #endif dmrs_idx++; k_prime++; - k_prime&=1; - n+=(k_prime)?0:1; - - } else if (is_ptrs == 1) { + k_prime &= 1; + n += (k_prime) ? 0 : 1; + + } else if (is_ptrs == 1) { uint16_t beta_ptrs = 1; // temp value until power control is implemented - ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15; - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; + tx_precoding[nl][sample_offsetF] = c16mulRealShift(mod_ptrs[ptrs_idx], beta_ptrs * AMP, 15); ptrs_idx++; - } else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) { - if (pusch_pdu->transform_precoding == transformPrecoder_disabled) { - ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = ((int16_t *)tx_layers[nl])[m<<1]; - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = ((int16_t *)tx_layers[nl])[(m<<1) + 1]; - } - else { - ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = ((int16_t *) y)[m<<1]; - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = ((int16_t *) y)[(m<<1) + 1]; - } + } else if (!is_dmrs_sym + || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) { + if (pusch_pdu->transform_precoding == transformPrecoder_disabled) + tx_precoding[nl][sample_offsetF] = tx_layers[nl][m]; + else + tx_precoding[nl][sample_offsetF] = y[m]; #ifdef DEBUG_PUSCH_MAPPING printf("DATA: layer %d\t m %d\t l %d \t k %d \t tx_precoding: %d %d\n", - nl, m, l, k, ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1], - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1]); + nl, + m, + l, + k, + ((int16_t *)tx_precoding[nl])[(sample_offsetF) << 1], + ((int16_t *)tx_precoding[nl])[((sample_offsetF) << 1) + 1]); #endif m++; } else { - ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = 0; - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = 0; + tx_precoding[nl][sample_offsetF] = (c16_t){0}; } if (++k >= frame_parms->ofdm_symbol_size) k -= frame_parms->ofdm_symbol_size; - } //for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) - }//for (l=start_symbol; lnb_antennas_tx; ap++) { - for (int l=start_symbol; lnb_antennas_tx; ap++) { + for (int l = start_symbol; l < start_symbol + number_of_symbols; l++) { uint16_t k = start_sc; - for (int rb=0; rbTpmi; - - if (pmi == 0) {//unitary Precoding + for (int rb = 0; rb < nb_rb; rb++) { + // get pmi info + uint8_t pmi = pusch_pdu->Tpmi; + + if (pmi == 0) { // unitary Precoding if (k + NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { // RB does not cross DC - if (apnrOfLayers) - memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], - &tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)], - NR_NB_SC_PER_RB*sizeof(int32_t)); + if (ap < pusch_pdu->nrOfLayers) + memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k], + &tx_precoding[ap][l * frame_parms->ofdm_symbol_size + k], + NR_NB_SC_PER_RB * sizeof(c16_t)); else - memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], - 0, - NR_NB_SC_PER_RB*sizeof(int32_t)); + memset(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k], 0, NR_NB_SC_PER_RB * sizeof(int32_t)); } else { // RB does cross DC int neg_length = frame_parms->ofdm_symbol_size - k; int pos_length = NR_NB_SC_PER_RB - neg_length; - if (apnrOfLayers) { - memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], - &tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)], - neg_length*sizeof(int32_t)); - memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size], - &tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size)], - pos_length*sizeof(int32_t)); + if (ap < pusch_pdu->nrOfLayers) { + memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k], + &tx_precoding[ap][l * frame_parms->ofdm_symbol_size + k], + neg_length * sizeof(c16_t)); + memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size], + &tx_precoding[ap][l * frame_parms->ofdm_symbol_size], + pos_length * sizeof(int32_t)); } else { - memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], - 0, - neg_length*sizeof(int32_t)); - memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size], - 0, - pos_length*sizeof(int32_t)); + memset(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k], 0, neg_length * sizeof(int32_t)); + memset(&txdataF[ap][l * frame_parms->ofdm_symbol_size], 0, pos_length * sizeof(int32_t)); } } k += NR_NB_SC_PER_RB; if (k >= frame_parms->ofdm_symbol_size) { k -= frame_parms->ofdm_symbol_size; } - } - else { - //get the precoding matrix weights: + } else { + // get the precoding matrix weights: const char *W_prec; switch (frame_parms->nb_antennas_tx) { - case 1://1 antenna port + case 1: // 1 antenna port W_prec = nr_W_1l_2p[pmi][ap]; break; - case 2://2 antenna ports - if (pusch_pdu->nrOfLayers == 1)//1 layer + case 2: // 2 antenna ports + if (pusch_pdu->nrOfLayers == 1) // 1 layer W_prec = nr_W_1l_2p[pmi][ap]; - else//2 layers + else // 2 layers W_prec = nr_W_2l_2p[pmi][ap]; break; - case 4://4 antenna ports - if (pusch_pdu->nrOfLayers == 1)//1 layer + case 4: // 4 antenna ports + if (pusch_pdu->nrOfLayers == 1) // 1 layer W_prec = nr_W_1l_4p[pmi][ap]; - else if (pusch_pdu->nrOfLayers == 2)//2 layers + else if (pusch_pdu->nrOfLayers == 2) // 2 layers W_prec = nr_W_2l_4p[pmi][ap]; - else if (pusch_pdu->nrOfLayers == 3)//3 layers + else if (pusch_pdu->nrOfLayers == 3) // 3 layers W_prec = nr_W_3l_4p[pmi][ap]; - else//4 layers + else // 4 layers W_prec = nr_W_4l_4p[pmi][ap]; break; default: - LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n"); + LOG_D(PHY, "Precoding 1,2, or 4 antenna ports are currently supported\n"); W_prec = nr_W_1l_2p[pmi][ap]; break; } - for (int i=0; iofdm_symbol_size + k; - int32_t precodatatx_F = nr_layer_precoder(tx_precoding, W_prec, pusch_pdu->nrOfLayers, re_offset); - ((int16_t*)txdataF[ap])[(re_offset<<1)] = ((int16_t *) &precodatatx_F)[0]; - ((int16_t*)txdataF[ap])[(re_offset<<1) + 1] = ((int16_t *) &precodatatx_F)[1]; - + for (int i = 0; i < NR_NB_SC_PER_RB; i++) { + int32_t re_offset = l * frame_parms->ofdm_symbol_size + k; + txdataF[ap][re_offset] = nr_layer_precoder(tx_precoding, W_prec, pusch_pdu->nrOfLayers, re_offset); if (++k >= frame_parms->ofdm_symbol_size) { k -= frame_parms->ofdm_symbol_size; } } } - } //RB loop + } // RB loop } // symbol loop - }// port loop + } // port loop - NR_UL_UE_HARQ_t *harq_process_ulsch=NULL; + NR_UL_UE_HARQ_t *harq_process_ulsch = NULL; harq_process_ulsch = &UE->ul_harq_processes[harq_pid]; harq_process_ulsch->status = SCH_IDLE; diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c index 6d1b775f44..4af545b931 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c @@ -179,13 +179,13 @@ uint16_t compute_n_b(frame_t frame_number, ***************************************************************************/ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, NR_DL_FRAME_PARMS *frame_parms, - int32_t **txdataF, + c16_t **txdataF, uint16_t symbol_offset, nr_srs_info_t *nr_srs_info, int16_t amp, frame_t frame_number, - slot_t slot_number) { - + slot_t slot_number) +{ #ifdef SRS_DEBUG LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__); #endif @@ -371,20 +371,15 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, // For each port, and for each OFDM symbol, here it is computed and mapped an SRS sequence with M_sc_b_SRS symbols for (int k = 0; k < M_sc_b_SRS; k++) { - - double shift_real = cos(alpha_i * k); - double shift_imag = sin(alpha_i * k); - int16_t r_overbar_real = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][k<<1]; - int16_t r_overbar_imag = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][(k<<1)+1]; + cd_t shift = {cos(alpha_i * k), sin(alpha_i * k)}; + const c16_t tmp = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][k]; + cd_t r_overbar = {tmp.r, tmp.i}; // cos(x+y) = cos(x)cos(y) - sin(x)sin(y) - double r_real = (shift_real*r_overbar_real - shift_imag*r_overbar_imag) / sqrt_N_ap; + cd_t r = cdMul(shift, r_overbar); - // sin(x+y) = sin(x)cos(y) + cos(x)sin(y) - double r_imag = (shift_imag*r_overbar_real + shift_real*r_overbar_imag) / sqrt_N_ap; - - int32_t r_real_amp = ((int32_t) round((double) amp * r_real)) >> 15; - int32_t r_imag_amp = ((int32_t) round((double) amp * r_imag)) >> 15; + c16_t r_amp = {(((int32_t)round((double)amp * r.r / sqrt_N_ap)) >> 15), + (((int32_t)round((double)amp * r.i / sqrt_N_ap)) >> 15)}; #ifdef SRS_DEBUG int subcarrier_log = subcarrier-subcarrier_offset; @@ -394,10 +389,10 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, if(subcarrier_log%12 == 0) { LOG_I(NR_PHY,"------------ %d ------------\n", subcarrier_log/12); } - LOG_I(NR_PHY,"(%d) \t%i\t%i\n", subcarrier_log, (int16_t)(r_real_amp&0xFFFF), (int16_t)(r_imag_amp&0xFFFF)); + LOG_I(NR_PHY, "(%d) \t%i\t%i\n", subcarrier_log, r_amp.r, r_amp.i); #endif - *(c16_t *)&txdataF[p_index][symbol_offset + l_line_offset + subcarrier] = (c16_t){r_real_amp, r_imag_amp}; + txdataF[p_index][symbol_offset + l_line_offset + subcarrier] = r_amp; // Subcarrier increment subcarrier += K_TC; @@ -465,14 +460,7 @@ int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_ NR_DL_FRAME_PARMS *frame_parms = &(ue->frame_parms); uint16_t symbol_offset = (frame_parms->symbols_per_slot - 1 - srs_config_pdu->time_start_position)*frame_parms->ofdm_symbol_size; - if (generate_srs_nr(srs_config_pdu, - frame_parms, - (int32_t **)txdataF, - symbol_offset, - ue->nr_srs_info, - AMP, - proc->frame_tx, - proc->nr_slot_tx) + if (generate_srs_nr(srs_config_pdu, frame_parms, txdataF, symbol_offset, ue->nr_srs_info, AMP, proc->frame_tx, proc->nr_slot_tx) == 0) { return 0; } else { diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h index e8e2483474..a017d79730 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h @@ -133,7 +133,7 @@ static const uint16_t srs_max_number_cs[3] = {8, 12, 6}; int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, NR_DL_FRAME_PARMS *frame_parms, - int32_t **txdataF, + c16_t **txdataF, uint16_t symbol_offset, nr_srs_info_t *nr_srs_info, int16_t amp, diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 9c860553a7..06e31542d5 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -183,6 +183,11 @@ extern "C" { return a.r * a.r + a.i * a.i; } + __attribute__((always_inline)) inline c16_t c16add(const c16_t a, const c16_t b) + { + return (c16_t){.r = (int16_t)(a.r + b.r), .i = (int16_t)(a.i + b.i)}; + } + __attribute__((always_inline)) inline c16_t c16sub(const c16_t a, const c16_t b) { return (c16_t) { .r = (int16_t) (a.r - b.r), diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index e99bcddaba..3a7e2032b9 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -115,7 +115,7 @@ typedef enum{ typedef struct { uint8_t k_0_p[MAX_NUM_NR_SRS_AP][MAX_NUM_NR_SRS_SYMBOLS]; uint8_t srs_generated_signal_bits; - int32_t **srs_generated_signal; + c16_t **srs_generated_signal; nfapi_nr_srs_pdu_t srs_pdu; } nr_srs_info_t; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index a7b9e5d120..47753c2448 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -951,7 +951,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) slot_rx, srs_pdu, gNB->nr_srs_info[i], - (const int32_t **)gNB->nr_srs_info[i]->srs_generated_signal, + (const c16_t**)gNB->nr_srs_info[i]->srs_generated_signal, srs_received_signal, srs_estimated_channel_freq, srs_estimated_channel_time, diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index b252f1cdd4..374234e55d 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -776,7 +776,7 @@ int main(int argc, char *argv[]) AssertFatal(enable_ptrs == 0, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); - int8_t index = get_index_for_dmrs_lowpapr_seq((NR_NB_SC_PER_RB/2) * nb_rb); + int index = get_index_for_dmrs_lowpapr_seq((NR_NB_SC_PER_RB / 2) * nb_rb); AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); dmrs_config_type = pusch_dmrs_type1; diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c index 235387acf7..ce52eb1f56 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c @@ -78,8 +78,8 @@ void generate_reference_signals(void) assert(0); } for (int n=0; nsrs_nr.p_SRS_ResourceSetList[0]->p_srs_ResourceList[0]; From 80d4d600f322273090cbcce6da6d2cf230c8928d Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 21 Mar 2024 14:52:26 +0100 Subject: [PATCH 5/9] print the mib when decoded --- openair2/RRC/NR_UE/rrc_UE.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 23da4916e0..42540222f0 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -459,7 +459,9 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, LOG_E(NR_RRC, "NR_BCCH_BCH decode error\n"); return; } - + if (LOG_DEBUGFLAG(DEBUG_ASN1)) + xer_fprint(stdout, &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message); + // Actions following cell selection while T311 is running NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; if (is_nr_timer_active(timers->T311)) { @@ -717,10 +719,6 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, (const void *)Sdu, Sdu_len); - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { - xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message); - } - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E(NR_RRC, "[UE %ld] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", rrc->ue_id, dec_rval.consumed); log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n"); @@ -730,6 +728,10 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, return -1; } + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message); + } + if (bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1) { switch (bcch_message->message.choice.c1->present) { case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: From a95dffc80eca0abe5e2ce39a77ba4902a421d6f6 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 21 Mar 2024 14:52:52 +0100 Subject: [PATCH 6/9] delete dead files --- openair1/PHY/MODULATION/nr_modulation.c | 4 +- openair1/PHY/MODULATION/nr_modulation.h | 4 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 39 +- openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c | 100 ----- openair2/PHY_INTERFACE/UE_MAC_interface.h | 438 --------------------- 5 files changed, 22 insertions(+), 563 deletions(-) delete mode 100644 openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c delete mode 100644 openair2/PHY_INTERFACE/UE_MAC_interface.h diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index f696b12b42..666d92a87d 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -318,7 +318,7 @@ void nr_layer_mapping(int nbCodes, } } -void nr_ue_layer_mapping(const c16_t *mod_symbs, const int n_layers, const int n_symbs, c16_t **tx_layers) +void nr_ue_layer_mapping(const c16_t *mod_symbs, const int n_layers, const int n_symbs, int sz, c16_t tx_layers[][sz]) { for (int i=0; iN_RB_UL*14*NR_NB_SC_PER_RB*mod_order*Nl; - c16_t **tx_precoding = malloc16_clear(Nl * sizeof(c16_t *)); - for (int nl=0; nlN_RB_UL * 14 * NR_NB_SC_PER_RB * mod_order * Nl; + c16_t tx_precoding[Nl][encoded_length]; + memset(tx_precoding, 0, sizeof(tx_precoding)); for (int nl=0; nl < Nl; nl++) { uint8_t k_prime = 0; @@ -428,7 +426,14 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, #ifdef DEBUG_PUSCH_MAPPING printf("DMRS: Layer: %d\t, dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", - nl, dmrs_idx, l, k, k_prime, n, tx_precoding[nl])[sample_offsetF].r,tx_precoding[nl])[sample_offsetF].i); + nl, + dmrs_idx, + l, + k, + k_prime, + n, + tx_precoding[nl][sample_offsetF].r, + tx_precoding[nl][sample_offsetF].i); #endif dmrs_idx++; @@ -453,8 +458,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, m, l, k, - ((int16_t *)tx_precoding[nl])[(sample_offsetF) << 1], - ((int16_t *)tx_precoding[nl])[((sample_offsetF) << 1) + 1]); + tx_precoding[nl][sample_offsetF].r, + tx_precoding[nl][sample_offsetF].i); #endif m++; @@ -543,7 +548,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, for (int i = 0; i < NR_NB_SC_PER_RB; i++) { int32_t re_offset = l * frame_parms->ofdm_symbol_size + k; - txdataF[ap][re_offset] = nr_layer_precoder(tx_precoding, W_prec, pusch_pdu->nrOfLayers, re_offset); + txdataF[ap][re_offset] = nr_layer_precoder(encoded_length, tx_precoding, W_prec, pusch_pdu->nrOfLayers, re_offset); if (++k >= frame_parms->ofdm_symbol_size) { k -= frame_parms->ofdm_symbol_size; } @@ -556,14 +561,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, NR_UL_UE_HARQ_t *harq_process_ulsch = NULL; harq_process_ulsch = &UE->ul_harq_processes[harq_pid]; harq_process_ulsch->status = SCH_IDLE; - - for (int nl = 0; nl < Nl; nl++) { - free_and_zero(tx_layers[nl]); - free_and_zero(tx_precoding[nl]); - } - free_and_zero(tx_layers); - free_and_zero(tx_precoding); - /////////// //////////////////////////////////////////////////////////////////////// } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c deleted file mode 100644 index 4012322111..0000000000 --- a/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/********************************************************************** -* -* FILENAME : pbch_nr.c -* -* MODULE : broacast channel -* -* DESCRIPTION : generation of pbch -* 3GPP TS 38.211 7.3.3 Physical broadcast channel -* -************************************************************************/ - -#include -#include -#include - -#include "PHY/defs.h" - -#define DEFINE_VARIABLES_PBCH_NR_H -#include "PHY/NR_REFSIG/pbch_nr.h" -#undef DEFINE_VARIABLES_PBCH_NR_H - -/******************************************************************* -* -* NAME : pseudo_random_gold_sequence -* -* PARAMETERS : -* -* RETURN : generate pseudo-random sequence which is a length-31 Gold sequence -* -* DESCRIPTION : 3GPP TS 38.211 5.2.1 Pseudo-random sequence generation -* Sequence generation -* -*********************************************************************/ - -#define NC (1600) -#define GOLD_LENGTH (31) - -uint32_t *pseudo_random_gold_sequence(length M_PN, uint32_t cinit) -{ - int size = M_PN * sizeof(uint32_t); - int size_x = sizeof(int)*M_PN + size; - int *x1 = malloc(size_x); - int *x2 = malloc(size_x); - - if ((x1 == NULL) || (x2 == NULL)) { - msg("Fatal memory allocation problem \n"); - assert(0); - } - else { - bzero(x1, size_x); - bzero(x2, size_x); - } - - x1[0] = 1; - - for (n = 0; n < 31; n++) { - x2[n] = (cinit >> n) & 0x1; - } - - for (int n = 0; n < (NC+M_PN); n++) { - x1(n+31) = (x1(n+3) + x1(n))%2; - x2(n+31) = (x2(n+3) + x2(n+2) + x2(n+1) + x2(n))%2; - } - - int *c = calloc(size); - if (c != NULL) { - bzero(c, size); - } - else { - msg("Fatal memory allocation problem \n"); - assert(0); - } - - for (int n = 0; n < M_PN; n++) { - c(i) = (x1(n+NC) + x2(n+NC))%2; - } - - return c; -} diff --git a/openair2/PHY_INTERFACE/UE_MAC_interface.h b/openair2/PHY_INTERFACE/UE_MAC_interface.h deleted file mode 100644 index e7a833adfa..0000000000 --- a/openair2/PHY_INTERFACE/UE_MAC_interface.h +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/* This is the interface module between PHY - * Provided the FAPI style interface structures for P7. - */ - -/*! \file openair2/PHY_INTERFACE/IF_Module.h -* \brief data structures for PHY/MAC interface modules -* \author EURECOM/NTUST -* \date 2017 -* \version 0.1 -* \company Eurecom -* \email: raymond.knopp@eurecom.fr -* \note -* \warning -*/ -#ifndef __UE_MAC_INTERFACE__H__ -#define __UE_MAC_INTERFACE__H__ - -#include "nfapi_interface.h" -#include "openair1/PHY/defs_RU.h" -#include "common/openairinterface5g_limits.h" - -#define MAX_NUM_DL_PDU 100 -#define MAX_NUM_UL_PDU 100 -#define MAX_NUM_HI_DCI0_PDU 100 -#define MAX_NUM_TX_REQUEST_PDU 100 - -#define MAX_NUM_HARQ_IND 100 -#define MAX_NUM_CRC_IND 100 -#define MAX_NUM_SR_IND 100 -#define MAX_NUM_CQI_IND 100 -#define MAX_NUM_RACH_IND 100 -#define MAX_NUM_SRS_IND 100 - - -// UE_MAC enums -typedef enum { - UE_MAC_DL_IND_PDSCH_PDU_TYPE =0, - UE_MAC_DL_IND_SI_PDSCH_PDU_TYPE, - UE_MAC_DL_IND_P_PDSCH_PDU_TYPE, - UE_MAC_DL_IND_DLSCH_RAR_PDU_TYPE -} UE_MAC_dl_ind_pdu_type_e; - -// UE_MAC enums -typedef enum { - UE_MAC_Tx_IND_Msg1_TYPE =0, - UE_MAC_Tx_IND_Msg3_TYPE -} UE_MAC_Tx_ind_type_e; - - -// *** UE_Tx.request related structures - -typedef struct { - uint16_t pdu_length; - uint16_t pdu_index; - uint8_t num_segments; - struct { - uint32_t segment_length; - uint8_t* segment_data; - } segments[NFAPI_TX_MAX_SEGMENTS]; -} UE_MAC_tx_request_pdu_t; - - -typedef struct { - nfapi_tl_t tl; - uint16_t number_of_pdus; - UE_MAC_tx_request_pdu_t* ue_tx_pdu_list; -} UE_MAC_tx_request_body_t; - - -typedef struct { - //nfapi_p7_message_header_t header; - uint16_t sfn_sf; - UE_MAC_tx_request_body_t ue_tx_request_body; -} UE_MAC_tx_request_t; - - -typedef struct{ - - -}UE_MAC_sl_config_request_Tx_t; - -typedef struct{ - - -}UE_MAC_sl_config_request_Rx_t; - - -typedef struct{ - - -}UE_MAC_sl_tx_request_t; - - - - - - -// *** UE_DL.indication related structures - -typedef struct{ - unsigned char eNB_index; - uint8_t first_sync; //boolean 0 or 1 - uint8_t sync; // boolean 0 or 1 to indicate whether rrc_out_of_sync_ind() or dl_phy_sync_success() - // should be called from the handler function of the interface respectively. -}UE_MAC_bch_indication_pdu_t; - - -typedef struct{ - nfapi_tl_t tl; - UE_MAC_bch_indication_pdu_t* bch_ind_list; -}UE_MAC_BCH_indication_body_t; - - -// Corresponding to inputs of MAC functions: ue_send_sdu(), ue_decode_si(), ue_decode_p(). -typedef struct{ - uint8_t* data; - uint16_t data_len; -}UE_MAC_dlsch_pdu; - - -// Corresponding to inputs of MAC function: process_rar(). -typedef struct{ - rnti_t ra_rnti; - uint8_t* rar_input_buffer; // Originating from PHY - rnti_t* t_crnti; - uint8_t preamble_index; - uint8_t* rar_output_buffer; //should be returned to PHY: dlsch0->harq_processes[0]->b -}UE_MAC_dlsch_rar_pdu; - - -typedef struct{ - uint8_t pdu_type; - uint8_t eNB_index; - union{ - UE_MAC_dlsch_pdu dlsch_pdu_ind; - UE_MAC_dlsch_rar_pdu dlsch_rar_pdu_ind; - }; -}UE_MAC_dlsch_indication_pdu_t; - - -typedef struct{ - nfapi_tl_t tl; - uint16_t number_of_pdus; - UE_MAC_dlsch_indication_pdu_t* dlsch_ind_list; -}UE_MAC_DLSCH_indication_body_t; - - - - - - -// *** UE_SL.indication related structures - -typedef struct{ - -}ue_sci_indication_body_t; - - -typedef struct{ - -}ue_SLSCH_indication_body_t; - - -typedef struct{ - -}ue_SLDCH_indication_body_t; - -typedef struct{ - -}ue_SLBCH_indication_body_t; - - -// *** UE_Config_common.request related structures - -typedef struct { - uint8_t subframeAssignment; - uint8_t specialSubframePatterns; -}UE_PHY_tdd_frame_structure_t; - - -typedef struct { - uint16_t rootSequenceIndex; - uint8_t prach_Config_enabled; - uint8_t prach_ConfigIndex; - uint8_t highSpeedFlag; - uint8_t zeroCorrelationZoneConfig; - uint8_t prach_FreqOffset; -}UE_PHY_prach_config_t; - -typedef struct { - uint8_t deltaPUCCH_Shift; - uint8_t nRB_CQI; - uint8_t nCS_AN; - uint16_t n1PUCCH_AN; -}UE_PHY_pucch_config_t; - - -typedef struct { - int8_t referenceSignalPower; - uint8_t p_b; -}UE_PHY_pdsch_config_t; - - -typedef struct { - uint8_t n_SB; - PUSCH_HOPPING_t hoppingMode; - uint8_t pusch_HoppingOffset; - uint8_t enable64QAM; - uint8_t groupHoppingEnabled; - uint8_t groupAssignmentPUSCH; - uint8_t sequenceHoppingEnabled; - uint8_t cyclicShift; -}UE_PHY_pusch_config_t; - - -typedef struct{ - uint8_t enabled_flag; - uint8_t srs_BandwidthConfig; - uint8_t srs_SubframeConfig; - uint8_t ackNackSRS_SimultaneousTransmission; - uint8_t srs_MaxUpPts; -}UE_PHY_SRS_config_t; - -typedef struct{ - int8_t p0_NominalPUSCH; - PUSCH_alpha_t alpha; - int8_t p0_NominalPUCCH; - int8_t deltaPreambleMsg3; - long deltaF_PUCCH_Format1; - long deltaF_PUCCH_Format1b; - long deltaF_PUCCH_Format2; - long deltaF_PUCCH_Format2a; - long deltaF_PUCCH_Format2b; -}UE_PHY_UL_power_control_config_t; - - -typedef struct{ - uint8_t maxHARQ_Msg3Tx; -}UE_PHY_HARQ_Msg3_config_t; - -typedef struct{ - uint8_t nb_antennas_tx; -}UE_PHY_antenna_config_t; - -typedef struct{ - PHICH_RESOURCE_t phich_resource; - PHICH_DURATION_t phich_duration; -}UE_PHY_phich_config_t; - - -typedef struct { - UE_PHY_tdd_frame_structure_t ue_tdd_frame_structure_config; - UE_PHY_prach_config_t ue_prach_config; - UE_PHY_pucch_config_t ue_pucch_config; - UE_PHY_pdsch_config_t ue_pdsch_config; - UE_PHY_pusch_config_t ue_pusch_config; - UE_PHY_SRS_config_t ue_srs_config; - UE_PHY_UL_power_control_config_t ue_ul_pow_cntl_config; - UE_PHY_HARQ_Msg3_config_t ue_harq_msg3_config; - /* Where can we find the types and values of the configuration for the PCH? - UE_MAC_pusch_config_t ue_pch_config - radioResourceConfigCommon->pcch_Config.defaultPagingCycle, radioResourceConfigCommon->pcch_Config.nB*/ - UE_PHY_antenna_config_t ue_ant_config; - UE_PHY_phich_config_t ue_phich_config; - /* MBSFN?*/ -}UE_PHY_config_common_request_t; - - - - - - - -// *** UE_Config_dedicated. request related structures - -typedef struct{ - PA_t p_a; -}UE_PHY_pdsch_config_dedicated_t; - - -typedef struct{ - uint8_t ackNackRepetition; - ANFBmode_t tdd_AckNackFeedbackMode; - //ACKNAKREP_t repetitionFactor; - //uint16_t n1PUCCH_AN_Rep; -}UE_PHY_pucch_config_dedicated_t; - - -typedef struct{ - uint16_t betaOffset_ACK_Index; - uint16_t betaOffset_RI_Index; - uint16_t betaOffset_CQI_Index; -}UE_PHY_pusch_config_dedicated_t; - - -typedef struct{ - int8_t p0_UE_PUSCH; - uint8_t deltaMCS_Enabled; - uint8_t accumulationEnabled; - int8_t p0_UE_PUCCH; - int8_t pSRS_Offset; - uint8_t filterCoefficient; -}UE_PHY_ul_power_control_config_dedicated_t; - - -typedef struct{ - uint16_t sr_PUCCH_ResourceIndex; - uint8_t sr_ConfigIndex; - DSR_TRANSMAX_t dsr_TransMax; -}UE_PHY_SR_config_dedicated_t; - - -typedef struct{ - uint8_t srsConfigDedicatedSetup; - uint8_t duration; - uint8_t cyclicShift; - uint8_t freqDomainPosition; - uint8_t srs_Bandwidth; - uint16_t srs_ConfigIndex; - uint8_t srs_HoppingBandwidth; - uint8_t transmissionComb; - //uint8_t srsCellSubframe; - //uint8_t srsUeSubframe; -}UE_PHY_srs_ul_config_dedicated_t; - - -typedef struct{ - CQI_REPORTMODEAPERIODIC cqi_ReportModeAperiodic; - CQI_REPORTPERIODIC CQI_ReportPeriodic; - //int8_t nomPDSCH_RS_EPRE_Offset; -}UE_PHY_cqi_report_config_dedicated_t; - - - -typedef struct{ - uint8_t transmission_mode [NUMBER_OF_CONNECTED_eNB_MAX]; - UE_PHY_pdsch_config_dedicated_t ue_pdsch_config; - UE_PHY_pucch_config_dedicated_t ue_pucch_config; - UE_PHY_pusch_config_dedicated_t ue_pusch_config; - UE_PHY_ul_power_control_config_dedicated_t ue_ul_pow_cntrl_config; - UE_PHY_SR_config_dedicated_t ue_SR_config; - UE_PHY_srs_ul_config_dedicated_t ue_srs_ul_config; - UE_PHY_cqi_report_config_dedicated_t ue_cqi_report_config; -}UE_PHY_config_dedicated_request_t; - -#endif - - - - - - - - - - - - - - - - - - - -/* -typedef struct { - nfapi_p4_p5_message_header_t header; - uint8_t num_tlv; - nfapi_subframe_config_t subframe_config; - nfapi_rf_config_t rf_config; - nfapi_phich_config_t phich_config; - nfapi_sch_config_t sch_config; - nfapi_prach_config_t prach_config; - nfapi_pusch_config_t pusch_config; - nfapi_pucch_config_t pucch_config; - nfapi_srs_config_t srs_config; - nfapi_uplink_reference_signal_config_t uplink_reference_signal_config; - nfapi_laa_config_t laa_config; - nfapi_emtc_config_t emtc_config; - nfapi_tdd_frame_structure_t tdd_frame_structure_config; - nfapi_l23_config_t l23_config; - nfapi_nb_iot_config_t nb_iot_config; - - // addition nfapi tlvs as per table 2-16 in idle or configure - nfapi_nfapi_t nfapi_config; - - nfapi_vendor_extension_tlv_t vendor_extension; -} nfapi_config_request_t; - - - - - -typedef struct { - nfapi_tl_t tl; - uint8_t dci_format; - uint8_t cce_index; - uint8_t aggregation_level; - uint16_t rnti; - uint8_t resource_block_start; - uint8_t number_of_resource_block; - uint8_t mcs_1; - uint8_t cyclic_shift_2_for_drms; - uint8_t frequency_hopping_enabled_flag; - uint8_t frequency_hopping_bits; - uint8_t new_data_indication_1; - uint8_t ue_tx_antenna_seleciton; - uint8_t tpc; - uint8_t cqi_csi_request; - uint8_t ul_index; - uint8_t dl_assignment_index; - uint32_t tpc_bitmap; - uint16_t transmission_power; -} nfapi_hi_dci0_dci_pdu_rel8_t; - -*/ From 9a4294ebab6d7705e1b3d0e9121c4ff38a79bb75 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Tue, 26 Mar 2024 13:46:03 +0100 Subject: [PATCH 7/9] for_review_then_squash --- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 4 +- openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 2 +- .../nr_dl_channel_estimation.c | 49 +++++----- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 12 +-- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 90 +++++++++++-------- openair1/PHY/defs_nr_UE.h | 7 -- 6 files changed, 83 insertions(+), 81 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 72da87cbdf..82c55a1465 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -202,7 +202,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, return(0); } -int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, c16_t *output) +void nr_pbch_dmrs_rx(const int symbol, const unsigned int *nr_gold_pbch, c16_t *output) { int m,m0,m1; uint8_t idx=0; @@ -232,8 +232,6 @@ int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, c16_t *output) } #endif } - - return(0); } /*! diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 763949150e..81c72f59ef 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -30,7 +30,7 @@ /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS. @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables */ -int nr_pbch_dmrs_rx(int dmrss, unsigned int *nr_gold_pbch, c16_t *output); +void nr_pbch_dmrs_rx(const int dmrss, const unsigned int *nr_gold_pbch, c16_t *output); /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS. @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 090518575e..c2dc115e5b 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -631,28 +631,19 @@ int nr_prs_channel_estimation(uint8_t gNB_id, return(0); } -int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - unsigned char symbol, - int dmrss, - NR_UE_SSB *current_ssb, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) +c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const int symbol, + const int dmrss, + const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD], + const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { - c16_t pilot[200] __attribute__((aligned(16))); - unsigned int pilot_cnt; - int symbol_offset; - - uint8_t ssb_index=current_ssb->i_ssb; - uint8_t n_hf=current_ssb->n_hf; + AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss); unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size; - AssertFatal(dmrss >= 0 && dmrss < 3, - "symbol %d is illegal for PBCH DM-RS \n", - dmrss); - - symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol; + int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol; unsigned int k = ue->frame_parms.Nid_cell % 4; @@ -665,64 +656,64 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, // generate pilot // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], pilot); - + c16_t pilot[200] __attribute__((aligned(16))); + nr_pbch_dmrs_rx(dmrss, nr_gold_pbch, pilot); + c32_t computed_val = {0}; for (int aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { int re_offset = ssb_offset; c16_t *pil = pilot; - c16_t *rxF = &rxdataF[aarx][symbol_offset + k]; + const c16_t *rxF = &rxdataF[aarx][symbol_offset + k]; DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", ue->frame_parms.N_RB_DL); DEBUG_PBCH("k %d, first_carrier %d\n", k, ue->frame_parms.first_carrier_offset); - //if ((ue->frame_parms.N_RB_DL&1)==0) { // Treat first 2 pilots specially (left edge) - current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); + computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); DEBUG_PBCH("ch 0 %d\n", pil->r * rxF[re_offset].r - pil->i * rxF[re_offset].i); DEBUG_PBCH("pilot 0 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); + computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); DEBUG_PBCH("pilot 1 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); + computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); DEBUG_PBCH("pilot 2 : rxF - > (%d,%d), pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); pil++; re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; - for (pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) { + for (int pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) { // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size; } - current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); + computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); + computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 1, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - current_ssb->c = c32x16maddShift(*pil, rxF[re_offset], current_ssb->c, 15); + computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 2, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); pil++; re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; } } - return(0); + return computed_val; } int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index f47d49f877..64875331e5 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -57,12 +57,12 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, c16_t pdcch_dl_ch_estimates[][pdcch_est_size], c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); -int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - unsigned char symbol, - int dmrss, - NR_UE_SSB *current_ssb, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); +c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const int symbol, + const int dmrss, + const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD], + const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int estimateSz, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 8d1253274a..2fa9b00b93 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -44,6 +44,7 @@ #include "PHY/NR_REFSIG/pss_nr.h" #include "PHY/NR_REFSIG/sss_nr.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "PHY/TOOLS/tools_defs.h" //static nfapi_nr_config_request_t config_t; //static nfapi_nr_config_request_t* config =&config_t; @@ -52,11 +53,22 @@ int cnt=0; // #define DEBUG_INITIAL_SYNCH #define DUMP_PBCH_CH_ESTIMATES 0 +// structure used for multiple SSB detection +typedef struct NR_UE_SSB { + uint i_ssb; // i_ssb between 0 and 7 (it corresponds to ssb_index only for Lmax=4,8) + uint n_hf; // n_hf = 0,1 for Lmax =4 or n_hf = 0 for Lmax =8,64 + uint32_t metric; // metric to order SSB hypothesis +} NR_UE_SSB; -int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, - PHY_VARS_NR_UE *ue, - int pbch_initial_symbol, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) +static int ssb_sort(const void *a, const void *b) +{ + return ((NR_UE_SSB *)b)->metric - ((NR_UE_SSB *)a)->metric; +} + +static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, + PHY_VARS_NR_UE *ue, + int pbch_initial_symbol, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; @@ -64,54 +76,62 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, const int N_hf = (frame_parms->Lmax == 4) ? 2 : 1; NR_UE_SSB best_ssb[N_L * N_hf]; NR_UE_SSB *current_ssb = best_ssb; - // loops over possible pbch dmrs cases to retrive best estimated i_ssb (and n_hf for Lmax=4) for multiple ssb detection + // loops over possible pbch dmrs cases to retrieve best estimated i_ssb (and n_hf for Lmax=4) for multiple ssb detection + start_meas(&ue->dlsch_channel_estimation_stats); for (int hf = 0; hf < N_hf; hf++) { - for (int l = 0; l < N_L ; l++) { - // initialization of structure - *current_ssb = (NR_UE_SSB){.i_ssb = l, .n_hf = hf}; - start_meas(&ue->dlsch_channel_estimation_stats); + for (int l = 0; l < N_L; l++) { // computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf - for(int i=pbch_initial_symbol; idlsch_channel_estimation_stats); + c32_t cumul = {0}; + for (int i = pbch_initial_symbol; i < pbch_initial_symbol + 3; i++) { + c32_t meas = nr_pbch_dmrs_correlation(ue, proc, i, i - pbch_initial_symbol, ue->nr_gold_pbch[hf][l], rxdataF); + csum(cumul, cumul, meas); + } + // initialization of structure + *current_ssb = (NR_UE_SSB){.i_ssb = l, .n_hf = hf, .metric = squaredMod(cumul)}; current_ssb++; } } + qsort(best_ssb, N_L * N_hf, sizeof(NR_UE_SSB), ssb_sort); + stop_meas(&ue->dlsch_channel_estimation_stats); - for (NR_UE_SSB *temp_ptr = best_ssb; ret != 0 && temp_ptr < best_ssb + N_L * N_hf; temp_ptr++) { + const int nb_ant = frame_parms->nb_antennas_rx; + for (NR_UE_SSB *ssb = best_ssb; ssb < best_ssb + N_L * N_hf; ssb++) { start_meas(&ue->dlsch_channel_estimation_stats); // computing channel estimation for selected best ssb const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; - __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz]; - __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; + __attribute__((aligned(32))) c16_t dl_ch_estimates[nb_ant][estimateSz]; + __attribute__((aligned(32))) c16_t dl_ch_estimates_time[nb_ant][frame_parms->ofdm_symbol_size]; for(int i=pbch_initial_symbol; ii_ssb,temp_ptr->n_hf,rxdataF); + nr_pbch_channel_estimation(ue, + estimateSz, + dl_ch_estimates, + dl_ch_estimates_time, + proc, + i, + i - pbch_initial_symbol, + ssb->i_ssb, + ssb->n_hf, + rxdataF); stop_meas(&ue->dlsch_channel_estimation_stats); fapiPbch_t result = {0}; - - int pbch_res = nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, frame_parms, temp_ptr->i_ssb, &result, rxdataF); - ret = pbch_res == 0; - - if (DUMP_PBCH_CH_ESTIMATES && ret) { - write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, frame_parms->nb_antennas_rx*estimateSz, 1, 1); - write_output("pbch_ch_estimates_time.m", - "pbch_ch_estimates_time", - dl_ch_estimates_time, - frame_parms->nb_antennas_rx * frame_parms->ofdm_symbol_size, - 1, - 1); + if (0 == nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, frame_parms, ssb->i_ssb, &result, rxdataF)) { + if (DUMP_PBCH_CH_ESTIMATES) { + write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, nb_ant * estimateSz, 1, 1); + write_output("pbch_ch_estimates_time.m", + "pbch_ch_estimates_time", + dl_ch_estimates_time, + nb_ant * frame_parms->ofdm_symbol_size, + 1, + 1); + } + return false; } } - if (ret == 0) { - LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); - } else { - LOG_W(PHY, "[UE%d] Initial sync: pbch not decoded, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); - } - return ret; + LOG_W(PHY, "[UE%d] Initial sync: pbch not decoded, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); + return true; } nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa) diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 5059ccd107..8bbb1f9d84 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -307,13 +307,6 @@ typedef struct { fapi_nr_ul_config_srs_pdu srs_config_pdu; } NR_UE_SRS; -// structure used for multiple SSB detection -typedef struct NR_UE_SSB { - uint8_t i_ssb; // i_ssb between 0 and 7 (it corresponds to ssb_index only for Lmax=4,8) - uint8_t n_hf; // n_hf = 0,1 for Lmax =4 or n_hf = 0 for Lmax =8,64 - c32_t c; -} NR_UE_SSB; - typedef struct UE_NR_SCAN_INFO_s { /// 10 best amplitudes (linear) for each pss signals int32_t amp[3][10]; From 86ebebf3f58d14bab4e7ad4a6fc204437f424987 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Tue, 26 Mar 2024 21:08:46 +0100 Subject: [PATCH 8/9] fix merge conflicts --- openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 2fa9b00b93..c8c67c017f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -57,7 +57,7 @@ int cnt=0; typedef struct NR_UE_SSB { uint i_ssb; // i_ssb between 0 and 7 (it corresponds to ssb_index only for Lmax=4,8) uint n_hf; // n_hf = 0,1 for Lmax =4 or n_hf = 0 for Lmax =8,64 - uint32_t metric; // metric to order SSB hypothesis + double metric; // metric to order SSB hypothesis } NR_UE_SSB; static int ssb_sort(const void *a, const void *b) @@ -81,12 +81,11 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, for (int hf = 0; hf < N_hf; hf++) { for (int l = 0; l < N_L; l++) { // computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf - c32_t cumul = {0}; + cd_t cumul = {0}; for (int i = pbch_initial_symbol; i < pbch_initial_symbol + 3; i++) { c32_t meas = nr_pbch_dmrs_correlation(ue, proc, i, i - pbch_initial_symbol, ue->nr_gold_pbch[hf][l], rxdataF); csum(cumul, cumul, meas); } - // initialization of structure *current_ssb = (NR_UE_SSB){.i_ssb = l, .n_hf = hf, .metric = squaredMod(cumul)}; current_ssb++; } @@ -126,12 +125,13 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, 1, 1); } - return false; + LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); + return true; } } LOG_W(PHY, "[UE%d] Initial sync: pbch not decoded, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); - return true; + return false; } nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa) From f4ac4fee42d93aef633c55498cc21ea4f1df99b9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 28 Mar 2024 10:47:10 +0000 Subject: [PATCH 9/9] Apply 1 suggestion(s) to 1 file(s) --- ci-scripts/cls_oaicitest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index ed121739b7..55ca34c9f3 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -1135,7 +1135,7 @@ class OaiCiTest(): logging.debug(f'\033[94m{mibMsg}\033[0m') frequency_found = True except Exception as e: - logging.error(f'\033[91m Measured Carrier Frequency not found \033[0m') + logging.error(f'\033[91m UE did not find PBCH\033[0m') result = re.search("PLMN MCC (?P\d{1,3}), MNC (?P\d{1,3}), TAC", str(line)) if result is not None and (not plmn_found): try: