Fix UL control decoding. Some minor aesthetic changes.

This commit is contained in:
Xavier Arteaga 2020-03-06 19:58:37 +01:00 committed by Xavier Arteaga
parent 44a5ce172e
commit 64caa4321b
5 changed files with 92 additions and 56 deletions

View File

@ -39,13 +39,14 @@
#include "srslte/phy/phch/pucch_cfg.h"
#include "srslte/phy/phch/uci.h"
#define SRSLTE_PUCCH_N_SEQ 12
#define SRSLTE_PUCCH_N_SEQ SRSLTE_NRE
#define SRSLTE_PUCCH2_NOF_BITS SRSLTE_UCI_CQI_CODED_PUCCH_B
#define SRSLTE_PUCCH2_N_SF (5)
#define SRSLTE_PUCCH_1A_2A_NOF_ACK (1)
#define SRSLTE_PUCCH_1B_2B_NOF_ACK (2)
#define SRSLTE_PUCCH3_NOF_BITS (4 * SRSLTE_NRE)
#define SRSLTE_PUCCH_MAX_BITS SRSLTE_CQI_MAX_BITS
#define SRSLTE_PUCCH_MAX_SYMBOLS 128
#define SRSLTE_PUCCH_MAX_SYMBOLS (SRSLTE_PUCCH_N_SEQ * SRSLTE_PUCCH2_N_SF * SRSLTE_NOF_SLOTS_PER_SF)
// PUCCH Format 1B Channel selection
#define SRSLTE_PUCCH_CS_MAX_ACK 4

View File

@ -356,7 +356,7 @@ static uint32_t get_N_sf(srslte_pucch_format_t format, uint32_t slot_idx, bool s
case SRSLTE_PUCCH_FORMAT_2:
case SRSLTE_PUCCH_FORMAT_2A:
case SRSLTE_PUCCH_FORMAT_2B:
return 5;
return SRSLTE_PUCCH2_N_SF;
case SRSLTE_PUCCH_FORMAT_3:
if (!slot_idx) {
return 5;
@ -474,8 +474,9 @@ static int encode_signal_format12(srslte_pucch_t* q,
return SRSLTE_ERROR;
}
} else {
for (int i = 0; i < SRSLTE_PUCCH_MAX_BITS / 2; i++) {
q->d[i] = 1.0;
// Set all ones
for (uint32_t i = 0; i < SRSLTE_PUCCH_MAX_BITS / 2; i++) {
q->d[i] = 1.0f;
}
}
uint32_t N_sf_0 = get_N_sf(cfg->format, 0, sf->shortened);
@ -774,19 +775,25 @@ static bool decode_signal(srslte_pucch_t* q,
case SRSLTE_PUCCH_FORMAT_2:
case SRSLTE_PUCCH_FORMAT_2A:
case SRSLTE_PUCCH_FORMAT_2B:
seq = get_user_sequence(q, cfg->rnti, sf->tti % 10);
seq = get_user_sequence(q, cfg->rnti, sf->tti % SRSLTE_NOF_SF_X_FRAME);
if (seq) {
encode_signal_format12(q, sf, cfg, NULL, ref, true);
srslte_vec_prod_conj_ccc(q->z, ref, q->z_tmp, SRSLTE_PUCCH_MAX_SYMBOLS);
for (int i = 0; i < SRSLTE_PUCCH2_NOF_BITS / 2; i++) {
q->z[i] = 0;
for (int j = 0; j < SRSLTE_NRE; j++) {
q->z[i] += q->z_tmp[i * SRSLTE_NRE + j] / SRSLTE_NRE;
}
for (int i = 0; i < (SRSLTE_PUCCH2_N_SF * SRSLTE_NOF_SLOTS_PER_SF); i++) {
q->z[i] = srslte_vec_acc_cc(&q->z_tmp[i * SRSLTE_NRE], SRSLTE_NRE) / SRSLTE_NRE;
}
srslte_demod_soft_demodulate_s(SRSLTE_MOD_QPSK, q->z, llr_pucch2, SRSLTE_PUCCH2_NOF_BITS / 2);
srslte_scrambling_s_offset(seq, llr_pucch2, 0, SRSLTE_PUCCH2_NOF_BITS);
corr = (float)srslte_uci_decode_cqi_pucch(&q->cqi, llr_pucch2, pucch_bits, nof_uci_bits) / 2000;
// Calculate the LLR RMS for normalising
float llr_pow = srslte_vec_avg_power_sf(llr_pucch2, SRSLTE_PUCCH2_NOF_BITS);
if (isnormal(llr_pow)) {
float llr_rms = sqrtf(llr_pow) * SRSLTE_PUCCH2_NOF_BITS;
corr = ((float)srslte_uci_decode_cqi_pucch(&q->cqi, llr_pucch2, pucch_bits, nof_uci_bits)) / (llr_rms);
} else {
corr = 0;
}
detected = true;
} else {
ERROR("Decoding PUCCH2: could not generate sequence\n");
@ -905,6 +912,19 @@ int srslte_pucch_decode(srslte_pucch_t* q,
// Equalization
srslte_predecoding_single(q->z_tmp, q->ce, q->z, NULL, nof_re, 1.0f, channel->noise_estimate);
// DMRS Detection
cf_t _dmrs_corr = srslte_vec_acc_cc(q->ce, nof_re) / nof_re;
float _rms = __real__(conjf(_dmrs_corr) * _dmrs_corr);
float _pow = srslte_vec_avg_power_cf(q->ce, nof_re);
float _r = _rms / _pow;
// Return not detected if the ratio is 0, NAN, +/- Infinity or below 0.1
if (!isnormal(_r) || _r < 0.1f) {
data->detected = false;
data->correlation = NAN;
return SRSLTE_SUCCESS;
}
// Perform ML-decoding
bool pucch_found = decode_signal(q, sf, cfg, pucch_bits, nof_re, nof_uci_bits, &data->correlation);
@ -922,8 +942,9 @@ int srslte_pucch_decode(srslte_pucch_t* q,
case SRSLTE_PUCCH_FORMAT_2:
case SRSLTE_PUCCH_FORMAT_2A:
case SRSLTE_PUCCH_FORMAT_2B:
data->uci_data.ack.valid = data->correlation > cfg->threshold_data_valid_format2;
data->uci_data.cqi.data_crc = data->correlation > cfg->threshold_data_valid_format2;
data->detected = data->correlation > cfg->threshold_data_valid_format2;
data->uci_data.ack.valid = data->detected;
data->uci_data.cqi.data_crc = data->detected;
break;
case SRSLTE_PUCCH_FORMAT_1:
case SRSLTE_PUCCH_FORMAT_3:

View File

@ -620,7 +620,7 @@ static uint32_t Q_prime_ri_ack(srslte_pusch_cfg_t* cfg, uint32_t O, uint32_t O_c
return Q_prime;
}
static uint32_t encode_ri_ack(uint8_t data[2], uint32_t O_ack, uint8_t Qm, srslte_uci_bit_t* q_encoded_bits)
static uint32_t encode_ri_ack(const uint8_t data[2], uint32_t O_ack, uint8_t Qm, srslte_uci_bit_t* q_encoded_bits)
{
uint32_t i = 0;
@ -652,7 +652,7 @@ static uint32_t encode_ri_ack(uint8_t data[2], uint32_t O_ack, uint8_t Qm, srslt
}
static uint32_t
encode_ack_long(uint8_t* data, uint32_t O_ack, uint8_t Q_m, uint32_t Q_prime, srslte_uci_bit_t* q_encoded_bits)
encode_ack_long(const uint8_t* data, uint32_t O_ack, uint8_t Q_m, uint32_t Q_prime, srslte_uci_bit_t* q_encoded_bits)
{
uint32_t Q_ack = Q_m * Q_prime;
@ -674,15 +674,8 @@ encode_ack_long(uint8_t* data, uint32_t O_ack, uint8_t Q_m, uint32_t Q_prime, sr
static void decode_ri_ack_1bit(const int16_t* q_bits, const uint8_t* c_seq, uint8_t data[1])
{
// Unscramble p1
int16_t q1 = c_seq[1] ? -q_bits[1] : q_bits[1];
// Scramble with correct position
int16_t q0 = q_bits[0];
q1 = c_seq[0] ? -q1 : q1;
if (data) {
data[0] = ((q0 + q1) > 0) ? 1 : 0;
data[0] = ((q_bits[0] + q_bits[1]) > 0) ? 1 : 0;
}
}
@ -829,9 +822,19 @@ int srslte_uci_decode_ack_ri(srslte_pusch_cfg_t* cfg,
for (uint32_t j = 0; j < Qm; j++, count_acc++) {
// Calculate circular LLR index
uint32_t acc_idx = count_acc % nof_acc;
uint32_t pos = ack_ri_bits[count_acc].position;
int16_t q = q_bits[pos];
// Remove scrambling of repeated bits
if (nof_bits == 1) {
if (acc_idx == 1 && pos > 0) {
q = (c_seq[pos] == c_seq[pos - 1]) ? +q : -q;
}
}
// Accumulate LLR
llr_acc[acc_idx] += q_bits[ack_ri_bits[count_acc].position];
llr_acc[acc_idx] += q;
/// Limit accumulator boundaries
llr_acc[acc_idx] = SRSLTE_MIN(llr_acc[acc_idx], INT16_MAX / 2);

View File

@ -969,7 +969,7 @@ static void gen_ack_fdd(const srslte_pdsch_ack_t* ack_info, srslte_uci_data_t* u
uci_data->value.ack.ack_value[cc_idx] = 2;
}
}
for (uint32_t i = 0; i < 2; i++) {
for (uint32_t i = 0; i < SRSLTE_PUCCH_CS_MAX_CARRIERS; i++) {
uci_data->cfg.ack[i].nof_acks = 1;
}
} else {
@ -1017,36 +1017,9 @@ static void gen_ack_fdd(const srslte_pdsch_ack_t* ack_info, srslte_uci_data_t* u
// subframe n 4 , the UE shall use PUCCH format 3 and PUCCH resource n_pucch_3 where the value of n PUCCH
// is determined according to higher layer configuration and Table 10.1.2.2.2-1.
uci_data->cfg.ack[0].nof_acks = tb_count_cc0; // So, set only PCell
} else if (uci_data->cfg.cqi.data_enable && !ack_info->is_pusch_available) {
// 3GPP 36.213 R.15 Section 10.1.1:
// For FDD or for FDD-TDD and primary cell frame structure type 1 and for a UE that is configured with more than
// one serving cell, in case of collision between a periodic CSI report and an HARQ-ACK in a same subframe without
// PUSCH,
if (tb_count_cc0 == tb_count && ack_info->simul_cqi_ack) {
// - if the parameter simultaneousAckNackAndCQI provided by higher layers is set TRUE and if the HARQ-ACK
// corresponds to a PDSCH transmission or PDCCH/EPDCCH indicating downlink SPS release only on the
// primary cell, then the periodic CSI report is multiplexed with HARQ-ACK on PUCCH using PUCCH format 2/2a/2b
uci_data->cfg.ack[0].nof_acks = tb_count_cc0;
} else if (ack_info->simul_cqi_ack_pucch3 && total_uci_bits <= 22) {
// - else if the UE is configured with PUCCH format 3 and if the parameter simultaneousAckNackAndCQI-Format3-
// r11 provided by higher layers is set TRUE, and if PUCCH resource is determined according to subclause
// 10.1.2.2.2, and
// - if the total number of bits in the subframe corresponding to HARQ-ACKs, SR (if any), and the CSI is not
// larger than 22 or
// - if the total number of bits in the subframe corresponding to spatially bundled HARQ-ACKs, SR (if any),
// and the CSI is not larger than 22 then the periodic CSI report is multiplexed with HARQ-ACK on PUCCH
// using the determined PUCCH format 3 resource according to [4]
for (int i = 0; i < ack_info->nof_cc; i++) {
uci_data->cfg.ack[i].nof_acks = nof_tb;
}
} else {
// - otherwise, CSI is dropped
uci_data->cfg.cqi.data_enable = false;
//
for (int i = 0; i < ack_info->nof_cc; i++) {
uci_data->cfg.ack[i].nof_acks = nof_tb;
}
for (int i = 1; i < ack_info->nof_cc; i++) {
uci_data->cfg.ack[i].nof_acks = 0;
}
} else {
// For 2 or more configured cells, report nof_tb per carrier except if there are no HARQ-ACK bits to report, in
@ -1055,6 +1028,44 @@ static void gen_ack_fdd(const srslte_pdsch_ack_t* ack_info, srslte_uci_data_t* u
uci_data->cfg.ack[i].nof_acks = nof_tb;
}
}
if (tb_count && uci_data->cfg.cqi.data_enable && !ack_info->is_pusch_available) {
bool drop_csi_report = true; ///< CSI report shall be dropped by default
// 3GPP 36.213 R.15 Section 10.1.1:
// For FDD or for FDD-TDD and primary cell frame structure type 1 and for a UE that is configured with more than
// one serving cell, in case of collision between a periodic CSI report and an HARQ-ACK in a same subframe without
// PUSCH,
// - if the parameter simultaneousAckNackAndCQI provided by higher layers is set TRUE and if the HARQ-ACK
// corresponds to a PDSCH transmission or PDCCH/EPDCCH indicating downlink SPS release only on the
// primary cell, then the periodic CSI report is multiplexed with HARQ-ACK on PUCCH using PUCCH format 2/2a/2b
if ((tb_count_cc0 == tb_count && ack_info->simul_cqi_ack)) {
// Do not drop CSI report
drop_csi_report = false;
// Set number of active only ACKs
uci_data->cfg.ack[0].nof_acks = tb_count_cc0;
// Set all SCell number of ACKs to 0
for (int i = 1; i < ack_info->nof_cc; i++) {
uci_data->cfg.ack[i].nof_acks = 0;
}
}
// - else if the UE is configured with PUCCH format 3 and if the parameter simultaneousAckNackAndCQI-Format3-
// r11 provided by higher layers is set TRUE, and if PUCCH resource is determined according to subclause
// 10.1.2.2.2, and
// - if the total number of bits in the subframe corresponding to HARQ-ACKs, SR (if any), and the CSI is not
// larger than 22 or
// - if the total number of bits in the subframe corresponding to spatially bundled HARQ-ACKs, SR (if any),
// and the CSI is not larger than 22 then the periodic CSI report is multiplexed with HARQ-ACK on PUCCH
// using the determined PUCCH format 3 resource according to [4]
drop_csi_report &= !(ack_info->simul_cqi_ack_pucch3 && total_uci_bits <= 22);
// - otherwise, CSI is dropped
uci_data->cfg.cqi.data_enable = !drop_csi_report;
}
}
// n_cce values are just copied

View File

@ -141,7 +141,7 @@ int sf_worker::add_rnti(uint16_t rnti, uint32_t cc_idx, bool is_pcell, bool is_t
int ret = SRSLTE_ERROR;
if (cc_idx < cc_workers.size()) {
cc_workers[cc_idx]->add_rnti(rnti, true, is_temporal);
cc_workers[cc_idx]->add_rnti(rnti, is_pcell, is_temporal);
ret = SRSLTE_SUCCESS;
}