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, unsigned char harq_pid,
uint32_t pdsch_est_size, uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][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], int16_t *llr[2],
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT], uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], 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 rx_size_symbol,
int nbRx, int nbRx,
c16_t rxdataF_comp[][dlsch->Nl][nbRx][rx_size_symbol], 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], c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT], int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
int G, 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]; __attribute__((aligned(32))) int32_t dl_ch_estimates_ext[matrixSz][rx_size_symbol];
memset(dl_ch_estimates_ext, 0, sizeof(dl_ch_estimates_ext)); 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; NR_UE_COMMON *common_vars = &ue->common_vars;
PHY_NR_MEASUREMENTS *measurements = &ue->measurements; PHY_NR_MEASUREMENTS *measurements = &ue->measurements;
const int frame = proc->frame_rx; const int frame = proc->frame_rx;
@@ -1268,9 +1261,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
nl, nl,
rxdataF_ext, rxdataF_ext,
dl_ch_estimates_ext, dl_ch_estimates_ext,
dl_ch_mag, dl_ch_mag[symbol],
dl_ch_magb, dl_ch_magb[symbol],
dl_ch_magr, dl_ch_magr[symbol],
rxdataF_comp, rxdataF_comp,
NULL, NULL,
fp, fp,
@@ -1319,9 +1312,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
n_rx, n_rx,
rxdataF_comp, rxdataF_comp,
NULL, NULL,
dl_ch_mag, dl_ch_mag[symbol],
dl_ch_magb, dl_ch_magb[symbol],
dl_ch_magr, dl_ch_magr[symbol],
symbol, symbol,
nb_re_pdsch); nb_re_pdsch);
if (nl >= 2) // Apply MMSE for 2, 3, and 4 Tx layers 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, n_rx,
nl, nl,
rxdataF_comp, rxdataF_comp,
dl_ch_mag, dl_ch_mag[symbol],
dl_ch_magb, dl_ch_magb[symbol],
dl_ch_magr, dl_ch_magr[symbol],
dl_ch_estimates_ext, dl_ch_estimates_ext,
dlsch_config->qamModOrder, dlsch_config->qamModOrder,
*log2_maxh, *log2_maxh,
@@ -1383,28 +1376,39 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
dlsch); dlsch);
dl_valid_re[symbol] -= ptrs_re_per_slot[0][symbol]; 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 if (symbol < startSymbIdx + nbSymb - 1) // up to the penultimate symbol
llr_offset[symbol + 1] = dl_valid_re[symbol] * dlsch_config->qamModOrder + llr_offset[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 */ /* at last symbol in a slot calculate LLR's for whole slot */
if (symbol == (startSymbIdx + nbSymb - 1)) { 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); 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); stop_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING);
/* /*
for (int i=0; i < 2; i++){ for (int i=0; i < 2; i++){
@@ -309,8 +309,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
unsigned char harq_pid, unsigned char harq_pid,
uint32_t pdsch_est_size, uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][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], int16_t *llr[2],
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT], uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], 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 rx_size_symbol,
int nbRx, int nbRx,
c16_t rxdataF_comp[][dlsch->Nl][nbRx][rx_size_symbol], 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], c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT], int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
int G, 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; 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); 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}; pdsch_scope_req_t scope_req = {.copy_chanest_to_scope = false, .copy_rxdataF_to_scope = false, .scope_rxdataF_offset = 0};
if (UEScopeHasTryLock(ue)) { 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, freq_alloc.num_rbs * NR_NB_SC_PER_RB * dlschCfg->number_symbols,
&mt); &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++) { for (int m = dlschCfg->start_symbol; m < (dlschCfg->number_symbols + dlschCfg->start_symbol); m++) {
bool first_symbol_flag = false; bool first_symbol_flag = false;
if (m == first_symbol_with_data) if (m == first_symbol_with_data)
@@ -730,8 +749,6 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
harq_pid, harq_pid,
pdsch_est_size, pdsch_est_size,
pdsch_dl_ch_estimates, pdsch_dl_ch_estimates,
rx_llr_layer_size,
layer_llr,
llr, llr,
dl_valid_re, dl_valid_re,
rxdataF, rxdataF,
@@ -740,6 +757,9 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
rx_size_symbol, rx_size_symbol,
ue->frame_parms.nb_antennas_rx, ue->frame_parms.nb_antennas_rx,
rxdataF_comp, rxdataF_comp,
dl_ch_mag,
dl_ch_magb,
dl_ch_magr,
ptrs_phase_per_slot, ptrs_phase_per_slot,
ptrs_re_per_slot, ptrs_re_per_slot,
G, G,
@@ -764,6 +784,9 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
} }
free(toFree); free(toFree);
free(toFree2); free(toFree2);
free(toFree3);
free(toFree4);
free(toFree5);
return 0; return 0;
} }