mirror of https://github.com/PentHertz/srsLTE.git
Fix UL control decoding. Some minor aesthetic changes.
This commit is contained in:
parent
44a5ce172e
commit
64caa4321b
|
@ -39,13 +39,14 @@
|
||||||
#include "srslte/phy/phch/pucch_cfg.h"
|
#include "srslte/phy/phch/pucch_cfg.h"
|
||||||
#include "srslte/phy/phch/uci.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_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_1A_2A_NOF_ACK (1)
|
||||||
#define SRSLTE_PUCCH_1B_2B_NOF_ACK (2)
|
#define SRSLTE_PUCCH_1B_2B_NOF_ACK (2)
|
||||||
#define SRSLTE_PUCCH3_NOF_BITS (4 * SRSLTE_NRE)
|
#define SRSLTE_PUCCH3_NOF_BITS (4 * SRSLTE_NRE)
|
||||||
#define SRSLTE_PUCCH_MAX_BITS SRSLTE_CQI_MAX_BITS
|
#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
|
// PUCCH Format 1B Channel selection
|
||||||
#define SRSLTE_PUCCH_CS_MAX_ACK 4
|
#define SRSLTE_PUCCH_CS_MAX_ACK 4
|
||||||
|
|
|
@ -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_2:
|
||||||
case SRSLTE_PUCCH_FORMAT_2A:
|
case SRSLTE_PUCCH_FORMAT_2A:
|
||||||
case SRSLTE_PUCCH_FORMAT_2B:
|
case SRSLTE_PUCCH_FORMAT_2B:
|
||||||
return 5;
|
return SRSLTE_PUCCH2_N_SF;
|
||||||
case SRSLTE_PUCCH_FORMAT_3:
|
case SRSLTE_PUCCH_FORMAT_3:
|
||||||
if (!slot_idx) {
|
if (!slot_idx) {
|
||||||
return 5;
|
return 5;
|
||||||
|
@ -474,8 +474,9 @@ static int encode_signal_format12(srslte_pucch_t* q,
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < SRSLTE_PUCCH_MAX_BITS / 2; i++) {
|
// Set all ones
|
||||||
q->d[i] = 1.0;
|
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);
|
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_2:
|
||||||
case SRSLTE_PUCCH_FORMAT_2A:
|
case SRSLTE_PUCCH_FORMAT_2A:
|
||||||
case SRSLTE_PUCCH_FORMAT_2B:
|
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) {
|
if (seq) {
|
||||||
encode_signal_format12(q, sf, cfg, NULL, ref, true);
|
encode_signal_format12(q, sf, cfg, NULL, ref, true);
|
||||||
srslte_vec_prod_conj_ccc(q->z, ref, q->z_tmp, SRSLTE_PUCCH_MAX_SYMBOLS);
|
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++) {
|
for (int i = 0; i < (SRSLTE_PUCCH2_N_SF * SRSLTE_NOF_SLOTS_PER_SF); i++) {
|
||||||
q->z[i] = 0;
|
q->z[i] = srslte_vec_acc_cc(&q->z_tmp[i * SRSLTE_NRE], SRSLTE_NRE) / SRSLTE_NRE;
|
||||||
for (int j = 0; j < SRSLTE_NRE; j++) {
|
|
||||||
q->z[i] += q->z_tmp[i * SRSLTE_NRE + j] / SRSLTE_NRE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
srslte_demod_soft_demodulate_s(SRSLTE_MOD_QPSK, q->z, llr_pucch2, SRSLTE_PUCCH2_NOF_BITS / 2);
|
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);
|
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;
|
detected = true;
|
||||||
} else {
|
} else {
|
||||||
ERROR("Decoding PUCCH2: could not generate sequence\n");
|
ERROR("Decoding PUCCH2: could not generate sequence\n");
|
||||||
|
@ -905,6 +912,19 @@ int srslte_pucch_decode(srslte_pucch_t* q,
|
||||||
// Equalization
|
// Equalization
|
||||||
srslte_predecoding_single(q->z_tmp, q->ce, q->z, NULL, nof_re, 1.0f, channel->noise_estimate);
|
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
|
// Perform ML-decoding
|
||||||
bool pucch_found = decode_signal(q, sf, cfg, pucch_bits, nof_re, nof_uci_bits, &data->correlation);
|
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_2:
|
||||||
case SRSLTE_PUCCH_FORMAT_2A:
|
case SRSLTE_PUCCH_FORMAT_2A:
|
||||||
case SRSLTE_PUCCH_FORMAT_2B:
|
case SRSLTE_PUCCH_FORMAT_2B:
|
||||||
data->uci_data.ack.valid = data->correlation > cfg->threshold_data_valid_format2;
|
data->detected = data->correlation > cfg->threshold_data_valid_format2;
|
||||||
data->uci_data.cqi.data_crc = data->correlation > cfg->threshold_data_valid_format2;
|
data->uci_data.ack.valid = data->detected;
|
||||||
|
data->uci_data.cqi.data_crc = data->detected;
|
||||||
break;
|
break;
|
||||||
case SRSLTE_PUCCH_FORMAT_1:
|
case SRSLTE_PUCCH_FORMAT_1:
|
||||||
case SRSLTE_PUCCH_FORMAT_3:
|
case SRSLTE_PUCCH_FORMAT_3:
|
||||||
|
|
|
@ -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;
|
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;
|
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
|
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;
|
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])
|
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) {
|
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++) {
|
for (uint32_t j = 0; j < Qm; j++, count_acc++) {
|
||||||
// Calculate circular LLR index
|
// Calculate circular LLR index
|
||||||
uint32_t acc_idx = count_acc % nof_acc;
|
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
|
// Accumulate LLR
|
||||||
llr_acc[acc_idx] += q_bits[ack_ri_bits[count_acc].position];
|
llr_acc[acc_idx] += q;
|
||||||
|
|
||||||
/// Limit accumulator boundaries
|
/// Limit accumulator boundaries
|
||||||
llr_acc[acc_idx] = SRSLTE_MIN(llr_acc[acc_idx], INT16_MAX / 2);
|
llr_acc[acc_idx] = SRSLTE_MIN(llr_acc[acc_idx], INT16_MAX / 2);
|
||||||
|
|
|
@ -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;
|
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;
|
uci_data->cfg.ack[i].nof_acks = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
// 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.
|
// 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
|
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 = 1; i < ack_info->nof_cc; i++) {
|
||||||
for (int i = 0; i < ack_info->nof_cc; i++) {
|
uci_data->cfg.ack[i].nof_acks = 0;
|
||||||
uci_data->cfg.ack[i].nof_acks = nof_tb;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// For 2 or more configured cells, report nof_tb per carrier except if there are no HARQ-ACK bits to report, in
|
// 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;
|
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
|
// n_cce values are just copied
|
||||||
|
|
|
@ -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;
|
int ret = SRSLTE_ERROR;
|
||||||
|
|
||||||
if (cc_idx < cc_workers.size()) {
|
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;
|
ret = SRSLTE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue