mirror of https://github.com/PentHertz/srsLTE.git
Apply minor comments in NR-PUCCH
This commit is contained in:
parent
4c6944b883
commit
4fe34b5e5b
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = {};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue