diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 4df0cc51e1..55cc1190c4 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1245,6 +1245,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_pss.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sss.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_pbch.c + ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c ${OPENAIR1_DIR}/PHY/TOOLS/file_output.c ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 41a5bf7ad5..27cc8785b8 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -88,6 +88,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, LTE_eNB_PUSCH** const pusch_vars = gNB->pusch_vars; LTE_eNB_SRS* const srs_vars = gNB->srs_vars; LTE_eNB_PRACH* const prach_vars = &gNB->prach_vars; + uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; int i, UE_id; @@ -118,6 +119,12 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, nr_init_pbch_dmrs(gNB); // Polar encoder init for PBCH nr_polar_init(&fp->pbch_polar_params, 1); + //PDCCH DMRS init + pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t**)); + for (int slot=0; slotslots_per_frame; slot++) + pdcch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot); + + nr_init_pdcch_dmrs(gNB, cfg->sch_config.physical_cell_id.value); /* lte_gold(fp,gNB->lte_gold_table,fp->Nid_cell); @@ -271,10 +278,12 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) { // NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms; nfapi_config_request_t *cfg = &gNB->gNB_config; + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; NR_gNB_COMMON* const common_vars = &gNB->common_vars; LTE_eNB_PUSCH** const pusch_vars = gNB->pusch_vars; LTE_eNB_SRS* const srs_vars = gNB->srs_vars; LTE_eNB_PRACH* const prach_vars = &gNB->prach_vars; + uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; int i, UE_id; @@ -287,6 +296,12 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(common_vars->txdataF); free_and_zero(common_vars->rxdataF); + // PDCCH DMRS sequences + pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t**)); + for (int slot=0; slotslots_per_frame; slot++) + free_and_zero(pdcch_dmrs[slot]); + free_and_zero(pdcch_dmrs); + // Channel estimates for SRS for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { for (i=0; i<64; i++) { diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 1fcaaed494..2cbb2fb5af 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -139,7 +139,7 @@ int nr_init_frame_parms(nfapi_config_request_t* config, AssertFatal(1==0,"Invalid numerology index %d", mu); } - + frame_parms->slots_per_frame = 10* frame_parms->slots_per_subframe; frame_parms->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats frame_parms->samples_per_subframe_wCP = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot * frame_parms->slots_per_subframe; frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP; @@ -289,6 +289,7 @@ int nr_init_frame_parms_ue(nfapi_config_request_t* config, frame_parms->samples_per_subframe = 30720 * frame_parms->ttis_per_subframe; frame_parms->first_carrier_offset = 2048-600; + frame_parms->slots_per_frame = 10* frame_parms->slots_per_subframe; frame_parms->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats frame_parms->samples_per_subframe_wCP = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot * frame_parms->slots_per_subframe; frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP; diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c index 110692bc0a..04e5b003b3 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold.c +++ b/openair1/PHY/NR_REFSIG/nr_gold.c @@ -24,9 +24,10 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB) { - unsigned int n, x1, x2; - unsigned char Nid, i_ssb, i_ssb2; - unsigned char Lmax, l, n_hf, N_hf; + uint32_t x1, x2; + uint8_t Nid, i_ssb, i_ssb2; + uint8_t Lmax, l, n_hf, N_hf; + uint8_t reset = 1; nfapi_config_request_t *cfg = &gNB->gNB_config; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; @@ -36,32 +37,40 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB) N_hf = (Lmax == 4)? 2:1; for (n_hf = 0; n_hf < N_hf; n_hf++) { - for (l = 0; l < Lmax ; l++) { i_ssb = l & (Lmax-1); i_ssb2 = (i_ssb<<2) + n_hf; - x1 = 1 + (1<<31); x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3); - x2 = x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31); - // skip first 50 double words (1600 bits) - for (n = 1; n < 50; n++) { - x1 = (x1>>1) ^ (x1>>4); - x1 = x1 ^ (x1<<31) ^ (x1<<28); - x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); - x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28); - } - - for (n=0; n>1) ^ (x1>>4); - x1 = x1 ^ (x1<<31) ^ (x1<<28); - x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); - x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28); - gNB->nr_gold_pbch_dmrs[n_hf][l][n] = x1 ^ x2; + for (uint8_t n=0; nnr_gold_pbch_dmrs[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset); + reset = 0; } } } } + +void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid) +{ + + uint32_t n, x1, x2; + uint8_t reset = 1; + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; + + for (uint8_t slot=0; fp->slots_per_frame; slot++) { + for (uint8_t symb=0; fp->symbols_per_slot; symb++) { + + x2 = ((1<<17) * (14*slot+symb+1) * ((Nid<<1)+1) + (Nid<<1))%(1<<31); + + for (uint32_t n=0; n>5]&(1<<(m&0x1f)))>>(m&0x1f)))<<1)]; + mod_dmrs[(m<<1)+1] = nr_mod_table[((NR_MOD_TABLE_BPSK_OFFSET + ((gold_pdcch_dmrs[m>>5]&(1<<(m&0x1f)))>>(m&0x1f)))<<1) + 1]; +#ifdef DEBUG_PBCH_DMRS + printf("m %d mod_dmrs %d %d\n", m, mod_dmrs[2*m], mod_dmrs[2*m+1]); +#endif + } + return 0; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index 6ed05e0e55..f9edb66ef6 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -76,9 +76,12 @@ typedef struct { } nr_pdcch_coreset_params_t; typedef struct { + uint8_t first_slot; + uint8_t nb_slots; + uint8_t sfn_mod2; nr_pdcch_ss_params_t ss_params; nr_pdcch_coreset_params_t coreset_params; -} nr_pdcch_params_t; +} nr_pdcch_vars_t; typedef struct { /// Length of DCI in bits @@ -100,10 +103,11 @@ typedef struct { uint8_t nr_get_dci_size(nr_dci_format_e format, nr_rnti_type_e rnti, - NR_BWP_PARMS bwp, + NR_BWP_PARMS* bwp, nfapi_config_request_t* config); uint8_t nr_generate_dci_top(NR_DCI_ALLOC_t dci_alloc, + uint32_t *gold_pdcch_dmrs, int32_t** txdataF, int16_t amp, NR_DL_FRAME_PARMS* frame_parms, diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index 42d651d140..7c66342338 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -51,7 +51,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, { int k,l; int16_t a; - int16_t mod_dmrs[2 * NR_PBCH_DMRS_LENGTH]; + int16_t mod_dmrs[NR_PBCH_DMRS_LENGTH<<2]; LOG_I(PHY, "PBCH DMRS mapping started at symbol %d shift %d\n", ssb_start_symbol+1, nushift); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 9728d6b2d0..038814b234 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -290,6 +290,9 @@ typedef struct PHY_VARS_gNB_s { /// PBCH DMRS sequence uint32_t nr_gold_pbch_dmrs[2][64][NR_PBCH_DMRS_LENGTH_DWORD]; + /// PDCCH DMRS sequence + uint32_t **nr_gold_pdcch_dmrs[NR_MAX_PDCCH_DMRS_LENGTH_DWORD]; + /// Indicator set to 0 after first SR uint8_t first_sr[NUMBER_OF_UE_MAX]; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 57b3159310..e55f2391c0 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -57,6 +57,9 @@ #define NR_PBCH_DMRS_LENGTH 144 #define NR_PBCH_DMRS_LENGTH_DWORD 5 // roundup(NR_PBCH_DMRS_LENGTH/32) +#define NR_MAX_PDCCH_DMRS_LENGTH 100 +#define NR_MAX_PDCCH_DMRS_LENGTH_DWORD 5 + #define NR_MAX_NUM_BWP 4 typedef enum { @@ -129,6 +132,8 @@ typedef struct NR_DL_FRAME_PARMS { uint16_t symbols_per_slot; /// Number of slots per subframe uint16_t slots_per_subframe; + /// Number of slots per frame + uint16_t slots_per_frame; /// Number of samples in a subframe uint32_t samples_per_subframe; /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL) diff --git a/openair1/SCHED_NR/phy_procedures_nr_common.c b/openair1/SCHED_NR/phy_procedures_nr_common.c index 8831efa54e..e685888232 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_common.c +++ b/openair1/SCHED_NR/phy_procedures_nr_common.c @@ -55,15 +55,15 @@ nr_subframe_t nr_subframe_select(nfapi_config_request_t *cfg,unsigned char subfr } -void nr_fill_pdcch_params(nr_pdcch_params_t *pdcch_params, - nfapi_config_request_t* config, +void nr_get_coreset_and_ss_params(nr_pdcch_vars_t *pdcch_vars, + uint8_t mu, uint8_t ssb_idx) { - nr_pdcch_coreset_params_t *coreset_params = &pdcch_params->coreset_params; - nr_pdcch_ss_params_t *ss_params = &pdcch_params->ss_params; + nr_pdcch_coreset_params_t *coreset_params = &pdcch_vars->coreset_params; + nr_pdcch_ss_params_t *ss_params = &pdcch_vars->ss_params; // the switch case below assumes that only the cases where the SSB and the PDCCH have the same SCS are supported along with type 1 PDCCH/ mux pattern 1 and FR1 - switch(config->subframe_config.numerology_index_mu.value) { + switch(mu) { case NR_MU_0: break; @@ -87,7 +87,25 @@ void nr_fill_pdcch_params(nr_pdcch_params_t *pdcch_params, break; default: - AssertFatal(1==0,"Invalid PDCCH numerology index %d", config->subframe_config.numerology_index_mu.value); + AssertFatal(1==0,"Invalid PDCCH numerology index %d\n", mu); } } + +void nr_get_pdcch_type_0_monitoring_period(nr_pdcch_vars_t *pdcch_vars, + uint8_t mu, + uint8_t nb_slots_per_frame, + uint8_t ssb_idx) +{ + uint8_t O = pdcch_vars->ss_params.param_O, M = pdcch_vars->ss_params.param_M; + + if (pdcch_vars->coreset_params.mux_pattern == nr_pdcch_mux_pattern_type_1) { + pdcch_vars->nb_slots = 2; + pdcch_vars->sfn_mod2 = ((uint8_t)(floor( (O*pow(2, mu) + floor(ssb_idx*M)) / nb_slots_per_frame )) & 1)? 1 : 0; + pdcch_vars->first_slot = (uint8_t)(O*pow(2, mu) + floor(ssb_idx*M)) % nb_slots_per_frame; + } + else { //nr_pdcch_mux_pattern_type_2, nr_pdcch_mux_pattern_type_3 + pdcch_vars->nb_slots = 1; + } + +} diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index e40d8e0a5c..5100e8fe61 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -46,7 +46,7 @@ extern uint8_t nfapi_mode; int return_ssb_type(nfapi_config_request_t *cfg) { int mu = cfg->subframe_config.numerology_index_mu.value; - nr_numerology_index_e ssb_type; + nr_ssb_type_e ssb_type; switch(mu) { @@ -181,5 +181,9 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, nr_common_signal_procedures(gNB,frame, subframe); //if (frame == 9) //write_output("txdataF.m","txdataF",gNB->common_vars.txdataF[aa],fp->samples_per_frame_wCP, 1, 1); + + //temporary DCI generation test + NR_DCI_ALLOC_t dci_alloc; + nr_generate_dci_top(dci_alloc, gNB->nr_gold_pdcch_dmrs[0][0],gNB->common_vars.txdataF, 512, fp, cfg); } } diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 238fd743da..b7d71cfc17 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -41,8 +41,12 @@ void nr_feptx_ofdm(RU_t *ru); void nr_feptx_ofdm_2thread(RU_t *ru); void nr_feptx0(RU_t *ru,int slot); -void nr_fill_pdcch_params(nr_pdcch_params_t *pdcch_params, - nfapi_config_request_t* config, - uint8_t ssb_idx); +void nr_get_coreset_and_ss_params(nr_pdcch_vars_t *pdcch_params, + uint8_t mu, + uint8_t ssb_idx); +void nr_get_pdcch_type_0_monitoring_period(nr_pdcch_vars_t *pdcch_vars, + uint8_t mu, + uint8_t nb_slots_per_frame, + uint8_t ssb_idx); #endif