bugfix: PTRS phase compensation

PTRS phase error is estimated in each symbol and should be compesation in the
last symbol. So far nr_dlsch_llr() used rxdataF_comp before PTRS phase
correction for all symbol except the last one. This commit fixes it by calling
nr_dlsch_llr() for all symbols after rxdataF_comp is compensated for PTRS phase
error. To do so, dl_ch_mag arrays are moved out of nr_rx_pdsch() to hold values
of all symbols.
This commit is contained in:
Sakthivel Velumani
2026-03-18 18:59:04 +00:00
parent 7c36011669
commit 07f5e01ee8
3 changed files with 76 additions and 48 deletions
@@ -985,8 +985,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
unsigned char harq_pid,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
int layer_llr_size,
int16_t layer_llr[][layer_llr_size],
int16_t *llr[2],
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
@@ -995,6 +993,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
int rx_size_symbol,
int nbRx,
c16_t rxdataF_comp[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t dl_ch_mag[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t dl_ch_magb[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t dl_ch_magr[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
int G,
@@ -1008,14 +1009,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
__attribute__((aligned(32))) int32_t dl_ch_estimates_ext[matrixSz][rx_size_symbol];
memset(dl_ch_estimates_ext, 0, sizeof(dl_ch_estimates_ext));
__attribute__((aligned(32))) c16_t dl_ch_mag[nl][n_rx][rx_size_symbol];
memset(dl_ch_mag, 0, sizeof(dl_ch_mag));
__attribute__((aligned(32))) c16_t dl_ch_magb[nl][nbRx][rx_size_symbol];
memset(dl_ch_magb, 0, sizeof(dl_ch_magb));
__attribute__((aligned(32))) c16_t dl_ch_magr[nl][nbRx][rx_size_symbol];
memset(dl_ch_magr, 0, sizeof(dl_ch_magr));
NR_UE_COMMON *common_vars = &ue->common_vars;
PHY_NR_MEASUREMENTS *measurements = &ue->measurements;
const int frame = proc->frame_rx;
@@ -1268,9 +1261,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
nl,
rxdataF_ext,
dl_ch_estimates_ext,
dl_ch_mag,
dl_ch_magb,
dl_ch_magr,
dl_ch_mag[symbol],
dl_ch_magb[symbol],
dl_ch_magr[symbol],
rxdataF_comp,
NULL,
fp,
@@ -1319,9 +1312,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
n_rx,
rxdataF_comp,
NULL,
dl_ch_mag,
dl_ch_magb,
dl_ch_magr,
dl_ch_mag[symbol],
dl_ch_magb[symbol],
dl_ch_magr[symbol],
symbol,
nb_re_pdsch);
if (nl >= 2) // Apply MMSE for 2, 3, and 4 Tx layers
@@ -1330,9 +1323,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
n_rx,
nl,
rxdataF_comp,
dl_ch_mag,
dl_ch_magb,
dl_ch_magr,
dl_ch_mag[symbol],
dl_ch_magb[symbol],
dl_ch_magr[symbol],
dl_ch_estimates_ext,
dlsch_config->qamModOrder,
*log2_maxh,
@@ -1383,28 +1376,39 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
dlsch);
dl_valid_re[symbol] -= ptrs_re_per_slot[0][symbol];
}
start_meas_nr_ue_phy(ue, DLSCH_LLR_STATS);
nr_dlsch_llr(rx_size_symbol,
nbRx,
layer_llr_size,
nl,
layer_llr,
rxdataF_comp,
dl_ch_mag[0][0],
dl_ch_magb[0][0],
dl_ch_magr[0][0],
dlsch1_harq,
symbol,
dl_valid_re[symbol],
dlsch,
llr_offset[symbol]);
if (symbol < startSymbIdx + nbSymb - 1) // up to the penultimate symbol
llr_offset[symbol + 1] = dl_valid_re[symbol] * dlsch_config->qamModOrder + llr_offset[symbol];
stop_meas_nr_ue_phy(ue, DLSCH_LLR_STATS);
/* at last symbol in a slot calculate LLR's for whole slot */
if (symbol == (startSymbIdx + nbSymb - 1)) {
const uint32_t rx_llr_layer_size = (G + dlsch[0].Nl - 1) / dlsch[0].Nl;
if (dlsch[0].Nl == 0 || rx_llr_layer_size == 0 || rx_llr_layer_size > 10 * 1000 * 1000) {
LOG_E(PHY, "rx_llr_layer_size %d, G %d, Nl, %d, discarding this pdsch\n", rx_llr_layer_size, G, dlsch[0].Nl);
return -1;
}
__attribute__((aligned(32))) int16_t layer_llr[dlsch[0].Nl][rx_llr_layer_size];
// Generate LLR from PTRS compensated signal
start_meas_nr_ue_phy(ue, DLSCH_LLR_STATS);
for (int llr_sym = startSymbIdx; llr_sym < startSymbIdx + nbSymb; llr_sym++) {
nr_dlsch_llr(rx_size_symbol,
nbRx,
rx_llr_layer_size,
nl,
layer_llr,
rxdataF_comp,
dl_ch_mag[llr_sym][0][0],
dl_ch_magb[llr_sym][0][0],
dl_ch_magr[llr_sym][0][0],
dlsch1_harq,
llr_sym,
dl_valid_re[llr_sym],
dlsch,
llr_offset[llr_sym]);
}
stop_meas_nr_ue_phy(ue, DLSCH_LLR_STATS);
start_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING);
nr_dlsch_layer_demapping(llr, dlsch[0].Nl, dlsch_config->qamModOrder, G, codeword_TB0, codeword_TB1, layer_llr_size, layer_llr);
nr_dlsch_layer_demapping(llr, dlsch[0].Nl, dlsch_config->qamModOrder, G, codeword_TB0, codeword_TB1, rx_llr_layer_size, layer_llr);
stop_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING);
/*
for (int i=0; i < 2; i++){
@@ -309,8 +309,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
unsigned char harq_pid,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
int layer_llr_size,
int16_t layer_llr[][layer_llr_size],
int16_t *llr[2],
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
@@ -319,6 +317,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
int rx_size_symbol,
int nbRx,
c16_t rxdataF_comp[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t dl_ch_mag[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t dl_ch_magb[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t dl_ch_magr[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
int G,
+33 -10
View File
@@ -689,14 +689,6 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
int32_t log2_maxh = 0;
const uint32_t rx_llr_layer_size = (G + dlsch[0].Nl - 1) / dlsch[0].Nl;
if (dlsch[0].Nl == 0 || rx_llr_layer_size == 0 || rx_llr_layer_size > 10 * 1000 * 1000) {
LOG_E(PHY, "rx_llr_layer_size %d, G %d, Nl, %d, discarding this pdsch\n", rx_llr_layer_size, G, dlsch[0].Nl);
return -1;
}
__attribute__((aligned(32))) int16_t layer_llr[dlsch[0].Nl][rx_llr_layer_size];
start_meas_nr_ue_phy(ue, RX_PDSCH_STATS);
pdsch_scope_req_t scope_req = {.copy_chanest_to_scope = false, .copy_rxdataF_to_scope = false, .scope_rxdataF_offset = 0};
if (UEScopeHasTryLock(ue)) {
@@ -714,6 +706,33 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
freq_alloc.num_rbs * NR_NB_SC_PER_RB * dlschCfg->number_symbols,
&mt);
}
fourDimArray_t *toFree3 = NULL;
allocCast4D(dl_ch_mag,
c16_t,
toFree3,
NR_SYMBOLS_PER_SLOT,
dlsch[0].Nl,
ue->frame_parms.nb_antennas_rx,
rx_size_symbol,
false);
fourDimArray_t *toFree4 = NULL;
allocCast4D(dl_ch_magb,
c16_t,
toFree4,
NR_SYMBOLS_PER_SLOT,
dlsch[0].Nl,
ue->frame_parms.nb_antennas_rx,
rx_size_symbol,
false);
fourDimArray_t *toFree5 = NULL;
allocCast4D(dl_ch_magr,
c16_t,
toFree5,
NR_SYMBOLS_PER_SLOT,
dlsch[0].Nl,
ue->frame_parms.nb_antennas_rx,
rx_size_symbol,
false);
for (int m = dlschCfg->start_symbol; m < (dlschCfg->number_symbols + dlschCfg->start_symbol); m++) {
bool first_symbol_flag = false;
if (m == first_symbol_with_data)
@@ -730,8 +749,6 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
harq_pid,
pdsch_est_size,
pdsch_dl_ch_estimates,
rx_llr_layer_size,
layer_llr,
llr,
dl_valid_re,
rxdataF,
@@ -740,6 +757,9 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
rx_size_symbol,
ue->frame_parms.nb_antennas_rx,
rxdataF_comp,
dl_ch_mag,
dl_ch_magb,
dl_ch_magr,
ptrs_phase_per_slot,
ptrs_re_per_slot,
G,
@@ -764,6 +784,9 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
}
free(toFree);
free(toFree2);
free(toFree3);
free(toFree4);
free(toFree5);
return 0;
}