Commit dc593dee authored by Rupanjali's avatar Rupanjali

NR UE PDSCH: Pre-allocate per-actor scratch buffers to eliminate per-slot heap allocations

Replace all per-slot heap allocations for rxdataF_comp, dl_ch_mag/magb/magr,
rho_dl and pdsch_dl_ch_estimates with a pre-allocated scratch buffer array
stored in PHY_VARS_NR_UE. One scratch set is allocated per DL actor
(num_dl_actors from UE params, defaulting to 1); the actor index is derived
as proc->nr_slot_rx % pdsch_num_actors, giving each parallel DL actor its
own non-overlapping buffer set and eliminating heap contention between actors.

Also remove redundant memset() calls on dl_ch_estimates_ext and rxdataF_ext
stack VLAs, which are fully overwritten by nr_dlsch_extract_rbs() before use.
Signed-off-by: default avatarRupanjali <rupanjali.srivastava@openairinterface.org>
parent 70508eba
......@@ -359,12 +359,26 @@ void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t harq_list[NR_MAX_HARQ_PROCESSES], int nu
}
}
void free_nr_ue_pdsch_buffers(pdsch_scratch_t *buffers, int num_actors)
{
for (int i = 0; i < num_actors; i++) {
free_and_zero(buffers[i].rxdataF_comp);
free_and_zero(buffers[i].dl_ch_mag);
free_and_zero(buffers[i].dl_ch_magb);
free_and_zero(buffers[i].dl_ch_magr);
free_and_zero(buffers[i].rho_dl);
free_and_zero(buffers[i].pdsch_dl_ch_estimates);
}
}
void term_nr_ue_transport(PHY_VARS_NR_UE *ue)
{
const int N_RB_DL = ue->frame_parms.N_RB_DL;
const int N_RB_UL = ue->frame_parms.N_RB_UL;
free_nr_ue_dl_harq(ue->dl_harq_processes, NR_MAX_HARQ_PROCESSES, N_RB_DL);
free_nr_ue_ul_harq(ue->ul_harq_processes, NR_MAX_HARQ_PROCESSES, N_RB_UL, ue->frame_parms.nb_antennas_tx);
free_nr_ue_pdsch_buffers(ue->pdsch_scratch, ue->pdsch_num_actors);
free_and_zero(ue->pdsch_scratch);
}
void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_HARQ_PROCESSES], int number_of_processes, int num_rb)
......@@ -434,10 +448,33 @@ void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t harq_list[NR_MAX_HARQ_PROCESSES],
}
}
void nr_init_pdsch_buffers(pdsch_scratch_t *buffers, int num_actors, const NR_DL_FRAME_PARMS *fp)
{
const uint32_t pdsch_buf_size_max = (fp->N_RB_DL * NR_NB_SC_PER_RB + 15) & ~15;
const uint32_t pdsch_est_size = fp->symbols_per_slot * fp->ofdm_symbol_size;
const size_t comp_elems = (size_t)NR_SYMBOLS_PER_SLOT * NR_MAX_NB_LAYERS * pdsch_buf_size_max;
const size_t rho_elems = (size_t)NR_SYMBOLS_PER_SLOT * NR_MAX_NB_LAYERS * NR_MAX_NB_LAYERS * pdsch_buf_size_max;
const size_t ch_est_elems = (size_t)fp->nb_antennas_rx * NR_MAX_NB_LAYERS * pdsch_est_size;
for (int i = 0; i < num_actors; i++) {
buffers[i].pdsch_buf_size_max = pdsch_buf_size_max;
buffers[i].pdsch_est_size = pdsch_est_size;
buffers[i].rxdataF_comp = malloc16_clear(comp_elems * sizeof(c16_t));
buffers[i].dl_ch_mag = malloc16_clear(comp_elems * sizeof(c16_t));
buffers[i].dl_ch_magb = malloc16_clear(comp_elems * sizeof(c16_t));
buffers[i].dl_ch_magr = malloc16_clear(comp_elems * sizeof(c16_t));
buffers[i].rho_dl = malloc16_clear(rho_elems * sizeof(c16_t));
buffers[i].pdsch_dl_ch_estimates = malloc16_clear(ch_est_elems * sizeof(int32_t));
}
}
void init_nr_ue_transport(PHY_VARS_NR_UE *ue)
{
nr_init_dl_harq_processes(ue->dl_harq_processes, NR_MAX_HARQ_PROCESSES, ue->frame_parms.N_RB_DL);
nr_init_ul_harq_processes(ue->ul_harq_processes, NR_MAX_HARQ_PROCESSES, ue->frame_parms.N_RB_UL, ue->frame_parms.nb_antennas_tx);
const int num_actors = get_nrUE_params()->num_dl_actors > 0 ? get_nrUE_params()->num_dl_actors : 1;
ue->pdsch_num_actors = num_actors;
ue->pdsch_scratch = calloc_or_fail(num_actors, sizeof(*ue->pdsch_scratch));
nr_init_pdsch_buffers(ue->pdsch_scratch, num_actors, &ue->frame_parms);
}
void clean_UE_harq(PHY_VARS_NR_UE *UE)
......
......@@ -28,6 +28,8 @@ void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_HARQ_PROCESSE
void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t harq_list[NR_MAX_HARQ_PROCESSES], int number_of_processes, int num_rb, int num_ant_tx);
void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_HARQ_PROCESSES], int number_of_processes, int num_rb);
void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t harq_list[NR_MAX_HARQ_PROCESSES], int number_of_processes, int num_rb, int num_ant_tx);
void nr_init_pdsch_buffers(pdsch_scratch_t *buffers, int num_actors, const NR_DL_FRAME_PARMS *fp);
void free_nr_ue_pdsch_buffers(pdsch_scratch_t *buffers, int num_actors);
void phy_init_nr_top(PHY_VARS_NR_UE *ue);
void phy_term_nr_top(void);
......
......@@ -247,6 +247,7 @@ static void inner_rx(PHY_VARS_gNB *gNB,
memset(&pusch_vars->rxdataF_comp[i][symbol * buffer_length], 0, sizeof(int32_t) * buffer_length);
nr_channel_compensation(buffer_length,
buffer_length,
nb_rx_ant,
nb_layer,
rxFext,
......@@ -298,6 +299,7 @@ static void inner_rx(PHY_VARS_gNB *gNB,
}
else {
nr_mmse_2layers(pusch_vars->rxdataF_comp,
buffer_length,
buffer_length,
nb_rx_ant,
nb_layer,
......
......@@ -1343,9 +1343,9 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
void nr_pdsch_ptrs_processing(int nbRx,
c16_t ptrs_phase_per_slot[][14],
int32_t ptrs_re_per_slot[][14],
uint32_t rx_size_symbol,
uint32_t pdsch_buf_size_max,
int nl,
c16_t rxdataF_comp[][nl][rx_size_symbol],
c16_t rxdataF_comp[][NR_MAX_NB_LAYERS][pdsch_buf_size_max],
NR_DL_FRAME_PARMS *frame_parms,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
uint8_t nr_slot_rx,
......@@ -1424,7 +1424,7 @@ void nr_pdsch_ptrs_processing(int nbRx,
}
#ifdef DEBUG_DL_PTRS
LOG_M("ptrsEst.m","est", ptrs_phase_per_slot[aarx], frame_parms->symbols_per_slot, 1, 1);
LOG_M("rxdataF_bf_ptrs_comp.m", "bf_ptrs_cmp", rxdataF_comp[0][aarx] + startSymbIndex * rx_size_symbol, rx_size_symbol * nbSymb, 1, 1);
LOG_M("rxdataF_bf_ptrs_comp.m", "bf_ptrs_cmp", rxdataF_comp[0][aarx] + startSymbIndex * pdsch_buf_size_max, pdsch_buf_size_max * nbSymb, 1, 1);
#endif
/*------------------------------------------------------------------------------------------------------- */
/* 3) Compensated DMRS based estimated signal with PTRS estimation */
......
......@@ -117,9 +117,9 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
void nr_pdsch_ptrs_processing(int nbRx,
c16_t ptrs_phase_per_slot[][14],
int32_t ptrs_re_per_slot[][14],
uint32_t rx_size_symbol,
uint32_t pdsch_buf_size_max,
int nl,
c16_t rxdataF_comp[][nl][rx_size_symbol],
c16_t rxdataF_comp[][NR_MAX_NB_LAYERS][pdsch_buf_size_max],
NR_DL_FRAME_PARMS *frame_parms,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
uint8_t nr_slot_rx,
......
......@@ -523,17 +523,17 @@ void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned sh
/*
* MMSE Rx function: up to 4 layers
*/
static void nr_dlsch_mmse(uint32_t rx_size_symbol,
static void nr_dlsch_mmse(uint32_t pdsch_buf_size_max,
uint32_t rx_size_symbol,
unsigned char n_rx,
unsigned char nl, // number of layer
c16_t rxdataF_comp[][nl][rx_size_symbol],
c16_t dl_ch_mag[][rx_size_symbol],
c16_t dl_ch_magb[][rx_size_symbol],
c16_t dl_ch_magr[][rx_size_symbol],
c16_t rxdataF_comp[nl][pdsch_buf_size_max],
c16_t dl_ch_mag[][pdsch_buf_size_max],
c16_t dl_ch_magb[][pdsch_buf_size_max],
c16_t dl_ch_magr[][pdsch_buf_size_max],
int32_t dl_ch_estimates_ext[][rx_size_symbol],
unsigned char mod_order,
int shift,
unsigned char symbol,
int length,
uint32_t noise_var)
{
......@@ -609,7 +609,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
// print_shorts(" H_h_H=",(int16_t*)&conjH_H_elements[ctx*nl+rtx][0][0]);
// print_shorts(" Inv_H_h_H=",(int16_t*)&inv_H_h_H[ctx*nl+rtx][0]);
mult_complex_vectors(inv_H_h_H[ctx][rtx],
rxdataF_comp[symbol][ctx],
rxdataF_comp[ctx],
outtemp,
sizeofArray(outtemp),
shift - (fp_flag == 1 ? 1 : 0));
......@@ -625,7 +625,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
//Copy zero_forcing out to output array
for (int rtx = 0; rtx < nl; rtx++)
nr_element_sign(rxdataF_zforcing[rtx], rxdataF_comp[symbol][rtx], nb_rb_0, +1);
nr_element_sign(rxdataF_zforcing[rtx], rxdataF_comp[rtx], nb_rb_0, +1);
//Update LLR thresholds with the Matrix determinant
simde__m128i *dl_ch_mag128_0=NULL,*dl_ch_mag128b_0=NULL,*dl_ch_mag128r_0=NULL,*determ_fin_128;
......@@ -719,12 +719,12 @@ static void nr_dlsch_layer_demapping(const uint8_t Nl,
/* Computes LLRs from compensated PDSCH signal per OFDM symbol for all layers */
static int nr_dlsch_llr(const NR_UE_DLSCH_t *dlsch,
const int len,
const int rx_size_symbol,
const c16_t dl_ch_mag[rx_size_symbol],
const c16_t dl_ch_magb[rx_size_symbol],
const c16_t dl_ch_magr[rx_size_symbol],
const int pdsch_buf_size_max,
const c16_t dl_ch_mag[pdsch_buf_size_max],
const c16_t dl_ch_magb[pdsch_buf_size_max],
const c16_t dl_ch_magr[pdsch_buf_size_max],
const int nb_antennas_rx,
const c16_t rxdataF_comp[dlsch->cw_info.Nl][rx_size_symbol],
const c16_t rxdataF_comp[dlsch->cw_info.Nl][pdsch_buf_size_max],
const int llrSize,
int16_t layer_llr[dlsch->cw_info.Nl][llrSize])
{
......@@ -775,23 +775,23 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
int32_t *log2_maxh,
int rx_size_symbol,
uint32_t pdsch_buf_size_max,
int nbRx,
c16_t rxdataF_comp[][dlsch->cw_info.Nl][rx_size_symbol],
c16_t dl_ch_mag[][dlsch->cw_info.Nl][rx_size_symbol],
c16_t dl_ch_magb[][dlsch->cw_info.Nl][rx_size_symbol],
c16_t dl_ch_magr[][dlsch->cw_info.Nl][rx_size_symbol],
c16_t rxdataF_comp[][NR_MAX_NB_LAYERS][pdsch_buf_size_max],
c16_t dl_ch_mag[][NR_MAX_NB_LAYERS][pdsch_buf_size_max],
c16_t dl_ch_magb[][NR_MAX_NB_LAYERS][pdsch_buf_size_max],
c16_t dl_ch_magr[][NR_MAX_NB_LAYERS][pdsch_buf_size_max],
c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
uint32_t nvar,
pdsch_scope_req_t *scope_req,
c16_t rho_dl[][dlsch->cw_info.Nl * dlsch->cw_info.Nl][rx_size_symbol])
c16_t rho_dl[][NR_MAX_NB_LAYERS * NR_MAX_NB_LAYERS][pdsch_buf_size_max])
{
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
const int nl = dlsch->cw_info.Nl;
const int matrixSz = nbRx * nl;
const uint32_t rx_size_symbol = (freq_alloc->num_rbs * NR_NB_SC_PER_RB + 15) & ~15;
__attribute__((aligned(32))) int32_t dl_ch_estimates_ext[matrixSz][rx_size_symbol];
memset(dl_ch_estimates_ext, 0, sizeof(dl_ch_estimates_ext));
// Use ML-based LLR for 2-layer MIMO with QPSK/16QAM/64QAM (nl==2, qamModOrder<=6).
// Controlled by ue->do_ml (set via -E flag in dlsim, or ue->do_ml in the UE struct).
......@@ -993,6 +993,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
//----------------------------------------------------------
start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_COMPENSATION_STATS);
nr_channel_compensation(rx_size_symbol,
pdsch_buf_size_max,
nbRx,
nl,
rxdataF_ext,
......@@ -1001,7 +1002,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
dl_ch_magb[symbol],
dl_ch_magr[symbol],
p_rxComp,
need_rho ? (c16_t(*)[nl][rx_size_symbol])rho_dl[symbol] : NULL,
need_rho ? (c16_t(*)[nl][pdsch_buf_size_max])rho_dl[symbol] : NULL,
dlsch->cw_info.qamModOrder,
0, // symbol already baked into p_rxComp
*log2_maxh);
......@@ -1028,7 +1029,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
snprintf(filename, 50, "dl_ch_estimates_ext0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx);
write_output(filename, "dl_ch_estimates_ext0", &dl_ch_estimates_ext[0][0], rx_size_symbol, 1, 1);
snprintf(filename, 50, "rxdataF_comp00_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx);
write_output(filename, "rxdataF_comp00", &rxdataF_comp[0][0][symbol * rx_size_symbol], rx_size_symbol, 1, 1);
write_output(filename, "rxdataF_comp00", &rxdataF_comp[0][0][symbol * pdsch_buf_size_max], pdsch_buf_size_max, 1, 1);
#endif
// MRC is performed inline by nr_channel_compensation; apply MMSE for multi-layer
......@@ -1037,22 +1038,23 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
const uint8_t qamModOrder = dlsch->cw_info.qamModOrder;
if ((nl > 2) || (nl == 2 && !do_ml)) {
nr_dlsch_mmse(rx_size_symbol,
nr_dlsch_mmse(pdsch_buf_size_max,
rx_size_symbol,
nbRx,
nl,
rxdataF_comp,
rxdataF_comp[symbol],
dl_ch_mag[symbol],
dl_ch_magb[symbol],
dl_ch_magr[symbol],
dl_ch_estimates_ext,
qamModOrder,
*log2_maxh,
symbol,
nb_re_pdsch,
nvar);
} else if ((nl == 2) && (qamModOrder > 6) && do_ml) {
nr_mmse_2layers(p_rxComp,
rx_size_symbol,
pdsch_buf_size_max,
nbRx,
nl,
dl_ch_mag[symbol],
......@@ -1101,7 +1103,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
nr_pdsch_ptrs_processing(1, // rxdataF_comp is MRCed so no point in processing all antenna ports. Fixme.
ptrs_phase_per_slot,
ptrs_re_per_slot,
rx_size_symbol,
pdsch_buf_size_max,
nl,
rxdataF_comp,
fp,
......@@ -1144,7 +1146,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
} else {
nr_dlsch_llr(dlsch,
dl_valid_re[llr_sym],
rx_size_symbol,
pdsch_buf_size_max,
dl_ch_mag[llr_sym][0],
dl_ch_magb[llr_sym][0],
dl_ch_magr[llr_sym][0],
......@@ -1175,7 +1177,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
UEunlockScopeData(ue, pdschRxdataF_comp)
}
} else {
UEscopeCopy(ue, pdschRxdataF_comp, rxdataF_comp[0], sizeof(c16_t), nl, rx_size_symbol, 0);
UEscopeCopy(ue, pdschRxdataF_comp, rxdataF_comp[0], sizeof(c16_t), nl, pdsch_buf_size_max, 0);
}
}
......@@ -1206,7 +1208,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
}
for (int l = 0; l < nl; l++) {
int offset = (void *)rxdataF_comp[symbol][l] - (void *)rxdataF_comp[0];
memcpy(ue->phy_sim_pdsch_rxdataF_comp + offset, rxdataF_comp[symbol][l], sizeof(c16_t) * rx_size_symbol);
memcpy(ue->phy_sim_pdsch_rxdataF_comp + offset, rxdataF_comp[symbol][l], sizeof(c16_t) * pdsch_buf_size_max);
}
}
if (ue->phy_sim_pdsch_dl_ch_estimates_ext)
......
......@@ -247,17 +247,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
int32_t *log2_maxh,
int rx_size_symbol,
uint32_t pdsch_buf_size_max,
int nbRx,
c16_t rxdataF_comp[][dlsch->cw_info.Nl][rx_size_symbol],
c16_t dl_ch_mag[][dlsch->cw_info.Nl][rx_size_symbol],
c16_t dl_ch_magb[][dlsch->cw_info.Nl][rx_size_symbol],
c16_t dl_ch_magr[][dlsch->cw_info.Nl][rx_size_symbol],
c16_t rxdataF_comp[][NR_MAX_NB_LAYERS][pdsch_buf_size_max],
c16_t dl_ch_mag[][NR_MAX_NB_LAYERS][pdsch_buf_size_max],
c16_t dl_ch_magb[][NR_MAX_NB_LAYERS][pdsch_buf_size_max],
c16_t dl_ch_magr[][NR_MAX_NB_LAYERS][pdsch_buf_size_max],
c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
uint32_t nvar,
pdsch_scope_req_t *scope_req,
c16_t rho_dl[][dlsch->cw_info.Nl * dlsch->cw_info.Nl][rx_size_symbol]);
c16_t rho_dl[][NR_MAX_NB_LAYERS * NR_MAX_NB_LAYERS][pdsch_buf_size_max]);
int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot, c16_t **txData);
void apply_ntn_config(PHY_VARS_NR_UE *UE,
......
......@@ -443,7 +443,20 @@ typedef struct PHY_VARS_NR_UE_s {
Actor_t *ul_actors;
pthread_t main_thread;
pthread_t stat_thread;
// Per-DL-actor pre-allocated PDSCH scratch buffers (one set per actor to avoid races)
struct pdsch_scratch_s {
c16_t *rxdataF_comp; // [NR_SYMBOLS_PER_SLOT][NR_MAX_NB_LAYERS][pdsch_buf_size_max]
c16_t *dl_ch_mag; // [NR_SYMBOLS_PER_SLOT][NR_MAX_NB_LAYERS][pdsch_buf_size_max]
c16_t *dl_ch_magb; // [NR_SYMBOLS_PER_SLOT][NR_MAX_NB_LAYERS][pdsch_buf_size_max]
c16_t *dl_ch_magr; // [NR_SYMBOLS_PER_SLOT][NR_MAX_NB_LAYERS][pdsch_buf_size_max]
c16_t *rho_dl; // [NR_SYMBOLS_PER_SLOT][NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS][pdsch_buf_size_max]
int32_t *pdsch_dl_ch_estimates; // [nb_antennas_rx*NR_MAX_NB_LAYERS][pdsch_est_size]
uint32_t pdsch_buf_size_max;
uint32_t pdsch_est_size;
} *pdsch_scratch;
int pdsch_num_actors;
} PHY_VARS_NR_UE;
typedef struct pdsch_scratch_s pdsch_scratch_t;
typedef struct {
openair0_timestamp_t timestamp_tx;
......
......@@ -15,31 +15,36 @@
* from all Rx antennas are accumulated into rxComp[layer * nb_rx_ant][symbol * buffer_length].
* Uses AVX2 (256-bit SIMD) for throughput.
*
* @param buffer_length Number of complex samples per symbol (must be a multiple of 8)
* @param buffer_length Number of complex samples per symbol (must be a multiple of 8);
* governs the loop count and the inner dim of rxFext/chFext.
* @param pdsch_buf_size_max Inner dimension of ch_maga/ch_magb/ch_magc/rho arrays.
* Pass the pre-allocated worst-case size for DL per-actor scratch
* buffers so that multi-layer row strides are correct.
* @param nb_rx_ant Number of Rx antennas
* @param nb_layers Number of spatial layers
* @param rxFext Extracted received signal [nb_rx_ant][buffer_length]
* @param chFext Extracted channel estimates [nb_layers][nb_rx_ant][buffer_length]
* @param ch_maga Output magnitude array for threshold 'a' [nb_layers][buffer_length]
* @param ch_magb Output magnitude array for threshold 'b' [nb_layers][buffer_length]
* @param ch_magc Output magnitude array for threshold 'c' [nb_layers][buffer_length]
* @param ch_maga Output magnitude array for threshold 'a' [nb_layers][pdsch_buf_size_max]
* @param ch_magb Output magnitude array for threshold 'b' [nb_layers][pdsch_buf_size_max]
* @param ch_magc Output magnitude array for threshold 'c' [nb_layers][pdsch_buf_size_max]
* @param rxComp Output compensated signal; row [l * nb_rx_ant] holds the MRC result
* for layer l at offset [symbol * buffer_length]
* @param rho Tx-correlation matrix [nb_layers][nb_layers][buffer_length], or NULL
* @param rho Tx-correlation matrix [nb_layers][nb_layers][pdsch_buf_size_max], or NULL
* @param mod_order Modulation order (2=QPSK, 4=16QAM, 6=64QAM, 8=256QAM)
* @param symbol OFDM symbol index (used to compute offset into rxComp rows)
* @param output_shift Right-shift applied after each complex multiply
*/
void nr_channel_compensation(uint32_t buffer_length,
uint32_t pdsch_buf_size_max,
int nb_rx_ant,
int nb_layers,
c16_t rxFext[nb_rx_ant][buffer_length],
c16_t chFext[nb_layers][nb_rx_ant][buffer_length],
c16_t ch_maga[nb_layers][buffer_length],
c16_t ch_magb[nb_layers][buffer_length],
c16_t ch_magc[nb_layers][buffer_length],
c16_t ch_maga[nb_layers][pdsch_buf_size_max],
c16_t ch_magb[nb_layers][pdsch_buf_size_max],
c16_t ch_magc[nb_layers][pdsch_buf_size_max],
c16_t **rxComp,
c16_t (*rho)[nb_layers][buffer_length],
c16_t (*rho)[nb_layers][pdsch_buf_size_max],
int mod_order,
uint32_t symbol,
uint32_t output_shift);
......
......@@ -47,11 +47,12 @@ void nr_compute_ML_llr(c16_t *rxdataF_comp0,
uint8_t nr_mmse_2layers(c16_t **rxdataF_comp,
uint32_t buffer_length,
uint32_t pdsch_buf_size_max,
int nb_rx_ant,
int nb_layers,
c16_t ch_mag[nb_layers][buffer_length],
c16_t ch_magb[nb_layers][buffer_length],
c16_t ch_magc[nb_layers][buffer_length],
c16_t ch_mag[nb_layers][pdsch_buf_size_max],
c16_t ch_magb[nb_layers][pdsch_buf_size_max],
c16_t ch_magc[nb_layers][pdsch_buf_size_max],
c16_t ch_estimates_ext[][nb_rx_ant][buffer_length],
unsigned short nb_rb,
unsigned char mod_order,
......
......@@ -12,15 +12,16 @@
#endif
void nr_channel_compensation(uint32_t buffer_length,
uint32_t pdsch_buf_size_max,
int nb_rx_ant,
int nb_layers,
c16_t rxFext[nb_rx_ant][buffer_length],
c16_t chFext[nb_layers][nb_rx_ant][buffer_length],
c16_t ch_maga[nb_layers][buffer_length],
c16_t ch_magb[nb_layers][buffer_length],
c16_t ch_magc[nb_layers][buffer_length],
c16_t ch_maga[nb_layers][pdsch_buf_size_max],
c16_t ch_magb[nb_layers][pdsch_buf_size_max],
c16_t ch_magc[nb_layers][pdsch_buf_size_max],
c16_t **rxComp,
c16_t (*rho)[nb_layers][buffer_length],
c16_t (*rho)[nb_layers][pdsch_buf_size_max],
int mod_order,
uint32_t symbol,
uint32_t output_shift)
......
......@@ -2757,11 +2757,12 @@ static void nr_construct_HhH_elements(c16_t *conjch00_ch00,
// MMSE Rx function: nr_mmse_2layers()
uint8_t nr_mmse_2layers(c16_t **rxdataF_comp,
uint32_t buffer_length,
uint32_t pdsch_buf_size_max,
int nb_rx_ant,
int nb_layers,
c16_t ch_mag[nb_layers][buffer_length],
c16_t ch_magb[nb_layers][buffer_length],
c16_t ch_magc[nb_layers][buffer_length],
c16_t ch_mag[nb_layers][pdsch_buf_size_max],
c16_t ch_magb[nb_layers][pdsch_buf_size_max],
c16_t ch_magc[nb_layers][pdsch_buf_size_max],
c16_t ch_estimates_ext[][nb_rx_ant][buffer_length],
unsigned short nb_rb,
unsigned char mod_order,
......
......@@ -466,9 +466,16 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
dlschCfg->dlDmrsSymbPos,
dlsch->cw_info.Nl);
const uint32_t pdsch_est_size = ((ue->frame_parms.symbols_per_slot * ue->frame_parms.ofdm_symbol_size + 15) / 16) * 16;
fourDimArray_t *toFree = NULL;
allocCast2D(pdsch_dl_ch_estimates, int32_t, toFree, ue->frame_parms.nb_antennas_rx * dlsch->cw_info.Nl, pdsch_est_size, false);
const int actor_idx = proc->nr_slot_rx % ue->pdsch_num_actors;
pdsch_scratch_t *scratch = &ue->pdsch_scratch[actor_idx];
const uint32_t pdsch_est_size = scratch->pdsch_est_size;
const uint32_t pdsch_buf_size_max = scratch->pdsch_buf_size_max;
int32_t (*pdsch_dl_ch_estimates)[pdsch_est_size] = (int32_t (*)[pdsch_est_size])scratch->pdsch_dl_ch_estimates;
c16_t (*rxdataF_comp)[NR_MAX_NB_LAYERS][pdsch_buf_size_max] = (c16_t (*)[NR_MAX_NB_LAYERS][pdsch_buf_size_max])scratch->rxdataF_comp;
c16_t (*dl_ch_mag)[NR_MAX_NB_LAYERS][pdsch_buf_size_max] = (c16_t (*)[NR_MAX_NB_LAYERS][pdsch_buf_size_max])scratch->dl_ch_mag;
c16_t (*dl_ch_magb)[NR_MAX_NB_LAYERS][pdsch_buf_size_max] = (c16_t (*)[NR_MAX_NB_LAYERS][pdsch_buf_size_max])scratch->dl_ch_magb;
c16_t (*dl_ch_magr)[NR_MAX_NB_LAYERS][pdsch_buf_size_max] = (c16_t (*)[NR_MAX_NB_LAYERS][pdsch_buf_size_max])scratch->dl_ch_magr;
c16_t (*rho_dl)[NR_MAX_NB_LAYERS * NR_MAX_NB_LAYERS][pdsch_buf_size_max] = (c16_t (*)[NR_MAX_NB_LAYERS * NR_MAX_NB_LAYERS][pdsch_buf_size_max])scratch->rho_dl;
c16_t ptrs_phase_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT];
memset(ptrs_phase_per_slot, 0, sizeof(ptrs_phase_per_slot));
......@@ -476,10 +483,6 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
int32_t ptrs_re_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT];
memset(ptrs_re_per_slot, 0, sizeof(ptrs_re_per_slot));
const uint32_t rx_size_symbol = (freq_alloc->num_rbs * NR_NB_SC_PER_RB + 15) & ~15;
fourDimArray_t *toFree2 = NULL;
allocCast3D(rxdataF_comp, c16_t, toFree2, ue->frame_parms.symbols_per_slot, dlsch->cw_info.Nl, rx_size_symbol, false);
uint32_t nvar = 0;
start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_ESTIMATION_STATS);
......@@ -561,19 +564,6 @@ 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;
allocCast3D(dl_ch_mag, c16_t, toFree3, NR_SYMBOLS_PER_SLOT, dlsch->cw_info.Nl, rx_size_symbol, false);
fourDimArray_t *toFree4 = NULL;
allocCast3D(dl_ch_magb, c16_t, toFree4, NR_SYMBOLS_PER_SLOT, dlsch->cw_info.Nl, rx_size_symbol, false);
fourDimArray_t *toFree5 = NULL;
allocCast3D(dl_ch_magr, c16_t, toFree5, NR_SYMBOLS_PER_SLOT, dlsch->cw_info.Nl, rx_size_symbol, false);
fourDimArray_t *toFreeRho = NULL;
const bool need_rho = ue->do_ml && dlsch->cw_info.Nl == 2 && dlsch->cw_info.qamModOrder <= 6;
c16_t(*rho_dl)[dlsch->cw_info.Nl * dlsch->cw_info.Nl][rx_size_symbol] = NULL;
if (need_rho) {
allocCast3D(rho_dl_buf, c16_t, toFreeRho, NR_SYMBOLS_PER_SLOT, dlsch->cw_info.Nl * dlsch->cw_info.Nl, rx_size_symbol, false);
rho_dl = rho_dl_buf;
}
for (int m = dlschCfg->start_symbol; m < (dlschCfg->number_symbols + dlschCfg->start_symbol); m++) {
bool first_symbol_flag = false;
......@@ -597,7 +587,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
dl_valid_re,
rxdataF,
&log2_maxh,
rx_size_symbol,
pdsch_buf_size_max,
ue->frame_parms.nb_antennas_rx,
rxdataF_comp,
dl_ch_mag,
......@@ -625,12 +615,6 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
if (scope_req.copy_rxdataF_to_scope) {
UEunlockScopeData(ue, pdschRxdataF);
}
free(toFree);
free(toFree2);
free(toFree3);
free(toFree4);
free(toFree5);
free(toFreeRho);
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment