diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 247bc9e073fc05190365e88524c595f79d6b5adb..f6fcabf82e93564a36faae081b9cae9320a51d5c 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1516,6 +1516,7 @@ set(PHY_SRC_UE ${PHY_SMALLBLOCKSRC} ${PHY_NR_CODINGIF} ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c + ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_uci_tools_common.c ) set(PHY_NR_UE_SRC ${OPENAIR1_DIR}/PHY/INIT/nr_parms.c @@ -1539,6 +1540,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_tools_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pucch_nr.c + ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_uci_tools_common.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index e03700e4f520367645c0783ba915d3671a73c740..8022ef82762b30c57c9b7c45af4b65bff1abaa42 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -963,12 +963,12 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO)); LOG_I(PHY,"Setting indication lists\n"); - gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list; + /*gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list; gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list; gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list; gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list; gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list; - gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list; + gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/ gNB->prach_energy_counter = 0; } diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index f69c928ed2794ae72321468eb9efc9e726ed3751..33951a27512fb42e19850573540e90e83f19b0e2 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -19,6 +19,7 @@ #define NFAPI_MAX_NUM_UL_UE_PER_GROUP 6 #define NFAPI_MAX_NUM_UL_PDU 8 +#define NFAPI_MAX_NUM_UCI_INDICATION 8 #define NFAPI_MAX_NUM_GROUPS 8 #define NFAPI_MAX_NUM_CB 8 @@ -1519,8 +1520,8 @@ typedef struct uint8_t ul_cqi; uint16_t timing_advance; uint16_t rssi; - nfapi_nr_sr_pdu_0_1_t sr;//67 - nfapi_nr_harq_pdu_0_1_t harq;//68 + nfapi_nr_sr_pdu_0_1_t *sr;//67 + nfapi_nr_harq_pdu_0_1_t *harq;//68 }nfapi_nr_uci_pucch_pdu_format_0_1_t; @@ -1542,28 +1543,22 @@ typedef struct }nfapi_nr_uci_pucch_pdu_format_2_3_4_t; -//for SR, HARQ and CSI Part 1/ 2 PDUs - -typedef struct -{ - nfapi_nr_uci_pusch_pdu_t* pusch_pdu; - nfapi_nr_uci_pucch_pdu_format_0_1_t* pucch_pdu_format_0_1; - nfapi_nr_uci_pucch_pdu_format_2_3_4_t* pucch_pdu_format_2_3_4; - nfapi_nr_sr_pdu_0_1_t* sr_pdu_0_1; - nfapi_nr_sr_pdu_2_3_4_t* sr_pdu_2_3_4; - nfapi_nr_harq_pdu_0_1_t* harq_pdu_0_1; - nfapi_nr_harq_pdu_2_3_4_t* harq_pdu_2_3_4; - nfapi_nr_csi_part1_pdu_t* csi_part1_pdu; - nfapi_nr_csi_part2_pdu_t* csi_part2_pdu; - -} nfapi_nr_uci_pdu_information_t; +typedef enum { + NFAPI_NR_UCI_PDCCH_PDU_TYPE = 0, + NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE = 1, + NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE = 2, +} nfapi_nr_uci_pdu_type_e; typedef struct { - uint16_t pdu_type; + uint16_t pdu_type; // 0 for PDU on PUSCH, 1 for PUCCH format 0 or 1, 2 for PUCCH format 2 to 4 uint16_t pdu_size; - nfapi_nr_uci_pdu_information_t uci_pdu; - + union + { + nfapi_nr_uci_pusch_pdu_t pusch_pdu; + nfapi_nr_uci_pucch_pdu_format_0_1_t pucch_pdu_format_0_1; + nfapi_nr_uci_pucch_pdu_format_2_3_4_t pucch_pdu_format_2_3_4; + }; } nfapi_nr_uci_t; typedef struct @@ -1571,7 +1566,7 @@ typedef struct uint16_t sfn; uint16_t slot; uint16_t num_ucis; - nfapi_nr_uci_t* uci_list; + nfapi_nr_uci_t uci_list[NFAPI_MAX_NUM_UCI_INDICATION]; } nfapi_nr_uci_indication_t; diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport.h b/openair1/PHY/NR_TRANSPORT/nr_transport.h index be738750588aaf124ab191631368aece7d301dbb..ba0791d33aa98bc2c067357a4b4d1d3b6b6cc236 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport.h @@ -123,4 +123,26 @@ void rx_nr_prach_ru(RU_t *ru, int frame, int subframe); +void nr_decode_pucch1(int32_t **rxdataF, + pucch_GroupHopping_t pucch_GroupHopping, + uint32_t n_id, // hoppingID higher layer parameter + uint64_t *payload, + NR_DL_FRAME_PARMS *frame_parms, + int16_t amp, + int nr_tti_tx, + uint8_t m0, + uint8_t nrofSymbols, + uint8_t startingSymbolIndex, + uint16_t startingPRB, + uint16_t startingPRB_intraSlotHopping, + uint8_t timeDomainOCC, + uint8_t nr_bit); + +void nr_decode_pucch0(int32_t **rxdataF, + NR_DL_FRAME_PARMS *frame_parms, + int slot, + nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu, + nfapi_nr_pucch_pdu_t* pucch_pdu); + + #endif /*__NR_TRANSPORT__H__*/ diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h index 762346048f94f9e62e7733ecdbb4010ffa107dd1..85f3c00b906888507449d9dcff5d9ee9c2a0786d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h @@ -41,7 +41,19 @@ #define NR_PUSCH_y 3 // UCI placeholder bit +void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping, + uint32_t n_id, + uint8_t n_hop, + int nr_tti_tx, + uint8_t *u, + uint8_t *v); +double nr_cyclic_shift_hopping(uint32_t n_id, + uint8_t m0, + uint8_t mcs, + uint8_t lnormal, + uint8_t lprime, + int nr_tti_tx); /** \brief Computes available bits G. */ diff --git a/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c b/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c new file mode 100644 index 0000000000000000000000000000000000000000..2b0cbe72b3a91c8757c12d3ccbf194d5d08f740c --- /dev/null +++ b/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c @@ -0,0 +1,167 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/NR_TRANSPORT/nr_dci_tools_common.c + * \brief + * \author + * \date 2020 + * \version 0.1 + * \company Eurecom + * \email: + * \note + * \warning + */ + +#include "nr_dci.h" + +void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, + uint32_t n_id, + uint8_t n_hop, + int nr_tti_tx, + uint8_t *u, + uint8_t *v) { + /* + * Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping + * The following variables are set by higher layers: + * - PUCCH_GroupHopping: + * - n_id: higher-layer parameter hoppingId + * - n_hop: frequency hopping index + * if intra-slot frequency hopping is disabled by the higher-layer parameter PUCCH-frequency-hopping + * n_hop=0 + * if frequency hopping is enabled by the higher-layer parameter PUCCH-frequency-hopping + * n_hop=0 for the first hop + * n_hop=1 for the second hop + */ + // depending on the value of the PUCCH_GroupHopping, we will obtain different values for u,v + //pucch_GroupHopping_t PUCCH_GroupHopping = ue->pucch_config_common_nr->pucch_GroupHopping; // from higher layers FIXME!!! + // n_id defined as per TS 38.211 subclause 6.3.2.2.1 (is given by the higher-layer parameter hoppingId) + // it is hoppingId from PUCCH-ConfigCommon: + // Cell-Specific scrambling ID for group hoppping and sequence hopping if enabled + // Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2) BIT STRING (SIZE (10)) + //uint16_t n_id = ue->pucch_config_common_nr->hoppingId; // from higher layers FIXME!!! +#ifdef DEBUG_NR_PUCCH_TX + printf("\t\t [nr_group_sequence_hopping] PUCCH_GroupHopping=%u, n_id=%u \n",PUCCH_GroupHopping,n_id); +#endif + uint8_t f_ss=0,f_gh=0; + *u=0; + *v=0; + uint32_t c_init = 0; + uint32_t x1,s; // TS 38.211 Subclause 5.2.1 + int l = 32, minShift = ((2*nr_tti_tx+n_hop)<<3); + int tmpShift =0; +#ifdef DEBUG_NR_PUCCH_TX + printf("\t\t [nr_group_sequence_hopping] calculating u,v -> "); +#endif + + if (PUCCH_GroupHopping == neither) { // PUCCH_GroupHopping 'neither' + f_ss = n_id%30; + } + + if (PUCCH_GroupHopping == enable) { // PUCCH_GroupHopping 'enabled' + c_init = floor(n_id/30); // we initialize c_init to calculate u,v according to 6.3.2.2.1 of 38.211 + s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 + for (int m=0; m<8; m++) { + while(minShift >= l) { + s = lte_gold_generic(&x1, &c_init, 0); + l = l+32; + } + + tmpShift = (minShift&((1<<5)-1)); //minShift%32; + f_gh = f_gh + ((1<<m)*((uint8_t)((s>>tmpShift)&1))); + minShift ++; + } + + f_gh = f_gh%30; + f_ss = n_id%30; + /* for (int m=0; m<8; m++){ + f_gh = f_gh + ((1<<m)*((uint8_t)((s>>(8*(2*nr_tti_tx+n_hop)+m))&1))); // Not sure we have to use nr_tti_tx FIXME!!! + } + f_gh = f_gh%30; + f_ss = n_id%30;*/ + } + + if (PUCCH_GroupHopping == disable) { // PUCCH_GroupHopping 'disabled' + c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v + s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 + f_ss = n_id%30; + l = 32, minShift = (2*nr_tti_tx+n_hop); + + while(minShift >= l) { + s = lte_gold_generic(&x1, &c_init, 0); + l = l+32; + } + + tmpShift = (minShift&((1<<5)-1)); //minShift%32; + *v = (uint8_t)((s>>tmpShift)&1); + // *v = (uint8_t)((s>>(2*nr_tti_tx+n_hop))&1); // Not sure we have to use nr_tti_tx FIXME!!! + } + + *u = (f_gh+f_ss)%30; +#ifdef DEBUG_NR_PUCCH_TX + printf("%d,%d\n",*u,*v); +#endif +} + +double nr_cyclic_shift_hopping(uint32_t n_id, + uint8_t m0, + uint8_t mcs, + uint8_t lnormal, + uint8_t lprime, + int nr_tti_tx) { + /* + * Implements TS 38.211 subclause 6.3.2.2.2 Cyclic shift hopping + * - n_id: higher-layer parameter hoppingId + * - m0: provided by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift of PUCCH-F0-resource-config + * - mcs: mcs=0 except for PUCCH format 0 when it depends on information to be transmitted according to TS 38.213 subclause 9.2 + * - lnormal: lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission + * - lprime: lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] + */ + // alpha_init initialized to 2*PI/12=0.5235987756 + double alpha = 0.5235987756; + uint32_t c_init = n_id; // we initialize c_init again to calculate n_cs + + uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 + uint8_t n_cs=0; + int l = 32, minShift = (14*8*nr_tti_tx )+ 8*(lnormal+lprime); + int tmpShift =0; +#ifdef DEBUG_NR_PUCCH_TX + printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%u -> \n",c_init); +#endif + + for (int m=0; m<8; m++) { + while(minShift >= l) { + s = lte_gold_generic(&x1, &c_init, 0); + l = l+32; + } + + tmpShift = (minShift&((1<<5)-1)); //minShift%32; + minShift ++; + n_cs = n_cs+((1<<m)*((uint8_t)((s>>tmpShift)&1))); + // calculating n_cs (Not sure we have to use nr_tti_tx FIXME!!!) + // n_cs = n_cs+((1<<m)*((uint8_t)((s>>((14*8*nr_tti_tx) + 8*(lnormal+lprime) + m))&1))); + } + + alpha = (alpha * (double)((m0+mcs+n_cs)%12)); +#ifdef DEBUG_NR_PUCCH_TX + printf("n_cs=%d -> %lf\n",n_cs,alpha); +#endif + return(alpha); +} diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index b74b078dfd6ffcd63faa97b59314335405e0f546..c1e202994bc6bde28d8e9f10269671bd259d35d8 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -10,35 +10,32 @@ #include "PHY/defs_nr_common.h" #include "PHY/defs_nr_UE.h" #include "PHY/NR_UE_TRANSPORT/pucch_nr.h" -#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" - +#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" +#include "PHY/NR_TRANSPORT/nr_transport.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "T.h" -void nr_decode_pucch0( int32_t **rxdataF, - pucch_GroupHopping_t pucch_GroupHopping, - uint32_t n_id, // hoppingID higher layer parameter - uint64_t *payload, - NR_DL_FRAME_PARMS *frame_parms, - int16_t amp, - int nr_tti_tx, - uint8_t m0, // should come from resource set - uint8_t nrofSymbols, // should come from resource set - uint8_t startingSymbolIndex, // should come from resource set - uint16_t startingPRB, // should come from resource set - uint8_t nr_bit) { // is number of UCI bits to be decoded +void nr_decode_pucch0(int32_t **rxdataF, + NR_DL_FRAME_PARMS *frame_parms, + int slot, + nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu, + nfapi_nr_pucch_pdu_t* pucch_pdu) { + int nr_sequences; const uint8_t *mcs; - if(nr_bit==1){ + + pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1); + + if(pucch_pdu->bit_len_harq==1){ mcs=table1_mcs; - nr_sequences=4; + nr_sequences=4>>(1-pucch_pdu->sr_flag); } else{ mcs=table2_mcs; - nr_sequences=8; + nr_sequences=8>>(1-pucch_pdu->sr_flag); } /* * Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation @@ -53,8 +50,6 @@ void nr_decode_pucch0( int32_t **rxdataF, //uint8_t lnormal; // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] //uint8_t lprime; - // mcs is provided by TC 38.213 subclauses 9.2.3, 9.2.4, 9.2.5 FIXME! - //uint8_t mcs; /* * in TS 38.213 Subclause 9.2.1 it is said that: @@ -73,26 +68,24 @@ void nr_decode_pucch0( int32_t **rxdataF, // if frequency hopping is enabled by the higher-layer parameter PUCCH-frequency-hopping // n_hop = 0 for first hop // n_hop = 1 for second hop - uint8_t n_hop = 0; - //uint8_t PUCCH_Frequency_Hopping; // from higher layers FIXME!! + uint8_t n_hop = 0; // Frequnecy hopping not implemented FIXME!! // x_n contains the sequence r_u_v_alpha_delta(n) int16_t x_n_re[nr_sequences][24],x_n_im[nr_sequences][24]; int n,i,l; for(i=0;i<nr_sequences;i++){ // we proceed to calculate alpha according to TS 38.211 Subclause 6.3.2.2.2 - for (l=0; l<nrofSymbols; l++){ - // if frequency hopping is enabled n_hop = 1 for second hop. Not sure frequency hopping concerns format 0. FIXME!!! - // if ((PUCCH_Frequency_Hopping == 1)&&(l == (nrofSymbols-1))) n_hop = 1; - nr_group_sequence_hopping(pucch_GroupHopping,n_id,n_hop,nr_tti_tx,&u,&v); // calculating u and v value - alpha = nr_cyclic_shift_hopping(n_id,m0,mcs[i],l,startingSymbolIndex,nr_tti_tx); + for (l=0; l<pucch_pdu->nr_of_symbols; l++){ + + nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,n_hop,slot,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,pucch_pdu->initial_cyclic_shift,mcs[i],l,pucch_pdu->start_symbol_index,slot); #ifdef DEBUG_NR_PUCCH_RX printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u,v,alpha,l); #endif for (n=0; n<12; n++){ - x_n_re[i][(12*l)+n] = (int16_t)((int32_t)(amp)*(int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) + x_n_re[i][(12*l)+n] = (int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))>>15); // Re part of base sequence shifted by alpha - x_n_im[i][(12*l)+n] =(int16_t)((int32_t)(amp)* (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) + x_n_im[i][(12*l)+n] =(int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))>>15); // Im part of base sequence shifted by alpha #ifdef DEBUG_NR_PUCCH_RX printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d)\n", @@ -103,38 +96,31 @@ void nr_decode_pucch0( int32_t **rxdataF, } int16_t r_re[24],r_im[24]; /* - * Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources FIXME! + * Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources */ uint32_t re_offset=0; - for (l=0; l<nrofSymbols; l++) { - if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; - } - if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))); - } - if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; - } - if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6; - } - if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; - } + uint8_t l2; + + for (l=0; l<pucch_pdu->nr_of_symbols; l++) { + + l2 = l+pucch_pdu->start_symbol_index; + re_offset = (12*pucch_pdu->prb_start) + frame_parms->first_carrier_offset; + if (re_offset>= frame_parms->ofdm_symbol_size) + re_offset-=frame_parms->ofdm_symbol_size; + for (n=0; n<12; n++){ - if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { - // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); - } - r_re[(12*l)+n]=((int16_t *)&rxdataF[0][re_offset])[0]; - r_im[(12*l)+n]=((int16_t *)&rxdataF[0][re_offset])[1]; + + r_re[(12*l)+n]=((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[0]; + r_im[(12*l)+n]=((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[1]; #ifdef DEBUG_NR_PUCCH_RX - printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", - amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,re_offset, - l,n,((int16_t *)&rxdataF[0][re_offset])[0],((int16_t *)&rxdataF[0][re_offset])[1]); + printf("\t [nr_generate_pucch0] mapping to RE \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,(l2*frame_parms->ofdm_symbol_size)+re_offset, + l,n,((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[0], + ((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[1]); #endif re_offset++; + if (re_offset>= frame_parms->ofdm_symbol_size) + re_offset-=frame_parms->ofdm_symbol_size; } } double corr[nr_sequences],corr_re[nr_sequences],corr_im[nr_sequences]; @@ -142,7 +128,7 @@ void nr_decode_pucch0( int32_t **rxdataF, memset(corr_re,0,nr_sequences*sizeof(double)); memset(corr_im,0,nr_sequences*sizeof(double)); for(i=0;i<nr_sequences;i++){ - for(l=0;l<nrofSymbols;l++){ + for(l=0;l<pucch_pdu->nr_of_symbols;l++){ for(n=0;n<12;n++){ corr_re[i]+= (double)(r_re[12*l+n])/32767*(double)(x_n_re[i][12*l+n])/32767+(double)(r_im[12*l+n])/32767*(double)(x_n_im[i][12*l+n])/32767; corr_im[i]+= (double)(r_re[12*l+n])/32767*(double)(x_n_im[i][12*l+n])/32767-(double)(r_im[12*l+n])/32767*(double)(x_n_re[i][12*l+n])/32767; @@ -151,14 +137,35 @@ void nr_decode_pucch0( int32_t **rxdataF, corr[i]=corr_re[i]*corr_re[i]+corr_im[i]*corr_im[i]; } float max_corr=corr[0]; - int index=0; + uint8_t index=0; for(i=1;i<nr_sequences;i++){ if(corr[i]>max_corr){ index= i; max_corr=corr[i]; } } - *payload=(uint64_t)index; // payload bits 00..b3b2b0, b0 is the SR bit and b3b2 are HARQ bits + + // first bit of bitmap for sr presence and second bit for acknack presence + uci_pdu->pdu_bit_map = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1); + uci_pdu->pucch_format = 0; // format 0 + uci_pdu->ul_cqi = 0xff; // currently not valid + uci_pdu->timing_advance = 0xffff; // currently not valid + uci_pdu->rssi = 0xffff; // currently not valid + if (pucch_pdu->sr_flag) { + //currently not supported + } + else + uci_pdu->sr = NULL; + if (pucch_pdu->bit_len_harq>0) { + uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq)); + uci_pdu->harq->num_harq = pucch_pdu->bit_len_harq; + uci_pdu->harq->harq_confidence_level = 0xff; // currently not valid + uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(uci_pdu->harq->num_harq); + for (i=0; i<uci_pdu->harq->num_harq; i++) // FIXME for non present + uci_pdu->harq->harq_list[i].harq_value = (index>>i)&0x01; + } + else + uci_pdu->harq = NULL; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index 351c4ea22a5126ef2e26dd447594210dd6f00d90..d63cef508539fcb1474ea5b7baee01abb3ad3bf8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -37,7 +37,7 @@ //#include "LAYER2/MAC/extern.h" #include "PHY/NR_UE_TRANSPORT/pucch_nr.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" - +#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -46,148 +46,9 @@ #define DEBUG_PUCCH_TX #define DEBUG_NR_PUCCH_TX #endif -//#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) - -void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, - uint32_t n_id, - uint8_t n_hop, - int nr_tti_tx, - uint8_t *u, - uint8_t *v) { - /* - * Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping - * The following variables are set by higher layers: - * - PUCCH_GroupHopping: - * - n_id: higher-layer parameter hoppingId - * - n_hop: frequency hopping index - * if intra-slot frequency hopping is disabled by the higher-layer parameter PUCCH-frequency-hopping - * n_hop=0 - * if frequency hopping is enabled by the higher-layer parameter PUCCH-frequency-hopping - * n_hop=0 for the first hop - * n_hop=1 for the second hop - */ - // depending on the value of the PUCCH_GroupHopping, we will obtain different values for u,v - //pucch_GroupHopping_t PUCCH_GroupHopping = ue->pucch_config_common_nr->pucch_GroupHopping; // from higher layers FIXME!!! - // n_id defined as per TS 38.211 subclause 6.3.2.2.1 (is given by the higher-layer parameter hoppingId) - // it is hoppingId from PUCCH-ConfigCommon: - // Cell-Specific scrambling ID for group hoppping and sequence hopping if enabled - // Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2) BIT STRING (SIZE (10)) - //uint16_t n_id = ue->pucch_config_common_nr->hoppingId; // from higher layers FIXME!!! -#ifdef DEBUG_NR_PUCCH_TX - // initialization to be removed - PUCCH_GroupHopping=neither; - n_id=10; - printf("\t\t [nr_group_sequence_hopping] initialization PUCCH_GroupHopping=%u, n_id=%u -> variable initializations TO BE REMOVED\n",PUCCH_GroupHopping,n_id); -#endif - uint8_t f_ss=0,f_gh=0; - *u=0; - *v=0; - uint32_t c_init = 0; - uint32_t x1,s; // TS 38.211 Subclause 5.2.1 - int l = 32, minShift = ((2*nr_tti_tx+n_hop)<<3); - int tmpShift =0; -#ifdef DEBUG_NR_PUCCH_TX - printf("\t\t [nr_group_sequence_hopping] calculating u,v -> "); -#endif - - if (PUCCH_GroupHopping == neither) { // PUCCH_GroupHopping 'neither' - f_ss = n_id%30; - } - - if (PUCCH_GroupHopping == enable) { // PUCCH_GroupHopping 'enabled' - c_init = floor(n_id/30); // we initialize c_init to calculate u,v according to 6.3.2.2.1 of 38.211 - s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 - for (int m=0; m<8; m++) { - while(minShift >= l) { - s = lte_gold_generic(&x1, &c_init, 0); - l = l+32; - } - - tmpShift = (minShift&((1<<5)-1)); //minShift%32; - f_gh = f_gh + ((1<<m)*((uint8_t)((s>>tmpShift)&1))); - minShift ++; - } - - f_gh = f_gh%30; - f_ss = n_id%30; - /* for (int m=0; m<8; m++){ - f_gh = f_gh + ((1<<m)*((uint8_t)((s>>(8*(2*nr_tti_tx+n_hop)+m))&1))); // Not sure we have to use nr_tti_tx FIXME!!! - } - f_gh = f_gh%30; - f_ss = n_id%30;*/ - } - - if (PUCCH_GroupHopping == disable) { // PUCCH_GroupHopping 'disabled' - c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v - s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 - f_ss = n_id%30; - l = 32, minShift = (2*nr_tti_tx+n_hop); - - while(minShift >= l) { - s = lte_gold_generic(&x1, &c_init, 0); - l = l+32; - } - - tmpShift = (minShift&((1<<5)-1)); //minShift%32; - *v = (uint8_t)((s>>tmpShift)&1); - // *v = (uint8_t)((s>>(2*nr_tti_tx+n_hop))&1); // Not sure we have to use nr_tti_tx FIXME!!! - } - - *u = (f_gh+f_ss)%30; -#ifdef DEBUG_NR_PUCCH_TX - printf("%d,%d\n",*u,*v); -#endif -} -double nr_cyclic_shift_hopping(uint32_t n_id, - uint8_t m0, - uint8_t mcs, - uint8_t lnormal, - uint8_t lprime, - int nr_tti_tx) { - /* - * Implements TS 38.211 subclause 6.3.2.2.2 Cyclic shift hopping - * - n_id: higher-layer parameter hoppingId - * - m0: provided by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift of PUCCH-F0-resource-config - * - mcs: mcs=0 except for PUCCH format 0 when it depends on information to be transmitted according to TS 38.213 subclause 9.2 - * - lnormal: lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission - * - lprime: lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] - */ - // alpha_init initialized to 2*PI/12=0.5235987756 - double alpha = 0.5235987756; - uint32_t c_init = n_id; // we initialize c_init again to calculate n_cs -#ifdef DEBUG_NR_PUCCH_TX - // initialization to be remo.ved - c_init=10; - printf("\t\t [nr_cyclic_shift_hopping] initialization c_init=%u -> variable initialization TO BE REMOVED\n",c_init); -#endif - uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 - uint8_t n_cs=0; - int l = 32, minShift = (14*8*nr_tti_tx )+ 8*(lnormal+lprime); - int tmpShift =0; -#ifdef DEBUG_NR_PUCCH_TX - printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%u -> \n",c_init); -#endif - - for (int m=0; m<8; m++) { - while(minShift >= l) { - s = lte_gold_generic(&x1, &c_init, 0); - l = l+32; - } - - tmpShift = (minShift&((1<<5)-1)); //minShift%32; - minShift ++; - n_cs = n_cs+((1<<m)*((uint8_t)((s>>tmpShift)&1))); - // calculating n_cs (Not sure we have to use nr_tti_tx FIXME!!!) - // n_cs = n_cs+((1<<m)*((uint8_t)((s>>((14*8*nr_tti_tx) + 8*(lnormal+lprime) + m))&1))); - } +//#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) - alpha = (alpha * (double)((m0+mcs+n_cs)%12)); -#ifdef DEBUG_NR_PUCCH_TX - printf("n_cs=%d -> %lf\n",n_cs,alpha); -#endif - return(alpha); -} void nr_generate_pucch0(PHY_VARS_NR_UE *ue, int32_t **txdataF, NR_DL_FRAME_PARMS *frame_parms, @@ -271,46 +132,31 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, */ //int32_t *txptr; uint32_t re_offset=0; + uint8_t l2; for (int l=0; l<nrofSymbols; l++) { - if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; - } - - if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))); - } - - if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; - } - - if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6; - } - - if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; - } + l2=l+startingSymbolIndex; + re_offset = (12*startingPRB) + frame_parms->first_carrier_offset; + if (re_offset>= frame_parms->ofdm_symbol_size) + re_offset-=frame_parms->ofdm_symbol_size; //txptr = &txdataF[0][re_offset]; for (int n=0; n<12; n++) { - if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { - // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); - } - ((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)(((int32_t)(amp) * x_n_re[(12*l)+n])>>15); - ((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)(((int32_t)(amp) * x_n_im[(12*l)+n])>>15); + ((int16_t *)&txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset])[0] = (int16_t)(((int32_t)(amp) * x_n_re[(12*l)+n])>>15); + ((int16_t *)&txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset])[1] = (int16_t)(((int32_t)(amp) * x_n_im[(12*l)+n])>>15); //((int16_t *)txptr[0][re_offset])[0] = (int16_t)((int32_t)amp * x_n_re[(12*l)+n])>>15; //((int16_t *)txptr[0][re_offset])[1] = (int16_t)((int32_t)amp * x_n_im[(12*l)+n])>>15; //txptr[re_offset] = (x_n_re[(12*l)+n]<<16) + x_n_im[(12*l)+n]; #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n", - amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,re_offset, - l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); + amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,(l2*frame_parms->ofdm_symbol_size) + re_offset, + l2,n,((int16_t *)&txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset])[0], + ((int16_t *)&txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset])[1]); #endif re_offset++; + if (re_offset>= frame_parms->ofdm_symbol_size) + re_offset-=frame_parms->ofdm_symbol_size; } } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h index e8cd147526be502ba16ab3e0e88e9c490e1c43b9..4c4847d7dec911451fe36eba8a5f4fdaf658060b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h @@ -42,46 +42,7 @@ #include "T.h" #define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) -void nr_decode_pucch1( int32_t **rxdataF, - pucch_GroupHopping_t pucch_GroupHopping, - uint32_t n_id, // hoppingID higher layer parameter - uint64_t *payload, - NR_DL_FRAME_PARMS *frame_parms, - int16_t amp, - int nr_tti_tx, - uint8_t m0, - uint8_t nrofSymbols, - uint8_t startingSymbolIndex, - uint16_t startingPRB, - uint16_t startingPRB_intraSlotHopping, - uint8_t timeDomainOCC, - uint8_t nr_bit); - -void nr_decode_pucch0( int32_t **rxdataF, - pucch_GroupHopping_t PUCCH_GroupHopping, - uint32_t n_id, //PHY_VARS_gNB *gNB, generally rxdataf is in gNB->common_vars - uint64_t *payload, - NR_DL_FRAME_PARMS *frame_parms, - int16_t amp, - int nr_tti_tx, - uint8_t m0, // should come from resource set - uint8_t nrofSymbols, // should come from resource set - uint8_t startingSymbolIndex, // should come from resource set - uint16_t startingPRB, // should come from resource set - uint8_t nr_bit); -void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, - uint32_t n_id, - uint8_t n_hop, - int nr_tti_tx, - uint8_t *u, - uint8_t *v); -double nr_cyclic_shift_hopping(uint32_t n_id, - uint8_t m0, - uint8_t mcs, - uint8_t lnormal, - uint8_t lprime, - int nr_tti_tx); void nr_generate_pucch0(PHY_VARS_NR_UE *ue, int32_t **txdataF, NR_DL_FRAME_PARMS *frame_parms, @@ -139,8 +100,8 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, uint8_t occ_index_format4); // tables for mcs values for different payloads - static const uint8_t table1_mcs[]={0,3,6,9}; - static const uint8_t table2_mcs[]={0,1,3,4,6,7,9,10}; + static const uint8_t table1_mcs[]={0,6,3,9}; + static const uint8_t table2_mcs[]={0,3,9,6,1,4,10,7}; /* * The following tables implement TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (rows->u {0,1,..,29} / columns->n {0,1,...,M_ZC-1) diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index b5a24ca793861953eab7ce384cdbda50e469c0a6..5175cd88115e2918c4911539a61f1fa320d1eb23 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -623,23 +623,12 @@ typedef struct PHY_VARS_gNB_s { NR_UL_IND_t UL_INFO; pthread_mutex_t UL_INFO_mutex; - /// NFAPI RX ULSCH information - nfapi_rx_indication_pdu_t rx_pdu_list[NFAPI_RX_IND_MAX_PDU]; - /// NFAPI RX ULSCH CRC information - nfapi_crc_indication_pdu_t crc_pdu_list[NFAPI_CRC_IND_MAX_PDU]; - /// NFAPI HARQ information - nfapi_harq_indication_pdu_t harq_pdu_list[NFAPI_HARQ_IND_MAX_PDU]; - /// NFAPI SR information - nfapi_sr_indication_pdu_t sr_pdu_list[NFAPI_SR_IND_MAX_PDU]; - /// NFAPI CQI information - nfapi_cqi_indication_pdu_t cqi_pdu_list[NFAPI_CQI_IND_MAX_PDU]; - /// NFAPI CQI information (raw component) - nfapi_cqi_indication_raw_pdu_t cqi_raw_pdu_list[NFAPI_CQI_IND_MAX_PDU]; - /// NFAPI PRACH information + /// NFAPI PRACH information (to be removed) nfapi_preamble_pdu_t preamble_list[MAX_NUM_RX_PRACH_PREAMBLES]; //Sched_Rsp_t Sched_INFO; nfapi_nr_ul_tti_request_t UL_tti_req; + nfapi_nr_uci_indication_t uci_indication; nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu; nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 292c8106aed835e0d5dc884d5197a4e6839583fc..d9d080c3d50c1ec7b4d56207da2181c987c82f5c 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -28,6 +28,7 @@ #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_ESTIMATION/nr_ul_estimation.h" +#include "PHY/NR_UE_TRANSPORT/pucch_nr.h" #include "SCHED/sched_eNB.h" #include "sched_nr.h" #include "SCHED/sched_common_extern.h" @@ -285,6 +286,7 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_ nfapi_rx_indication_pdu_t *pdu; + int timing_advance_update; int sync_pos; @@ -393,35 +395,63 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { - nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req; - int num_pusch_pdu = UL_tti_req->n_pdus; - - LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d, num_pusch_pdu %d\n",frame_rx,slot_rx,num_pusch_pdu); + nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req; + int num_pdus = UL_tti_req->n_pdus; gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0; - for (int i = 0; i < num_pusch_pdu; i++) { + nfapi_nr_uci_indication_t *uci_indication = &gNB->uci_indication; + uci_indication->sfn = frame_rx; + uci_indication->slot = slot_rx; + uci_indication->num_ucis = 0; + + LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d, num_pdus %d\n",frame_rx,slot_rx,num_pdus); + + for (int i = 0; i < num_pdus; i++) { switch (UL_tti_req->pdus_list[i].pdu_type) { - case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:{ - LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx); + case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: + LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx); - nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; - nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu); - - uint8_t ULSCH_id = find_nr_ulsch(pusch_pdu->rnti,gNB,SEARCH_EXIST); - uint8_t harq_pid = pusch_pdu->pusch_data.harq_process_id; - uint8_t symbol_start = pusch_pdu->start_symbol_index; - uint8_t symbol_end = symbol_start + pusch_pdu->nr_of_symbols; - - for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { - nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); - } - //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1); - //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1); - nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); - nr_fill_rx_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); // indicate SDU to MAC - nr_fill_crc_indication(gNB, frame_rx, slot_rx, ULSCH_id, 0); - } + nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[i].pusch_pdu; + nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu); + + uint8_t ULSCH_id = find_nr_ulsch(pusch_pdu->rnti,gNB,SEARCH_EXIST); + uint8_t harq_pid = pusch_pdu->pusch_data.harq_process_id; + uint8_t symbol_start = pusch_pdu->start_symbol_index; + uint8_t symbol_end = symbol_start + pusch_pdu->nr_of_symbols; + + for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { + nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); + } + //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1); + //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1); + nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); + nr_fill_rx_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); // indicate SDU to MAC + break; + case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: + LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE\n",frame_rx,slot_rx); + + nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[i].pucch_pdu; + switch (pucch_pdu->format_type) { + case 0: + uci_indication->uci_list[uci_indication->num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE; + uci_indication->uci_list[uci_indication->num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t); + nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &uci_indication->uci_list[uci_indication->num_ucis].pucch_pdu_format_0_1; + + nr_decode_pucch0(gNB->common_vars.rxdataF, + &gNB->frame_parms, + slot_rx, + uci_pdu_format0, + pucch_pdu); + + uci_indication->num_ucis += 1; + break; + case 1: + break; + default: + AssertFatal(1==0,"Only PUCCH format 0 and 1 are currently supported\n"); + } + break; } } } diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 445c45693ed7ce5c46a52cd7021f9101adc0a29c..ecba9de2d492b0436c2680eac225373e73fb5a20 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -87,12 +87,13 @@ int main(int argc, char **argv) uint8_t nacktoack_flag=0; int16_t amp=0x7FFF; int nr_tti_tx=0; - uint64_t actual_payload=0,payload_received;//payload bits b7b6...b2b1b0 where b7..b3=0 b2b1=HARQ b0 is SR. payload maximum value is 7 for pucch format 0 + uint64_t actual_payload=0,payload_received; int nr_bit=1; // maximum value possible is 2 uint8_t m0=0;// higher layer paramater initial cyclic shift uint8_t nrofSymbols=1; //number of OFDM symbols can be 1-2 for format 1 uint8_t startingSymbolIndex=0; // resource allocated see 9.2.1, 38.213 for more info.should be actually present in the resource set provided uint16_t startingPRB=0,startingPRB_intraSlotHopping=0; //PRB number not sure see 9.2.1, 38.213 for more info. Should be actually present in the resource set provided + uint32_t hoppingId=40; uint8_t timeDomainOCC=0; SCM_t channel_model=AWGN;//Rayleigh1_anticorr; @@ -114,7 +115,7 @@ int main(int argc, char **argv) logInit(); set_glog(loglvl); - while ((c = getopt (argc, argv, "f:hA:f:g:i:P:b:T:n:o:s:S:x:y:z:N:F:GR:IL")) != -1) { + while ((c = getopt (argc, argv, "f:hA:f:g:i:I:P:B:b:T:m:n:r:o:s:S:x:y:z:N:F:GR:IL")) != -1) { switch (c) { case 'f': //write_output_file=1; @@ -257,12 +258,24 @@ int main(int argc, char **argv) case 'i': nrofSymbols=(uint8_t)atoi(optarg); break; + case 'I': + startingSymbolIndex=(uint8_t)atoi(optarg); + break; + case 'r': + startingPRB=atoi(optarg); + break; case 'P': format=atoi(optarg); break; + case 'm': + m0=atoi(optarg); + break; case 'b': nr_bit=atoi(optarg); break; + case 'B': + actual_payload=atoi(optarg); + break; case 'T': nacktoack_flag=(uint8_t)atoi(optarg); target_error_rate=0.001; @@ -292,8 +305,12 @@ int main(int argc, char **argv) printf("-f Output filename (.txt format) for Pe/SNR results\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); printf("-i Enter number of ofdm symbols for pucch\n"); + printf("-I Starting symbol index for pucch\n"); + printf("-r PUCCCH starting PRB\n"); printf("-P Enter the format of PUCCH\n"); printf("-b number of HARQ bits (1-2)\n"); + printf("-B payload to be transmitted on PUCCH\n"); + printf("-m initial cyclic shift m0\n"); printf("-T to check nacktoack miss for format 1"); exit (-1); break; @@ -304,6 +321,16 @@ int main(int argc, char **argv) printf("Initializing gNodeB for mu %d, N_RB_DL %d\n",mu,N_RB_DL); + if((format!=0) && (format!=1)){ + printf("PUCCH format %d not supported\n",format); + exit(0); + } + + AssertFatal((nr_bit<3)&&(actual_payload<4),"Only format 0 and 1 currently supported. 2 bits max supported"); + + if (nr_bit==1) actual_payload = actual_payload&1; + + printf("Transmitted payload is %ld\n",actual_payload); RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *)); RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB)); @@ -398,6 +425,7 @@ int main(int argc, char **argv) //configure UE UE = malloc(sizeof(PHY_VARS_NR_UE)); memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); + UE->pucch_config_common_nr->hoppingId = hoppingId; //phy_init_nr_top(UE); //called from init_nr_ue_signal UE->perfect_ce = 0; @@ -414,35 +442,15 @@ int main(int argc, char **argv) startingPRB_intraSlotHopping=N_RB_DL-1; pucch_GroupHopping_t PUCCH_GroupHopping=UE->pucch_config_common_nr->pucch_GroupHopping; uint32_t n_id=UE->pucch_config_common_nr->hoppingId; - if((format!=0) && (format!=1)){ - printf("format not supported\n"); - exit(0); + + if(format==0){ + // for now we are not considering SR just HARQ-ACK + if(nr_bit==1) + mcs=table1_mcs[actual_payload]; + else if(nr_bit==2) + mcs=table2_mcs[actual_payload]; } - if(nacktoack_flag==0){ - if(format==0){ - if(nr_bit==1){ - actual_payload=2; - mcs=table1_mcs[actual_payload]; - } - else if(nr_bit==2){ - actual_payload=6; - mcs=table2_mcs[actual_payload]; - } - else{ - printf("Number of HARQ bits possible is 1-2\n"); - exit(0); - } - } - else { - if(nr_bit==1) - actual_payload=1; - else if(nr_bit==2) - actual_payload=3; - else{ - printf("number of bits carried by PUCCH format1 is 1-2\n"); - } - } - } + for(SNR=snr0;SNR<=snr1;SNR=SNR+1){ ack_nack_errors=0; n_errors = 0; @@ -488,6 +496,7 @@ int main(int argc, char **argv) } n_errors=((actual_payload^payload_received)&1)+(((actual_payload^payload_received)&2)>>1)+(((actual_payload^payload_received)&4)>>2)+n_errors; } + printf("Decoded payload is %ld\n",payload_received); printf("SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,n_errors); if((float)ack_nack_errors/(float)(nr_bit*n_trials)<=target_error_rate){ printf("PUCCH test OK\n"); diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h index 82873f22b4bcdbf8ab68b3ca73e023c12b91a832..4c5da80764c98b150d2c94e7c52af54756126df0 100644 --- a/openair2/GNB_APP/RRC_nr_paramsvalues.h +++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h @@ -128,18 +128,18 @@ #define GNB_CONFIG_STRING_RARESPONSEWINDOW "ra_ResponseWindow" #define GNB_CONFIG_STRING_SSBPERRACHOCCASIONANDCBPREAMBLESPERSSBPR "ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR" #define GNB_CONFIG_STRING_SSBPERRACHOCCASIONANDCBPREAMBLESPERSSB "ssb_perRACH_OccasionAndCB_PreamblesPerSSB" -#define GNB_CONFIG_STRING_RACONTENTIONRESOLUTIONTIMER "ra_ContentionResolutionTimer" -#define GNB_CONFIG_STRING_RSRPTHRESHOLDSSB "rsrp_ThresholdSSB" -#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR "prach_RootSequenceIndex_PR" -#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX "prach_RootSequenceIndex" -#define GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING "msg1_SubcarrierSpacing" -#define GNB_CONFIG_STRING_RESTRICTEDSETCONFIG "restrictedSetConfig" -#define GNB_CONFIG_STRING_PUSCHTIMEDOMAINALLOCATIONLIST "puschTimeDomainAllocationList" -#define GNB_CONFIG_STRING_MSG3DELTAPREABMLE "msg3_DeltaPreamble" -#define GNB_CONFIG_STRING_P0NOMINALWITHGRANT "p0_NominalWithGrant" -#define GNB_CONFIG_STRING_PUCCHGROUPHOPPING "pucchGroupHopping" -#define GNB_CONFIG_STRING_HOPPINGID "hoppingId" -#define GNB_CONFIG_STRING_P0NOMINAL "p0_nominal" +#define GNB_CONFIG_STRING_RACONTENTIONRESOLUTIONTIMER "ra_ContentionResolutionTimer" +#define GNB_CONFIG_STRING_RSRPTHRESHOLDSSB "rsrp_ThresholdSSB" +#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR "prach_RootSequenceIndex_PR" +#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX "prach_RootSequenceIndex" +#define GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING "msg1_SubcarrierSpacing" +#define GNB_CONFIG_STRING_RESTRICTEDSETCONFIG "restrictedSetConfig" +#define GNB_CONFIG_STRING_PUSCHTIMEDOMAINALLOCATIONLIST "puschTimeDomainAllocationList" +#define GNB_CONFIG_STRING_MSG3DELTAPREABMLE "msg3_DeltaPreamble" +#define GNB_CONFIG_STRING_P0NOMINALWITHGRANT "p0_NominalWithGrant" +#define GNB_CONFIG_STRING_PUCCHGROUPHOPPING "pucchGroupHopping" +#define GNB_CONFIG_STRING_HOPPINGID "hoppingId" +#define GNB_CONFIG_STRING_P0NOMINAL "p0_nominal" #define GNB_CONFIG_STRING_INITIALULBWPK2_0 "initialULBWPk2_0" #define GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_0 "initialULBWPmappingType_0" #define GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_0 "initialULBWPstartSymbolAndLength_0" diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index c911fbd56a6c6aa5d53048131067815e014b4d0b..b5fdea6760450ecaf8f2c89d0c0f0a3886e4e19b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -51,7 +51,6 @@ extern RAN_CONTEXT_t RC; extern void mac_top_init_gNB(void); extern uint8_t nfapi_mode; - void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) { nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0]; @@ -283,7 +282,6 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm else LOG_I(PHY,"TDD has been properly configurated\n"); } - /* // PDCCH-ConfigCommon cfg->pdcch_config.controlResourceSetZero.value = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 90c56c2ef592fbcbb87c7a474c52acc13dde8e43..8dcf7cd073597e2e4b59b5b89eb8c1b2853a5501 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -61,6 +61,8 @@ uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; +uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160}; + void clear_nr_nfapi_information(gNB_MAC_INST * gNB, int CC_idP, frame_t frameP, @@ -299,6 +301,67 @@ void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) } */ +void nr_schedule_pucch(int Mod_idP, + int UE_id, + frame_t frameP, + sub_frame_t slotP) { + + uint16_t O_uci; + uint16_t O_ack; + uint8_t SR_flag = 0; // no SR in PUCCH implemented for now + NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; + NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; + AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n",UE_id); + + NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + int bwp_id=1; + NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]; + nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0]; + + NR_sched_pucch *curr_pucch = UE_list->UE_sched_ctrl[UE_id].sched_pucch; + NR_sched_pucch *temp_pucch; + int release_pucch = 0; + + if (curr_pucch != NULL) { + if ((frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) { + UL_tti_req->SFN = frameP; + UL_tti_req->Slot = slotP; + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE; + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t); + nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pucch_pdu; + memset(pucch_pdu,0,sizeof(nfapi_nr_pucch_pdu_t)); + UL_tti_req->n_pdus+=1; + O_ack = curr_pucch->dai_c; + O_uci = O_ack; // for now we are just sending acknacks in pucch + + nr_configure_pucch(pucch_pdu, + scc, + ubwp, + curr_pucch->resource_indicator, + O_uci, + O_ack, + SR_flag); + + release_pucch = 1; + } + } + + if (release_pucch) { + temp_pucch = UE_list->UE_sched_ctrl[UE_id].sched_pucch; + UE_list->UE_sched_ctrl[UE_id].sched_pucch = UE_list->UE_sched_ctrl[UE_id].sched_pucch->next_sched_pucch; + free(temp_pucch); + } + +} + +bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot){ + + if((bitmap>>slot)&0x01) + return true; + else + return false; +} + void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame_rxP, sub_frame_t slot_rxP, @@ -308,11 +371,24 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, //printf("gNB_dlsch_ulsch_scheduler frameRX %d slotRX %d frameTX %d slotTX %d\n",frame_rxP,slot_rxP,frame_txP,slot_txP); protocol_ctxt_t ctxt; - int CC_id, UE_id = 0; + + int CC_id; + int UE_id; + uint64_t *dlsch_in_slot_bitmap=NULL; + uint64_t *ulsch_in_slot_bitmap=NULL; + NR_sched_pucch *pucch_sched = (NR_sched_pucch*) malloc(sizeof(NR_sched_pucch)); + + if (get_softmodem_params()->phy_test) UE_id=0; + gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_UE_list_t *UE_list = &gNB->UE_list; - UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - NR_COMMON_channels_t *cc = gNB->common_channels; + NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + int num_slots_per_tdd = (nr_slots_per_frame[*scc->ssbSubcarrierSpacing])>>(7-scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); + + //nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = NULL; + start_meas(&RC.nrmac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN); @@ -323,73 +399,99 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, RC.nrmac[module_idP]->frame = frame_rxP; RC.nrmac[module_idP]->slot = slot_rxP; + if (get_softmodem_params()->phy_test) { + dlsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch + ulsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].ulsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains ulsch + + // hardcoding dlsch to be in slot 1 + if (!(slot_txP%num_slots_per_tdd)) { + if(slot_txP==0) + *dlsch_in_slot_bitmap = 0x02; + else + *dlsch_in_slot_bitmap = 0x00; + } + + // hardcoding ulsch to be in slot 8 + if (!(slot_rxP%num_slots_per_tdd)) { + if(slot_rxP==0) + *ulsch_in_slot_bitmap = 0x100; + else + *ulsch_in_slot_bitmap = 0x00; + } + } + // Check if there are downlink symbols in the slot, if (is_nr_DL_slot(cc->ServingCellConfigCommon,slot_txP)) { - memset(RC.nrmac[module_idP]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int)); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - //mbsfn_status[CC_id] = 0; + memset(RC.nrmac[module_idP]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int)); + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + //mbsfn_status[CC_id] = 0; - // clear vrb_maps - memset(cc[CC_id].vrb_map, 0, 100); - memset(cc[CC_id].vrb_map_UL, 0, 100); + // clear vrb_maps + memset(cc[CC_id].vrb_map, 0, 100); + memset(cc[CC_id].vrb_map_UL, 0, 100); - clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP); - } + clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP); + } - // refresh UE list based on UEs dropped by PHY in previous subframe - /* - for (i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (UE_list->active[i]) { + // refresh UE list based on UEs dropped by PHY in previous subframe + /* + for (i = 0; i < MAX_MOBILES_PER_GNB; i++) { + if (UE_list->active[i]) { - nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id]; + nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id]; - rnti = 0;//UE_RNTI(module_idP, i); - CC_id = 0;//UE_PCCID(module_idP, i); + rnti = 0;//UE_RNTI(module_idP, i); + CC_id = 0;//UE_PCCID(module_idP, i); - } //END if (UE_list->active[i]) - } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++) - */ - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES,NOT_A_RNTI, frame_txP, slot_txP,module_idP); + } //END if (UE_list->active[i]) + } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++) + */ + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES,NOT_A_RNTI, frame_txP, slot_txP,module_idP); - // This schedules MIB - if((slot_txP == 0) && (frame_txP & 7) == 0){ - schedule_nr_mib(module_idP, frame_txP, slot_txP); - } + // This schedules MIB + if((slot_txP == 0) && (frame_txP & 7) == 0){ + schedule_nr_mib(module_idP, frame_txP, slot_txP); + } - // TbD once RACH is available, start ta_timer when UE is connected - if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--; - - if (ue_sched_ctl->ta_timer == 0) { - gNB->ta_command = ue_sched_ctl->ta_update; - /* if time is up, then set the timer to not send it for 5 frames - // regardless of the TA value */ - ue_sched_ctl->ta_timer = 100; - /* reset ta_update */ - ue_sched_ctl->ta_update = 31; - /* MAC CE flag indicating TA length */ - gNB->ta_len = 2; - } + // TbD once RACH is available, start ta_timer when UE is connected + if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--; + + if (ue_sched_ctl->ta_timer == 0) { + gNB->ta_command = ue_sched_ctl->ta_update; + /* if time is up, then set the timer to not send it for 5 frames + // regardless of the TA value */ + ue_sched_ctl->ta_timer = 100; + /* reset ta_update */ + ue_sched_ctl->ta_update = 31; + /* MAC CE flag indicating TA length */ + gNB->ta_len = 2; + } - // Phytest scheduling - if (get_softmodem_params()->phy_test && slot_txP==1){ - nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP,NULL); - // resetting ta flag - gNB->ta_len = 0; - } + // Phytest scheduling + if (get_softmodem_params()->phy_test && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot_txP%num_slots_per_tdd))) { + nr_update_pucch_scheduling(module_idP, UE_id, frame_txP, slot_txP, num_slots_per_tdd,pucch_sched); + nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP, pucch_sched, NULL); + // resetting ta flag + gNB->ta_len = 0; + } - /* - // Allocate CCEs for good after scheduling is done - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) - allocate_CCEs(module_idP, CC_id, subframeP, 0); - */ + /* + // Allocate CCEs for good after scheduling is done + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) + allocate_CCEs(module_idP, CC_id, subframeP, 0); + */ } //is_nr_DL_slot if (is_nr_UL_slot(cc->ServingCellConfigCommon,slot_rxP)) { - if (get_softmodem_params()->phy_test && slot_rxP==8){ - nr_schedule_uss_ulsch_phytest(module_idP, frame_rxP, slot_rxP); + + if (get_softmodem_params()->phy_test){ + nr_schedule_pucch(module_idP, UE_id, frame_rxP, slot_rxP); + if (is_xlsch_in_slot(*ulsch_in_slot_bitmap,slot_rxP%num_slots_per_tdd)){ + nr_schedule_uss_ulsch_phytest(module_idP, frame_rxP, slot_rxP); + } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 0c58ba325a5877ccff6dbd234e658c1806c11993..37f45e42d508bfc2338ffddd74900d4f46242ad8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -252,20 +252,25 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, int configure_fapi_dl_pdu(int Mod_idP, int *CCEIndex, nfapi_nr_dl_tti_request_body_t *dl_req, + NR_sched_pucch *pucch_sched, uint8_t *mcsIndex, uint16_t *rbSize, uint16_t *rbStart) { + gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP]; NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu; nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu; - int TBS, bwp_id = 1, UE_id = 0; - NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; + int TBS; + int bwp_id=1; + int UE_id = 0; + + NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, @@ -351,10 +356,10 @@ int configure_fapi_dl_pdu(int Mod_idP, dci_pdu_rel15[0].ndi = 1; dci_pdu_rel15[0].rv = 0; dci_pdu_rel15[0].harq_pid = 0; - dci_pdu_rel15[0].dai = 2; + dci_pdu_rel15[0].dai = (pucch_sched->dai_c-1)&3; dci_pdu_rel15[0].tpc = 2; - dci_pdu_rel15[0].pucch_resource_indicator = 7; - dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator = 7; + dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator; + dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator = pucch_sched->timing_indicator; LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", dci_pdu_rel15[0].frequency_domain_assignment, @@ -491,6 +496,7 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP, void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, + NR_sched_pucch *pucch_sched, nfapi_nr_dl_tti_pdsch_pdu_rel15_t *dlsch_config){ LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest \n"); @@ -537,7 +543,8 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, TBS_bytes = configure_fapi_dl_pdu(module_idP, CCEIndices, - dl_req, + dl_req, + pucch_sched, dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); @@ -719,12 +726,12 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, UL_tti_req->SFN = frameP; UL_tti_req->Slot = slotP; - UL_tti_req->n_pdus = 1; - UL_tti_req->pdus_list[0].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; - UL_tti_req->pdus_list[0].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); - nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); + nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu; memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t)); - + UL_tti_req->n_pdus+=1; + LOG_D(MAC, "Scheduling UE specific PUSCH\n"); //UL_tti_req = &nr_mac->UL_tti_req[CC_id]; /* @@ -821,7 +828,6 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, 1, // ue-specific, scc, bwp); - dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 4e8ef2dd44807ea20a471a223b15184f67bbdf96..53414562d73524809efefaa96abe1b072ceeb52c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -563,14 +563,199 @@ uint8_t getNRBG(uint16_t bwp_size, uint16_t bwp_start, long rbg_size_config) { return (uint8_t)ceil((bwp_size+(bwp_start % rbg_size))/rbg_size); } + +// This function configures pucch pdu fapi structure +void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, + NR_ServingCellConfigCommon_t *scc, + NR_BWP_Uplink_t *bwp, + uint8_t pucch_resource, + uint16_t O_uci, + uint16_t O_ack, + uint8_t SR_flag) { + + NR_PUCCH_Config_t *pucch_Config; + NR_PUCCH_Resource_t *pucchres; + NR_PUCCH_ResourceSet_t *pucchresset; + NR_PUCCH_FormatConfig_t *pucchfmt; + NR_PUCCH_ResourceId_t *resource_id = NULL; + + long *id0 = NULL; + int n_list, n_set; + uint16_t N2,N3; + int res_found = 0; + + pucch_pdu->bit_len_harq = O_ack; + + if (bwp) { // This is not the InitialBWP + + NR_PUSCH_Config_t *pusch_Config = bwp->bwp_Dedicated->pusch_Config->choice.setup; + long *pusch_id = pusch_Config->dataScramblingIdentityPUSCH; + + if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL) + id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->transformPrecodingDisabled->scramblingID0; + if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB != NULL) + id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->transformPrecodingDisabled->scramblingID0; + + // hop flags and hopping id are valid for any BWP + switch (bwp->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_GroupHopping){ + case 0 : + // if neither, both disabled + pucch_pdu->group_hop_flag = 0; + pucch_pdu->sequence_hop_flag = 0; + break; + case 1 : + // if enable, group enabled + pucch_pdu->group_hop_flag = 1; + pucch_pdu->sequence_hop_flag = 0; + break; + case 2 : + // if disable, sequence disabled + pucch_pdu->group_hop_flag = 0; + pucch_pdu->sequence_hop_flag = 1; + break; + default: + AssertFatal(1==0,"Group hopping flag %ld undefined (0,1,2) \n", bwp->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_GroupHopping); + } + + if (bwp->bwp_Common->pucch_ConfigCommon->choice.setup->hoppingId != NULL) + pucch_pdu->hopping_id = *bwp->bwp_Common->pucch_ConfigCommon->choice.setup->hoppingId; + else + pucch_pdu->hopping_id = *scc->physCellId; + + pucch_pdu->bwp_size = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pucch_pdu->bwp_start = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pucch_pdu->subcarrier_spacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; + pucch_pdu->cyclic_prefix = (bwp->bwp_Common->genericParameters.cyclicPrefix==NULL) ? 0 : *bwp->bwp_Common->genericParameters.cyclicPrefix; + + pucch_Config = bwp->bwp_Dedicated->pucch_Config->choice.setup; + + AssertFatal(pucch_Config->resourceSetToAddModList!=NULL, + "PUCCH resourceSetToAddModList is null\n"); + + n_set = pucch_Config->resourceSetToAddModList->list.count; + AssertFatal(n_set>0,"PUCCH resourceSetToAddModList is empty\n"); + + N2 = 2; + // procedure to select pucch resource id from resource sets according to + // number of uci bits and pucch resource indicator pucch_resource + // ( see table 9.2.3.2 in 38.213) + for (int i=0; i<n_set; i++) { + pucchresset = pucch_Config->resourceSetToAddModList->list.array[i]; + n_list = pucchresset->resourceList.list.count; + if (pucchresset->pucch_ResourceSetId == 0 && O_uci<3) { + if (pucch_resource < n_list) + resource_id = pucchresset->resourceList.list.array[pucch_resource]; + else + AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci); + } + else { + N3 = pucchresset->maxPayloadMinus1!= NULL ? *pucchresset->maxPayloadMinus1 : 1706; + if (N2<O_uci && N3>O_uci) { + if (pucch_resource < n_list) + resource_id = pucchresset->resourceList.list.array[pucch_resource]; + else + AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci); + } + else N2 = N3; + } + } + + AssertFatal(resource_id!=NULL,"Couldn-t find any matching PUCCH resource in the PUCCH resource sets"); + + AssertFatal(pucch_Config->resourceToAddModList!=NULL, + "PUCCH resourceToAddModList is null\n"); + + n_list = pucch_Config->resourceToAddModList->list.count; + AssertFatal(n_list>0,"PUCCH resourceToAddModList is empty\n"); + + // going through the list of PUCCH resources to find the one indexed by resource_id + for (int i=0; i<n_list; i++) { + pucchres = pucch_Config->resourceToAddModList->list.array[i]; + if (pucchres->pucch_ResourceId == *resource_id) { + res_found = 1; + pucch_pdu->prb_start = pucchres->startingPRB; + // FIXME why there is only one frequency hopping flag + // what about inter slot frequency hopping? + pucch_pdu->freq_hop_flag = pucchres->intraSlotFrequencyHopping!= NULL ? 1 : 0; + pucch_pdu->second_hop_prb = pucchres->secondHopPRB!= NULL ? *pucchres->secondHopPRB : 0; + switch(pucchres->format.present) { + case NR_PUCCH_Resource__format_PR_format0 : + pucch_pdu->format_type = 0; + pucch_pdu->initial_cyclic_shift = pucchres->format.choice.format0->initialCyclicShift; + pucch_pdu->nr_of_symbols = pucchres->format.choice.format0->nrofSymbols; + pucch_pdu->start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex; + pucch_pdu->sr_flag = SR_flag; + break; + case NR_PUCCH_Resource__format_PR_format1 : + pucch_pdu->format_type = 1; + pucch_pdu->initial_cyclic_shift = pucchres->format.choice.format1->initialCyclicShift; + pucch_pdu->nr_of_symbols = pucchres->format.choice.format1->nrofSymbols; + pucch_pdu->start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex; + pucch_pdu->time_domain_occ_idx = pucchres->format.choice.format1->timeDomainOCC; + pucch_pdu->sr_flag = SR_flag; + break; + case NR_PUCCH_Resource__format_PR_format2 : + pucch_pdu->format_type = 2; + pucch_pdu->nr_of_symbols = pucchres->format.choice.format2->nrofSymbols; + pucch_pdu->start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex; + pucch_pdu->prb_size = pucchres->format.choice.format2->nrofPRBs; + pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId; + pucch_pdu->dmrs_scrambling_id = id0!= NULL ? *id0 : *scc->physCellId; + break; + case NR_PUCCH_Resource__format_PR_format3 : + pucch_pdu->format_type = 3; + pucch_pdu->nr_of_symbols = pucchres->format.choice.format3->nrofSymbols; + pucch_pdu->start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex; + pucch_pdu->prb_size = pucchres->format.choice.format3->nrofPRBs; + pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId; + if (pucch_Config->format3 == NULL) { + pucch_pdu->pi_2bpsk = 0; + pucch_pdu->add_dmrs_flag = 0; + } + else { + pucchfmt = pucch_Config->format3->choice.setup; + pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ? 1 : 0; + pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ? 1 : 0; + } + break; + case NR_PUCCH_Resource__format_PR_format4 : + pucch_pdu->format_type = 4; + pucch_pdu->nr_of_symbols = pucchres->format.choice.format4->nrofSymbols; + pucch_pdu->start_symbol_index = pucchres->format.choice.format4->startingSymbolIndex; + pucch_pdu->pre_dft_occ_len = pucchres->format.choice.format4->occ_Length; + pucch_pdu->pre_dft_occ_idx = pucchres->format.choice.format4->occ_Index; + pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId; + if (pucch_Config->format3 == NULL) { + pucch_pdu->pi_2bpsk = 0; + pucch_pdu->add_dmrs_flag = 0; + } + else { + pucchfmt = pucch_Config->format3->choice.setup; + pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ? 1 : 0; + pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ? 1 : 0; + } + break; + default : + AssertFatal(1==0,"Undefined PUCCH format \n"); + } + } + } + AssertFatal(res_found==1,"No PUCCH resource found corresponding to id %ld\n",*resource_id); + } + else { // this is for InitialBWP + AssertFatal(1==0,"Fill in InitialBWP PUCCH configuration\n"); + } + +} + + void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup, nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, - int *rnti_types - ) { + int *rnti_types) { NR_PDSCH_Config_t *pdsch_config = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup; uint16_t N_RB = pdcch_pdu_rel15->BWPSize; @@ -1143,6 +1328,171 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ return -1; } + +void get_pdsch_to_harq_feedback(int Mod_idP, + int UE_id, + NR_SearchSpace__searchSpaceType_PR ss_type, + uint8_t *pdsch_to_harq_feedback) { + + int bwp_id=1; + NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; + NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; + NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]; + + NR_SearchSpace_t *ss; + + // common search type uses DCI format 1_0 + if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { + for (int i=0; i<8; i++) + pdsch_to_harq_feedback[i] = i+1; + } + else { + // searching for a ue specific search space + int found=0; + + for (int i=0;i<bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) { + ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; + AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n"); + AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n"); + if (ss->searchSpaceType->present == ss_type) { + found=1; + break; + } + } + AssertFatal(found==1,"Couldn't find a ue specific searchspace\n"); + if (ss->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_0_And_1_0) { + for (int i=0; i<8; i++) + pdsch_to_harq_feedback[i] = i+1; + } + else { + if(ubwp->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK != NULL) + pdsch_to_harq_feedback = (uint8_t *)ubwp->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK; + else + AssertFatal(found==1,"There is no allocated dl_DataToUL_ACK for pdsch to harq feedback\n"); + } + } +} + + +// function to update pucch scheduling parameters in UE list when a USS DL is scheduled +void nr_update_pucch_scheduling(int Mod_idP, + int UE_id, + frame_t frameP, + sub_frame_t slotP, + int slots_per_tdd, + NR_sched_pucch *sched_pucch) { + + NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; + NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; + int first_ul_slot_tdd,k; + NR_sched_pucch *curr_pucch; + uint8_t pdsch_to_harq_feedback[8]; + int found = 0; + int i = 0; + int nr_ulmix_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; + if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0) + nr_ulmix_slots++; + + // this is hardcoded for now as ue specific + NR_SearchSpace__searchSpaceType_PR ss_type = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + get_pdsch_to_harq_feedback(Mod_idP,UE_id,ss_type,pdsch_to_harq_feedback); + + // if the list of pucch to be scheduled is empty + if (UE_list->UE_sched_ctrl[UE_id].sched_pucch == NULL) { + sched_pucch->frame = frameP; + sched_pucch->next_sched_pucch = NULL; + sched_pucch->dai_c = 1; + sched_pucch->resource_indicator = 0; // in phytest with only 1 UE we are using just the 1st resource + if ( nr_ulmix_slots > 0 ) { + // first pucch occasion in first UL or MIXED slot + first_ul_slot_tdd = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots; + for (k=0; k<nr_ulmix_slots; k++) { // for each possible UL or mixed slot + while (i<8 && found == 0) { // look if timing indicator is among allowed values + if (pdsch_to_harq_feedback[i]==(first_ul_slot_tdd+k)-(slotP % slots_per_tdd)) + found = 1; + if (found == 0) i++; + } + if (found == 1) break; + } + if (found == 1) { + // computing slot in which pucch is scheduled + sched_pucch->ul_slot = first_ul_slot_tdd + k + (slotP - (slotP % slots_per_tdd)); + sched_pucch->timing_indicator = pdsch_to_harq_feedback[i]; + } + else + AssertFatal(1==0,"No Uplink slot available in accordance to allowed timing indicator\n"); + } + else + AssertFatal(1==0,"No Uplink Slots in this Frame\n"); + + UE_list->UE_sched_ctrl[UE_id].sched_pucch = sched_pucch; + } + else { // to be tested + curr_pucch = UE_list->UE_sched_ctrl[UE_id].sched_pucch; + if (curr_pucch->dai_c<11) { // we are scheduling at most 11 harq-ack in the same pucch + while (i<8 && found == 0) { // look if timing indicator is among allowed values for current pucch + if (pdsch_to_harq_feedback[i]==(curr_pucch->ul_slot % slots_per_tdd)-(slotP % slots_per_tdd)) + found = 1; + if (found == 0) i++; + } + if (found == 1) { // scheduling this harq-ack in current pucch + sched_pucch = curr_pucch; + sched_pucch->dai_c = 1 + sched_pucch->dai_c; + sched_pucch->timing_indicator = pdsch_to_harq_feedback[i]; + } + } + if (curr_pucch->dai_c==11 || found == 0) { // if current pucch is full or no timing indicator allowed + // look for pucch occasions in other UL of mixed slots + for (k=scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots; k<slots_per_tdd; k++) { // for each possible UL or mixed slot + if (k!=(curr_pucch->ul_slot % slots_per_tdd)) { // skip current scheduled slot (already checked) + i = 0; + while (i<8 && found == 0) { // look if timing indicator is among allowed values + if (pdsch_to_harq_feedback[i]==k-(slotP % slots_per_tdd)) + found = 1; + if (found == 0) i++; + } + if (found == 1) { + if (k<(curr_pucch->ul_slot % slots_per_tdd)) { // we need to add a pucch occasion before current pucch + sched_pucch->frame = frameP; + sched_pucch->ul_slot = k + (slotP - (slotP % slots_per_tdd)); + sched_pucch->next_sched_pucch = curr_pucch; + sched_pucch->dai_c = 1; + sched_pucch->resource_indicator = 0; // in phytest with only 1 UE we are using just the 1st resource + sched_pucch->timing_indicator = pdsch_to_harq_feedback[i]; + UE_list->UE_sched_ctrl[UE_id].sched_pucch = sched_pucch; + } + else { + while (curr_pucch->next_sched_pucch != NULL && k!=(curr_pucch->ul_slot % slots_per_tdd)) + curr_pucch = curr_pucch->next_sched_pucch; + if (curr_pucch == NULL) { // creating a new item in the list + sched_pucch->frame = frameP; + sched_pucch->next_sched_pucch = NULL; + sched_pucch->dai_c = 1; + sched_pucch->timing_indicator = pdsch_to_harq_feedback[i]; + sched_pucch->resource_indicator = 0; // in phytest with only 1 UE we are using just the 1st resource + sched_pucch->ul_slot = k + (slotP - (slotP % slots_per_tdd)); + curr_pucch->next_sched_pucch = (NR_sched_pucch*) malloc(sizeof(NR_sched_pucch)); + curr_pucch->next_sched_pucch = sched_pucch; + } + else { + if (curr_pucch->dai_c==11) + found = 0; // if pucch at index k is already full we have to find a new one in a following occasion + else { // scheduling this harq-ack in current pucch + sched_pucch = curr_pucch; + sched_pucch->dai_c = 1 + sched_pucch->dai_c; + sched_pucch->timing_indicator = pdsch_to_harq_feedback[i]; + } + } + } + } + } + } + } + } +} + + /*void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg, nfapi_nr_coreset_t *coreset, nfapi_nr_search_space_t *search_space) { diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index fd02368c0df0a6fb41b5de9dc2f041b19a1faa97..368ca27fb01197fc23658f9942fa4bd986cff596 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -80,13 +80,16 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); + int configure_fapi_dl_pdu(int Mod_id, int *CCEIndeces, nfapi_nr_dl_tti_request_body_t *dl_req, + NR_sched_pucch *pucch_sched, uint8_t *mcsIndex, uint16_t *rbSize, uint16_t *rbStart); + void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types); void configure_fapi_dl_Tx(module_id_t Mod_idP, @@ -100,11 +103,24 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP, void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, + NR_sched_pucch *pucch_sched, nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_config); void nr_schedule_uss_ulsch_phytest(int Mod_idP, frame_t frameP, sub_frame_t slotP); + +void nr_update_pucch_scheduling(int Mod_idP, + int UE_id, + frame_t frameP, + sub_frame_t slotP, + int slots_per_tdd, + NR_sched_pucch *sched_pucch); + +void get_pdsch_to_harq_feedback(int Mod_idP, + int UE_id, + NR_SearchSpace__searchSpaceType_PR ss_type, + uint8_t *pdsch_to_harq_feedback); void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, nr_scs_e scs_common, @@ -125,6 +141,7 @@ int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space, nfapi_nr_config_request_scf_t cfg); */ + void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, int ss_type, NR_ServingCellConfigCommon_t *scc, @@ -138,6 +155,15 @@ void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup, int *dci_formats, int *rnti_types); +void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, + NR_ServingCellConfigCommon_t *scc, + NR_BWP_Uplink_t *bwp, + uint8_t pucch_resource, + uint16_t O_uci, + uint16_t O_ack, + uint8_t SR_flag); + + int get_spf(nfapi_nr_config_request_scf_t *cfg); int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 5bc320d5e2ee67ec8d0e76e12fb5f07d3b4b716f..34b710770eeabb0cc3ebcb5e9a7f3f97bf10b325 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -102,9 +102,22 @@ typedef struct { uint8_t num_sf_allocation_pattern; } NR_COMMON_channels_t; -/*! \brief scheduling control information set through an API (not used)*/ +typedef struct NR_sched_pucch { + int frame; + int ul_slot; + uint8_t dai_c; + uint8_t timing_indicator; + uint8_t resource_indicator; + struct NR_sched_pucch *next_sched_pucch; +} NR_sched_pucch; + +/*! \brief scheduling control information set through an API */ typedef struct { - int dummy; + uint64_t dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch + uint64_t ulsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains ulsch + NR_sched_pucch *sched_pucch; + uint16_t ta_timer; + int16_t ta_update; } NR_UE_sched_ctrl_t; /*! \brief UE list used by eNB to order UEs/CC for scheduling*/ @@ -112,7 +125,7 @@ typedef struct { DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB]; /// scheduling control info - UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB]; + NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB]; int next[MAX_MOBILES_PER_GNB]; int head; int next_ul[MAX_MOBILES_PER_GNB]; @@ -124,7 +137,7 @@ typedef struct { NR_CellGroupConfig_t *secondaryCellGroup[MAX_MOBILES_PER_GNB]; } NR_UE_list_t; -/*! \brief top level eNB MAC structure */ +/*! \brief top level gNB MAC structure */ typedef struct gNB_MAC_INST_s { /// Ethernet parameters for northbound midhaul interface eth_params_t eth_params_n;