diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index c4e2399351da779e7367aeef57e8601c6a15b0f5..40fbb2d117d3a190518cfb99911b3baac0e70ca2 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2651,7 +2651,7 @@ if (${T_TRACER}) #all "add_executable" definitions (except tests, rb_tool, updatefw) lte-softmodem lte-softmodem-nos1 lte-uesoftmodem lte-uesoftmodem-nos1 nr-softmodem nr-softmodem-nos1 nr-uesoftmodem nr-uesoftmodem-nos1 - dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim + dlsim_tm4 nr_dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim ulsim ldpctest polartest #all "add_library" definitions diff --git a/maketags b/maketags index ac8d4151d4b198d3c4f6b7af08cd43dc1d4b6ded..eb7c474a38b3ce208a97cda0c6fdae41443af086 100755 --- a/maketags +++ b/maketags @@ -1,4 +1,4 @@ #!/bin/sh echo "building ctags for openair1 and openair2 ..." -ctags -e -R --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair2/RRC/CELLULAR/ --exclude=openair2/NAS/DRIVER/CELLULAR/ --exclude=openair2/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common nfapi +ctags -e -R --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair1/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common nfapi diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h index 4273186dcf42d164ab19cd2c2c2f0d74f1d4ca18..94b7121998fade8d9a46ef51fa859555454c4733 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h @@ -13,6 +13,9 @@ #define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5 +#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64 +#define NFAPI_NR_MAX_NB_CORESETS 12 +#define NFAPI_NR_MAX_NB_SEARCH_SPACES 40 // Extension to the generic structures for single tlv values typedef struct { @@ -356,7 +359,8 @@ typedef enum { typedef enum { NFAPI_NR_CSET_CONFIG_MIB_SIB1=0, - NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG + NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG, // implicit assumption of coreset Id other than 0 + NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG_CSET_0 } nfapi_nr_coreset_config_type_e; typedef enum { @@ -364,6 +368,31 @@ typedef enum { NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS } nfapi_nr_coreset_precoder_granularity_type_e; +typedef enum { + NFAPI_NR_QCL_TYPE_A=0, + NFAPI_NR_QCL_TYPE_B, + NFAPI_NR_QCL_TYPE_C, + NFAPI_NR_QCL_TYPE_D +} nfapi_nr_qcl_type_e; + +typedef enum { + NFAPI_NR_SS_PERIODICITY_SL1=1, + NFAPI_NR_SS_PERIODICITY_SL2=2, + NFAPI_NR_SS_PERIODICITY_SL4=4, + NFAPI_NR_SS_PERIODICITY_SL5=5, + NFAPI_NR_SS_PERIODICITY_SL8=8, + NFAPI_NR_SS_PERIODICITY_SL10=10, + NFAPI_NR_SS_PERIODICITY_SL16=16, + NFAPI_NR_SS_PERIODICITY_SL20=20, + NFAPI_NR_SS_PERIODICITY_SL40=40, + NFAPI_NR_SS_PERIODICITY_SL80=80, + NFAPI_NR_SS_PERIODICITY_SL160=160, + NFAPI_NR_SS_PERIODICITY_SL320=320, + NFAPI_NR_SS_PERIODICITY_SL640=640, + NFAPI_NR_SS_PERIODICITY_SL1280=1280, + NFAPI_NR_SS_PERIODICITY_SL2560=2560 +} nfapi_nr_search_space_monitoring_periodicity_e; + typedef enum { NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A=0, NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_B, @@ -496,9 +525,9 @@ typedef struct{ uint8_t css_format_2_2; uint8_t css_format_2_3; uint8_t uss_dci_formats; - uint8_t srs_monitoring_periodicity; - uint8_t slot_monitoring_periodicity; - uint8_t slot_monitoring_offset; + uint16_t srs_monitoring_periodicity; + uint16_t slot_monitoring_periodicity; + uint16_t slot_monitoring_offset; uint16_t monitoring_symbols_in_slot; uint16_t number_of_candidates[NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS]; } nfapi_nr_search_space_t; @@ -516,7 +545,7 @@ typedef struct { uint8_t aggregation_level; uint8_t n_rb; uint8_t n_symb; - uint8_t rb_offset; + int8_t rb_offset; uint8_t cr_mapping_type; uint8_t reg_bundle_size; uint8_t interleaver_size; diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 305a9c62663c488c2c9cc10aeac0fe2380dff0d5..91d20b51bb70ddcde447eac729d8411144166e13 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -1160,7 +1160,6 @@ uint32_t polar_decoder_int16(int16_t *input, out[0]=Ar; - return(crc^rxcrc); diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 22eb395da90e81d61a561f1a6560d2bcbcc50ed1..1e1751fe24adabdeaf9ff76fa21a31f2b7f6daff 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -54,13 +54,19 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, //int i; unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10; unsigned int rx_offset; - NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[Ns>>1]][0]; - uint16_t coreset_start_subcarrier = frame_parms->first_carrier_offset+((int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_vars->coreset[0].rb_offset)*NR_NB_SC_PER_RB; - uint16_t nb_rb_coreset = 24; - uint16_t bwp_start_subcarrier = frame_parms->first_carrier_offset+516; + NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[Ns]][0]; + uint16_t coreset_start_subcarrier = frame_parms->first_carrier_offset;//+((int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_vars->coreset[0].rb_offset)*NR_NB_SC_PER_RB; + uint16_t nb_rb_coreset = 0; + uint16_t bwp_start_subcarrier = frame_parms->first_carrier_offset;//+516; uint16_t nb_rb_pdsch = 50; uint8_t p=0; - uint8_t l0 = 2; + uint8_t l0 = pdcch_vars->coreset[0].duration; + uint64_t coreset_freq_dom = pdcch_vars->coreset[0].frequencyDomainResources; + for (int i = 0; i < 45; i++) { + if (((coreset_freq_dom & 0x1FFFFFFFFFFF) >> i) & 0x1) nb_rb_coreset++; + } + nb_rb_coreset = 6 * nb_rb_coreset; + //printf("corset duration %d nb_rb_coreset %d\n", l0, nb_rb_coreset); void (*dft)(int16_t *,int16_t *, int); int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs @@ -104,9 +110,9 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, } if (no_prefix) { - slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot*frame_parms->slots_per_subframe) * (Ns>>1); + slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns); } else { - slot_offset = (frame_parms->samples_per_subframe) * (Ns>>1); + slot_offset = (frame_parms->samples_per_slot) * (Ns); } /*if (l<0 || l>=7-frame_parms->Ncp) { @@ -122,7 +128,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { - memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); + memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); rx_offset = sample_offset + slot_offset + nb_prefix_samples0 - SOFFSET; // Align with 256 bit @@ -130,7 +136,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, #ifdef DEBUG_FEP // if (ue->frame <100) - /*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx,Ns, symbol, + /*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx,Ns, symbol, nb_prefix_samples,nb_prefix_samples0,slot_offset,sample_offset,rx_offset,frame_length_samples); #endif @@ -146,14 +152,14 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, (void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples], frame_parms->ofdm_symbol_size*sizeof(int)); dft((int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly #if UE_TIMING_TRACE start_meas(&ue->rx_dft_stats); #endif dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); #endif @@ -175,11 +181,11 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, (void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], frame_parms->ofdm_symbol_size*sizeof(int)); dft((int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 2e5ad47d9172fe1356fb53ef78d8acab1a5d6547..e0c17bfb7511ea268c44e4d93c12a12bec403482 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -32,6 +32,7 @@ //#define NR_PBCH_DMRS_LENGTH_DWORD 5 //#define NR_PBCH_DMRS_LENGTH 144 +//#define DEBUG_PDCCH #include "refsig_defs_ue.h" #include "PHY/defs_nr_UE.h" diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index bd2abebdf0f0fd4dbf90b3c4226e0f915e219d1c..dba114ed8ad07e0318349b9bcc8e3bf31047f2bc 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -20,7 +20,7 @@ */ /*! \file PHY/NR_TRANSPORT/nr_dci.c -* \brief Implements DCI encoding and PDCCH TX procedures (38.212/38.213/38.214). V15.2.0 2018-06. +* \brief Implements DCI encoding and PDCCH TX procedures (38.212/38.213/38.214). V15.4.0 2019-01. * \author Guy De Souza * \date 2018 * \version 0.1 @@ -35,7 +35,6 @@ //#define DEBUG_PDCCH_DMRS //#define DEBUG_DCI //#define DEBUG_CHANNEL_CODING -#define PDCCH_TEST_POLAR_TEMP_FIX extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT]; @@ -154,7 +153,7 @@ void nr_pdcch_scrambling(uint32_t *in, } } (*out) ^= ((((*in)>>(i&0x1f))&1) ^ ((s>>(i&0x1f))&1))<<(i&0x1f); - // printf("nr_pdcch_scrambling: in %d => out %d\n",((*in)>>(i&0x1f))&1,((*out)>>(i&0x1f))&1); + //printf("nr_pdcch_scrambling: in %d seq 0x%08x => out %d\n",((*in)>>(i&0x1f))&1,s,((*out)>>(i&0x1f))&1); } } @@ -169,8 +168,10 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, { int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1]; // 3 for the max coreset duration - uint8_t idx=0; - //uint16_t a; + uint32_t dmrs_seq[NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD]; + uint16_t dmrs_offset=0; + uint16_t cset_start_sc; + uint8_t cset_start_symb, cset_nsymb; int k,l,k_prime,dci_idx, dmrs_idx; nr_cce_t cce; nr_reg_t reg; @@ -179,62 +180,88 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, /*First iteration: single DCI*/ NR_gNB_DCI_ALLOC_t dci_alloc = pdcch_vars.dci_alloc[0]; nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params; - uint16_t dmrs_length = dci_alloc.L*36; //2(QPSK)*3(per RB)*6(REG per CCE) - uint16_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE) /*The coreset is initialised - * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset + * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0 + * or the rb_offset for other coresets * in time: by its first slot and its first symbol*/ - uint16_t cset_start_sc = frame_parms.first_carrier_offset + ((int)floor(frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_params.rb_offset)*NR_NB_SC_PER_RB; - // uint8_t cset_start_symb = pdcch_params.first_slot*frame_parms.symbols_per_slot + pdcch_params.first_symbol; - uint8_t cset_start_symb = pdcch_params.first_symbol; - uint8_t cset_nsymb = pdcch_params.n_symb; + if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1){ + cset_start_sc = frame_parms.first_carrier_offset + (frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB + + pdcch_params.rb_offset)*NR_NB_SC_PER_RB; + } + else + cset_start_sc = frame_parms.first_carrier_offset + pdcch_params.rb_offset*NR_NB_SC_PER_RB; + + cset_start_symb = pdcch_params.first_symbol; + cset_nsymb = pdcch_params.n_symb; dci_idx = 0; + LOG_I(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb); + + // DMRS length is per OFDM symbol + uint16_t dmrs_length = (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS)? + (pdcch_params.n_rb*6) : (dci_alloc.L*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE) + uint16_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE) + LOG_I(PHY, "DMRS length per symbol %d\t DCI encoded length %d\n", dmrs_length, encoded_length); /// DMRS QPSK modulation /*There is a need to shift from which index the pregenerated DMRS sequence is used * see 38211 r15.2.0 section 7.4.1.3.2: assumption is the reference point for k refers to the DMRS sequence*/ - if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) - gold_pdcch_dmrs += ((int)floor(frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_params.rb_offset)*3/32; + if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) { + for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_params.n_symb; symb++) + gold_pdcch_dmrs[symb] += (pdcch_params.rb_offset*3)>>5; + dmrs_offset = (pdcch_params.rb_offset*3)&0x1f; + LOG_I(PHY, "PDCCH DMRS offset %d\n", dmrs_offset); + } for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_params.n_symb; symb++) { - for (int i=0; i<dmrs_length>>1; i++) { - idx = ((((gold_pdcch_dmrs[symb][(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((gold_pdcch_dmrs[symb][((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); - mod_dmrs[symb][i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; - mod_dmrs[symb][(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; - #ifdef DEBUG_PDCCH_DMRS - printf("symb %d i %d idx %d gold seq %u b0-b1 %d-%d mod_dmrs %d %d\n", symb, i, idx, gold_pdcch_dmrs[symb][(i<<1)>>5], - (((gold_pdcch_dmrs[symb][(i<<1)>>5])>>((i<<1)&0x1f))&1), (((gold_pdcch_dmrs[symb][((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), - mod_dmrs[symb][(i<<1)], mod_dmrs[symb][(i<<1)+1]); - #endif + if (dmrs_offset) { + // a non zero offset requires the DMRS sequence to be rearranged + memset(dmrs_seq,0, NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t)); + for (int i=0; i<dmrs_length; i++) { + dmrs_seq[(i>>5)] |= ((gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]>>((i+dmrs_offset)&0x1f))&1)<<(i&0x1f); +#ifdef DEBUG_PDCCH_DMRS + //printf("out 0x%08x in 0x%08x \n", dmrs_seq[(i>>5)], gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]); +#endif + } + nr_modulation(dmrs_seq, dmrs_length, MOD_QPSK, mod_dmrs[symb]); } + else + nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, MOD_QPSK, mod_dmrs[symb]); + +#ifdef DEBUG_PDCCH_DMRS + for (int i=0; i<dmrs_length>>1; i++) + if (dmrs_offset) + printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, dmrs_seq[i>>5], + mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] ); + else + printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, + gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] ); +#endif + } + /// DCI payload processing // CRC attachment + Scrambling + Channel coding + Rate matching uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD]; - uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? ((pdcch_params.scrambling_id)?pdcch_params.rnti:0) : 0; - uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value; -//#ifdef PDCCH_TEST_POLAR_TEMP_FIX -// nr_polar_init(¤tPtr, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L); -// t_nrPolar_paramsPtr currentPtr = nr_polar_params(*nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L); -//#else + uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.rnti:0; + uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? + pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value; + nr_polar_init(nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L); t_nrPolar_paramsPtr currentPtr = nr_polar_params(*nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L); -//#endif - //polar_encoder_dci(dci_alloc.dci_pdu, encoder_output, currentPtr, pdcch_params.rnti); polar_encoder_fast(dci_alloc.dci_pdu, encoder_output, pdcch_params.rnti,currentPtr); #ifdef DEBUG_CHANNEL_CODING printf("polar rnti %d\n",pdcch_params.rnti); - for (int i=0;i<54;i++) printf("Encoded Payload: [%d]->0x%08x \n", i,encoder_output[i]); - - printf("DCI PDU: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", - dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1], dci_alloc.dci_pdu[2], dci_alloc.dci_pdu[3]); - printf("Encoded Payload: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", - encoder_output[0], encoder_output[1], encoder_output[2], encoder_output[3]); + printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n", + dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1]); + printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5); + for (int i=0;i<encoded_length>>5;i++) + printf("[%d]->0x%08x \t", i,encoder_output[i]); + printf("\n"); #endif /// Scrambling @@ -247,17 +274,13 @@ printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%0 scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] ); #endif - // QPSK modulation + /// QPSK modulation int16_t mod_dci[NR_MAX_DCI_SIZE>>1]; - for (int i=0; i<encoded_length>>1; i++) { - idx = ((((scrambled_output[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((scrambled_output[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); - mod_dci[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; - mod_dci[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; + nr_modulation(scrambled_output, encoded_length, MOD_QPSK, mod_dci); #ifdef DEBUG_DCI - printf("i %d idx %d b0-b1 %d-%d mod_dci %d %d\n", i, idx, (((scrambled_output[(i<<1)>>5])>>((i<<1)&0x1f))&1), - (((scrambled_output[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), mod_dci[(i<<1)], mod_dci[(i<<1)+1]); + for (int i=0; i<encoded_length>>1; i++) + printf("i %d mod_dci %d %d\n", i, mod_dci[i<<1], mod_dci[(i<<1)+1] ); #endif - } /// Resource mapping @@ -289,10 +312,11 @@ printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%0 dmrs_idx = 0; k = cset_start_sc + 1; while (dmrs_idx<3*pdcch_params.n_rb) { - ((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[l][dmrs_idx<<1]) >> 15; - ((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; + ((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = ((amp>>1) * mod_dmrs[l][dmrs_idx<<1]) >> 15; + ((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; #ifdef DEBUG_PDCCH_DMRS - printf("symbol %d position %d => (%d,%d)\n",l,k,((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] , ((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); + printf("symbol %d position %d => (%d,%d)\n",l,k,((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] , + ((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); #endif k+=4; if (k >= frame_parms.ofdm_symbol_size) @@ -315,19 +339,23 @@ printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%0 for (int m=0; m<NR_NB_SC_PER_RB; m++) { if ( m == (k_prime<<2)+1) { // DMRS if not already mapped if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_SAME_AS_REG_BUNDLE) { - ((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[l][dmrs_idx<<1]) >> 15; - ((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; + ((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = ((amp>>1) * mod_dmrs[l][dmrs_idx<<1]) >> 15; + ((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; #ifdef DEBUG_PDCCH_DMRS - printf("l %d position %d => (%d,%d)\n",l,k,((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] , ((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); + printf("l %d position %d => (%d,%d)\n",l,k,((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] , + ((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); #endif - k_prime++; dmrs_idx++; } + k_prime++; } else { // DCI payload ((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dci[dci_idx<<1]) >> 15; ((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dci[(dci_idx<<1) + 1]) >> 15; - //printf("dci output %d %d\n",(a * mod_dci[dci_idx<<1]) >> 15, (a * mod_dci[(dci_idx<<1) + 1]) >> 15); +#ifdef DEBUG_DCI + printf("l %d position %d => (%d,%d)\n",l,k,((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] , + ((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); +#endif dci_idx++; } k++; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c index 1d29b057fc16a277f4ade82790b867f9bd6e2d74..59adce5fb53582f26ff0efeef8dc039d188d20c4 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c @@ -61,11 +61,13 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m else { //NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC } - uint8_t cond = N_reg%(bsize*R); - AssertFatal(cond==0, "CCE to REG interleaving: Invalid configuration leading to non integer C\n"); - C = N_reg/(bsize*R); + if (pdcch_params->cr_mapping_type == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { + AssertFatal((N_reg%(bsize*R))==0, "CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %d, bsize %d R %d)\n", + N_reg, bsize, R); + C = N_reg/(bsize*R); + } - tmp = L * (( Y + (m*N_cce)/(L*M_s_max) + n_CI ) % (N_cce/L)); + tmp = L * (( Y + (m*N_cce)/(L*M_s_max) + n_CI ) % CEILIDIV(N_cce,L)); LOG_I(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d tmp %d\n", m, bsize, R, tmp); for (uint8_t cce_idx=0; cce_idx<L; cce_idx++) { @@ -189,14 +191,16 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, #endif break; - case NFAPI_NR_RNTI_C: + case NFAPI_NR_RNTI_C: + // indicating a DL DCI format 1bit pos++; *dci_pdu |= (pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos); + // Freq domain assignment (275rb >> fsize = 16) fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); pos+=fsize; - *dci_pdu |= ((pdu_rel15->frequency_domain_assignment&((1<<fsize)-1)) << (dci_alloc->size-pos)); + *dci_pdu |= ((pdu_rel15->frequency_domain_assignment&((1<<fsize)-1)) << (dci_alloc->size-pos)); if (((pdu_rel15->frequency_domain_assignment+1)&1) ==0) //fsize are all 1 38.212 p86 { @@ -223,8 +227,7 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, // Time domain assignment 4bit pos+=4; - *dci_pdu |= ((pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos)); - + *dci_pdu |= ((pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos)); // VRB to PRB mapping 1bit pos++; @@ -244,7 +247,7 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, // HARQ process number 4bit pos+=4; - *dci_pdu |= ((pdu_rel15->harq_pid&0xf)<<(dci_alloc->size-pos)); + *dci_pdu |= ((pdu_rel15->harq_pid&0xf)<<(dci_alloc->size-pos)); // Downlink assignment index 2bit pos+=2; @@ -252,15 +255,15 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, // TPC command for scheduled PUCCH 2bit pos+=2; - *dci_pdu |= ((pdu_rel15->tpc&3)<<(dci_alloc->size-pos)); + *dci_pdu |= ((pdu_rel15->tpc&3)<<(dci_alloc->size-pos)); // PUCCH resource indicator 3bit pos+=3; - *dci_pdu |= ((pdu_rel15->pucch_resource_indicator&0x7)<<(dci_alloc->size-pos)); + *dci_pdu |= ((pdu_rel15->pucch_resource_indicator&0x7)<<(dci_alloc->size-pos)); // PDSCH-to-HARQ_feedback timing indicator 3bit pos+=3; - *dci_pdu |= ((pdu_rel15->pdsch_to_harq_feedback_timing_indicator&0x7)<<(dci_alloc->size-pos)); + *dci_pdu |= ((pdu_rel15->pdsch_to_harq_feedback_timing_indicator&0x7)<<(dci_alloc->size-pos)); } //end else break; 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 145c779be909055b42294cd705ec6c6c9d631c7c..a90450b0a5ff2d50a2f30d4b87fb0aba389a7985 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -28,6 +28,7 @@ #include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "filt16a_32.h" #include "T.h" +//#define DEBUG_PDSCH //#define DEBUG_PDCCH @@ -271,8 +272,8 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; uint8_t nushift; - int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset]; - int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF; + int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset]; + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF; nushift = 1; ue->frame_parms.nushift = nushift; @@ -287,7 +288,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, k = coreset_start_subcarrier; #ifdef DEBUG_PDCCH - printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, + printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,l,Ns,k, symbol); #endif @@ -297,7 +298,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot - nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns>>1][symbol], &pilot[0],2000,nb_rb_coreset); + nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset); for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { @@ -459,16 +460,16 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, break; } - //if( (Ns== 2) && (l == 0)) + if( (Ns== 1) && (l == 0)) { // do ifft of channel estimate for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) { - if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx]) + if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset][(p<<1)+aarx]) { - LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns>>1], l); - idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][0], - (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1); + LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], l); + idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][0], + (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1); } } } @@ -496,8 +497,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; uint8_t nushift; - int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset]; - int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF; + int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset]; + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF; nushift = (p>>1)&1; ue->frame_parms.nushift = nushift; diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 3d481a0468a670caf59bb021931575d52541ce78..5ea5416ea68e24d15000aadbe0448ac74fec32bd 100755 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -805,7 +805,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, // For each BWP the number of CORESETs is limited to 3 (including initial CORESET Id=0 -> ControlResourceSetId (0..maxNrofControlReourceSets-1) (0..12-1) //uint32_t n_BWP_start = 0; //uint32_t n_rb_offset = 0; - uint32_t n_rb_offset = pdcch_vars2->coreset[nb_coreset_active].rb_offset+(int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB); + uint32_t n_rb_offset = pdcch_vars2->coreset[nb_coreset_active].rb_offset/*+(int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB)*/; // start time position for CORESET // parameter symbol_mon is a 14 bits bitmap indicating monitoring symbols within a slot uint8_t start_symbol = 0; @@ -1048,7 +1048,7 @@ void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8 x2 = (((1<<16)*n_rnti)+n_id); //mod 2^31 is implicit //this is c_init in 38.211 v15.1.0 Section 7.3.2.3 // x2 = (nr_tti_rx << 9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> (c_init=%d, n_id=%d, n_rnti=%d, length=%d)\n",x2,n_id,n_rnti,length); + //printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> (c_init=%d, n_id=%d, n_rnti=%d, length=%d)\n",x2,n_id,n_rnti,length); #endif for (i = 0; i < length; i++) { if ((i & 0x1f) == 0) { @@ -1118,13 +1118,13 @@ void nr_dci_decoding_procedure0(int s, uint32_t *CCEmap1, uint32_t *CCEmap2) { - uint16_t crc, CCEind, nCCE[3]; + uint32_t crc, CCEind, nCCE[3]; uint32_t *CCEmap = NULL, CCEmap_mask = 0; uint8_t L2 = (1 << L); unsigned int Yk, nb_candidates = 0, i, m; unsigned int CCEmap_cand; - int8_t decoderState=0; + uint32_t decoderState=0; // A[p], p is the current active CORESET uint16_t A[3]={39827,39829,39839}; @@ -1361,17 +1361,17 @@ void nr_dci_decoding_procedure0(int s, #endif */ - uint32_t dci_estimation[4]={0}; - + uint64_t dci_estimation[2]={0}; nr_polar_init(&nrPolar_params, 1, sizeof_bits, L2); - t_nrPolar_paramsPtr currentPtrDCI=nr_polar_params(nrPolar_params, 1, sizeof_bits, L2); decoderState = polar_decoder_int16(&pdcch_vars[eNB_id]->e_rx[CCEind*9*6*2], - (uint64_t*)dci_estimation, + dci_estimation, currentPtrDCI); - crc = decoderState; + crc = decoderState; + + //crc = (crc16(&dci_decoded_output[current_thread_id][0], sizeof_bits) >> 16) ^ extract_crc(&dci_decoded_output[current_thread_id][0], sizeof_bits); #ifdef NR_PDCCH_DCI_DEBUG printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we end function dci_decoding() with crc=%x\n",crc); @@ -1451,12 +1451,12 @@ void nr_dci_decoding_procedure0(int s, dci_alloc[*dci_cnt].dci_pdu[1] = dci_estimation[1]; dci_alloc[*dci_cnt].dci_pdu[2] = dci_estimation[2]; dci_alloc[*dci_cnt].dci_pdu[3] = dci_estimation[3]; -#ifdef NR_PDCCH_DCI_DEBUG +//#ifdef NR_PDCCH_DCI_DEBUG printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> rnti matches -> DCI FOUND !!! crc =>%x, sizeof_bits %d, sizeof_bytes %d \n", dci_alloc[*dci_cnt].rnti, dci_alloc[*dci_cnt].dci_length, sizeof_bytes); printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> dci_cnt %d (format_css %d crc_scrambled %d) L %d, firstCCE %d pdu[0] %x pdu[1] %x pdu[2] %x pdu[3] %x \n", *dci_cnt, format_css,*crc_scrambled,dci_alloc[*dci_cnt].L, dci_alloc[*dci_cnt].firstCCE,dci_alloc[*dci_cnt].dci_pdu[0],dci_alloc[*dci_cnt].dci_pdu[1],dci_alloc[*dci_cnt].dci_pdu[2],dci_alloc[*dci_cnt].dci_pdu[3]); -#endif +//#endif if ((format_css == cformat0_0_and_1_0) || (format_uss == uformat0_0_and_1_0)){ if ((*crc_scrambled == _p_rnti) || (*crc_scrambled == _si_rnti) || (*crc_scrambled == _ra_rnti)){ dci_alloc[*dci_cnt].format = format1_0; @@ -2675,7 +2675,7 @@ uint8_t nr_dci_decoding_procedure(int s, printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", css_dci_format,format_0_0_1_0_size_bits,format_0_0_1_0_size_bytes); #endif - for (int aggregationLevel = 3; aggregationLevel<4 ; aggregationLevel++) { // We fix aggregationLevel to 3 for testing=> nbr of CCE=8 + for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { // We fix aggregationLevel to 3 for testing=> nbr of CCE=8 //for (int aggregationLevel = 2; aggregationLevel<5 ; aggregationLevel++) { // for aggregation level aggregationLevel. The number of candidates (for L2= 2^aggregationLevel) will be calculated in function nr_dci_decoding_procedure0 #ifdef NR_PDCCH_DCI_DEBUG diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c index 1eafbfb7dcc1b5e355272c00145b252f92834142..40bb1a40cdd39f84caa97292bc9e798452af77f2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c @@ -52,7 +52,7 @@ //#define DEBUG_DCI #define NR_PDCCH_DCI_TOOLS -#define NR_PDCCH_DCI_TOOLS_DEBUG +//#define NR_PDCCH_DCI_TOOLS_DEBUG typedef unsigned __int128 uint128_t; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index a0b150eda14add4a657f2deb0ae85d02855872ae..89fdfbd050d46006993a7a2380961fee9c1dac59 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -708,10 +708,10 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, #ifdef DEBUG_PBCH printf("xtra_byte %x payload %x\n", xtra_byte, payload); - for (i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++){ - // printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]); - printf("[PBCH] decoder payload[%d] = %x\n",i,decoded_output[i]); - } + for (int i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++){ + // printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]); + printf("[PBCH] decoder payload[%d] = %x\n",i,decoded_output[i]); + } #endif ue->dl_indication.rx_ind = &ue->rx_ind; // hang on rx_ind instance diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 54aed7adb18d9a7177e8bf1a5c67711d3bbe70bf..2823a58f39a16f8694a34d17bbbc521751770819 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -1032,7 +1032,7 @@ typedef struct { fapi_nr_dci_indication_t dci_ind; // point to the current rxTx thread index - uint8_t current_thread_id[10]; + uint8_t current_thread_id[40]; NR_UE_PDSCH *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads NR_UE_PDSCH_FLP *pdsch_vars_flp[NUMBER_OF_CONNECTED_eNB_MAX+1]; diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 9b53dd050ce6035e9ff5675d3c104f7ba1401abf..a120b8c1402ff187525fb8328a045c139dbf8b50 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -49,6 +49,9 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p nr_frequency_range_e freq_range, uint8_t rmsi_pdcch_config, uint8_t ssb_idx, + uint8_t k_ssb, + uint16_t sfn_ssb, + uint8_t n_ssb, uint16_t nb_slots_per_frame, uint16_t N_RB); diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 1daaf90cd6715c12f504971589cc3101eda6c16d..ca30ab1cec789a8f2fe05d2e3f39f9a82b13b72f 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -48,11 +48,13 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ /// component carrier id uint8_t cc_id = scheduled_response->CC_id; uint32_t i; + int slot = scheduled_response->slot; + uint8_t thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot]; if(scheduled_response != NULL){ // Note: we have to handle the thread IDs for this. To be revisited completely. - NR_UE_PDCCH *pdcch_vars2 = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[0][0]; - NR_UE_DLSCH_t *dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[0][0][0]; + NR_UE_PDCCH *pdcch_vars2 = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0]; + NR_UE_DLSCH_t *dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0]; NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[0]; NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms; PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0]; @@ -88,8 +90,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ pdcch_vars2->coreset[i].cce_reg_mappingType.interleaversize = dci_config->coreset.cce_reg_interleaved_interleaver_size; }else{ //CCE_REG_MAPPING_TYPE_NON_INTERLEAVED pdcch_vars2->coreset[i].cce_reg_mappingType.shiftIndex = 0; - pdcch_vars2->coreset[i].cce_reg_mappingType.reg_bundlesize = 0; - pdcch_vars2->coreset[i].cce_reg_mappingType.interleaversize = 0; + pdcch_vars2->coreset[i].cce_reg_mappingType.reg_bundlesize = 6; + pdcch_vars2->coreset[i].cce_reg_mappingType.interleaversize = 1; } pdcch_vars2->coreset[i].precoderGranularity = dci_config->coreset.precoder_granularity; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 5eee7b9c0c45c8dfcf0d9889366812125d9cc924..3c48e73889bd84d06f783c13b92dc89bfcea4cf3 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -56,7 +56,7 @@ //#define DEBUG_PHY_PROC #define NR_PDCCH_SCHED -#define NR_PDCCH_SCHED_DEBUG +//#define NR_PDCCH_SCHED_DEBUG //#define NR_PUCCH_SCHED //#define NR_PUCCH_SCHED_DEBUG @@ -3078,6 +3078,8 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t * // Higher layers have updated the number of searchSpaces with are active in the current slot and this value is stored in variable nb_searchspace_total int nb_searchspace_total = pdcch_vars2->nb_search_space; + pdcch_vars[eNB_id]->crnti = 0x1234; //to be check how to set when using loop memory + uint16_t c_rnti=pdcch_vars[eNB_id]->crnti; uint16_t cs_rnti,new_rnti,tc_rnti; uint16_t p_rnti=P_RNTI; @@ -3153,7 +3155,7 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t * // FIXME! A table of five enum elements // searchSpaceType indicates whether this is a common search space or a UE-specific search space //int searchSpaceType = pdcch_vars2->searchSpace[nb_searchspace_active].searchSpaceType.type; - NR_SEARCHSPACE_TYPE_t searchSpaceType = common; + NR_SEARCHSPACE_TYPE_t searchSpaceType = ue_specific;//common; #ifdef NR_PDCCH_SCHED_DEBUG printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> searchSpaceType=%d is hardcoded THIS HAS TO BE FIXED!!!\n", searchSpaceType); @@ -4964,96 +4966,21 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN int frame_rx = proc->frame_rx; int nr_tti_rx = proc->nr_tti_rx; + NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0]; uint16_t nb_symb_sch = 8; // to be updated by higher layer - uint8_t nb_symb_pdcch =2; - //proc->decoder_switch = 0; - //int counter_decoder = 0; + uint8_t nb_symb_pdcch = pdcch_vars->coreset[0].duration; - LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, nr_tti_rx); + LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx); uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1); uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); -#if 0 - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN); - -#if T_TRACER - T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_tti_rx)); - - T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_tti_rx), T_INT(0), - T_BUFFER(&ue->common_vars.rxdata[0][nr_tti_rx*ue->frame_parms.samples_per_subframe], - ue->frame_parms.samples_per_subframe * 4)); -#endif - - // start timers - //#ifdef UE_DEBUG_TRACE - LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, nr_tti_rx); - //#endif - -#if UE_TIMING_TRACE - start_meas(&ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]]); - start_meas(&ue->generic_stat); -#endif - - if (do_pdcch_flag) { - // deactivate reception until we scan pdcch - if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]) - ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0; - if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][1]) - ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][1]->active = 0; - - if (ue->dlsch_SI[eNB_id]) - ue->dlsch_SI[eNB_id]->active = 0; - if (ue->dlsch_p[eNB_id]) - ue->dlsch_p[eNB_id]->active = 0; - if (ue->dlsch_ra[eNB_id]) - ue->dlsch_ra[eNB_id]->active = 0; - } - -#ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[%s %d] Frame %d nr_tti_rx %d: Doing phy_procedures_UE_RX\n", - (r_type == multicast_relay) ? "RN/UE" : "UE", - ue->Mod_id,frame_rx, nr_tti_rx); -#endif - - - if (ue->frame_parms.Ncp == 0) { // normal prefix - pilot1 = 4; - } else { // extended prefix - pilot1 = 3; - } - - /* - if (nr_subframe_select(&ue->frame_parms,nr_tti_rx) == SF_S) { // S-subframe, do first 5 symbols only - l2 = 5; - } else */ - { // normal nr_tti_rx, last symbol to be processed is the first of the second slot - l2 = (ue->frame_parms.symbols_per_tti/2)-1; - } - - int prev_nr_tti_rx = (nr_tti_rx - 1)<0? 9: (nr_tti_rx - 1);/* - if (nr_subframe_select(&ue->frame_parms,prev_nr_tti_rx) != SF_DL) { - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // RX processing of symbols l=0...l2 - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - l=0; - } else */ - { - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch) - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - l=1; - } - - LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); - LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); -#endif - #ifdef NR_PDCCH_SCHED - //nr_gold_pdcch(ue,0, 2); + nr_gold_pdcch(ue,0, 2); - if (nr_tti_rx==1){ - for (uint16_t l=0; l<nb_symb_pdcch; l++) { + //if (nr_tti_rx==1){ + LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + for (uint16_t l=0; l<nb_symb_pdcch; l++) { #if UE_TIMING_TRACE start_meas(&ue->ofdm_demod_stats); @@ -5061,7 +4988,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); nr_slot_fep(ue, l, - nr_tti_rx<<1, + nr_tti_rx, 0, 0, 1, @@ -5072,7 +4999,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN #endif //printf("phy procedure pdcch start measurement l =%d\n",l); - nr_ue_measurement_procedures(l,ue,proc,eNB_id,(nr_tti_rx<<1),mode); + nr_ue_measurement_procedures(l,ue,proc,eNB_id,(nr_tti_rx),mode); } @@ -5080,19 +5007,19 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,nr_tti_rx); return(-1); } - } + //} #endif //NR_PDCCH_SCHED - LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); if (nr_tti_rx==1){ + LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); //to update from pdsch config nr_gold_pdsch(ue,nb_symb_pdcch,0, 1); for (uint16_t m=nb_symb_pdcch;m<=(nb_symb_sch+nb_symb_pdcch-1) ; m++){ nr_slot_fep(ue, m, //to be updated from higher layer - nr_tti_rx<<1, + nr_tti_rx, 0, 0, 1, @@ -5126,7 +5053,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); } - LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); @@ -5168,62 +5094,12 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN ue->frame_parms.symbols_per_tti>>1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); } -//#if 0 - LOG_D(PHY," ------ slot 1 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); - LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); - - /*if (nr_subframe_select(&ue->frame_parms,nr_tti_rx) != SF_S)*/ - { // do front-end processing for second slot, and first symbol of next nr_tti_rx - for (l=1; l<ue->frame_parms.symbols_per_tti>>1; l++) { -#if UE_TIMING_TRACE - start_meas(&ue->ofdm_demod_stats); -#endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); - /*nr_slot_fep(ue, - l, - 1+(nr_tti_rx<<1), - 0, - 0, - 0, - NR_PDSCH_EST);*/ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); - -#if UE_TIMING_TRACE - stop_meas(&ue->ofdm_demod_stats); -#endif - - //ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(nr_tti_rx<<1),abstraction_flag,mode); - - } // for l=1..l2 - - // do first symbol of next downlink nr_tti_rx for channel estimation - int next_nr_tti_rx = (1+nr_tti_rx)%10; - /* if (nr_subframe_select(&ue->frame_parms,next_nr_tti_rx) != SF_UL)*/ - { - /*nr_slot_fep(ue, - 0, - (next_nr_tti_rx<<1), - 0, - 0, - 0, - NR_PDSCH_EST);*/ - } - } // not an S-subframe -#if UE_TIMING_TRACE - stop_meas(&ue->generic_stat); -#if DISABLE_LOG_X - printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",nr_tti_rx,ue->generic_stat.p_time/(cpuf*1000.0)); -#else - LOG_D(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",nr_tti_rx,ue->generic_stat.p_time/(cpuf*1000.0)); -#endif - -#endif - //LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1)) { + LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); for (int i=0; i<3; i++) nr_slot_fep(ue, (5+i), //mu=1 case B @@ -5237,7 +5113,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN } // do procedures for C-RNTI - LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 1d440c5d0dc27077da62138d5eaddf3fe61e5b89..7a08ede7135c108eb30671fc11f836dc40129489 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -157,6 +157,7 @@ int main(int argc, char **argv) int frame=0,slot=1; int frame_length_complex_samples; int frame_length_complex_samples_no_prefix; + int slot_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; nfapi_nr_config_request_t *gNB_config; gNB_L1_rxtx_proc_t gNB_proc; @@ -399,7 +400,7 @@ int main(int argc, char **argv) // call MAC to configure common parameters phy_init_nr_gNB(gNB,0,0); - + mac_top_init_gNB(); double fs,bw; @@ -437,7 +438,8 @@ int main(int argc, char **argv) } frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; - frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; + frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + slot_length_complex_samples_no_prefix = frame_parms->samples_per_slot_wCP; s_re = malloc(2*sizeof(double*)); s_im = malloc(2*sizeof(double*)); @@ -480,6 +482,7 @@ int main(int argc, char **argv) else {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;} UE->perfect_ce = 0; + for (i=0;i<10;i++) UE->current_thread_id[i] = 0; if (init_nr_ue_signal(UE, 1, 0) != 0) { @@ -501,6 +504,8 @@ int main(int argc, char **argv) nr_l2_init_ue(); UE_mac = get_mac_inst(0); + + UE->pdcch_vars[0][0]->crnti = 0x1234; UE->if_inst = nr_ue_if_module_init(0); UE->if_inst->scheduled_response = nr_ue_scheduled_response; @@ -517,7 +522,7 @@ int main(int argc, char **argv) gNB->pbch_configured = 1; for (int i=0;i<4;i++) gNB->pbch_pdu[i]=i+1; - nr_schedule_css_dlsch_phytest(0,frame,slot); + nr_schedule_uss_dlsch_phytest(0,frame,slot); Sched_INFO.module_id = 0; Sched_INFO.CC_id = 0; Sched_INFO.frame = frame; @@ -534,22 +539,24 @@ int main(int argc, char **argv) //nr_common_signal_procedures (gNB,frame,subframe); - LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); - if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1); + LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); + if (gNB->frame_parms.nb_antennas_tx>1) + LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1); + + int tx_offset = slot*frame_parms->samples_per_slot; //TODO: loop over slots for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) { if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) { PHY_ofdm_mod(gNB->common_vars.txdataF[aa], - txdata[aa], + &txdata[aa][tx_offset], frame_parms->ofdm_symbol_size, 12, frame_parms->nb_prefix_samples, CYCLIC_PREFIX); } else { nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], - txdata[aa], + &txdata[aa][tx_offset], 14, frame_parms); } @@ -562,7 +569,7 @@ int main(int argc, char **argv) frame_length_complex_samples, input_fd) != frame_length_complex_samples) { printf("error reading from file\n"); - exit(-1); + //exit(-1); } } @@ -598,7 +605,7 @@ int main(int argc, char **argv) // Type0 PDCCH search space dl_config.number_pdus = 1; dl_config.dl_config_list[0].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI; - dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.rnti = 3; // to be set + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.rnti = 0x1234; // to be set uint64_t mask = 0x0; uint16_t num_rbs=24; @@ -613,9 +620,9 @@ int main(int argc, char **argv) dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.rb_offset = rb_offset; // additional parameter other than coreset dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.duration = num_symbols; - dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_mapping_type =CCE_REG_MAPPING_TYPE_INTERLEAVED; - dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_reg_bundle_size = 6; // L 38.211 7.3.2.2 - dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_interleaver_size = 2; // R 38.211 7.3.2.2 + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_mapping_type =CCE_REG_MAPPING_TYPE_NON_INTERLEAVED; + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_reg_bundle_size = 0; // L 38.211 7.3.2.2 + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_interleaver_size = 0; // R 38.211 7.3.2.2 dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_shift_index = cell_id; dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.precoder_granularity = PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE; dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.pdcch_dmrs_scrambling_id = cell_id; @@ -663,7 +670,7 @@ int main(int argc, char **argv) if (n_trials==1) { LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0],frame_length_complex_samples,1,1); - if (gNB->frame_parms.nb_antennas_tx>1) + if (UE->frame_parms.nb_antennas_rx>1) LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_length_complex_samples,1,1); } if (UE->is_synchronized == 0) { @@ -689,7 +696,12 @@ int main(int argc, char **argv) do_pdcch_flag, normal_txrx); - + if (n_trials==1) { + LOG_M("rxsigF0.m","rxsF0", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0],slot_length_complex_samples_no_prefix,1,1); + if (UE->frame_parms.nb_antennas_rx>1) + LOG_M("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[1],slot_length_complex_samples_no_prefix,1,1); + } + if (UE->dci_ind.number_of_dcis==0) n_errors++; } } //noise trials diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index d29a9fb90887cc9185595dcd111b3b132c8b56b9..79939efdf52cc41ef895b82b78d393e8e0d48f65 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -322,6 +322,16 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id]; + nfapi_nr_coreset_t coreset = RC.nrmac[module_idP]->coreset[CC_id][1]; + nfapi_nr_search_space_t search_space = RC.nrmac[module_idP]->search_space[CC_id][1]; + + if (nr_is_dci_opportunity(search_space, + coreset, + frameP, + slotP, + *cfg)) + nr_schedule_uss_dlsch_phytest(module_idP, frameP, slotP); + rnti = UE_RNTI(module_idP, i); CC_id = UE_PCCID(module_idP, i); int spf = get_spf(cfg); @@ -424,9 +434,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, // Phytest scheduling/ option not activated because of pending bug - if (slotP==2) - nr_schedule_css_dlsch_phytest(module_idP, frameP, slotP); + /*if (slotP==2) + nr_schedule_css_dlsch_phytest(module_idP, frameP, slotP);*/ + if (slotP==1) + nr_schedule_uss_dlsch_phytest(module_idP, frameP, slotP); /* // Allocate CCEs for good after scheduling is done diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 131e64a93be88ed999c0bc81561736fc301e35a4..dcf372198e87ecd18e4c77db91912ff8f7756746 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -92,7 +92,8 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, nr_configure_css_dci_initial(params_rel15, - scs, scs, nr_FR1, 0, 0, + scs, scs, nr_FR1, 0, 0, 0, + sfn_sf, slotP, slots_per_frame, dl_carrier_bandwidth); @@ -179,3 +180,145 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, } } + +/*Scheduling of DLSCH with associated DCI in user specific search space + * current version has only a DCI for type 1 PDCCH for C_RNTI*/ +void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, + frame_t frameP, + sub_frame_t slotP) +{ + uint8_t CC_id; + + gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; + //NR_COMMON_channels_t *cc = nr_mac->common_channels; + nfapi_nr_dl_config_request_body_t *dl_req; + nfapi_nr_dl_config_request_pdu_t *dl_config_dci_pdu; + nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu; + nfapi_tx_request_pdu_t *TX_req; + + nfapi_nr_config_request_t *cfg = &nr_mac->config[0]; + uint16_t rnti = 0x1234; + + uint16_t sfn_sf = frameP << 7 | slotP; + int dl_carrier_bandwidth = cfg->rf_config.dl_carrier_bandwidth.value; + + // everything here is hard-coded to 30 kHz + int scs = get_dlscs(cfg); + int slots_per_frame = get_spf(cfg); + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + LOG_I(MAC, "Scheduling UE specific search space DCI type 1 for CC_id %d\n",CC_id); + + nfapi_nr_coreset_t* coreset = &nr_mac->coreset[CC_id][1]; + nfapi_nr_search_space_t* search_space = &nr_mac->search_space[CC_id][1]; + + dl_req = &nr_mac->DL_req[CC_id].dl_config_request_body; + dl_config_dci_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void*)dl_config_dci_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); + dl_config_dci_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_dci_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dci_dl_pdu)); + + dl_config_dlsch_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu+1]; + memset((void*)dl_config_dlsch_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); + dl_config_dlsch_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_dlsch_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dlsch_pdu)); + + nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &dl_config_dci_pdu->dci_dl_pdu.dci_dl_pdu_rel15; + nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &dl_config_dci_pdu->dci_dl_pdu.pdcch_params_rel15; + nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu_rel15 = &dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15; + + dlsch_pdu_rel15->start_prb = 0; + dlsch_pdu_rel15->n_prb = 50; + dlsch_pdu_rel15->start_symbol = 2; + dlsch_pdu_rel15->nb_symbols = 8; + dlsch_pdu_rel15->rnti = rnti; + dlsch_pdu_rel15->nb_layers =1; + dlsch_pdu_rel15->nb_codewords = 1; + dlsch_pdu_rel15->mcs_idx = 9; + dlsch_pdu_rel15->ndi = 1; + dlsch_pdu_rel15->redundancy_version = 0; + + nr_configure_dci_from_pdcch_config(params_rel15, + coreset, + search_space, + *cfg, + dl_carrier_bandwidth); + + pdu_rel15->frequency_domain_assignment = get_RIV(dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, cfg->rf_config.dl_carrier_bandwidth.value); + pdu_rel15->time_domain_assignment = get_SLIV(dlsch_pdu_rel15->start_symbol, dlsch_pdu_rel15->nb_symbols); + pdu_rel15->vrb_to_prb_mapping = 1; + pdu_rel15->mcs = 9; + pdu_rel15->tb_scaling = 1; + + pdu_rel15->ra_preamble_index = 25; + pdu_rel15->format_indicator = 1; + pdu_rel15->ndi = 1; + pdu_rel15->rv = 0; + pdu_rel15->harq_pid = 0; + pdu_rel15->dai = 2; + pdu_rel15->tpc = 2; + pdu_rel15->pucch_resource_indicator = 7; + pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7; + + LOG_I(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", + pdu_rel15->frequency_domain_assignment, + pdu_rel15->time_domain_assignment, + pdu_rel15->vrb_to_prb_mapping, + pdu_rel15->mcs, + pdu_rel15->tb_scaling, + pdu_rel15->ndi, + pdu_rel15->rv); + + params_rel15->rnti = rnti; + params_rel15->rnti_type = NFAPI_NR_RNTI_C; + params_rel15->dci_format = NFAPI_NR_DL_DCI_FORMAT_1_0; + + //params_rel15->aggregation_level = 1; + LOG_I(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d, config type %d\n \ + coreset params: mux_pattern %d, n_rb %d, n_symb %d, rb_offset %d \n \ + ss params : first symb %d, ss type %d\n", + params_rel15->rnti, + params_rel15->rnti_type, + params_rel15->config_type, + params_rel15->dci_format, + params_rel15->mux_pattern, + params_rel15->n_rb, + params_rel15->n_symb, + params_rel15->rb_offset, + params_rel15->first_symbol, + params_rel15->search_space_type); + nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg); + LOG_I(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d\n", + dlsch_pdu_rel15->start_prb, + dlsch_pdu_rel15->n_prb, + dlsch_pdu_rel15->start_symbol, + dlsch_pdu_rel15->nb_symbols, + dlsch_pdu_rel15->nb_layers, + dlsch_pdu_rel15->nb_codewords, + dlsch_pdu_rel15->mcs_idx); + + dl_req->number_dci++; + dl_req->number_pdsch_rnti++; + dl_req->number_pdu+=2; + + TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = 6; + TX_req->pdu_index = nr_mac->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = 8; + nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; + nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; + nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + + TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus+1]; + TX_req->pdu_length = dlsch_pdu_rel15->transport_block_size; + TX_req->pdu_index = nr_mac->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = 8; + nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; + nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; + nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + + } +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index ca0f103a437742f9b2018d79d23e027b0d78d023..483bc0e0bf340559939620e8012ccb8253a7921a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -21,11 +21,11 @@ /*! \file gNB_scheduler_primitives.c * \brief primitives used by gNB for BCH, RACH, ULSCH, DLSCH scheduling - * \author Navid Nikaein and Raymond Knopp, WEI-TAI CHEN - * \date 2010 - 2014, 2018 - * \email: navid.nikaein@eurecom.fr, kroempa@gmail.com + * \author Raymond Knopp, Guy De Souza + * \date 2018, 2019 + * \email: knopp@eurecom.fr, desouza@eurecom.fr * \version 1.0 - * \company Eurecom, NTUST + * \company Eurecom * @ingroup _mac */ @@ -65,23 +65,64 @@ extern RAN_CONTEXT_t RC; extern int n_active_slices; + // Note the 2 scs values in the table names represent resp. scs_common and pdcch_scs /// LUT for the number of symbols in the coreset indexed by coreset index (4 MSB rmsi_pdcch_config) -uint8_t nr_coreset_nsymb_pdcch_type_0_b40Mhz[16] = {2,2,2,2,2,3,3,3,3,3,1,1,1,2,2,2}; // below 40Mhz bw -uint8_t nr_coreset_nsymb_pdcch_type_0_a40Mhz[10] = {2,2,3,3,1,1,2,2,3,3}; // above 40Mhz bw +uint8_t nr_coreset_nsymb_pdcch_type_0_scs_15_15[15] = {2,2,2,3,3,3,1,1,2,2,3,3,1,2,3}; +uint8_t nr_coreset_nsymb_pdcch_type_0_scs_15_30[14] = {2,2,2,2,3,3,3,3,1,1,2,2,3,3}; +uint8_t nr_coreset_nsymb_pdcch_type_0_scs_30_15_b40Mhz[9] = {1,1,2,2,3,3,1,2,3}; +uint8_t nr_coreset_nsymb_pdcch_type_0_scs_30_15_a40Mhz[9] = {1,2,3,1,1,2,2,3,3}; +uint8_t nr_coreset_nsymb_pdcch_type_0_scs_30_30_b40Mhz[16] = {2,2,2,2,2,3,3,3,3,3,1,1,1,2,2,2}; // below 40Mhz bw +uint8_t nr_coreset_nsymb_pdcch_type_0_scs_30_30_a40Mhz[10] = {2,2,3,3,1,1,2,2,3,3}; // above 40Mhz bw +uint8_t nr_coreset_nsymb_pdcch_type_0_scs_120_60[12] = {1,1,2,2,3,3,1,2,1,1,1,1}; + /// LUT for the number of RBs in the coreset indexed by coreset index -uint8_t nr_coreset_rb_offset_pdcch_type_0_b40Mhz[16] = {0,1,2,3,4,0,1,2,3,4,12,14,16,12,14,16}; -uint8_t nr_coreset_rb_offset_pdcch_type_0_a40Mhz[10] = {0,4,0,4,0,28,0,28,0,28}; +uint8_t nr_coreset_rb_offset_pdcch_type_0_scs_15_15[15] = {0,2,4,0,2,4,12,16,12,16,12,16,38,38,38}; +uint8_t nr_coreset_rb_offset_pdcch_type_0_scs_15_30[14] = {5,6,7,8,5,6,7,8,18,20,18,20,18,20}; +uint8_t nr_coreset_rb_offset_pdcch_type_0_scs_30_15_b40Mhz[9] = {2,6,2,6,2,6,28,28,28}; +uint8_t nr_coreset_rb_offset_pdcch_type_0_scs_30_15_a40Mhz[9] = {4,4,4,0,56,0,56,0,56}; +uint8_t nr_coreset_rb_offset_pdcch_type_0_scs_30_30_b40Mhz[16] = {0,1,2,3,4,0,1,2,3,4,12,14,16,12,14,16}; +uint8_t nr_coreset_rb_offset_pdcch_type_0_scs_30_30_a40Mhz[10] = {0,4,0,4,0,28,0,28,0,28}; +int8_t nr_coreset_rb_offset_pdcch_type_0_scs_120_60[12] = {0,8,0,8,0,8,28,28,-1,49,-1,97}; +int8_t nr_coreset_rb_offset_pdcch_type_0_scs_120_120[8] = {0,4,14,14,-1,24,-1,48}; +int8_t nr_coreset_rb_offset_pdcch_type_0_scs_240_120[8] = {0,8,0,8,-1,25,-1,49}; + /// LUT for monitoring occasions param O indexed by ss index (4 LSB rmsi_pdcch_config) + // Note: scaling is used to avoid decimal values for O and M, original values commented uint8_t nr_ss_param_O_type_0_mux1_FR1[16] = {0,0,2,2,5,5,7,7,0,5,0,0,2,2,5,5}; -uint8_t nr_ss_param_O_type_0_mux1_FR2[14] = {0,0,2.5,2.5,5,5,0,2.5,5,7.5,7.5,7.5,0,5}; +uint8_t nr_ss_param_O_type_0_mux1_FR2[14] = {0,0,5,5,5,5,0,5,5,15,15,15,0,5}; //{0,0,2.5,2.5,5,5,0,2.5,5,7.5,7.5,7.5,0,5} +uint8_t nr_ss_scale_O_mux1_FR2[14] = {0,0,1,1,0,0,0,1,0,1,1,1,0,0}; + /// LUT for number of SS sets per slot indexed by ss index uint8_t nr_ss_sets_per_slot_type_0_FR1[16] = {1,2,1,2,1,2,1,2,1,1,1,1,1,1,1,1}; uint8_t nr_ss_sets_per_slot_type_0_FR2[14] = {1,2,1,2,1,2,2,2,2,1,2,2,1,1}; + /// LUT for monitoring occasions param M indexed by ss index -uint8_t nr_ss_param_M_type_0_mux1_FR1[16] = {1,0.5,1,0.5,1,0.5,1,0.5,2,2,1,1,1,1,1,1}; -uint8_t nr_ss_param_M_type_0_mux1_FR2[14] = {1,0.5,1,0.5,1,0.5,0.5,0.5,0.5,1,0.5,0.5,2,2}; +uint8_t nr_ss_param_M_type_0_mux1_FR1[16] = {1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1}; //{1,0.5,1,0.5,1,0.5,1,0.5,2,2,1,1,1,1,1,1} +uint8_t nr_ss_scale_M_mux1_FR1[16] = {0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0}; +uint8_t nr_ss_param_M_type_0_mux1_FR2[14] = {1,1,1,1,1,1,1,1,1,1,1,1,2,2}; //{1,0.5,1,0.5,1,0.5,0.5,0.5,0.5,1,0.5,0.5,2,2} +uint8_t nr_ss_scale_M_mux1_FR2[14] = {0,1,0,1,0,1,1,1,1,0,1,1,0,0}; + /// LUT for SS first symbol index indexed by ss index uint8_t nr_ss_first_symb_idx_type_0_mux1_FR1[8] = {0,0,1,2,1,2,1,2}; + // Mux pattern type 2 +uint8_t nr_ss_first_symb_idx_scs_120_60_mux2[4] = {0,1,6,7}; +uint8_t nr_ss_first_symb_idx_scs_240_120_set1_mux2[6] = {0,1,2,3,0,1}; + // Mux pattern type 3 +uint8_t nr_ss_first_symb_idx_scs_120_120_mux3[4] = {4,8,2,6}; + +/// Search space max values indexed by scs +uint8_t nr_max_number_of_candidates_per_slot[4] = {44, 36, 22, 20}; +uint8_t nr_max_number_of_cces_per_slot[4] = {56, 56, 48, 32}; + +static inline uint8_t get_max_candidates(uint8_t scs) { + AssertFatal(scs<4, "Invalid PDCCH subcarrier spacing %d\n", scs); + return (nr_max_number_of_candidates_per_slot[scs]); +} + +static inline uint8_t get_max_cces(uint8_t scs) { + AssertFatal(scs<4, "Invalid PDCCH subcarrier spacing %d\n", scs); + return (nr_max_number_of_cces_per_slot[scs]); +} int is_nr_UL_slot(NR_COMMON_channels_t * ccP, int slot){ @@ -94,69 +135,143 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p nr_frequency_range_e freq_range, uint8_t rmsi_pdcch_config, uint8_t ssb_idx, + uint8_t k_ssb, + uint16_t sfn_ssb, + uint8_t n_ssb, /*slot index overlapping the corresponding SSB index*/ uint16_t nb_slots_per_frame, uint16_t N_RB) { uint8_t O, M; uint8_t ss_idx = rmsi_pdcch_config&0xf; uint8_t cset_idx = (rmsi_pdcch_config>>4)&0xf; - uint8_t mu; + uint8_t mu = scs_common; + uint8_t O_scale=0, M_scale=0; // used to decide if the values of O and M need to be divided by 2 /// Coreset params switch(scs_common) { case kHz15: - mu = 0; + + switch(pdcch_scs) { + case kHz15: + AssertFatal(cset_idx<15,"Coreset index %d reserved for scs kHz15/kHz15\n", cset_idx); + pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; + pdcch_params->n_rb = (cset_idx < 6)? 24 : (cset_idx < 12)? 48 : 96; + pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_15_15[cset_idx]; + pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_15_15[cset_idx]; + break; + + case kHz30: + AssertFatal(cset_idx<14,"Coreset index %d reserved for scs kHz15/kHz30\n", cset_idx); + pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; + pdcch_params->n_rb = (cset_idx < 8)? 24 : 48; + pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_15_30[cset_idx]; + pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_15_15[cset_idx]; + break; + + default: + AssertFatal(1==0,"Invalid scs_common/pdcch_scs combination %d/%d \n", scs_common, pdcch_scs); + + } break; case kHz30: - mu = 1; if (N_RB < 106) { // Minimum 40Mhz bandwidth not satisfied switch(pdcch_scs) { case kHz15: - AssertFatal(1==0,"kHz15 not supported yet\n"); - break; + AssertFatal(cset_idx<9,"Coreset index %d reserved for scs kHz30/kHz15\n", cset_idx); + pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; + pdcch_params->n_rb = (cset_idx < 10)? 48 : 96; + pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_30_15_b40Mhz[cset_idx]; + pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_30_15_b40Mhz[cset_idx]; + break; case kHz30: pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; - pdcch_params->n_rb = (cset_idx < 10)? 24 : 48; - pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_b40Mhz[cset_idx]; - pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_b40Mhz[cset_idx]; - break; + pdcch_params->n_rb = (cset_idx < 6)? 24 : 48; + pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_30_30_b40Mhz[cset_idx]; + pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_30_30_b40Mhz[cset_idx]; + break; default: AssertFatal(1==0,"Invalid scs_common/pdcch_scs combination %d/%d \n", scs_common, pdcch_scs); } } - else { - AssertFatal(ss_idx<10 ,"Invalid scs_common/pdcch_scs combination %d/%d \n", scs_common, pdcch_scs); + else { // above 40Mhz switch(pdcch_scs) { case kHz15: - AssertFatal(1==0,"15 kHz SCS not supported yet\n"); - break; + AssertFatal(cset_idx<9,"Coreset index %d reserved for scs kHz30/kHz15\n", cset_idx); + pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; + pdcch_params->n_rb = (cset_idx < 3)? 48 : 96; + pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_30_15_a40Mhz[cset_idx]; + pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_30_15_a40Mhz[cset_idx]; + break; case kHz30: + AssertFatal(cset_idx<10,"Coreset index %d reserved for scs kHz30/kHz30\n", cset_idx); pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; pdcch_params->n_rb = (cset_idx < 4)? 24 : 48; - pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_b40Mhz[cset_idx]; - pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_b40Mhz[cset_idx]; - break; + pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_30_30_a40Mhz[cset_idx]; + pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_30_30_a40Mhz[cset_idx]; + break; default: AssertFatal(1==0,"Invalid scs_common/pdcch_scs combination %d/%d \n", scs_common, pdcch_scs); } } - - case kHz60: - mu = 2; break; case kHz120: - mu = 3; + switch(pdcch_scs) { + case kHz60: + AssertFatal(cset_idx<12,"Coreset index %d reserved for scs kHz120/kHz60\n", cset_idx); + pdcch_params->mux_pattern = (cset_idx < 8)?NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 : NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2; + pdcch_params->n_rb = (cset_idx < 6)? 48 : (cset_idx < 8)? 96 : (cset_idx < 10)? 48 : 96; + pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_120_60[cset_idx]; + pdcch_params->rb_offset = (nr_coreset_rb_offset_pdcch_type_0_scs_120_60[cset_idx]>0)?nr_coreset_rb_offset_pdcch_type_0_scs_120_60[cset_idx] : + (k_ssb == 0)? -41 : -42; + break; + + case kHz120: + AssertFatal(cset_idx<8,"Coreset index %d reserved for scs kHz120/kHz120\n", cset_idx); + pdcch_params->mux_pattern = (cset_idx < 4)?NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 : NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE3; + pdcch_params->n_rb = (cset_idx < 2)? 24 : (cset_idx < 4)? 48 : (cset_idx < 6)? 24 : 48; + pdcch_params->n_symb = (cset_idx == 2)? 1 : 2; + pdcch_params->rb_offset = (nr_coreset_rb_offset_pdcch_type_0_scs_120_120[cset_idx]>0)? nr_coreset_rb_offset_pdcch_type_0_scs_120_120[cset_idx] : + (k_ssb == 0)? -20 : -21; + break; + + default: + AssertFatal(1==0,"Invalid scs_common/pdcch_scs combination %d/%d \n", scs_common, pdcch_scs); + } + break; + + case kHz240: + switch(pdcch_scs) { + case kHz60: + AssertFatal(cset_idx<4,"Coreset index %d reserved for scs kHz240/kHz60\n", cset_idx); + pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; + pdcch_params->n_rb = 96; + pdcch_params->n_symb = (cset_idx < 2)? 1 : 2; + pdcch_params->rb_offset = (cset_idx&1)? 16 : 0; + break; + + case kHz120: + AssertFatal(cset_idx<8,"Coreset index %d reserved for scs kHz240/kHz120\n", cset_idx); + pdcch_params->mux_pattern = (cset_idx < 4)? NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 : NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2; + pdcch_params->n_rb = (cset_idx < 4)? 48 : (cset_idx < 6)? 24 : 48; + pdcch_params->n_symb = ((cset_idx==2)||(cset_idx==3))? 2 : 1; + pdcch_params->rb_offset = (nr_coreset_rb_offset_pdcch_type_0_scs_240_120[cset_idx]>0)? nr_coreset_rb_offset_pdcch_type_0_scs_240_120[cset_idx] : + (k_ssb == 0)? -41 : -42; break; + default: + AssertFatal(1==0,"Invalid scs_common/pdcch_scs combination %d/%d \n", scs_common, pdcch_scs); + } + break; + default: AssertFatal(1==0,"Invalid common subcarrier spacing %d\n", scs_common); @@ -170,27 +285,50 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p O = nr_ss_param_O_type_0_mux1_FR1[ss_idx]; pdcch_params->nb_ss_sets_per_slot = nr_ss_sets_per_slot_type_0_FR1[ss_idx]; M = nr_ss_param_M_type_0_mux1_FR1[ss_idx]; - pdcch_params->first_symbol = (ss_idx < 8)? ( (ss_idx&1)? pdcch_params->n_symb : 0 ) : nr_ss_first_symb_idx_type_0_mux1_FR1[ss_idx - 8]; + M_scale = nr_ss_scale_M_mux1_FR1[ss_idx]; + pdcch_params->first_symbol = (ss_idx < 8)? ( (ssb_idx&1)? pdcch_params->n_symb : 0 ) : nr_ss_first_symb_idx_type_0_mux1_FR1[ss_idx - 8]; } else { AssertFatal(ss_idx<14 ,"Invalid search space index for multiplexing type 1 and FR2 %d\n", ss_idx); O = nr_ss_param_O_type_0_mux1_FR2[ss_idx]; + O_scale = nr_ss_scale_O_mux1_FR2[ss_idx]; pdcch_params->nb_ss_sets_per_slot = nr_ss_sets_per_slot_type_0_FR2[ss_idx]; M = nr_ss_param_M_type_0_mux1_FR2[ss_idx]; + M_scale = nr_ss_scale_M_mux1_FR2[ss_idx]; pdcch_params->first_symbol = (ss_idx < 12)? ( (ss_idx&1)? 7 : 0 ) : 0; } pdcch_params->nb_slots = 2; - pdcch_params->sfn_mod2 = ((uint8_t)(floor( (O*pow(2, mu) + floor(ssb_idx*M)) / nb_slots_per_frame )) & 1)? 1 : 0; - pdcch_params->first_slot = (uint8_t)(O*pow(2, mu) + floor(ssb_idx*M)) % nb_slots_per_frame; + pdcch_params->sfn_mod2 = (CEILIDIV( (((O<<mu)>>O_scale) + ((ssb_idx*M)>>M_scale)), nb_slots_per_frame ) & 1)? 1 : 0; + pdcch_params->first_slot = (((O<<mu)>>O_scale) + ((ssb_idx*M)>>M_scale)) % nb_slots_per_frame; - break; + break; case NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2: - break; + AssertFatal( ((scs_common==kHz120)&&(pdcch_scs==kHz60)) || ((scs_common==kHz240)&&(pdcch_scs==kHz120)), + "Invalid scs_common/pdcch_scs combination %d/%d for Mux type 2\n", scs_common, pdcch_scs ); + AssertFatal(ss_idx==0, "Search space index %d reserved for scs_common/pdcch_scs combination %d/%d", ss_idx, scs_common, pdcch_scs); + + pdcch_params->nb_slots = 1; + + if ((scs_common==kHz120)&&(pdcch_scs==kHz60)) { + pdcch_params->first_symbol = nr_ss_first_symb_idx_scs_120_60_mux2[ssb_idx&3]; + // Missing in pdcch_params sfn_C and n_C here and in else case + } + else { + pdcch_params->first_symbol = ((ssb_idx&7)==4)?12 : ((ssb_idx&7)==4)?13 : nr_ss_first_symb_idx_scs_240_120_set1_mux2[ssb_idx&7]; //??? + } + + break; case NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE3: - break; + AssertFatal( (scs_common==kHz120)&&(pdcch_scs==kHz120), + "Invalid scs_common/pdcch_scs combination %d/%d for Mux type 3\n", scs_common, pdcch_scs ); + AssertFatal(ss_idx==0, "Search space index %d reserved for scs_common/pdcch_scs combination %d/%d", ss_idx, scs_common, pdcch_scs); + + pdcch_params->first_symbol = nr_ss_first_symb_idx_scs_120_120_mux3[ssb_idx&3]; + + break; default: AssertFatal(1==0, "Invalid SSB and coreset multiplexing pattern %d\n", pdcch_params->mux_pattern); @@ -206,11 +344,179 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p } -void nr_configure_css_dci_from_pdcch_config(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params, +void nr_configure_dci_from_pdcch_config(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params, nfapi_nr_coreset_t* coreset, - nfapi_nr_search_space_t* search_space) { + nfapi_nr_search_space_t* search_space, + nfapi_nr_config_request_t cfg, + uint16_t N_RB) { +/// coreset + + //ControlResourceSetId + pdcch_params->config_type = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; + + //frequencyDomainResources + uint8_t count=0, start=0, start_set=0; + uint64_t bitmap = coreset->frequency_domain_resources; + for (int i=0; i<45; i++) + if ((bitmap>>(44-i))&1) { + count++; + if (!start_set) { + start = i; + start_set = 1; + } + } + pdcch_params->rb_offset = 6*start; + pdcch_params->n_rb = 6*count; + + //duration + pdcch_params->n_symb = coreset->duration; + + //cce-REG-MappingType + pdcch_params->cr_mapping_type = coreset->cce_reg_mapping_type; + if (pdcch_params->cr_mapping_type == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { + pdcch_params->reg_bundle_size = coreset->reg_bundle_size; + pdcch_params->interleaver_size = coreset->interleaver_size; + } + else { + pdcch_params->reg_bundle_size = 0; + pdcch_params->interleaver_size = 0; + } + + //shift index + pdcch_params->shift_index = coreset->shift_index; + //precoderGranularity + pdcch_params->precoder_granularity = coreset->precoder_granularity; + + //TCI states + // PDCCH params does not yet include information about TCI and QCL (needed for DCI 1.1 and 0.1) + + //pdcch-DMRS-ScramblingID + pdcch_params->scrambling_id = coreset->dmrs_scrambling_id; + +/// SearchSpace + + // first symbol + //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored"); + for (int i=0; i<get_symbolsperslot(&cfg); i++) + if ((search_space->monitoring_symbols_in_slot>>(15-i))&1) { + pdcch_params->first_symbol=i; + break; + } + + //searchSpaceType + pdcch_params->search_space_type = search_space->search_space_type; + +/* + //searchSpaceId + AssertFatal(search_space->search_space_id<40, "Search space index out of range %d\n", search_space->search_space_id); + + //controlResourceSetId + + //monitoringSlotPeriodicityAndOffset + + //duration + pdcch_params->nb_ss_sets_per_slot = search_space->duration; + + + //monitoringSymbolsWithinSlot + pdcch_params->first_symbol = search_space->monitoring_symbols_in_slot; + + //nrofCandidates + pdcch_params->aggregation_level = (uint8_t)number_of_candidates[NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS - 1]; + + + //Common_CSS + if (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_COMMON){ + switch(search_space->css_formats_0_0_and_1_0){ + case NFAPI_NR_RNTI_C: + pdcch_params->rnti_type = NFAPI_NR_RNTI_C; + break; + case NFAPI_NR_RNTI_CS: + pdcch_params->rnti_type = NFAPI_NR_RNTI_CS; + break; + case NFAPI_NR_RNTI_SP_CSI: + pdcch_params->rnti_type = NFAPI_NR_RNTI_SP_CSI; + break; + case NFAPI_NR_RNTI_RA: + pdcch_params->rnti_type = NFAPI_NR_RNTI_RA; + break; + case NFAPI_NR_RNTI_TC: + pdcch_params->rnti_type = NFAPI_NR_RNTI_TC; + break; + case NFAPI_NR_RNTI_P: + pdcch_params->rnti_type = NFAPI_NR_RNTI_P; + break; + case NFAPI_NR_RNTI_SI: + pdcch_params->rnti_type = NFAPI_NR_RNTI_SI; + break; + } + + switch (search_space->css_format_2_0){ + case NFAPI_NR_RNTI_SFI: + pdcch_params->rnti_type = NFAPI_NR_RNTI_SFI; + break; + } + + switch (search_space->css_format_2_1){ + case NFAPI_NR_RNTI_INT: + pdcch_params->rnti_type = NFAPI_NR_RNTI_INT; + break; + } + + switch (search_space->css_format_2_2){ + case NFAPI_NR_RNTI_TPC_PUSCH: + pdcch_params->rnti_type = NFAPI_NR_RNTI_TPC_PUSCH; + break; + case NFAPI_NR_RNTI_TPC_PUCCH: + pdcch_params->rnti_type = NFAPI_NR_RNTI_TPC_PUCCH; + break; + } + + switch (search_space->css_format_2_3){ + case NFAPI_NR_RNTI_TPC_SRS: + pdcch_params->rnti_type = NFAPI_NR_RNTI_TPC_SRS; + break; + } + } + + //Ue_Specific_USS + if (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC){ + switch (search_space->uss_dci_formats){ + case NFAPI_NR_RNTI_C: + pdcch_params->rnti_type = NFAPI_NR_RNTI_C; + break; + case NFAPI_NR_RNTI_CS: + pdcch_params->rnti_type = NFAPI_NR_RNTI_CS; + break; + case NFAPI_NR_RNTI_SP_CSI: + pdcch_params->rnti_type = NFAPI_NR_RNTI_SP_CSI; + break; + } + } +*/ + pdcch_params->n_RB_BWP = N_RB; +} + +int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space, + nfapi_nr_coreset_t coreset, + uint16_t frame, + uint16_t slot, + nfapi_nr_config_request_t cfg) { + + AssertFatal(search_space.coreset_id==coreset.coreset_id, "Invalid association of coreset(%d) and search space(%d)\n", + search_space.search_space_id, coreset.coreset_id); + + uint8_t is_dci_opportunity=0; + uint16_t Ks=search_space.slot_monitoring_periodicity; + uint16_t Os=search_space.slot_monitoring_offset; + uint8_t Ts=search_space.duration; + + if (((frame*get_spf(&cfg) + slot - Os)%Ks)<Ts) + is_dci_opportunity=1; + + return is_dci_opportunity; } int get_dlscs(nfapi_nr_config_request_t *cfg) { @@ -237,3 +543,13 @@ int to_absslot(nfapi_nr_config_request_t *cfg,int frame,int slot) { return(get_spf(cfg)*frame) + slot; } + +int get_symbolsperslot(nfapi_nr_config_request_t *cfg) { + + return ((cfg->subframe_config.dl_cyclic_prefix_type.value==NFAPI_CP_EXTENDED)?12:14); + +} + +int nr_schedule_dci() { + +} diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 784496ff9e50e4db61909fbd40cea4a3ac4dbabb..c0ba26fb5de2bae912e0386e625827eed5931bb8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -72,13 +72,23 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p nr_frequency_range_e freq_range, uint8_t rmsi_pdcch_config, uint8_t ssb_idx, + uint8_t k_ssb, + uint16_t sfn_ssb, + uint8_t n_ssb, uint16_t nb_slots_per_frame, uint16_t N_RB); +int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space, + nfapi_nr_coreset_t coreset, + uint16_t frame, + uint16_t slot, + nfapi_nr_config_request_t cfg); -void nr_configure_css_dci_from_pdcch_config(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params, +void nr_configure_dci_from_pdcch_config(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params, nfapi_nr_coreset_t* coreset, - nfapi_nr_search_space_t* search_space); + nfapi_nr_search_space_t* search_space, + nfapi_nr_config_request_t cfg, + uint16_t N_RB); int get_dlscs(nfapi_nr_config_request_t *cfg); @@ -88,4 +98,6 @@ int get_spf(nfapi_nr_config_request_t *cfg); int to_absslot(nfapi_nr_config_request_t *cfg,int frame,int slot); +int get_symbolsperslot(nfapi_nr_config_request_t *cfg); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 8387f748a7820ea64227b1352f7ef7154618ce4c..7e6705d87f9c2ab161adf75c6c10fd207a4874f4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -44,6 +44,34 @@ extern RAN_CONTEXT_t RC; +void nr_init_coreset(nfapi_nr_coreset_t *coreset) { + + coreset->coreset_id = 1; + coreset->frequency_domain_resources = 0x1E0000000000;//0x1FFFE0000000; // 96 RB starting from CRB0 + coreset->duration = 2; + coreset->cce_reg_mapping_type = NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED; + coreset->reg_bundle_size = 6; + coreset->interleaver_size = 2; + coreset->precoder_granularity = NFAPI_NR_CSET_SAME_AS_REG_BUNDLE; + coreset->tci_present_in_dci = 0; + coreset->dmrs_scrambling_id = 0; +} + +void nr_init_search_space(nfapi_nr_search_space_t *search_space) { + + search_space->search_space_id = 1; + search_space->coreset_id = 1; + search_space->search_space_type = NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC; + search_space->duration = 5; + search_space->slot_monitoring_periodicity = NFAPI_NR_SS_PERIODICITY_SL10; + search_space->slot_monitoring_offset = 1; + search_space->monitoring_symbols_in_slot = 0xC0000000; // first 2 ofdm symbols + search_space->css_formats_0_0_and_1_0 = 1; + search_space->uss_dci_formats = 0; // enum to be defined-- formats 0.0 and 1.0 + for (int i=0; i<NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS; i++) + search_space->number_of_candidates[i] = 4; // TODO +} + void mac_top_init_gNB(void) { module_id_t i,j; @@ -56,24 +84,24 @@ void mac_top_init_gNB(void) if (RC.nb_nr_macrlc_inst > 0) { RC.nrmac = (gNB_MAC_INST **) malloc16(RC.nb_nr_macrlc_inst *sizeof(gNB_MAC_INST *)); - + AssertFatal(RC.nrmac != NULL,"can't ALLOCATE %zu Bytes for %d gNB_MAC_INST with size %zu \n", RC.nb_nr_macrlc_inst * sizeof(gNB_MAC_INST *), RC.nb_nr_macrlc_inst, sizeof(gNB_MAC_INST)); for (i = 0; i < RC.nb_nr_macrlc_inst; i++) { RC.nrmac[i] = (gNB_MAC_INST *) malloc16(sizeof(gNB_MAC_INST)); - + AssertFatal(RC.nrmac != NULL,"can't ALLOCATE %zu Bytes for %d gNB_MAC_INST with size %zu \n", RC.nb_nr_macrlc_inst * sizeof(gNB_MAC_INST *), RC.nb_nr_macrlc_inst, sizeof(gNB_MAC_INST)); LOG_D(MAC,"[MAIN] ALLOCATE %zu Bytes for %d gNB_MAC_INST @ %p\n",sizeof(gNB_MAC_INST), RC.nb_nr_macrlc_inst, RC.mac); - + bzero(RC.nrmac[i], sizeof(gNB_MAC_INST)); - + RC.nrmac[i]->Mod_id = i; - + for (j = 0; j < MAX_NUM_CCs; j++) { RC.nrmac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list = RC.nrmac[i]->dl_config_pdu_list[j]; @@ -84,7 +112,11 @@ void mac_top_init_gNB(void) RC.nrmac[i]->HI_DCI0_req[j].hi_dci0_request_body.hi_dci0_pdu_list = RC.nrmac[i]->hi_dci0_pdu_list[j]; RC.nrmac[i]->TX_req[j].tx_request_body.tx_pdu_list = RC.nrmac[i]->tx_request_pdu[j]; - RC.nrmac[i]->ul_handle = 0; + RC.nrmac[i]->ul_handle = 0; + + // Init PDCCH structures + nr_init_coreset(&RC.nrmac[i]->coreset[j][1]); + nr_init_search_space(&RC.nrmac[i]->search_space[j][1]); } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 3af2a4a7c9051da3e6d96243a2097204a078a18b..6cd15fd32bdf82e2987bd764f4bc92162f1d175f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -138,6 +138,10 @@ typedef struct gNB_MAC_INST_s { nfapi_tx_request_pdu_t tx_request_pdu[NFAPI_CC_MAX][MAX_NUM_TX_REQUEST_PDU]; /// NFAPI DL PDU structure nfapi_tx_request_t TX_req[NFAPI_CC_MAX]; + /// NFAPI coreset structure + nfapi_nr_coreset_t coreset[NFAPI_CC_MAX][NFAPI_NR_MAX_NB_CORESETS]; + /// NFAPI search space structure + nfapi_nr_search_space_t search_space[NFAPI_CC_MAX][NFAPI_NR_MAX_NB_SEARCH_SPACES]; UE_list_t UE_list; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 4e8b72614d2d5a9f9de157a76d2df7e91aa4a38e..a0b07c4fbd04bb4fa886353c889d7dfaa6bdf1bd 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -283,9 +283,9 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq) { dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.rb_offset = rb_offset; // additional parameter other than coreset dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.duration = num_symbols; - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_mapping_type =CCE_REG_MAPPING_TYPE_INTERLEAVED; - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_reg_bundle_size = 6; // L 38.211 7.3.2.2 - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_interleaver_size = 2; // R 38.211 7.3.2.2 + dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_mapping_type =CCE_REG_MAPPING_TYPE_NON_INTERLEAVED; + dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_reg_bundle_size = 0; // L 38.211 7.3.2.2 + dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_interleaver_size = 0; // R 38.211 7.3.2.2 dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_shift_index = cell_id; dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.precoder_granularity = PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE; dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.pdcch_dmrs_scrambling_id = cell_id; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 8b4279dc317051098797d3cf620a67e78306d86e..7efc4e8bed949fcb5c595c965d19e28d0fe687ef 100755 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -322,25 +322,24 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message( (const void *)bufferP, buffer_len ); - if(bcch_message->message.choice.mib->systemFrameNumber.buf != 0){ - if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) { - printf("NR_CellGroupConfig decode error\n"); - for (i=0; i<buffer_len; i++){ - printf("%02x ",bufferP[i]); - } - printf("\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message, 1 ); - return -1; - } - - // link to rrc instance - mib = bcch_message->message.choice.mib; - //memcpy( (void *)mib, - // (void *)&bcch_message->message.choice.mib, - // sizeof(NR_MIB_t) ); - - nr_rrc_mac_config_req_ue( 0, 0, 0, mib, NULL, NULL, NULL); + if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) { + printf("NR_BCCH_BCH decode error\n"); + for (i=0; i<buffer_len; i++){ + printf("%02x ",bufferP[i]); + } + printf("\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message, 1 ); + return -1; + } + else { + // link to rrc instance + mib = bcch_message->message.choice.mib; + //memcpy( (void *)mib, + // (void *)&bcch_message->message.choice.mib, + // sizeof(NR_MIB_t) ); + + nr_rrc_mac_config_req_ue( 0, 0, 0, mib, NULL, NULL, NULL); } return 0; diff --git a/targets/RT/USER/nr-ru.c b/targets/RT/USER/nr-ru.c index af3916604e519a52fe94cfcf66125c474d81ac06..c0598b9144d188bce1fd9ba3d7ab1029c1227204 100644 --- a/targets/RT/USER/nr-ru.c +++ b/targets/RT/USER/nr-ru.c @@ -1333,7 +1333,7 @@ static void* ru_thread_tx( void* param ) { { for (i=0; i<ru->nb_tx; i++) { - sprintf(filename,"tx%ddataF_frame%d_sf%d.m", i, print_frame, proc->tti_tx); + sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); if(proc->tti_tx == 9) { @@ -1554,7 +1554,7 @@ static void* ru_thread( void* param ) { { for (i=0; i<ru->nb_tx; i++) { - sprintf(filename,"tx%ddataF_frame%d_sf%d.m", i, print_frame, proc->tti_tx); + sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_slot_wCP, 1, 1); if(proc->tti_tx == 9) { diff --git a/targets/RT/USER/nr-ue.c b/targets/RT/USER/nr-ue.c index b289811b015dfe7059928c35082b8dfb4fabaf30..ce56bc95ff0a455b9b598de426531b24074ca082 100644 --- a/targets/RT/USER/nr-ue.c +++ b/targets/RT/USER/nr-ue.c @@ -442,10 +442,10 @@ static void *UE_thread_synch(void *arg) { #endif if (nr_initial_sync( UE, UE->mode ) == 0) { - //write_output("txdata_sym.m", "txdata_sym", UE->common_vars.rxdata[0], (10*UE->frame_parms.samples_per_subframe), 1, 1); + //write_output("txdata_sym.m", "txdata_sym", UE->common_vars.rxdata[0], (10*UE->frame_parms.samples_per_slot), 1, 1); freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync - hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe; + hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_slot; printf("Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", hw_slot_offset, freq_offset, @@ -691,6 +691,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0); UE_mac->scheduled_response.dl_config = &UE->dcireq.dl_config_req; + UE_mac->scheduled_response.slot = proc->nr_tti_rx; nr_ue_scheduled_response(&UE_mac->scheduled_response); #ifdef UE_SLOT_PARALLELISATION @@ -792,6 +793,8 @@ void *UE_thread(void *arg) { UE->proc.proc_rxtx[2].counter_decoder = 0; static uint8_t thread_idx = 0; + uint16_t table_sf_slot[20] = {0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9}; + cpu_set_t cpuset; CPU_ZERO(&cpuset); @@ -812,7 +815,8 @@ void *UE_thread(void *arg) { //itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p); #endif - int subframe_nr=-1; + int nb_slot_frame = 10*UE->frame_parms.slots_per_subframe; + int slot_nr=-1; //int cumulated_shift=0; if ((oaisim_flag == 0) && (UE->mode != loop_through_memory)) AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n"); @@ -915,11 +919,13 @@ void *UE_thread(void *arg) { if(thread_idx>=RX_NB_TH) thread_idx = 0; - subframe_nr++; - subframe_nr %= NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + //printf("slot_nr %d nb slot frame %d\n",slot_nr, nb_slot_frame); + + slot_nr++; + slot_nr %= nb_slot_frame; UE_nr_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx]; // update thread index for received subframe - UE->current_thread_id[subframe_nr] = thread_idx; + UE->current_thread_id[slot_nr] = thread_idx; #if BASIC_SIMULATOR { @@ -933,38 +939,38 @@ void *UE_thread(void *arg) { } #endif - LOG_D(PHY,"Process subframe %d thread Idx %d \n", subframe_nr, UE->current_thread_id[subframe_nr]); + LOG_D(PHY,"Process slot %d thread Idx %d \n", slot_nr, UE->current_thread_id[slot_nr]); if (UE->mode != loop_through_memory) { for (i=0; i<UE->frame_parms.nb_antennas_rx; i++) rxp[i] = (void*)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+ UE->frame_parms.nb_prefix_samples0+ - subframe_nr*UE->frame_parms.samples_per_subframe]; + slot_nr*UE->frame_parms.samples_per_slot]; for (i=0; i<UE->frame_parms.nb_antennas_tx; i++) - txp[i] = (void*)&UE->common_vars.txdata[i][((subframe_nr+2)%NR_NUMBER_OF_SUBFRAMES_PER_FRAME)*UE->frame_parms.samples_per_subframe]; + txp[i] = (void*)&UE->common_vars.txdata[i][((slot_nr+2)%NR_NUMBER_OF_SUBFRAMES_PER_FRAME)*UE->frame_parms.samples_per_slot]; int readBlockSize, writeBlockSize; - if (subframe_nr<(NR_NUMBER_OF_SUBFRAMES_PER_FRAME - 1)) { - readBlockSize=UE->frame_parms.samples_per_subframe; - writeBlockSize=UE->frame_parms.samples_per_subframe; + if (slot_nr<(nb_slot_frame - 1)) { + readBlockSize=UE->frame_parms.samples_per_slot; + writeBlockSize=UE->frame_parms.samples_per_slot; } else { // set TO compensation to zero UE->rx_offset_diff = 0; // compute TO compensation that should be applied for this frame - if ( UE->rx_offset < 5*UE->frame_parms.samples_per_subframe && + if ( UE->rx_offset < 5*UE->frame_parms.samples_per_slot && UE->rx_offset > 0 ) UE->rx_offset_diff = -1 ; - if ( UE->rx_offset > 5*UE->frame_parms.samples_per_subframe && - UE->rx_offset < 10*UE->frame_parms.samples_per_subframe ) + if ( UE->rx_offset > 5*UE->frame_parms.samples_per_slot && + UE->rx_offset < 10*UE->frame_parms.samples_per_slot ) UE->rx_offset_diff = 1; - LOG_D(PHY,"AbsSubframe %d.%d TTI SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,subframe_nr,UE->rx_offset_diff,UE->rx_offset); - readBlockSize=UE->frame_parms.samples_per_subframe - + LOG_D(PHY,"AbsSubframe %d.%d TTI SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,slot_nr,UE->rx_offset_diff,UE->rx_offset); + readBlockSize=UE->frame_parms.samples_per_slot - UE->frame_parms.ofdm_symbol_size - UE->frame_parms.nb_prefix_samples0 - UE->rx_offset_diff; - writeBlockSize=UE->frame_parms.samples_per_subframe - + writeBlockSize=UE->frame_parms.samples_per_slot - UE->rx_offset_diff; } @@ -977,7 +983,7 @@ void *UE_thread(void *arg) { AssertFatal( writeBlockSize == UE->rfdevice.trx_write_func(&UE->rfdevice, timestamp+ - (2*UE->frame_parms.samples_per_subframe) - + (2*UE->frame_parms.samples_per_slot) - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - openair0_cfg[0].tx_sample_advance, txp, @@ -985,7 +991,7 @@ void *UE_thread(void *arg) { UE->frame_parms.nb_antennas_tx, 1),""); - if( subframe_nr==(NR_NUMBER_OF_SUBFRAMES_PER_FRAME-1)) { + if( slot_nr==(nb_slot_frame-1)) { // read in first symbol of next frame and adjust for timing drift int first_symbols=writeBlockSize-readBlockSize; if ( first_symbols > 0 ) @@ -1002,7 +1008,7 @@ void *UE_thread(void *arg) { pickTime(gotIQs); // operate on thread sf mod 2 AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); - if(subframe_nr == 0) { + if(slot_nr == 0) { UE->proc.proc_rxtx[0].frame_rx++; //UE->proc.proc_rxtx[1].frame_rx++; for (th_id=1; th_id < RX_NB_TH; th_id++) { @@ -1024,18 +1030,18 @@ void *UE_thread(void *arg) { UE->proc.proc_rxtx[th_id].gotIQs=readTime(gotIQs); } - proc->nr_tti_rx=subframe_nr; - proc->subframe_rx=subframe_nr; + proc->nr_tti_rx=slot_nr; + proc->subframe_rx=table_sf_slot[slot_nr]; proc->frame_tx = proc->frame_rx; - proc->nr_tti_tx= subframe_nr + DURATION_RX_TO_TX; - if (proc->nr_tti_tx > NR_NUMBER_OF_SUBFRAMES_PER_FRAME) { + proc->nr_tti_tx= slot_nr + DURATION_RX_TO_TX; + if (proc->nr_tti_tx > nb_slot_frame) { proc->frame_tx = (proc->frame_tx + 1)%MAX_FRAME_NUMBER; - proc->nr_tti_tx %= NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + proc->nr_tti_tx %= nb_slot_frame; } proc->subframe_tx=proc->nr_tti_rx; proc->timestamp_tx = timestamp+ - (DURATION_RX_TO_TX*UE->frame_parms.samples_per_subframe)- + (DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot)- UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; proc->instance_cnt_rxtx++; @@ -1055,7 +1061,7 @@ void *UE_thread(void *arg) { char exit_fun_string[256]; sprintf(exit_fun_string,"[SCHED][UE %d] !!! UE instance_cnt_rxtx > 2 (IC %d) (Proc %d)!!", UE->Mod_id, proc->instance_cnt_rxtx, - UE->current_thread_id[subframe_nr]); + UE->current_thread_id[slot_nr]); printf("%s\n",exit_fun_string); fflush(stdout); sleep(1); @@ -1071,20 +1077,20 @@ void *UE_thread(void *arg) { // pickStaticTime(lastTime); } //UE->mode != loop_through_memory else { - proc->nr_tti_rx=subframe_nr; - proc->subframe_rx=subframe_nr; - if(subframe_nr == 0) { + proc->nr_tti_rx=slot_nr; + proc->subframe_rx=table_sf_slot[slot_nr]; + if(slot_nr == 0) { for (th_id=0; th_id < RX_NB_TH; th_id++) { UE->proc.proc_rxtx[th_id].frame_rx++; } } proc->frame_tx = proc->frame_rx; - proc->nr_tti_tx= subframe_nr + DURATION_RX_TO_TX; - if (proc->nr_tti_tx > NR_NUMBER_OF_SUBFRAMES_PER_FRAME) { + proc->nr_tti_tx= slot_nr + DURATION_RX_TO_TX; + if (proc->nr_tti_tx > nb_slot_frame) { proc->frame_tx = (proc->frame_tx + 1)%MAX_FRAME_NUMBER; - proc->nr_tti_tx %= NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + proc->nr_tti_tx %= nb_slot_frame; } - proc->subframe_tx=proc->nr_tti_tx; + proc->subframe_tx=table_sf_slot[proc->nr_tti_tx]; if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) { @@ -1103,10 +1109,12 @@ void *UE_thread(void *arg) { NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0); UE_mac->scheduled_response.dl_config = &UE->dcireq.dl_config_req; + UE_mac->scheduled_response.slot = proc->nr_tti_rx; nr_ue_scheduled_response(&UE_mac->scheduled_response); - - printf("Processing subframe %d\n",proc->subframe_rx); + //write_output("uerxdata_frame.m", "uerxdata_frame", UE->common_vars.rxdata[0], UE->frame_parms.samples_per_frame, 1, 1); + + printf("Processing slot %d\n",proc->nr_tti_rx); phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode); }