From 4fe34b5e5b2463f8a5079f47fb68f32190067727 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 27 Jan 2021 11:50:12 +0100 Subject: [PATCH] Apply minor comments in NR-PUCCH --- lib/include/srslte/phy/phch/pucch_cfg_nr.h | 2 + lib/include/srslte/phy/phch/pucch_nr.h | 5 -- lib/include/srslte/phy/phch/ra_ul_nr.h | 5 +- lib/include/srslte/phy/phch/uci_cfg_nr.h | 35 ++++++++-- lib/include/srslte/phy/phch/uci_nr.h | 16 ++++- lib/src/phy/phch/pucch_nr.c | 8 +-- lib/src/phy/phch/test/pucch_nr_test.c | 25 +++++--- lib/src/phy/phch/uci_nr.c | 74 +++++++++++++--------- 8 files changed, 113 insertions(+), 57 deletions(-) diff --git a/lib/include/srslte/phy/phch/pucch_cfg_nr.h b/lib/include/srslte/phy/phch/pucch_cfg_nr.h index d7ff1ff85..577198577 100644 --- a/lib/include/srslte/phy/phch/pucch_cfg_nr.h +++ b/lib/include/srslte/phy/phch/pucch_cfg_nr.h @@ -33,6 +33,7 @@ #define SRSLTE_PUCCH_NR_FORMAT1_MIN_NSYMB 4 #define SRSLTE_PUCCH_NR_FORMAT1_MAX_NSYMB 14 #define SRSLTE_PUCCH_NR_FORMAT1_MAX_STARTSYMB 10 +#define SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS 2 /** * NR-PUCCH Format 2 ranges @@ -42,6 +43,7 @@ #define SRSLTE_PUCCH_NR_FORMAT2_MIN_NSYMB 1 #define SRSLTE_PUCCH_NR_FORMAT2_MAX_NSYMB 2 #define SRSLTE_PUCCH_NR_FORMAT2_MAX_STARTSYMB 13 +#define SRSLTE_PUCCH_NR_FORMAT2_MIN_NOF_BITS 3 /** * NR-PUCCH Format 3 ranges diff --git a/lib/include/srslte/phy/phch/pucch_nr.h b/lib/include/srslte/phy/phch/pucch_nr.h index 6ddc1507d..eeeb11418 100644 --- a/lib/include/srslte/phy/phch/pucch_nr.h +++ b/lib/include/srslte/phy/phch/pucch_nr.h @@ -24,11 +24,6 @@ */ #define SRSLTE_PUCCH_NR_FORMAT1_N_MAX 7 -/** - * @brief Maximum number of bit that NR-PUCCH format 1 can carry - */ -#define SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS 2 - typedef struct SRSLTE_API { srslte_uci_nr_args_t uci; uint32_t max_nof_prb; diff --git a/lib/include/srslte/phy/phch/ra_ul_nr.h b/lib/include/srslte/phy/phch/ra_ul_nr.h index 510480d9c..12bc5b1ff 100644 --- a/lib/include/srslte/phy/phch/ra_ul_nr.h +++ b/lib/include/srslte/phy/phch/ra_ul_nr.h @@ -18,8 +18,9 @@ #include "uci_cfg_nr.h" /** - * @brief - * @return + * @brief Calculates the minimum number of PRB required for transmitting NR-PUCCH Format 2, 3 or 4 + * @remark Based in TS 38.213 9.2.5.1 UE procedure for multiplexing HARQ-ACK or CSI and SR in a PUCCH + * @return The number of PRB if the provided configuration is valid, SRSLTE_ERROR code otherwise */ SRSLTE_API int srslte_ra_ul_nr_pucch_format_2_3_min_prb(const srslte_pucch_nr_resource_t* resource, const srslte_uci_cfg_nr_t* uci_cfg); diff --git a/lib/include/srslte/phy/phch/uci_cfg_nr.h b/lib/include/srslte/phy/phch/uci_cfg_nr.h index dc24ec7ba..b87a6c8a2 100644 --- a/lib/include/srslte/phy/phch/uci_cfg_nr.h +++ b/lib/include/srslte/phy/phch/uci_cfg_nr.h @@ -17,26 +17,49 @@ #include #include +/** + * @brief Maximum number of HARQ ACK feedback bits that can be carried in Uplink Control Information (UCI) message + */ #define SRSLTE_UCI_NR_MAX_ACK_BITS 360 + +/** + * @brief Maximum number of Scheduling Request (SR) bits that can be carried in Uplink Control Information (UCI) message + */ #define SRSLTE_UCI_NR_MAX_SR_BITS 10 + +/** + * @brief Maximum number of Channel State Information part 1 (CSI1) bits that can be carried in Uplink Control + * Information (UCI) message + */ #define SRSLTE_UCI_NR_MAX_CSI1_BITS 10 + +/** + * @brief Maximum number of Channel State Information part 2 (CSI2) bits that can be carried in Uplink Control + * Information (UCI) message + */ #define SRSLTE_UCI_NR_MAX_CSI2_BITS 10 +/** + * @brief Uplink Control Information (UCI) message configuration + */ typedef struct SRSLTE_API { uint32_t o_ack; ///< Number of HARQ-ACK bits uint32_t o_sr; ///< Number of SR bits uint32_t o_csi1; ///< Number of CSI1 report number of bits uint32_t o_csi2; ///< Number of CSI2 report number of bits - srslte_mod_t modulation; ///< Modulation + srslte_mod_t modulation; ///< Modulation (PUSCH only) uint16_t rnti; ///< RNTI } srslte_uci_cfg_nr_t; +/** + * @brief Uplink Control Information (UCI) message packed information + */ typedef struct SRSLTE_API { - uint8_t ack[SRSLTE_UCI_NR_MAX_ACK_BITS]; - uint8_t sr[SRSLTE_UCI_NR_MAX_SR_BITS]; - uint8_t csi1[SRSLTE_UCI_NR_MAX_CSI1_BITS]; - uint8_t csi2[SRSLTE_UCI_NR_MAX_CSI2_BITS]; - bool valid; + uint8_t ack[SRSLTE_UCI_NR_MAX_ACK_BITS]; ///< HARQ ACK feedback bits + uint8_t sr[SRSLTE_UCI_NR_MAX_SR_BITS]; ///< Scheduling Request bits + uint8_t csi1[SRSLTE_UCI_NR_MAX_CSI1_BITS]; ///< Channel State Information part 1 + uint8_t csi2[SRSLTE_UCI_NR_MAX_CSI2_BITS]; ///< Channel State Information part 2 + bool valid; ///< Indicates whether the message has been decoded successfully, ignored in the transmitter } srslte_uci_value_nr_t; #endif // SRSLTE_UCI_CFG_NR_H diff --git a/lib/include/srslte/phy/phch/uci_nr.h b/lib/include/srslte/phy/phch/uci_nr.h index fe1000646..df5d68e8f 100644 --- a/lib/include/srslte/phy/phch/uci_nr.h +++ b/lib/include/srslte/phy/phch/uci_nr.h @@ -24,8 +24,12 @@ #include #include +/** + * @brief NR-UCI Encoder/decoder initialization arguments + */ typedef struct { - bool disable_simd; + bool disable_simd; ///< Disable Polar code SIMD + float block_code_threshold; ///< Set normalised block code threshold (receiver only) } srslte_uci_nr_args_t; typedef struct { @@ -40,10 +44,20 @@ typedef struct { uint8_t* c; ///< UCI code-block prior encoding or after decoding uint8_t* allocated; ///< Polar code intermediate uint8_t* d; ///< Polar code encoded intermediate + float block_code_threshold; } srslte_uci_nr_t; +/** + * @brief Calculates the number of bits carried by PUCCH formats 2, 3 and 4 from the PUCCH resource + * @remark Defined in TS 38.212 Table 6.3.1.4-1: Total rate matching output sequence length Etot + * @param resource PUCCH format 2, 3 or 4 Resource provided by upper layers + * @return The number of bits if the provided resource is valid, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_uci_nr_pucch_format_2_3_4_E(const srslte_pucch_nr_resource_t* resource); + /** * @brief Calculates in advance how many CRC bits will be appended for a given amount of UCI bits (A) + * @remark Defined in TS 38.212 section 6.3.1.2 Code block segmentation and CRC attachment * @param A Number of UCI bits to transmit */ SRSLTE_API uint32_t srslte_uci_nr_crc_len(uint32_t A); diff --git a/lib/src/phy/phch/pucch_nr.c b/lib/src/phy/phch/pucch_nr.c index 4dcbe93c7..cd83f7b33 100644 --- a/lib/src/phy/phch/pucch_nr.c +++ b/lib/src/phy/phch/pucch_nr.c @@ -380,7 +380,7 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, return SRSLTE_SUCCESS; } - if (nof_bits > 2) { + if (nof_bits > SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS) { ERROR("Invalid number of bits (%d)\n", nof_bits); return SRSLTE_ERROR; } @@ -458,7 +458,7 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, return SRSLTE_SUCCESS; } - if (nof_bits > 2) { + if (nof_bits > SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS) { ERROR("Invalid number of bits (%d)\n", nof_bits); return SRSLTE_ERROR; } @@ -544,7 +544,7 @@ static int pucch_nr_format2_encode(srslte_pucch_nr_t* q, } // Calculate number of encoded symbols - uint32_t E = 16 * resource->nof_symbols * resource->nof_prb; + uint32_t E = srslte_uci_nr_pucch_format_2_3_4_E(resource); // 6.3.2.5.1 Scrambling uint32_t cinit = pucch_nr_format2_cinit(cfg, uci_cfg); @@ -584,7 +584,7 @@ static int pucch_nr_format2_decode(srslte_pucch_nr_t* q, } // Calculate number of encoded symbols - uint32_t E = 16 * resource->nof_symbols * resource->nof_prb; + uint32_t E = srslte_uci_nr_pucch_format_2_3_4_E(resource); // Undo mapping to physical resources uint32_t l_start = resource->start_symbol_idx; diff --git a/lib/src/phy/phch/test/pucch_nr_test.c b/lib/src/phy/phch/test/pucch_nr_test.c index 9f024b008..ad787e2e2 100644 --- a/lib/src/phy/phch/test/pucch_nr_test.c +++ b/lib/src/phy/phch/test/pucch_nr_test.c @@ -34,7 +34,7 @@ static uint32_t starting_prb_stride = 4; static uint32_t starting_symbol_stride = 4; static srslte_random_t random_gen = NULL; static int format = -1; -static float snr_db = 30.0f; +static float snr_db = 20.0f; static srslte_channel_awgn_t awgn = {}; static int test_pucch_format0(srslte_pucch_nr_t* pucch, const srslte_pucch_nr_common_cfg_t* cfg, cf_t* slot_symbols) @@ -176,14 +176,19 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch, SRSLTE_MIN(SRSLTE_PUCCH_NR_FORMAT2_MAX_STARTSYMB, SRSLTE_NSYMB_PER_SLOT_NR - resource.nof_symbols); resource.start_symbol_idx += starting_symbol_stride) { - // Maximum code rate is reserved - for (resource.max_code_rate = 0; resource.max_code_rate < SRSLTE_PUCCH_NR_MAX_CODE_RATE; - resource.max_code_rate++) { + srslte_uci_cfg_nr_t uci_cfg = {}; - srslte_uci_cfg_nr_t uci_cfg = {}; + for (uci_cfg.o_ack = SRSLTE_PUCCH_NR_FORMAT2_MIN_NOF_BITS; uci_cfg.o_ack <= SRSLTE_UCI_NR_MAX_ACK_BITS; + uci_cfg.o_ack++) { + srslte_uci_value_nr_t uci_value = {}; - for (uci_cfg.o_ack = 12; uci_cfg.o_ack <= SRSLTE_UCI_NR_MAX_ACK_BITS; uci_cfg.o_ack++) { - srslte_uci_value_nr_t uci_value = {}; + // Maximum code rate is reserved + uint32_t max_code_rate_end = SRSLTE_PUCCH_NR_MAX_CODE_RATE; + if (uci_cfg.o_ack == 11) { + max_code_rate_end = SRSLTE_PUCCH_NR_MAX_CODE_RATE - 1; + } + + for (resource.max_code_rate = 0; resource.max_code_rate < max_code_rate_end; resource.max_code_rate++) { // Skip case if not enough PRB are used int min_nof_prb = srslte_ra_ul_nr_pucch_format_2_3_min_prb(&resource, &uci_cfg); @@ -217,9 +222,13 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch, // Estimate channel TESTASSERT(srslte_dmrs_pucch_format2_estimate( pucch, &carrier, cfg, &slot, &resource, slot_symbols, chest_res) == SRSLTE_SUCCESS); + INFO("RSRP=%+.2f; EPRE=%+.2f; SNR=%+.2f;\n", + chest_res->rsrp_dBfs, + chest_res->epre_dBfs, + chest_res->snr_db); TESTASSERT(fabsf(chest_res->rsrp_dBfs - 0.0f) < 3.0f); TESTASSERT(fabsf(chest_res->epre_dBfs - 0.0f) < 3.0f); - TESTASSERT(fabsf(chest_res->snr_db - snr_db) < 10.0f); + TESTASSERT(fabsf(chest_res->snr_db - snr_db) < 20.0f); // Decode PUCCH srslte_uci_value_nr_t uci_value_rx = {}; diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index a8a433711..cd72c71e1 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -26,7 +26,7 @@ #define UCI_NR_POLAR_MAX 2048U #define UCI_NR_POLAR_RM_IBIL 0 #define UCI_NR_PUCCH_POLAR_N_MAX 10 -#define UCI_NR_BLOCK_CORR_THRESHOLD 0.5f +#define UCI_NR_BLOCK_DEFAULT_CORR_THRESHOLD 0.5f uint32_t srslte_uci_nr_crc_len(uint32_t A) { @@ -109,6 +109,12 @@ int srslte_uci_nr_init(srslte_uci_nr_t* q, const srslte_uci_nr_args_t* args) return SRSLTE_ERROR; } + if (isnormal(args->block_code_threshold)) { + q->block_code_threshold = args->block_code_threshold; + } else { + q->block_code_threshold = UCI_NR_BLOCK_DEFAULT_CORR_THRESHOLD; + } + return SRSLTE_SUCCESS; } @@ -410,25 +416,38 @@ static int uci_nr_decode_3_11_bit(srslte_uci_nr_t* q, return SRSLTE_ERROR_INVALID_INPUTS; } - // Compute average LLR power - float pwr = sqrtf(srslte_vec_avg_power_bf(llr, E)); - if (!isnormal(pwr)) { + if (A == 11 && E <= 16) { + ERROR("NR-UCI Impossible to decode A=%d; E=%d\n", A, E); return SRSLTE_ERROR; } - if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { - UCI_NR_INFO_RX("Block decoding NR-UCI llr="); - srslte_vec_fprint_bs(stdout, llr, E); + // Compute average LLR power + float pwr = srslte_vec_avg_power_bf(llr, E); + if (!isnormal(pwr)) { + return SRSLTE_ERROR; } // Decode float corr = (float)srslte_block_decode_i8(llr, E, q->bit_sequence, A); // Normalise correlation - corr /= sqrtf(pwr) * E; + float norm_corr = corr / (sqrtf(pwr) * E); // Take decoded decision with threshold - *decoded_ok = (corr > UCI_NR_BLOCK_CORR_THRESHOLD); + *decoded_ok = (corr > q->block_code_threshold); + + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { + UCI_NR_INFO_RX("Block decoding NR-UCI llr="); + srslte_vec_fprint_bs(stdout, llr, E); + UCI_NR_INFO_RX("Block decoding NR-UCI A=%d; E=%d; pwr=%f; corr=%f; norm=%f; thr=%f; %s\n", + A, + E, + pwr, + corr, + norm_corr, + q->block_code_threshold, + *decoded_ok ? "OK" : "KO"); + } return SRSLTE_SUCCESS; } @@ -687,38 +706,31 @@ static int uci_nr_decode(srslte_uci_nr_t* q, return SRSLTE_SUCCESS; } -// Implements TS 38.212 Table 6.3.1.4-1: Total rate matching output sequence length Etot -static int uci_nr_pucch_E_tot(const srslte_pucch_nr_resource_t* pucch_cfg, const srslte_uci_cfg_nr_t* uci_cfg) +int srslte_uci_nr_pucch_format_2_3_4_E(const srslte_pucch_nr_resource_t* resource) { - if (pucch_cfg == NULL || uci_cfg == NULL) { + if (resource == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } - switch (pucch_cfg->format) { + switch (resource->format) { case SRSLTE_PUCCH_NR_FORMAT_2: - return (int)(16 * pucch_cfg->nof_symbols * pucch_cfg->nof_prb); + return (int)(16 * resource->nof_symbols * resource->nof_prb); case SRSLTE_PUCCH_NR_FORMAT_3: - if (uci_cfg->modulation == SRSLTE_MOD_QPSK) { - return (int)(24 * pucch_cfg->nof_symbols * pucch_cfg->nof_prb); + if (!resource->enable_pi_bpsk) { + return (int)(24 * resource->nof_symbols * resource->nof_prb); } - if (uci_cfg->modulation == SRSLTE_MOD_BPSK) { - return (int)(12 * pucch_cfg->nof_symbols * pucch_cfg->nof_prb); - } - break; + return (int)(12 * resource->nof_symbols * resource->nof_prb); case SRSLTE_PUCCH_NR_FORMAT_4: - if (pucch_cfg->occ_lenth != 1 && pucch_cfg->occ_lenth != 2) { - ERROR("Invalid spreading factor (%d)\n", pucch_cfg->occ_lenth); + if (resource->occ_lenth != 1 && resource->occ_lenth != 2) { + ERROR("Invalid spreading factor (%d)\n", resource->occ_lenth); return SRSLTE_ERROR; } - if (uci_cfg->modulation == SRSLTE_MOD_QPSK) { - return (int)(24 * pucch_cfg->nof_symbols / pucch_cfg->occ_lenth); + if (!resource->enable_pi_bpsk) { + return (int)(24 * resource->nof_symbols / resource->occ_lenth); } - if (uci_cfg->modulation == SRSLTE_MOD_BPSK) { - return (int)(12 * pucch_cfg->nof_symbols / pucch_cfg->occ_lenth); - } - break; + return (int)(12 * resource->nof_symbols / resource->occ_lenth); default: - return SRSLTE_ERROR; + ERROR("Invalid case\n"); } return SRSLTE_ERROR; } @@ -741,7 +753,7 @@ int srslte_uci_nr_encode_pucch(srslte_uci_nr_t* q, const srslte_uci_value_nr_t* value, uint8_t* o) { - int E_tot = uci_nr_pucch_E_tot(pucch_resource_cfg, uci_cfg); + int E_tot = srslte_uci_nr_pucch_format_2_3_4_E(pucch_resource_cfg); if (E_tot < SRSLTE_SUCCESS) { ERROR("Error calculating number of bits\n"); return SRSLTE_ERROR; @@ -762,7 +774,7 @@ int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q, int8_t* llr, srslte_uci_value_nr_t* value) { - int E_tot = uci_nr_pucch_E_tot(pucch_resource_cfg, uci_cfg); + int E_tot = srslte_uci_nr_pucch_format_2_3_4_E(pucch_resource_cfg); if (E_tot < SRSLTE_SUCCESS) { return SRSLTE_ERROR; }