From 79c8d9322807d5c38c5a2f81bdb4d1a331a67af7 Mon Sep 17 00:00:00 2001 From: Guy De Souza Date: Tue, 23 Oct 2018 12:14:40 +0200 Subject: [PATCH] ceil/round macros- TBS calculation corrections --- .../nfapi/public_inc/nfapi_nr_interface.h | 4 +- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 28 +++--- openair1/PHY/NR_TRANSPORT/nr_dlsch.h | 7 +- openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c | 12 +-- openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h | 6 +- openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c | 87 ++++++++++--------- openair1/PHY/defs_common.h | 4 + openair1/PHY/defs_nr_common.h | 10 +-- 8 files changed, 84 insertions(+), 74 deletions(-) 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 a3faead178..f9154eee69 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h @@ -508,8 +508,8 @@ typedef struct { uint8_t S; uint8_t L; uint8_t Imcs; - uint8_t n_codewords; - uint8_t n_layers; + uint8_t nb_codewords; + uint8_t nb_layers; /*uint8_t R; uint8_t Qm; uint16_t TBS; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index c38486aec0..77886beb1b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -35,6 +35,9 @@ #define DEBUG_DLSCH +uint8_t mod_order[5] = {1, 2, 4, 6, 8}; +uint16_t mod_offset[5] = {1,3,7,23,87}; + void nr_pdsch_codeword_scrambling(uint32_t *in, uint8_t size, uint8_t q, @@ -189,11 +192,11 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch, NR_DL_gNB_HARQ_t *harq = dlsch.harq_processes[dci_alloc.harq_pid]; nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &harq->dlsch_pdu.dlsch_pdu_rel15; nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params; - uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH]={0}; - uint16_t mod_symbs[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>1] = {0}; + uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH]; + int16_t mod_symbs[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>1]; uint16_t tx_layers[NR_MAX_NB_LAYERS][NR_MAX_PDSCH_ENCODED_LENGTH>>1]; - uint16_t n_symbs[NR_MAX_NB_CODEWORDS] = {0}; - int8_t Wf[2], Wt[2], l0[2], delta; + uint16_t n_symbs[NR_MAX_NB_CODEWORDS]; + int8_t Wf[2], Wt[2], l0, delta; /// CRC, coding, interleaving and rate matching @@ -229,9 +232,9 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch, /// DMRS QPSK modulation uint16_t n_dmrs = rel15->n_prb<<1; - uint16_t mod_dmrs[n_dmrs<<1] = {0}; + int16_t mod_dmrs[n_dmrs<<1]; uint8_t dmrs_type = config.pdsch_config.dmrs_type.value; - nr_modulation(pdsch_dmrs, n_dmrs, QPSK, mod_dmrs); + nr_modulation(pdsch_dmrs, n_dmrs, MOD_QPSK, mod_dmrs); /// Resource mapping AssertFatal(harq->Nl<=config.rf_config.tx_antenna_ports.value, "Not enough Tx antennas (%d) for %d layers\n",\ @@ -245,8 +248,8 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch, for (int ap=0; apnb_layers; ap++) { // DMRS params for this ap - Wt = get_Wt(ap, dmrs_type); - Wf = get_Wf(ap, dmrs_type); + get_Wt(Wt, ap, dmrs_type); + get_Wf(Wf, ap, dmrs_type); l0 = get_l0(0, config.pdsch_config.dmrs_typeA_position.value); delta = get_delta(ap, dmrs_type); uint8_t k_prime=0, n=0, dmrs_idx=0; @@ -258,11 +261,12 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch, k -= frame_parms.ofdm_symbol_size; if ((l==l0) && (k == ((dmrs_type)? (6*n+k_prime+delta):((n<<2)+(k_prime<<1)+delta)))) { - ((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (Wt*Wf*amp*mod_dmrs[dmrs_idx<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (Wt*Wf*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; - mod_dmrs++; + ((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (Wt[k_prime]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (Wt[k_prime]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; + dmrs_idx++; n++; - k_prime = (++k_prime)&1; + k_prime++; + k_prime&=1; } ((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * tx_layers[ap][m<<1]) >> 15; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index a8ecba0582..cd3640619d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -56,9 +56,10 @@ uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx); uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx); -void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, - nfapi_nr_dl_config_dci_dl_pdu dci_pdu, - nfapi_nr_config_request_t config); +void nr_get_tbs(NR_gNB_DLSCH_t *dlsch, + nfapi_nr_dl_config_dci_dl_pdu dci_pdu, + nfapi_nr_config_request_t config, + uint8_t harq_pid); void nr_pdsch_codeword_scrambling(uint32_t *in, uint8_t size, diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c index b016e4d008..df4f9716fb 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c @@ -33,8 +33,6 @@ #include "nr_sch_dmrs.h" - - /*Table 7.4.1.1.2-1 and 7.4.1.1.2-2 38211 Columns: ap - CDM group - Delta - Wf(0) - Wf(1) - Wt(0) - Wt(1)*/ int8_t pdsch_dmrs_1[8][7] = {{0,0,0,1,1,1,1}, {1,0,0,1,-1,1,1}, @@ -76,24 +74,20 @@ static inline void *get_antenna_ports(uint8_t n_symbs, uint8_t config) { return ap; } -int8_t *get_Wt(uint8_t ap, uint8_t config) { - int8_t *Wt; +void get_Wt(int8_t *Wt, uint8_t ap, uint8_t config) { for (int i=0; i<2; i++) *(Wt+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][3+i]):(pdsch_dmrs_2[ap][3+i]); - return Wt; } -int8_t *get_Wf(uint8_t ap, uint8_t config) { - int8_t *Wf; +void *get_Wf(int8_t *Wf, uint8_t ap, uint8_t config) { for (int i=0; i<2; i++) *(Wf+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][5+i]):(pdsch_dmrs_2[ap][5+i]); - return Wf; } uint8_t get_delta(uint8_t ap, uint8_t config) { return ((config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][2]):(pdsch_dmrs_2[ap][2])); } -uint8_t *get_l0(uint8_t config, uint8_t dmrs_typeA_position) { +uint8_t get_l0(uint8_t config, uint8_t dmrs_typeA_position) { return ((config==NFAPI_NR_DMRS_TYPE1)?dmrs_typeA_position:0); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h index daec8324b0..d2dc88a407 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h +++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h @@ -35,10 +35,10 @@ #define NR_PDSCH_DMRS_ANTENNA_PORT0 1000 #define NR_PDSCH_DMRS_NB_ANTENNA_PORTS 12 -int8_t *get_Wt(uint8_t ap, uint8_t config); +void get_Wt(int8_t *Wt, uint8_t ap, uint8_t config); -int8_t *get_Wf(uint8_t ap, uint8_t config); +void get_Wf(int8_t *Wf, uint8_t ap, uint8_t config); uint8_t get_delta(uint8_t ap, uint8_t config); -uint8_t *get_l0(uint8_t config, uint8_t dmrs_typeA_position); +uint8_t get_l0(uint8_t config, uint8_t dmrs_typeA_position); diff --git a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c index d8b8c10c2b..48709c9dc8 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c @@ -35,9 +35,9 @@ /// Target code rate tables indexed by Imcs uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \ 616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948}; - // The -1 values correspond to non integer factors which are handled differently for indexes 20(682.5) and 26(916.5) + // Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point uint16_t nr_target_code_rate_table2[28] = {120, 193, 308, 449, 602, 378, 434, 490, 553, 616, 658, 466, 517, 567, \ - 616, 666, 719, 772, 822, 873, -1, 711, 754, 797, 841, 885, -1, 948}; + 616, 666, 719, 772, 822, 873, 1365, 711, 754, 797, 841, 885, 1833, 948}; uint16_t nr_target_code_rate_table3[29] = {30, 40, 50, 64, 78, 99, 120, 157, 193, 251, 308, 379, 449, 526, 602, 340, \ 378, 434, 490, 553, 616, 438, 466, 517, 567, 616, 666, 719, 772}; uint16_t nr_tbs_table[93] = {24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 208, 224, 240, 256, 272, 288, 304, 320, \ @@ -67,15 +67,15 @@ uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx) { uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) { switch(table_idx) { case 1: - return (nr_target_code_rate_table1[Imcs]<<10); + return (nr_target_code_rate_table1[Imcs]); break; case 2: - return ((Imcs==20)?0xaaa00 : (Imcs==26)?0xe5200 : nr_target_code_rate_table2[Imcs]<<10); + return (nr_target_code_rate_table2[Imcs]); break; case 3: - return (nr_target_code_rate_table3[Imcs]<<10); + return (nr_target_code_rate_table3[Imcs]); break; default: @@ -87,72 +87,79 @@ static inline uint8_t is_codeword_disabled(uint8_t format, uint8_t Imcs, uint8_t return ((format==NFAPI_NR_DL_DCI_FORMAT_1_1)&&(Imcs==26)&&(rv==1)); } +static inline uint8_t get_table_idx(uint8_t mcs_table, uint8_t dci_format, uint8_t rnti_type, uint8_t ss_type) { + if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1) && ((rnti_type==NFAPI_NR_RNTI_C)||(rnti_type==NFAPI_NR_RNTI_CS))) + return 2; + else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type!=NFAPI_NR_RNTI_new) && (rnti_type==NFAPI_NR_RNTI_C) && (ss_type==NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)) + return 3; + else if (rnti_type==NFAPI_NR_RNTI_new) + return 3; + else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (rnti_type==NFAPI_NR_RNTI_CS) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1)) + return 2; // Condition mcs_table not configured in sps_config necessary here but not yet implemented + /*else if((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type==NFAPI_NR_RNTI_CS)) + * table_idx = 3; + * Note: the commented block refers to the case where the mcs_table is from sps_config*/ + else + return 1; +} + void nr_get_tbs(NR_gNB_DLSCH_t *dlsch, nfapi_nr_dl_config_dci_dl_pdu dci_pdu, - nfapi_nr_config_request_t config) { -uint8_t N_PRB_DMRS=2; // tmp hardcoding + nfapi_nr_config_request_t config, + uint8_t harq_pid) { - nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_rel15 = &dlsch->dlsch_pdu.dlsch_pdu_rel15; nfapi_nr_dl_config_pdcch_parameters_rel15_t params_rel15 = dci_pdu.pdcch_params_rel15; - NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[dlsch_rel15->harq_pid]; + NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[harq_pid]; + nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_rel15 = &harq->dlsch_pdu.dlsch_pdu_rel15; uint8_t rnti_type = params_rel15.rnti_type; uint8_t dci_format = params_rel15.dci_format; uint8_t ss_type = params_rel15.search_space_type; uint8_t N_PRB_oh = ((rnti_type==NFAPI_NR_RNTI_SI)||(rnti_type==NFAPI_NR_RNTI_RA)||(rnti_type==NFAPI_NR_RNTI_P))? 0 : \ (config.pdsch_config.x_overhead.value); + uint8_t N_PRB_DMRS = (config.pdsch_config.dmrs_type.value == NFAPI_NR_DMRS_TYPE1)?4:6; //This only works for antenna port 1000 uint8_t mcs_table = config.pdsch_config.mcs_table.value; uint8_t N_sh_symb = dlsch_rel15->L; uint8_t Imcs = dlsch_rel15->Imcs; uint16_t N_prime_RE = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh; LOG_I(MAC, "N_prime_RE %d for %d symbols %d DMRS per PRB and %d overhead\n", N_prime_RE, N_sh_symb, N_PRB_DMRS, N_PRB_oh); - uint16_t N_RE, N_info, N_info_prime; - uint8_t table_idx, R, Qm, n; - float tmp, C; // temporary N_info_prime in float to avoid back and forth casting to int + uint16_t N_RE, Ninfo, Ninfo_prime, C; + uint8_t table_idx, R, Qm, n, scale; + table_idx = get_table_idx(mcs_table, dci_format, rnti_type, ss_type); + scale = 10 + (((table_idx==2)&&((Imcs==20)||(Imcs==26)))?1:0); + N_RE = min(156, N_RE)*dlsch_rel15->n_prb; - if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1) && ((rnti_type==NFAPI_NR_RNTI_C)||(rnti_type==NFAPI_NR_RNTI_CS))) - table_idx = 2; - else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type!=NFAPI_NR_RNTI_new) && (rnti_type==NFAPI_NR_RNTI_C) && (ss_type==NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)) - table_idx = 3; - else if (rnti_type==NFAPI_NR_RNTI_new) - table_idx = 3; - else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (rnti_type==NFAPI_NR_RNTI_CS) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1)) - table_idx = 2; // Condition mcs_table not configured in sps_config necessary here but not yet implemented - /*else if((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type==NFAPI_NR_RNTI_CS)) - * table_idx = 3; - * Note: the commented block refers to the case where the mcs_table is from sps_config*/ - else - table_idx = 1; - R = nr_get_code_rate(Imcs, table_idx); Qm = nr_get_Qm(Imcs, table_idx); - N_info = N_RE*R*Qm*harq->Nl; + Ninfo = (N_RE*R*Qm*harq->Nl)>>scale; - if (N_info <= 3824) { - n = max(3, (uint8_t)(floor(log2(N_info)-6))); - N_info_prime = max(24, (N_info>>n)<>n)<= N_info_prime) { + if (nr_tbs_table[i] >= Ninfo_prime) { harq->TBS = nr_tbs_table[i]; break; } } else { - n = (uint8_t)floor(log2(N_info)-24) - 5; - tmp = max(3840, ((uint16_t)round(((float)N_info-24)/(1<TBS = ((uint16_t)(C*ceil((tmp+24)/(8*C))))<<3; + if (R<256) { + C = CEILIDIV((Ninfo_prime+24),3816); + harq->TBS = (C*CEILIDIV((Ninfo_prime+24),(C<<3)))<<3; } else { - if (tmp>8424) { - C = ceil((tmp+24)/8424); - harq->TBS = ((uint16_t)(C*ceil((tmp+24)/(8*C))))<<3; + if (Ninfo_prime>8424) { + C = CEILIDIV((Ninfo_prime+24),8424); + harq->TBS = (C*CEILIDIV((Ninfo_prime+24),(C<<3)))<<3; } else - harq->TBS = ((uint16_t)ceil((tmp+24)/8) - 24)<<3; + harq->TBS = (CEILIDIV((Ninfo_prime+24),8) - 24)<<3; } } + LOG_I(MAC, "TBS %d : N_RE %d N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d Ninfo %d Ninfo_prime %d R %d Qm %d table %d scale %d\n", + harq->TBS, N_RE, N_PRB_DMRS, N_sh_symb, N_PRB_oh, Ninfo, Ninfo_prime, R, Qm, table_idx, scale); } diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index fe8bf7b402..8435dd6e8c 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -102,6 +102,10 @@ #ifdef OCP_FRAMEWORK #include "enums.h" #else + +#define CEILIDIV(a,b) ((a+b-1)/b) +#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) + typedef enum {TDD=1,FDD=0} lte_frame_type_t; typedef enum {EXTENDED=1,NORMAL=0} lte_prefix_type_t; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 53e3a14d62..848a9a4258 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -119,11 +119,11 @@ typedef enum { } nr_frequency_range_e; typedef enum { - BPSK=0, - QPSK, - QAM16, - QAM64, - QAM256 + MOD_BPSK=0, + MOD_QPSK, + MOD_QAM16, + MOD_QAM64, + MOD_QAM256 }nr_mod_t; typedef struct {