mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Merge remote-tracking branch 'alexjiao2021/fix-issue-216' into integration_2026_w26
Fix for issue 216 (#221) When O_ACK <= 2, the reserved HARQ-ACK positions are selected from the codeword using a d-factor stepping algorithm. The d-factor was computed and applied at bit granularity, causing it to step through the flat positions array mid-modulation-group when Qm > 1. This scattered ACK/placeholder bits across more REs than intended, mismatching the RE selection of the demultiplexer which operates at RE granularity. As a result, placeholder positions were marked on REs that the gNB treats as pure ULSCH, causing those positions to be transmitted without the normal scrambling sequence XOR. This corrupts the ULSCH soft bits at the gNB side, leading to PUSCH CRC failure. Fix: compute the d-factor in RE units and step through the positions array in strides of d_factor_re * Qm so that whole Qm-bit modulation groups are always selected or skipped together. Observed with O_ACK=1, MCS27 (256QAM), beta_offset_idx=11 where Q_dash_ACK=6 (reserved) vs Q_dash_ACK_actual=3, giving d_factor=2. PUSCH CRC was KO at third-party signal analyzers (MATLAB/WaveJudge) while the OCUDU gNB could still decode due to soft LDPC margin. Closes: #216 Reviewed-by: Francesco Mani <email@francescomani.it> Reviewed-by: Sakthivel Velumani <s.velumani@northeastern.edu>
This commit is contained in:
@@ -882,15 +882,19 @@ static void map_overlapped_ack(uci_on_pusch_bit_type_t *template,
|
||||
const int32_t num_ack_remaining = G_ack - ack_bits_marked;
|
||||
if (num_ack_remaining <= 0)
|
||||
continue;
|
||||
const uint32_t d_factor_re = get_d_factor_re(num_ack_remaining, num_reserved_bits_on_sym);
|
||||
for (uint32_t i = 0; i < num_reserved_bits_on_sym && ack_bits_marked < G_ack; i += d_factor_re) {
|
||||
uint32_t pos = reserved_indices_on_this_sym[i];
|
||||
int bit_in_group = pos % Qm;
|
||||
if (template[pos] == BIT_TYPE_ULSCH) // puncturing ULSCH
|
||||
template[pos] = (bit_in_group >= placeholder_start) ? BIT_TYPE_ACK_PLACEHOLDER : BIT_TYPE_ACK_RESERVED;
|
||||
else // puncturing CSIp2
|
||||
template[pos] = (bit_in_group >= placeholder_start) ? BIT_TYPE_ACK_PLACEHOLDER_CSI2 : BIT_TYPE_ACK_RESERVED_CSI2;
|
||||
ack_bits_marked++;
|
||||
const uint32_t num_reserved_re = num_reserved_bits_on_sym / Qm;
|
||||
const uint32_t num_ack_re_remaining = num_ack_remaining / Qm;
|
||||
const uint32_t d_factor_re = get_d_factor_re(num_ack_re_remaining, num_reserved_re);
|
||||
for (uint32_t re = 0; re < num_reserved_re && ack_bits_marked < G_ack; re += d_factor_re) {
|
||||
for (int b = 0; b < Qm; b++) {
|
||||
uint32_t pos = reserved_indices_on_this_sym[re * Qm + b];
|
||||
int bit_in_group = pos % Qm;
|
||||
if (template[pos] == BIT_TYPE_ULSCH) // puncturing ULSCH
|
||||
template[pos] = (bit_in_group >= placeholder_start) ? BIT_TYPE_ACK_PLACEHOLDER : BIT_TYPE_ACK_RESERVED;
|
||||
else // puncturing CSIp2
|
||||
template[pos] = (bit_in_group >= placeholder_start) ? BIT_TYPE_ACK_PLACEHOLDER_CSI2 : BIT_TYPE_ACK_RESERVED_CSI2;
|
||||
ack_bits_marked++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user