|
|
|
@ -26,6 +26,7 @@
|
|
|
|
|
#define UCI_NR_POLAR_RM_IBIL 0
|
|
|
|
|
#define UCI_NR_PUCCH_POLAR_N_MAX 10
|
|
|
|
|
#define UCI_NR_BLOCK_DEFAULT_CORR_THRESHOLD 0.5f
|
|
|
|
|
#define UCI_NR_ONE_BIT_CORR_THRESHOLD 0.5f
|
|
|
|
|
|
|
|
|
|
uint32_t srslte_uci_nr_crc_len(uint32_t A)
|
|
|
|
|
{
|
|
|
|
@ -113,6 +114,11 @@ int srslte_uci_nr_init(srslte_uci_nr_t* q, const srslte_uci_nr_args_t* args)
|
|
|
|
|
} else {
|
|
|
|
|
q->block_code_threshold = UCI_NR_BLOCK_DEFAULT_CORR_THRESHOLD;
|
|
|
|
|
}
|
|
|
|
|
if (isnormal(args->one_bit_threshold)) {
|
|
|
|
|
q->one_bit_threshold = args->one_bit_threshold;
|
|
|
|
|
} else {
|
|
|
|
|
q->one_bit_threshold = UCI_NR_ONE_BIT_CORR_THRESHOLD;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
@ -200,7 +206,7 @@ static int uci_nr_unpack_ack_sr(const srslte_uci_cfg_nr_t* cfg, uint8_t* sequenc
|
|
|
|
|
|
|
|
|
|
static int uci_nr_A(const srslte_uci_cfg_nr_t* cfg)
|
|
|
|
|
{
|
|
|
|
|
int o_csi = srslte_csi_nof_bits(cfg->csi, cfg->nof_csi);
|
|
|
|
|
int o_csi = srslte_csi_part1_nof_bits(cfg->csi, cfg->nof_csi);
|
|
|
|
|
|
|
|
|
|
// 6.3.1.1.1 HARQ-ACK/SR only UCI bit sequence generation
|
|
|
|
|
if (o_csi == 0) {
|
|
|
|
@ -219,7 +225,7 @@ static int uci_nr_A(const srslte_uci_cfg_nr_t* cfg)
|
|
|
|
|
|
|
|
|
|
static int uci_nr_pack_pucch(const srslte_uci_cfg_nr_t* cfg, const srslte_uci_value_nr_t* value, uint8_t* sequence)
|
|
|
|
|
{
|
|
|
|
|
int o_csi = srslte_csi_nof_bits(cfg->csi, cfg->nof_csi);
|
|
|
|
|
int o_csi = srslte_csi_part1_nof_bits(cfg->csi, cfg->nof_csi);
|
|
|
|
|
|
|
|
|
|
// 6.3.1.1.1 HARQ-ACK/SR only UCI bit sequence generation
|
|
|
|
|
if (o_csi == 0) {
|
|
|
|
@ -238,7 +244,7 @@ static int uci_nr_pack_pucch(const srslte_uci_cfg_nr_t* cfg, const srslte_uci_va
|
|
|
|
|
|
|
|
|
|
static int uci_nr_unpack_pucch(const srslte_uci_cfg_nr_t* cfg, uint8_t* sequence, srslte_uci_value_nr_t* value)
|
|
|
|
|
{
|
|
|
|
|
int o_csi = srslte_csi_nof_bits(cfg->csi, cfg->nof_csi);
|
|
|
|
|
int o_csi = srslte_csi_part1_nof_bits(cfg->csi, cfg->nof_csi);
|
|
|
|
|
|
|
|
|
|
// 6.3.1.1.1 HARQ-ACK/SR only UCI bit sequence generation
|
|
|
|
|
if (o_csi == 0) {
|
|
|
|
@ -270,39 +276,39 @@ static int uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg
|
|
|
|
|
case SRSLTE_MOD_QPSK:
|
|
|
|
|
while (i < E) {
|
|
|
|
|
o[i++] = c0;
|
|
|
|
|
o[i++] = UCI_BIT_REPETITION;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_REPETITION;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SRSLTE_MOD_16QAM:
|
|
|
|
|
while (i < E) {
|
|
|
|
|
o[i++] = c0;
|
|
|
|
|
o[i++] = UCI_BIT_REPETITION;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_REPETITION;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SRSLTE_MOD_64QAM:
|
|
|
|
|
while (i < E) {
|
|
|
|
|
while (i < E) {
|
|
|
|
|
o[i++] = c0;
|
|
|
|
|
o[i++] = UCI_BIT_REPETITION;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_REPETITION;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SRSLTE_MOD_256QAM:
|
|
|
|
|
while (i < E) {
|
|
|
|
|
o[i++] = c0;
|
|
|
|
|
o[i++] = UCI_BIT_REPETITION;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_REPETITION;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SRSLTE_MOD_NITEMS:
|
|
|
|
@ -311,15 +317,67 @@ static int uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
|
|
|
|
|
UCI_NR_INFO_TX("One bit encoded NR-UCI; o=");
|
|
|
|
|
srslte_vec_fprint_b(stdout, o, E);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return E;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int uci_nr_decode_1_bit(srslte_uci_nr_t* q,
|
|
|
|
|
const srslte_uci_cfg_nr_t* cfg,
|
|
|
|
|
uint32_t A,
|
|
|
|
|
const int8_t* llr,
|
|
|
|
|
uint32_t E,
|
|
|
|
|
bool* decoded_ok)
|
|
|
|
|
{
|
|
|
|
|
uint32_t Qm = srslte_mod_bits_x_symbol(cfg->pusch.modulation);
|
|
|
|
|
if (Qm == 0) {
|
|
|
|
|
ERROR("Invalid modulation (%s)", srslte_mod_string(cfg->pusch.modulation));
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Correlate LLR
|
|
|
|
|
float corr = 0.0f;
|
|
|
|
|
float pwr = 0.0f;
|
|
|
|
|
for (uint32_t i = 0; i < E; i += Qm) {
|
|
|
|
|
float t = (float)llr[i];
|
|
|
|
|
corr += t;
|
|
|
|
|
pwr += t * t;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Normalise correlation
|
|
|
|
|
float norm_corr = Qm * corr / (E * sqrtf(pwr));
|
|
|
|
|
|
|
|
|
|
// Take decoded decision with threshold
|
|
|
|
|
*decoded_ok = (norm_corr > q->one_bit_threshold);
|
|
|
|
|
|
|
|
|
|
// Save decoded bit
|
|
|
|
|
q->bit_sequence[0] = (corr < 0) ? 0 : 1;
|
|
|
|
|
|
|
|
|
|
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
|
|
|
|
|
UCI_NR_INFO_RX("One bit decoding NR-UCI llr=");
|
|
|
|
|
srslte_vec_fprint_bs(stdout, llr, E);
|
|
|
|
|
UCI_NR_INFO_RX("One bit decoding NR-UCI A=%d; E=%d; pwr=%f; corr=%f; norm=%f; thr=%f; %s",
|
|
|
|
|
A,
|
|
|
|
|
E,
|
|
|
|
|
pwr,
|
|
|
|
|
corr,
|
|
|
|
|
norm_corr,
|
|
|
|
|
q->block_code_threshold,
|
|
|
|
|
*decoded_ok ? "OK" : "KO");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, uint8_t* o, uint32_t E)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i = 0;
|
|
|
|
|
srslte_uci_bit_type_t c0 = (q->bit_sequence[0] == 0) ? UCI_BIT_0 : UCI_BIT_1;
|
|
|
|
|
srslte_uci_bit_type_t c1 = (q->bit_sequence[1] == 0) ? UCI_BIT_0 : UCI_BIT_1;
|
|
|
|
|
srslte_uci_bit_type_t c2 = ((q->bit_sequence[0] ^ q->bit_sequence[1]) == 0) ? UCI_BIT_0 : UCI_BIT_1;
|
|
|
|
|
uint32_t i = 0;
|
|
|
|
|
uint8_t c0 = (uint8_t)((q->bit_sequence[0] == 0) ? UCI_BIT_0 : UCI_BIT_1);
|
|
|
|
|
uint8_t c1 = (uint8_t)((q->bit_sequence[1] == 0) ? UCI_BIT_0 : UCI_BIT_1);
|
|
|
|
|
uint8_t c2 = (uint8_t)(((q->bit_sequence[0] ^ q->bit_sequence[1]) == 0) ? UCI_BIT_0 : UCI_BIT_1);
|
|
|
|
|
|
|
|
|
|
switch (cfg->pusch.modulation) {
|
|
|
|
|
case SRSLTE_MOD_BPSK:
|
|
|
|
@ -334,38 +392,38 @@ static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg
|
|
|
|
|
while (i < E) {
|
|
|
|
|
o[i++] = c0;
|
|
|
|
|
o[i++] = c1;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = c2;
|
|
|
|
|
o[i++] = c0;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = c1;
|
|
|
|
|
o[i++] = c2;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SRSLTE_MOD_64QAM:
|
|
|
|
|
while (i < E) {
|
|
|
|
|
o[i++] = c0;
|
|
|
|
|
o[i++] = c1;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = c2;
|
|
|
|
|
o[i++] = c0;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = c1;
|
|
|
|
|
o[i++] = c2;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SRSLTE_MOD_256QAM:
|
|
|
|
@ -373,28 +431,28 @@ static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg
|
|
|
|
|
while (i < E) {
|
|
|
|
|
o[i++] = c0;
|
|
|
|
|
o[i++] = c1;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = c2;
|
|
|
|
|
o[i++] = c0;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = c1;
|
|
|
|
|
o[i++] = c2;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SRSLTE_MOD_NITEMS:
|
|
|
|
@ -403,9 +461,68 @@ static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
|
|
|
|
|
UCI_NR_INFO_TX("Two bit encoded NR-UCI; o=");
|
|
|
|
|
srslte_vec_fprint_b(stdout, o, E);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return E;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int uci_nr_decode_2_bit(srslte_uci_nr_t* q,
|
|
|
|
|
const srslte_uci_cfg_nr_t* cfg,
|
|
|
|
|
uint32_t A,
|
|
|
|
|
const int8_t* llr,
|
|
|
|
|
uint32_t E,
|
|
|
|
|
bool* decoded_ok)
|
|
|
|
|
{
|
|
|
|
|
uint32_t Qm = srslte_mod_bits_x_symbol(cfg->pusch.modulation);
|
|
|
|
|
if (Qm == 0) {
|
|
|
|
|
ERROR("Invalid modulation (%s)", srslte_mod_string(cfg->pusch.modulation));
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Correlate LLR
|
|
|
|
|
float corr[3] = {};
|
|
|
|
|
if (Qm == 1) {
|
|
|
|
|
for (uint32_t i = 0; i < E / Qm; i++) {
|
|
|
|
|
corr[i % 3] = llr[i];
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for (uint32_t i = 0, j = 0; i < E; i += Qm) {
|
|
|
|
|
corr[(j++) % 3] = llr[i + 0];
|
|
|
|
|
corr[(j++) % 3] = llr[i + 1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Take decoded decision
|
|
|
|
|
bool c0 = corr[0] > 0.0f;
|
|
|
|
|
bool c1 = corr[1] > 0.0f;
|
|
|
|
|
bool c2 = corr[2] > 0.0f;
|
|
|
|
|
|
|
|
|
|
// Check redundancy bit
|
|
|
|
|
*decoded_ok = (c2 == (c0 ^ c1));
|
|
|
|
|
|
|
|
|
|
// Save decoded bits
|
|
|
|
|
q->bit_sequence[0] = c0 ? 1 : 0;
|
|
|
|
|
q->bit_sequence[1] = c1 ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
|
|
|
|
|
UCI_NR_INFO_RX("Two bit decoding NR-UCI llr=");
|
|
|
|
|
srslte_vec_fprint_bs(stdout, llr, E);
|
|
|
|
|
UCI_NR_INFO_RX("Two bit decoding NR-UCI A=%d; E=%d; Qm=%d; c0=%d; c1=%d; c2=%d %s",
|
|
|
|
|
A,
|
|
|
|
|
E,
|
|
|
|
|
Qm,
|
|
|
|
|
c0,
|
|
|
|
|
c1,
|
|
|
|
|
c2,
|
|
|
|
|
*decoded_ok ? "OK" : "KO");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
uci_nr_encode_3_11_bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, uint32_t A, uint8_t* o, uint32_t E)
|
|
|
|
|
{
|
|
|
|
@ -439,6 +556,7 @@ static int uci_nr_decode_3_11_bit(srslte_uci_nr_t* q,
|
|
|
|
|
// Compute average LLR power
|
|
|
|
|
float pwr = srslte_vec_avg_power_bf(llr, E);
|
|
|
|
|
if (!isnormal(pwr)) {
|
|
|
|
|
ERROR("Received all zeros");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -491,6 +609,7 @@ uci_nr_encode_11_1706_bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, ui
|
|
|
|
|
uint32_t K_r = A_prime / C + L;
|
|
|
|
|
uint32_t E_r = E_uci / C;
|
|
|
|
|
if (srslte_polar_code_get(&q->code, K_r, E_r, UCI_NR_PUCCH_POLAR_N_MAX) < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error computing Polar code");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -662,25 +781,26 @@ static int uci_nr_encode(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* uci_cfg,
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
uci_nr_decode(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* uci_cfg, int8_t* llr, uint32_t E_uci, bool* valid)
|
|
|
|
|
static int uci_nr_decode(srslte_uci_nr_t* q,
|
|
|
|
|
const srslte_uci_cfg_nr_t* uci_cfg,
|
|
|
|
|
int8_t* llr,
|
|
|
|
|
uint32_t A,
|
|
|
|
|
uint32_t E_uci,
|
|
|
|
|
bool* valid)
|
|
|
|
|
{
|
|
|
|
|
if (q == NULL || uci_cfg == NULL || valid == NULL || llr == NULL) {
|
|
|
|
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 6.3.1.1 UCI bit sequence generation
|
|
|
|
|
int A = uci_nr_A(uci_cfg);
|
|
|
|
|
if (A < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error getting number of bits");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Decode LLR
|
|
|
|
|
if (A == 1) {
|
|
|
|
|
ERROR("Not implemented");
|
|
|
|
|
if (uci_nr_decode_1_bit(q, uci_cfg, A, llr, E_uci, valid) < SRSLTE_SUCCESS) {
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
} else if (A == 2) {
|
|
|
|
|
ERROR("Not implemented");
|
|
|
|
|
if (uci_nr_decode_2_bit(q, uci_cfg, A, llr, E_uci, valid) < SRSLTE_SUCCESS) {
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
} else if (A <= 11) {
|
|
|
|
|
if (uci_nr_decode_3_11_bit(q, uci_cfg, A, llr, E_uci, valid) < SRSLTE_SUCCESS) {
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
@ -782,7 +902,14 @@ int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q,
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (uci_nr_decode(q, uci_cfg, llr, E_uci, &value->valid) < SRSLTE_SUCCESS) {
|
|
|
|
|
// 6.3.1.1 UCI bit sequence generation
|
|
|
|
|
int A = uci_nr_A(uci_cfg);
|
|
|
|
|
if (A < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error getting number of bits");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (uci_nr_decode(q, uci_cfg, llr, A, E_uci, &value->valid) < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error decoding UCI bits");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
@ -802,7 +929,7 @@ uint32_t srslte_uci_nr_total_bits(const srslte_uci_cfg_nr_t* uci_cfg)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return uci_cfg->o_ack + uci_cfg->o_sr + srslte_csi_nof_bits(uci_cfg->csi, uci_cfg->nof_csi);
|
|
|
|
|
return uci_cfg->o_ack + uci_cfg->o_sr + srslte_csi_part1_nof_bits(uci_cfg->csi, uci_cfg->nof_csi);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t srslte_uci_nr_info(const srslte_uci_data_nr_t* uci_data, char* str, uint32_t str_len)
|
|
|
|
@ -828,7 +955,7 @@ uint32_t srslte_uci_nr_info(const srslte_uci_data_nr_t* uci_data, char* str, uin
|
|
|
|
|
return len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int srslte_uci_nr_pusch_ack_nof_re(const srslte_uci_nr_pusch_cfg_t* cfg, uint32_t O_ack)
|
|
|
|
|
static int uci_nr_pusch_Q_prime_ack(const srslte_uci_nr_pusch_cfg_t* cfg, uint32_t O_ack)
|
|
|
|
|
{
|
|
|
|
|
if (cfg == NULL) {
|
|
|
|
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
|
|
|
@ -866,7 +993,7 @@ int srslte_uci_nr_pusch_ack_nof_bits(const srslte_uci_nr_pusch_cfg_t* cfg, uint3
|
|
|
|
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int Q_ack_prime = srslte_uci_nr_pusch_ack_nof_re(cfg, O_ack);
|
|
|
|
|
int Q_ack_prime = uci_nr_pusch_Q_prime_ack(cfg, O_ack);
|
|
|
|
|
if (Q_ack_prime < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error calculating number of RE");
|
|
|
|
|
return Q_ack_prime;
|
|
|
|
@ -935,7 +1062,7 @@ int srslte_uci_nr_decode_pusch_ack(srslte_uci_nr_t* q,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Decode
|
|
|
|
|
if (uci_nr_decode(q, cfg, llr, E_uci, &value->valid) < SRSLTE_SUCCESS) {
|
|
|
|
|
if (uci_nr_decode(q, cfg, llr, A, E_uci, &value->valid) < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error decoding UCI");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
@ -943,5 +1070,133 @@ int srslte_uci_nr_decode_pusch_ack(srslte_uci_nr_t* q,
|
|
|
|
|
// Unpack
|
|
|
|
|
srslte_vec_u8_copy(value->ack, q->bit_sequence, A);
|
|
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int uci_nr_pusch_Q_prime_csi1(const srslte_uci_nr_pusch_cfg_t* cfg, uint32_t O_csi1, uint32_t O_ack)
|
|
|
|
|
{
|
|
|
|
|
if (cfg == NULL) {
|
|
|
|
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t L_ack = srslte_uci_nr_crc_len(O_csi1); // Number of CRC bits
|
|
|
|
|
uint32_t Qm = srslte_mod_bits_x_symbol(cfg->modulation); // modulation order of the PUSCH
|
|
|
|
|
|
|
|
|
|
uint32_t Q_prime_ack = 0;
|
|
|
|
|
int n = uci_nr_pusch_Q_prime_ack(cfg, SRSLTE_MAX(2, O_ack));
|
|
|
|
|
if (n < SRSLTE_ERROR) {
|
|
|
|
|
ERROR("Calculating Q_prime_ack");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t M_uci_sum = 0;
|
|
|
|
|
uint32_t M_uci_l0_sum = 0;
|
|
|
|
|
for (uint32_t l = 0; l < SRSLTE_NSYMB_PER_SLOT_NR; l++) {
|
|
|
|
|
M_uci_sum += cfg->M_uci_sc[l];
|
|
|
|
|
if (l >= cfg->l0) {
|
|
|
|
|
M_uci_l0_sum += cfg->M_uci_sc[l];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isnormal(cfg->R)) {
|
|
|
|
|
ERROR("Invalid Rate (%f)", cfg->R);
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cfg->K_sum == 0) {
|
|
|
|
|
if (cfg->csi_part2_present) {
|
|
|
|
|
return (int)SRSLTE_MIN(ceilf(((O_csi1 + L_ack) * cfg->beta_csi1_offset) / (Qm * cfg->R)),
|
|
|
|
|
cfg->alpha * M_uci_l0_sum - Q_prime_ack);
|
|
|
|
|
}
|
|
|
|
|
return (int)(M_uci_sum - Q_prime_ack);
|
|
|
|
|
}
|
|
|
|
|
return (int)SRSLTE_MIN(ceilf(((O_csi1 + L_ack) * cfg->beta_csi1_offset * M_uci_sum) / cfg->K_sum),
|
|
|
|
|
ceilf(cfg->alpha * M_uci_l0_sum) - Q_prime_ack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int srslte_uci_nr_pusch_csi1_nof_bits(const srslte_uci_cfg_nr_t* cfg)
|
|
|
|
|
{
|
|
|
|
|
// Check inputs
|
|
|
|
|
if (cfg == NULL) {
|
|
|
|
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int O_csi1 = srslte_csi_part1_nof_bits(cfg->csi, cfg->nof_csi);
|
|
|
|
|
if (O_csi1 < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Errpr calculating CSI part 1 number of bits");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
uint32_t O_ack = SRSLTE_MAX(2, cfg->o_ack);
|
|
|
|
|
|
|
|
|
|
int Q_csi1_prime = uci_nr_pusch_Q_prime_csi1(&cfg->pusch, (uint32_t)O_csi1, O_ack);
|
|
|
|
|
if (Q_csi1_prime < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error calculating number of RE");
|
|
|
|
|
return Q_csi1_prime;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (int)(Q_csi1_prime * cfg->pusch.nof_layers * srslte_mod_bits_x_symbol(cfg->pusch.modulation));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int srslte_uci_nr_encode_pusch_csi1(srslte_uci_nr_t* q,
|
|
|
|
|
const srslte_uci_cfg_nr_t* cfg,
|
|
|
|
|
const srslte_uci_value_nr_t* value,
|
|
|
|
|
uint8_t* o)
|
|
|
|
|
{
|
|
|
|
|
// Check inputs
|
|
|
|
|
if (q == NULL || cfg == NULL || value == NULL || o == NULL) {
|
|
|
|
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int A = srslte_csi_part1_pack(cfg->csi, value->csi, cfg->nof_csi, q->bit_sequence, SRSLTE_UCI_NR_MAX_NOF_BITS);
|
|
|
|
|
if (A < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error packing CSI part 1 report");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Compute total of encoded bits according to 6.3.2.4 Rate matching
|
|
|
|
|
int E_uci = srslte_uci_nr_pusch_csi1_nof_bits(cfg);
|
|
|
|
|
if (E_uci < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error calculating number of encoded bits");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return uci_nr_encode(q, cfg, A, o, E_uci);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int srslte_uci_nr_decode_pusch_csi1(srslte_uci_nr_t* q,
|
|
|
|
|
const srslte_uci_cfg_nr_t* cfg,
|
|
|
|
|
int8_t* llr,
|
|
|
|
|
srslte_uci_value_nr_t* value)
|
|
|
|
|
{
|
|
|
|
|
// Check inputs
|
|
|
|
|
if (q == NULL || cfg == NULL || llr == NULL || value == NULL) {
|
|
|
|
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Compute total of encoded bits according to 6.3.2.4 Rate matching
|
|
|
|
|
int E_uci = srslte_uci_nr_pusch_csi1_nof_bits(cfg);
|
|
|
|
|
if (E_uci < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error calculating number of encoded bits");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int A = srslte_csi_part1_nof_bits(cfg->csi, cfg->nof_csi);
|
|
|
|
|
if (A < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error getting number of CSI part 1 bits");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Decode
|
|
|
|
|
if (uci_nr_decode(q, cfg, llr, (uint32_t)A, (uint32_t)E_uci, &value->valid) < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error decoding UCI");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Unpack
|
|
|
|
|
if (srslte_csi_part1_unpack(cfg->csi, cfg->nof_csi, q->bit_sequence, A, value->csi) < SRSLTE_SUCCESS) {
|
|
|
|
|
ERROR("Error unpacking CSI");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
|
}
|