Apply minor comments in NR-PUCCH

This commit is contained in:
Xavier Arteaga 2021-01-27 11:50:12 +01:00 committed by Xavier Arteaga
parent 4c6944b883
commit 4fe34b5e5b
8 changed files with 113 additions and 57 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -17,26 +17,49 @@
#include <stdbool.h>
#include <stdint.h>
/**
* @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

View File

@ -24,8 +24,12 @@
#include <stdbool.h>
#include <stdint.h>
/**
* @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);

View File

@ -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;

View File

@ -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 = {};

View File

@ -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;
}