Cleanup nr_slot_fep_ul

Rename nr_slot_fep_ul to nr_symbol_fep_ul to relfect its function

Simplify logic so that the function does not require RU context and
the implementation is not dependent on the implementation of RU buffer management.

This makes the function easier to understand and moves the responsibility
to set the correct buffer offset on the caller.
This commit is contained in:
Bartosz Podrygajlo
2026-01-20 12:18:18 +01:00
parent 102965a669
commit 28d821bd0f
5 changed files with 74 additions and 98 deletions
+11 -11
View File
@@ -68,22 +68,22 @@ void nr_layer_mapping(int nbCodes,
@param[out] tx_layers, modulated symbols for each layer
*/
void nr_ue_layer_mapping(const c16_t *mod_symbs, const int n_layers, const int n_symbs, c16_t tx_layers[][n_symbs]);
/*!
\brief This function implements the OFDM front end processor on reception (FEP)
\param frame_parms Pointer to frame parameters
\param rxdata Pointer to input data in time domain
\param rxdataF Pointer to output data in frequency domain
\param rxdata Pointer to input data in time domain for one frame
\param rxdataF Pointer to output data in frequency domain for one symbol
\param symbol symbol within slot (0..12/14)
\param Ns Slot number (0..19)
\param sample_offset offset within rxdata (points to beginning of subframe)
\param slot Slot number
\param sample_offset offset within rxdata (points to beginning of symbol)
*/
int nr_slot_fep_ul(const NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdata,
int32_t *rxdataF,
unsigned char symbol,
unsigned char Ns,
int sample_offset);
int nr_symbol_fep_ul(const NR_DL_FRAME_PARMS *fp,
const c16_t *rxdata,
c16_t *rxdataF,
unsigned char symbol,
unsigned char slot,
int sample_offset);
/*!
\brief This function implements the dft transform precoding in PUSCH
+27 -43
View File
@@ -21,6 +21,7 @@
#include "PHY/defs_nr_UE.h"
#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_common.h"
#include "modulation_UE.h"
#include "nr_modulation.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
@@ -135,61 +136,44 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
return 0;
}
int nr_slot_fep_ul(const NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdata,
int32_t *rxdataF,
unsigned char symbol,
unsigned char Ns,
int sample_offset)
int nr_symbol_fep_ul(const NR_DL_FRAME_PARMS *fp,
const c16_t *rxdata,
c16_t *rxdataF,
unsigned char symbol,
unsigned char slot,
int sample_offset)
{
unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples;
unsigned int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size);
dft_size_idx_t dftsize = get_dft(fp->ofdm_symbol_size);
// This is for misalignment issues
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
int32_t tmp_dft_in[fp->ofdm_symbol_size] __attribute__((aligned(32)));
// offset of first OFDM symbol
unsigned int rxdata_offset = get_samples_slot_timestamp(frame_parms, Ns);
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rxdata_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rxdata_offset += frame_parms->ofdm_symbol_size * symbol;
uint32_t prefix_length = get_samples_symbol_duration(fp, slot, symbol, 1) - fp->ofdm_symbol_size;
unsigned int rxdata_offset =
get_samples_slot_timestamp(fp, slot) + get_samples_symbol_timestamp(fp, slot, symbol) + prefix_length;
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rxdata_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
rxdata_offset -= (fp->nb_prefix_samples / fp->ofdm_offset_divisor);
int16_t *rxdata_ptr;
if (rxdata_offset >= sample_offset)
rxdata_offset -= sample_offset;
else
rxdata_offset += fp->samples_per_frame - sample_offset;
if(sample_offset > rxdata_offset) {
memcpy((void *)&tmp_dft_in[0],
(void *)&rxdata[frame_parms->samples_per_frame - sample_offset + rxdata_offset],
(sample_offset - rxdata_offset) * sizeof(int32_t));
memcpy((void *)&tmp_dft_in[sample_offset - rxdata_offset],
(void *)&rxdata[0],
(frame_parms->ofdm_symbol_size - sample_offset + rxdata_offset) * sizeof(int32_t));
if (rxdata_offset + fp->ofdm_symbol_size > fp->samples_per_frame) {
memcpy(&tmp_dft_in[0],
&rxdata[rxdata_offset],
(fp->samples_per_frame - rxdata_offset) * sizeof(int32_t));
memcpy(&tmp_dft_in[fp->samples_per_frame - rxdata_offset],
&rxdata[0],
(fp->ofdm_symbol_size - fp->samples_per_frame + rxdata_offset) * sizeof(int32_t));
rxdata_ptr = (int16_t *)tmp_dft_in;
} else if (((rxdata_offset - sample_offset) & 7) != 0) {
// if input to dft is not 256-bit aligned
memcpy((void *)&tmp_dft_in[0],
(void *)&rxdata[rxdata_offset - sample_offset],
(frame_parms->ofdm_symbol_size) * sizeof(int32_t));
rxdata_ptr = (int16_t *)tmp_dft_in;
} else {
// use dft input from RX buffer directly
rxdata_ptr = (int16_t *)&rxdata[rxdata_offset - sample_offset];
rxdata_ptr = (int16_t *)&rxdata[rxdata_offset];
}
dft(dftsize,
rxdata_ptr,
(int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size],
1);
dft(dftsize, rxdata_ptr, (int16_t *)rxdataF, 1);
return 0;
}
@@ -250,7 +234,7 @@ void nr_ofdm_demod_and_rx_rotation(c16_t **rxdata,
for (int aa = 0; aa < nb_antennas; aa++) {
for (uint8_t symbol = 0; symbol < fp->symbols_per_slot; symbol++) {
if (was_symbol_used[symbol] == true) {
nr_slot_fep_ul(fp, (int32_t *)&rxdata[aa][0], (int32_t *)&rxdataF[aa][slot_offsetF], symbol, slot, 0);
nr_symbol_fep_ul(fp, &rxdata[aa][0], &rxdataF[aa][slot_offsetF + symbol * fp->ofdm_symbol_size], symbol, slot, 0);
apply_nr_rotation_symbol_RX(fp,
&rxdataF[aa][slot_offsetF + symbol * fp->ofdm_symbol_size],
fp->symbol_rotation[linktype],
+4 -3
View File
@@ -171,12 +171,13 @@ typedef struct RU_prec_t_s{
} RU_prec_t;
typedef struct {
int aid;
int beam;
struct RU_t_s *ru;
int startSymbol;
int endSymbol;
int slot;
const c16_t *rxdata;
c16_t *rxdataF;
const struct NR_DL_FRAME_PARMS *fp;
int32_t sample_offet;
task_ans_t *ans;
} feprx_cmd_t;
+26 -40
View File
@@ -31,6 +31,7 @@
*/
#include "PHY/defs_gNB.h"
#include "common/platform_types.h"
#include "sched_nr.h"
#include "PHY/MODULATION/modulation_common.h"
#include "PHY/MODULATION/nr_modulation.h"
@@ -320,33 +321,21 @@ void nr_feptx_tp(RU_t *ru, int frame_tx, int slot)
}
// core RX FEP routine, called by threads in RU thread-pool
void nr_fep(void* arg)
void nr_fep(void *arg)
{
feprx_cmd_t *feprx_cmd = (feprx_cmd_t *)arg;
RU_t *ru = feprx_cmd->ru;
int aid = feprx_cmd->aid;
int beam = feprx_cmd->beam;
int slot = feprx_cmd->slot;
int startSymbol = feprx_cmd->startSymbol;
int endSymbol = feprx_cmd->endSymbol;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
LOG_D(PHY,"aid %d, frame %d slot %d, startSymbol %d, endSymbol %d\n", aid, ru->proc.frame_rx, slot, startSymbol, endSymbol);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 1);
int idx = aid + beam * ru->nb_rx;
int offset = (slot % RU_RX_SLOT_DEPTH) * fp->symbols_per_slot * fp->ofdm_symbol_size;
for (int l = startSymbol; l <= endSymbol; l++)
nr_slot_fep_ul(fp,
ru->common.rxdata[idx],
&ru->common.rxdataF[idx][offset],
for (int l = startSymbol; l <= endSymbol; l++)
nr_symbol_fep_ul(feprx_cmd->fp,
feprx_cmd->rxdata,
&feprx_cmd->rxdataF[l * feprx_cmd->fp->ofdm_symbol_size],
l,
slot,
ru->N_TA_offset);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 0);
feprx_cmd->sample_offet);
// Task completed in //
completed_task_ans(feprx_cmd->ans);
}
@@ -358,39 +347,36 @@ void nr_fep_tp(RU_t *ru, int slot) {
start_meas(&ru->ofdm_demod_stats);
int nt = ru->nb_rx * ru->num_beams_period;
size_t const sz = nt + (ru->half_slot_parallelization > 0) * nt;
int tasks_per_slot = (ru->half_slot_parallelization > 0) ? 2 : 1;
size_t const sz = nt * tasks_per_slot;
feprx_cmd_t arr[sz];
task_ans_t ans;
init_task_ans(&ans, sz);
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
int rxdataF_offset = (slot % RU_RX_SLOT_DEPTH) * fp->symbols_per_slot * fp->ofdm_symbol_size;
for (int beam = 0; beam < ru->num_beams_period; beam++) {
for (int aid = 0; aid < ru->nb_rx; aid++) {
feprx_cmd_t *feprx_cmd = &arr[nbfeprx];
feprx_cmd->ans = &ans;
feprx_cmd->beam = beam;
feprx_cmd->aid = aid;
feprx_cmd->ru = ru;
feprx_cmd->slot = ru->proc.tti_rx;
feprx_cmd->startSymbol = 0;
feprx_cmd->endSymbol = (ru->half_slot_parallelization > 0) ? (ru->nr_frame_parms->symbols_per_slot >> 1) - 1
: (ru->nr_frame_parms->symbols_per_slot - 1);
int symbols_per_task = fp->symbols_per_slot / tasks_per_slot;
task_t t = {.func = nr_fep, .args = feprx_cmd};
pushTpool(ru->threadPool, t);
nbfeprx++;
if (ru->half_slot_parallelization > 0) {
for (int task_idx = 0; task_idx < tasks_per_slot; task_idx++) {
int start_symbol = task_idx * symbols_per_task;
int end_symbol = (task_idx + 1) * symbols_per_task - 1;
if (task_idx == tasks_per_slot - 1)
end_symbol = fp->symbols_per_slot - 1;
for (int beam = 0; beam < ru->num_beams_period; beam++) {
for (int aid = 0; aid < ru->nb_rx; aid++) {
feprx_cmd_t *feprx_cmd = &arr[nbfeprx];
feprx_cmd->ans = &ans;
feprx_cmd->beam = beam;
feprx_cmd->aid = aid;
feprx_cmd->ru = ru;
feprx_cmd->fp = fp;
feprx_cmd->slot = ru->proc.tti_rx;
feprx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot >> 1;
feprx_cmd->endSymbol = ru->nr_frame_parms->symbols_per_slot - 1;
feprx_cmd->startSymbol = start_symbol;
feprx_cmd->endSymbol = end_symbol;
feprx_cmd->rxdata = (const c16_t *)ru->common.rxdata[aid + beam * ru->nb_rx];
feprx_cmd->rxdataF = (c16_t *)&ru->common.rxdataF[aid + beam * ru->nb_rx][rxdataF_offset];
feprx_cmd->sample_offet = ru->N_TA_offset;
task_t t = {.func = nr_fep, .args = feprx_cmd};
pushTpool(ru->threadPool, t);
nbfeprx++;
}
}
+6 -1
View File
@@ -758,7 +758,12 @@ int main(int argc, char **argv){
for (l = 0; l < frame_parms->symbols_per_slot; l++) {
for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
nr_slot_fep_ul(frame_parms, ru->common.rxdata[aa], ru->common.rxdataF[aa], l, slot, ru->N_TA_offset);
nr_symbol_fep_ul(frame_parms,
(c16_t *)ru->common.rxdata[aa],
(c16_t *)&ru->common.rxdataF[aa][frame_parms->ofdm_symbol_size * l],
l,
slot,
ru->N_TA_offset);
}
}