phy: remove function pointers in frame param

1. Removed function pointers for functions get_samples_per_slot(),
   get_samples_slot_timestamp() and get_slot_from_timestamp() as it does
   not offer any advantage. The functions are now called directly from
   everywhere.
2. Optimized these functions by removing loops where ever possible.
This commit is contained in:
Sakthivel Velumani
2025-12-10 23:25:24 +00:00
parent 10852cc89b
commit 5b92859cce
14 changed files with 118 additions and 102 deletions
+50 -25
View File
@@ -310,31 +310,65 @@ uint32_t get_samples_symbol_timestamp(const NR_DL_FRAME_PARMS *fp, int slot, int
uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, const NR_DL_FRAME_PARMS *fp)
{
uint32_t slot_idx = 0;
int samples_till_the_slot = fp->get_samples_per_slot(slot_idx,fp)-1;
timestamp_rx = timestamp_rx%fp->samples_per_frame;
timestamp_rx = timestamp_rx % fp->samples_per_frame;
if (timestamp_rx < fp->samples_per_slot0)
return 0;
while (timestamp_rx > samples_till_the_slot) {
slot_idx++;
samples_till_the_slot += fp->get_samples_per_slot(slot_idx,fp);
}
return slot_idx;
if (fp->numerology_index == 0)
return timestamp_rx / fp->samples_per_subframe;
const unsigned int num_half_sf = timestamp_rx / (fp->samples_per_subframe / 2);
const unsigned int slot_per_half_sf = fp->slots_per_subframe / 2;
uint32_t slot_count = num_half_sf * slot_per_half_sf;
int samp_idx = num_half_sf * (fp->samples_per_subframe / 2) - 1;
// Remaining samples
if (samp_idx < timestamp_rx) {
slot_count++;
samp_idx += fp->samples_per_slot0; // First slot of half subframe
}
if (samp_idx < timestamp_rx) {
const unsigned int rem_samples = timestamp_rx - samp_idx;
const unsigned int num_slots = ceil((double)rem_samples / fp->samples_per_slotN0);
slot_count += num_slots;
}
return slot_count - 1;
}
uint32_t get_samples_slot_timestamp(int slot, const NR_DL_FRAME_PARMS *fp, unsigned int sl_ahead)
uint32_t get_samples_slot_timestamp(const NR_DL_FRAME_PARMS *fp, unsigned int slot)
{
uint32_t samp_count = 0;
if (slot == 0)
return 0;
if(!sl_ahead) {
for(unsigned int idx_slot = 0; idx_slot < slot; idx_slot++)
samp_count += fp->get_samples_per_slot(idx_slot, fp);
} else {
for (unsigned int idx_slot = slot; idx_slot < slot + sl_ahead; idx_slot++)
samp_count += fp->get_samples_per_slot(idx_slot, fp);
if (fp->numerology_index == 0)
return slot * fp->samples_per_subframe;
uint32_t samp_count = 0;
// Number of half subframes
const unsigned int num_half_sf = slot / (fp->slots_per_subframe / 2);
samp_count += num_half_sf * fp->samples_per_subframe / 2;
// Remaining slots
unsigned int rem_slots = slot % (fp->slots_per_subframe / 2);
if (rem_slots > 0) {
samp_count += fp->samples_per_slot0; // First slot of the last half subframe
rem_slots--;
}
samp_count += rem_slots * fp->samples_per_slotN0; // Remaining slots of the last half subframe
return samp_count;
}
uint32_t get_samples_slot_duration(const NR_DL_FRAME_PARMS *fp, unsigned int start_slot, unsigned int num_slots)
{
if (start_slot == 0 && num_slots == 0)
return 0;
return (get_samples_slot_timestamp(fp, start_slot + num_slots) - get_samples_slot_timestamp(fp, start_slot));
}
void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS *fp)
{
@@ -371,9 +405,6 @@ void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS *
fp->samples_per_slot0 = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size);
fp->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2 +
(fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2);
fp->get_samples_per_slot = &get_samples_per_slot;
fp->get_samples_slot_timestamp = &get_samples_slot_timestamp;
fp->get_slot_from_timestamp = &get_slot_from_timestamp;
fp->samples_per_frame = 10 * fp->samples_per_subframe;
fp->freq_range = get_freq_range_from_freq(fp->dl_CarrierFreq);
@@ -454,8 +485,6 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
fp->samples_per_slot0 = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size);
fp->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2 +
(fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2);
fp->get_samples_per_slot = &get_samples_per_slot;
fp->get_samples_slot_timestamp = &get_samples_slot_timestamp;
fp->samples_per_frame = 10 * fp->samples_per_subframe;
fp->freq_range = get_freq_range_from_freq(fp->dl_CarrierFreq);
@@ -512,8 +541,6 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink
frame_parms->samples_per_slot0 = frame_parms->nb_prefix_samples0 + ((frame_parms->symbols_per_slot-1)*frame_parms->nb_prefix_samples) + (frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size);
frame_parms->samples_per_subframe = (frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size) * 2 +
(frame_parms->nb_prefix_samples + frame_parms->ofdm_symbol_size) * (frame_parms->symbols_per_slot * frame_parms->slots_per_subframe - 2);
frame_parms->get_samples_per_slot = &get_samples_per_slot;
frame_parms->get_samples_slot_timestamp = &get_samples_slot_timestamp;
frame_parms->samples_per_frame = 10 * frame_parms->samples_per_subframe;
LOG_W(PHY, "samples_per_subframe %d/per second %d, wCP %d\n", frame_parms->samples_per_subframe, 1000*frame_parms->samples_per_subframe, frame_parms->samples_per_subframe_wCP);
@@ -613,8 +640,6 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp,
fp->nb_prefix_samples0 + ((fp->symbols_per_slot - 1) * fp->nb_prefix_samples) + (fp->symbols_per_slot * fp->ofdm_symbol_size);
fp->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2
+ (fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2);
fp->get_samples_per_slot = &get_samples_per_slot;
fp->get_samples_slot_timestamp = &get_samples_slot_timestamp;
fp->samples_per_frame = 10 * fp->samples_per_subframe;
fp->freq_range = get_freq_range_from_freq(fp->sl_CarrierFreq);
@@ -33,11 +33,11 @@ softmodem_params_t *get_softmodem_params(void)
void test_coherence_symbol_api(NR_DL_FRAME_PARMS *fp)
{
EXPECT_EQ(get_samples_symbol_timestamp(fp, 0, 0), fp->get_samples_slot_timestamp(0, fp, 0));
EXPECT_EQ(get_samples_symbol_timestamp(fp, 0, 0), get_samples_slot_timestamp(fp, 0));
for (int slot = 0; slot < 4; slot++) {
EXPECT_EQ(get_samples_symbol_duration(fp, slot, 0, fp->symbols_per_slot) + fp->get_samples_slot_timestamp(slot, fp, 0),
fp->get_samples_slot_timestamp(slot + 1, fp, 0));
EXPECT_EQ(get_samples_symbol_duration(fp, slot, 0, fp->symbols_per_slot) + get_samples_slot_timestamp(fp, slot),
get_samples_slot_timestamp(fp, slot + 1));
}
for (int symbol = 0; symbol < fp->symbols_per_slot - 1; symbol++) {
+2 -2
View File
@@ -80,7 +80,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
// For Sidelink 16 frames worth of samples is processed to find SSB, for 5G-NR 2.
const unsigned int total_samples = (is_sl) ? 16 * frame_parms->samples_per_frame : 2 * frame_parms->samples_per_frame;
unsigned int rx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
unsigned int rx_offset = get_samples_slot_timestamp(frame_parms, slot);
const unsigned int abs_symbol = slot * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = slot * frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (idx_symb % (0x7 << frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
@@ -150,7 +150,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
// offset of first OFDM symbol
unsigned int rxdata_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
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;
+1 -1
View File
@@ -362,7 +362,7 @@ static void rx_nr_prach_ru_internal(prach_item_t *p,
// Fixme: slot or slot makes no sense ???
int slot2 = p->prach_sequence_length ? p->slot : p->slot;
int idx = aa + beam_id * p->nb_rx;
c16_t *prach = (c16_t *)&rxdata[idx][fp->get_samples_slot_timestamp(slot2, fp, 0) + sample_offset_slot - N_TA_offset];
c16_t *prach = (c16_t *)&rxdata[idx][get_samples_slot_timestamp(fp, slot2) + sample_offset_slot - N_TA_offset];
// do DFT
c16_t *prach2 = prach + Ncp;
+8 -11
View File
@@ -165,11 +165,6 @@ void init_prach_list(prach_list_t *);
typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS;
typedef uint32_t (*get_samples_per_slot_t)(int slot, const NR_DL_FRAME_PARMS *fp);
typedef uint32_t (*get_slot_from_timestamp_t)(openair0_timestamp timestamp_rx, const NR_DL_FRAME_PARMS *fp);
typedef uint32_t (*get_samples_slot_timestamp_t)(int slot, const NR_DL_FRAME_PARMS *fp, unsigned int sl_ahead);
struct NR_DL_FRAME_PARMS {
/// frequency range
frequency_range_t freq_range;
@@ -225,12 +220,6 @@ struct NR_DL_FRAME_PARMS {
uint16_t slots_per_frame;
/// Number of samples in a subframe
uint32_t samples_per_subframe;
/// Number of samples in current slot
get_samples_per_slot_t get_samples_per_slot;
/// slot calculation from timestamp
get_slot_from_timestamp_t get_slot_from_timestamp;
/// Number of samples before slot
get_samples_slot_timestamp_t get_samples_slot_timestamp;
/// Number of samples in 0th and center slot of a subframe
uint32_t samples_per_slot0;
/// Number of samples in other slots of the subframe
@@ -340,5 +329,13 @@ typedef struct {
uint32_t get_samples_symbol_duration(const NR_DL_FRAME_PARMS *fp, int slot, int start_symbol, int num_symbols);
// Get timestamp of symbol within slot in samples
uint32_t get_samples_symbol_timestamp(const NR_DL_FRAME_PARMS *fp, int slot, int symbol);
// Get slot duration between two slot
uint32_t get_samples_slot_duration(const NR_DL_FRAME_PARMS *fp, unsigned int start_slot, unsigned int num_slots);
// Get timestamp of slot from start of frame
uint32_t get_samples_slot_timestamp(const NR_DL_FRAME_PARMS *fp, unsigned int slot);
// Get slot from timestamp
uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, const NR_DL_FRAME_PARMS *fp);
// Get number of samples in the slot
uint32_t get_samples_per_slot(int slot, const NR_DL_FRAME_PARMS *fp);
#endif
+9 -6
View File
@@ -58,7 +58,7 @@ void nr_feptx0(RU_t *ru, int tti_tx, int first_symbol, int num_symbols, int aa)
if (aa == 0 && first_symbol == 0)
start_meas(&ru->ofdm_mod_stats);
slot_offset = fp->get_samples_slot_timestamp(slot, fp, 0);
slot_offset = get_samples_slot_timestamp(fp, slot);
slot_offsetF = first_symbol * fp->ofdm_symbol_size;
int abs_first_symbol = slot * fp->symbols_per_slot;
@@ -156,7 +156,7 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) {
int slot_sizeF = (fp->ofdm_symbol_size)*
((cyclic_prefix_type == 1) ? 12 : 14);
int slot = tti_tx;
int *txdata = &ru->common.txdata[aa][fp->get_samples_slot_timestamp(slot,fp,0)];
int *txdata = &ru->common.txdata[aa][get_samples_slot_timestamp(fp, slot)];
if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return;
@@ -169,10 +169,13 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 );
LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, slot %d: txp (time %p) %d dB, txp (freq) %d dB\n",
frame_tx,slot,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->get_samples_per_slot(
slot,fp))),dB_fixed(signal_energy_nodc((c16_t*)ru->common.txdataF_BF[aa],2*slot_sizeF)));
LOG_D(PHY,
"feptx_ofdm (TXPATH): frame %d, slot %d: txp (time %p) %d dB, txp (freq) %d dB\n",
frame_tx,
slot,
txdata,
dB_fixed(signal_energy((int32_t *)txdata, get_samples_per_slot(slot, fp))),
dB_fixed(signal_energy_nodc((c16_t *)ru->common.txdataF_BF[aa], 2 * slot_sizeF)));
}
void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
+4 -7
View File
@@ -969,17 +969,14 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
buf[7] = (int16_t)ulsch->harq_pid;
memcpy(&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset + 4],
&ru->common.rxdata[0][slot_offset],
frame_parms->get_samples_per_slot(slot_rx, frame_parms) * sizeof(int32_t));
gNB->common_vars.debugBuff_sample_offset += (frame_parms->get_samples_per_slot(slot_rx, frame_parms) + 1000 + 4);
if (gNB->common_vars.debugBuff_sample_offset > ((frame_parms->get_samples_per_slot(slot_rx, frame_parms) + 1000 + 2) * 20)) {
get_samples_per_slot(slot_rx, frame_parms) * sizeof(int32_t));
gNB->common_vars.debugBuff_sample_offset += (get_samples_per_slot(slot_rx, frame_parms) + 1000 + 4);
if (gNB->common_vars.debugBuff_sample_offset > ((get_samples_per_slot(slot_rx, frame_parms) + 1000 + 2) * 20)) {
FILE *f;
f = fopen("rxdata_buff.raw", "w");
if (f == NULL)
exit(1);
fwrite((int16_t *)gNB->common_vars.debugBuff,
2,
(frame_parms->get_samples_per_slot(slot_rx, frame_parms) + 1000 + 4) * 20 * 2,
f);
fwrite((int16_t *)gNB->common_vars.debugBuff, 2, (get_samples_per_slot(slot_rx, frame_parms) + 1000 + 4) * 20 * 2, f);
fclose(f);
exit(-1);
}
+2 -2
View File
@@ -878,8 +878,8 @@ int main(int argc, char **argv)
frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
//frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0);
int slot_offset = get_samples_slot_timestamp(frame_parms, slot);
int slot_length = slot_offset - get_samples_slot_timestamp(frame_parms, slot - 1);
s_re = malloc(n_tx*sizeof(double*));
s_im = malloc(n_tx*sizeof(double*));
+1 -1
View File
@@ -543,7 +543,7 @@ int main(int argc, char **argv)
nr_common_signal_procedures (gNB,frame,slot, &ssb_pdu[i]);
int samp = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
int samp = get_samples_slot_timestamp(frame_parms, slot);
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
if (cyclic_prefix_type == 1) {
apply_nr_rotation_TX(frame_parms,
+1 -1
View File
@@ -665,7 +665,7 @@ int main(int argc, char **argv){
UE->X_u);
int prach_start = subframe * frame_parms->samples_per_subframe;
int slot_start = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
int slot_start = get_samples_slot_timestamp(frame_parms, slot);
c16_t *tx[frame_parms->nb_antennas_rx];
for (int i = 0; i < frame_parms->nb_antennas_rx; i++)
tx[i] = txdata[i] + slot_start;
+1 -1
View File
@@ -576,7 +576,7 @@ int main(int argc, char **argv)
proc.frame_rx,
proc.nr_slot_rx,
sl_uerx->sl_config.sl_sync_source.rx_slss_id);
int slot_start = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
int slot_start = get_samples_slot_timestamp(frame_parms, slot);
c16_t *tx[frame_parms->nb_antennas_rx];
for (int i = 0; i < frame_parms->nb_antennas_rx; i++)
tx[i] = UE_TX->common_vars.txData[i] + slot_start;
+4 -4
View File
@@ -1052,8 +1052,8 @@ int main(int argc, char *argv[])
//for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
int read_errors=0;
int slot_offset = gNB->frame_parms.get_samples_slot_timestamp(slot, &gNB->frame_parms, 0);
int slot_length = slot_offset - gNB->frame_parms.get_samples_slot_timestamp(slot - 1, &gNB->frame_parms, 0);
int slot_offset = get_samples_slot_timestamp(&gNB->frame_parms, slot);
int slot_length = slot_offset - get_samples_slot_timestamp(&gNB->frame_parms, slot - 1);
if (input_fd != NULL) {
// 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s,
@@ -1373,7 +1373,7 @@ int main(int argc, char *argv[])
/////////////////////////phy_procedures_nr_ue_TX///////////////////////
///////////
int slot_start = UE->frame_parms.get_samples_slot_timestamp(slot, &UE->frame_parms, 0);
int slot_start = get_samples_slot_timestamp(&UE->frame_parms, slot);
c16_t *tx[UE->frame_parms.nb_antennas_tx];
for (int i = 0; i < UE->frame_parms.nb_antennas_tx; i++)
tx[i] = UE->common_vars.txData[i] + slot_start;
@@ -1391,7 +1391,7 @@ int main(int argc, char *argv[])
}
///////////
////////////////////////////////////////////////////
tx_offset = gNB->frame_parms.get_samples_slot_timestamp(slot, &gNB->frame_parms, 0);
tx_offset = get_samples_slot_timestamp(&gNB->frame_parms, slot);
txlev_sum = 0;
for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) {
atxlev[aa] =