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 e1bd4191b35744f7fd8041b154c8d7c693337ccd..b227acd5e479a7301a8851ad01d28c39d258be59 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h @@ -375,8 +375,8 @@ typedef struct{ typedef struct { nfapi_tl_t tl; - nfapi_nr_search_space_t search_space; - + nfapi_nr_coreset_t coreset; + nfapi_nr_search_space_t search_space; } nfapi_nr_dl_config_pdcch_parameters_rel15_t; typedef struct { diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index ac745d05bbe4dfd29ee10b286417011f65f03ca7..f99a201d183534c8d354fad5d2d31d7f90a48470 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -165,25 +165,69 @@ uint8_t nr_generate_dci_top(NR_gNB_DCI_ALLOC_t dci_alloc, uint16_t mod_dmrs[NR_MAX_PDCCH_DMRS_LENGTH<<1]; uint8_t idx=0; + uint16_t a; + int k,l; + nr_cce_t cce; /// DMRS QPSK modulation - for (int m=0; m<NR_MAX_PDCCH_DMRS_LENGTH>>1; m++) { - idx = ((((gold_pdcch_dmrs[(m<<1)>>5])>>((m<<1)&0x1f))&1)<<1) ^ (((gold_pdcch_dmrs[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1); - mod_dmrs[m<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; - mod_dmrs[(m<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; + for (int i=0; i<NR_MAX_PDCCH_DMRS_LENGTH>>1; i++) { + idx = ((((gold_pdcch_dmrs[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((gold_pdcch_dmrs[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); + mod_dmrs[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; + mod_dmrs[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; #ifdef DEBUG_PDCCH_DMRS - printf("m %d idx %d gold seq %d b0-b1 %d-%d mod_dmrs %d %d\n", m, idx, gold_pdcch_dmrs[(m<<1)>>5], (((gold_pdcch_dmrs[(m<<1)>>5])>>((m<<1)&0x1f))&1), - (((gold_pdcch_dmrs[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1), mod_dmrs[(m<<1)], mod_dmrs[(m<<1)+1]); + printf("i %d idx %d gold seq %d b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, gold_pdcch_dmrs[(i<<1)>>5], (((gold_pdcch_dmrs[(i<<1)>>5])>>((i<<1)&0x1f))&1), + (((gold_pdcch_dmrs[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), mod_dmrs[(i<<1)], mod_dmrs[(i<<1)+1]); #endif } /// DCI payload processing + //channel coding + // scrambling uint32_t scrambled_payload[4]; nr_pdcch_scrambling(dci_alloc, pdcch_vars, config, scrambled_payload); // QPSK modulation - + uint32_t mod_dci[NR_MAX_DCI_SIZE>>1]; + for (int i=0; i<dci_alloc.size>>1; i++) { + idx = (((scrambled_payload[i<<1]>>(i<<1))&1)<<1) ^ ((scrambled_payload[(i<<1)+1]>>((i<<1)+1))&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]; + } + + /// Resource mapping + a = (config.rf_config.tx_antenna_ports.value == 1) ? amp : (amp*ONE_OVER_SQRT2_Q15)>>15; + uint8_t n_rb = pdcch_vars.coreset_params.n_rb; + uint8_t rb_offset = pdcch_vars.coreset_params.n_symb; + uint8_t n_symb = pdcch_vars.coreset_params.rb_offset; + uint8_t first_slot = pdcch_vars.first_slot; + uint8_t first_symb = pdcch_vars.ss_params.first_symbol_idx; + + /*The coreset is initialised + * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset + * in time: by its first slot and its first symbol*/ + uint8_t cset_start_sc = frame_parms.first_carrier_offset + ((int)floor(frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB)+rb_offset)*NR_NB_SC_PER_RB; + uint8_t cset_start_symb = first_slot*frame_parms.symbols_per_slot + first_symb; + + for (int aa = 0; aa < config.rf_config.tx_antenna_ports.value; aa++) + { + if (cset_start_sc >= frame_parms.ofdm_symbol_size) + cset_start_sc -= frame_parms.ofdm_symbol_size; + + for (int cce_idx=0; cce_idx<dci_alloc.L; cce_idx++){ + cce = pdcch_vars.cce_list[cce_idx]; + k = cset_start_sc + cce.start_sc_idx; + l = cset_start_symb + cce.symb_idx; + for (int m=0; m<NR_NB_SC_PER_RB; m++) { + ((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (a * mod_dci[m<<1]) >> 15; + ((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (a * mod_dci[(m<<1) + 1]) >> 15; + k++; + if (k >= frame_parms.ofdm_symbol_size) + k -= frame_parms.ofdm_symbol_size; + } + } + + } return 0; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index 6ada2948b2ecb4de6e59d621fb28fecd8f1d5881..ab7cb5023a58f0e2467b375772c07c59df364743 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -78,15 +78,21 @@ typedef struct { uint8_t n_rb; uint8_t n_symb; uint8_t rb_offset; + nr_cce_reg_mapping_type_e cr_mapping_type; nr_ssb_and_cset_mux_pattern_type_e mux_pattern; } nr_pdcch_coreset_params_t; +typedef struct { + uint8_t start_sc_idx; + uint8_t symb_idx; +} nr_cce_t; + typedef struct { uint8_t first_slot; uint8_t nb_slots; uint8_t sfn_mod2; uint32_t dmrs_scrambling_id; - nr_cce_reg_mapping_type_e cr_mapping_type; + nr_cce_t cce_list[NR_MAX_PDCCH_AGG_LEVEL]; nr_pdcch_ss_params_t ss_params; nr_pdcch_coreset_params_t coreset_params; } nr_pdcch_vars_t; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index f760fe344ada268d12e651e4686a9c85b0b56163..b30ed9e4a31dfdedd2d8591c28fb946d83ae2381 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -42,6 +42,8 @@ #define MAX_NUM_SUBCARRIER_SPACING 5 +#define NR_NB_SC_PER_RB 12 + #define NR_SYMBOLS_PER_SLOT 14 #define ONE_OVER_SQRT2_Q15 23170 @@ -60,8 +62,13 @@ #define NR_MAX_PDCCH_DMRS_LENGTH 100 #define NR_MAX_PDCCH_DMRS_LENGTH_DWORD 5 +#define NR_MAX_DCI_PAYLOAD_SIZE 64 +#define NR_MAX_DCI_SIZE 200 //random values + #define NR_MAX_NUM_BWP 4 +#define NR_MAX_PDCCH_AGG_LEVEL 16 + typedef enum { NR_MU_0=0, NR_MU_1, diff --git a/openair1/SCHED_NR/phy_procedures_nr_common.c b/openair1/SCHED_NR/phy_procedures_nr_common.c index 8b2263781444d9e421ecb910b5b09c810b1fe41e..8d88770acfcb0b91ed23b066e299a633d8654152 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_common.c +++ b/openair1/SCHED_NR/phy_procedures_nr_common.c @@ -39,7 +39,7 @@ uint8_t nr_coreset_nsymb_pdcch_type_0_a40Mhz[10] = {2,2,3,3,1,1,2,2,3,3}; // abo /// 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}; -/// LUT for monitoring occasions param O indexed by ss index (4 MSB rmsi_pdcch_config) +/// LUT for monitoring occasions param O indexed by ss index (4 LSB rmsi_pdcch_config) 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}; /// LUT for number of SS sets per slot indexed by ss index