Optimization for unused symbols in NR UE
After processing TX frequency domain data skip IFFT call for symbols that aren't used, the time domain buffer is memset instead.
This commit is contained in:
@@ -84,6 +84,7 @@ static inline const char *rnti_types(nr_rnti_type_t rr)
|
||||
#define MU_SCS(m) (15 << m)
|
||||
#define MAX_GSCN_BAND 620 // n78 has the highest GSCN range of 619
|
||||
#define NR_NUMBER_OF_SYMBOLS_PER_SLOT 14
|
||||
#define NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP 12
|
||||
#define NR_MAX_NB_LAYERS 4 // 8
|
||||
|
||||
// Since the IQ samples are represented by SQ15 R+I (see https://en.wikipedia.org/wiki/Q_(number_format)) we need to compensate when
|
||||
|
||||
@@ -48,7 +48,12 @@ void PHY_ofdm_mod(const int *input,
|
||||
|
||||
|
||||
void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms);
|
||||
void nr_normal_prefix_mod(c16_t *txdataF, c16_t *txdata, uint8_t nsymb, const NR_DL_FRAME_PARMS *frame_parms, uint32_t slot);
|
||||
void nr_normal_prefix_mod(c16_t *txdataF,
|
||||
c16_t *txdata,
|
||||
uint8_t nsymb,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint32_t slot,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]);
|
||||
|
||||
void do_OFDM_mod(c16_t **txdataF, c16_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
|
||||
@@ -67,31 +67,55 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA
|
||||
|
||||
}
|
||||
|
||||
void nr_normal_prefix_mod(c16_t *txdataF, c16_t *txdata, uint8_t nsymb, const NR_DL_FRAME_PARMS *frame_parms, uint32_t slot)
|
||||
void nr_normal_prefix_mod(c16_t *txdataF,
|
||||
c16_t *txdata,
|
||||
uint8_t nsymb,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint32_t slot,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
|
||||
{
|
||||
// This function works only slot wise. For more generic symbol generation refer nr_feptx0()
|
||||
if (frame_parms->numerology_index != 0) { // case where numerology != 0
|
||||
if (!(slot%(frame_parms->slots_per_subframe/2))) {
|
||||
PHY_ofdm_mod((int *)txdataF,
|
||||
(int *)txdata,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
frame_parms->nb_prefix_samples0,
|
||||
CYCLIC_PREFIX);
|
||||
PHY_ofdm_mod((int *)txdataF + frame_parms->ofdm_symbol_size,
|
||||
(int *)txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
nsymb - 1,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
if (was_symbol_used[0]) {
|
||||
PHY_ofdm_mod((int *)txdataF,
|
||||
(int *)txdata,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
frame_parms->nb_prefix_samples0,
|
||||
CYCLIC_PREFIX);
|
||||
} else {
|
||||
memset(txdata, 0, (frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size) * sizeof(c16_t));
|
||||
}
|
||||
for (int i = 1; i < nsymb; i++) {
|
||||
c16_t* tx_data_ptr = txdata + (i - 1) * (frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples) +
|
||||
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0;
|
||||
if (was_symbol_used[i]) {
|
||||
PHY_ofdm_mod((int *)txdataF + frame_parms->ofdm_symbol_size * i,
|
||||
(int *)tx_data_ptr,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
} else {
|
||||
memset(tx_data_ptr, 0, (frame_parms->nb_prefix_samples + frame_parms->ofdm_symbol_size) * sizeof(c16_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
PHY_ofdm_mod((int *)txdataF,
|
||||
(int *)txdata,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
nsymb,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
for (int i = 0; i < nsymb; i++) {
|
||||
c16_t* tx_data_ptr = txdata + i * (frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
|
||||
if (was_symbol_used[i]) {
|
||||
PHY_ofdm_mod((int *)txdataF + frame_parms->ofdm_symbol_size * i,
|
||||
(int *)tx_data_ptr,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
} else {
|
||||
memset(tx_data_ptr, 0, (frame_parms->nb_prefix_samples + frame_parms->ofdm_symbol_size) * sizeof(c16_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // numerology = 0, longer CP for every 7th symbol
|
||||
|
||||
@@ -144,7 +144,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
c16_t **txdataF);
|
||||
c16_t **txdataF,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]);
|
||||
|
||||
/** \brief This function does IFFT for PUSCH
|
||||
*/
|
||||
@@ -154,7 +155,8 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint8_t n_antenna_ports,
|
||||
c16_t **txdataF,
|
||||
uint32_t linktype);
|
||||
uint32_t linktype,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]);
|
||||
|
||||
void clean_UE_harq(PHY_VARS_NR_UE *UE);
|
||||
|
||||
|
||||
@@ -465,7 +465,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
c16_t **txdataF)
|
||||
c16_t **txdataF,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
|
||||
{
|
||||
|
||||
int harq_pid = phy_data->ulsch.pusch_pdu.pusch_data.harq_process_id;
|
||||
@@ -500,6 +501,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
uint16_t rnti = pusch_pdu->rnti;
|
||||
|
||||
for (int i = start_symbol; i < start_symbol + number_of_symbols; i++) {
|
||||
was_symbol_used[i] = true;
|
||||
if ((ul_dmrs_symb_pos >> i) & 0x01)
|
||||
number_dmrs_symbols += 1;
|
||||
}
|
||||
@@ -831,37 +833,52 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint8_t n_antenna_ports,
|
||||
c16_t **txdataF,
|
||||
uint32_t linktype)
|
||||
uint32_t linktype,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
|
||||
{
|
||||
const int tx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
|
||||
|
||||
int N_RB = (linktype == link_type_sl) ? frame_parms->N_RB_SL : frame_parms->N_RB_UL;
|
||||
|
||||
c16_t **txdata = UE->common_vars.txData;
|
||||
for(int ap = 0; ap < n_antenna_ports; ap++) {
|
||||
apply_nr_rotation_TX(frame_parms,
|
||||
txdataF[ap],
|
||||
frame_parms->symbol_rotation[linktype],
|
||||
slot,
|
||||
N_RB,
|
||||
0,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT);
|
||||
for (int i = 0; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT; i++) {
|
||||
if (was_symbol_used[i] == false)
|
||||
continue;
|
||||
for(int ap = 0; ap < n_antenna_ports; ap++) {
|
||||
apply_nr_rotation_TX(frame_parms,
|
||||
txdataF[ap],
|
||||
frame_parms->symbol_rotation[linktype],
|
||||
slot,
|
||||
N_RB,
|
||||
i,
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int ap = 0; ap < n_antenna_ports; ap++) {
|
||||
if (frame_parms->Ncp == 1) { // extended cyclic prefix
|
||||
PHY_ofdm_mod((int *)txdataF[ap],
|
||||
(int *)&txdata[ap][tx_offset],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
12,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
for (int i = 0; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP; i++) {
|
||||
if (was_symbol_used[i] == false) {
|
||||
memset(&txdata[ap][tx_offset + (frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples) * i],
|
||||
0,
|
||||
(frame_parms->nb_prefix_samples + frame_parms->ofdm_symbol_size) * sizeof(int32_t));
|
||||
continue;
|
||||
}
|
||||
PHY_ofdm_mod((int *)&txdataF[ap][frame_parms->ofdm_symbol_size * i],
|
||||
(int *)&txdata[ap][tx_offset + frame_parms->ofdm_symbol_size * i],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
}
|
||||
} else { // normal cyclic prefix
|
||||
nr_normal_prefix_mod(txdataF[ap],
|
||||
&txdata[ap][tx_offset],
|
||||
14,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
frame_parms,
|
||||
slot);
|
||||
slot,
|
||||
was_symbol_used);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -423,7 +423,10 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu,
|
||||
* send srs according to current configuration
|
||||
*
|
||||
*********************************************************************/
|
||||
int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txdataF)
|
||||
int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
c16_t **txdataF,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
|
||||
{
|
||||
if(!ue->srs_vars[0]->active) {
|
||||
return -1;
|
||||
@@ -432,6 +435,14 @@ int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_
|
||||
|
||||
nfapi_nr_srs_pdu_t *srs_config_pdu = (nfapi_nr_srs_pdu_t*)&ue->srs_vars[0]->srs_config_pdu;
|
||||
|
||||
int first_srs_symbol = ue->frame_parms.symbols_per_slot - 1 - srs_config_pdu->time_start_position;
|
||||
// Num consecutive SRS symbols according to 38.211 6.4.1.4.1
|
||||
int num_srs_symbols[] = {1, 2, 4, 8, 12};
|
||||
int last_srs_symbol = first_srs_symbol + num_srs_symbols[srs_config_pdu->num_symbols] - 1;
|
||||
for (int i = first_srs_symbol; i <= last_srs_symbol; i++) {
|
||||
was_symbol_used[i] = true;
|
||||
}
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY,"Frame = %i, slot = %i\n", proc->frame_tx, proc->nr_slot_tx);
|
||||
LOG_I(NR_PHY,"srs_config_pdu->rnti = 0x%04x\n", srs_config_pdu->rnti);
|
||||
|
||||
@@ -79,6 +79,6 @@ int is_srs_period_nr(SRS_Resource_t *p_SRS_Resource,
|
||||
@param current gNB_id identifier
|
||||
@returns 0 if srs is transmitted -1 otherwise */
|
||||
|
||||
int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txdataF);
|
||||
int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txdataF, bool was_symbol_used[14]);
|
||||
|
||||
#endif /* SRS_MODULATION_NR_H */
|
||||
|
||||
@@ -284,14 +284,15 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
|
||||
txdataF[i] = &txdataF_buf[i * samplesF_per_slot];
|
||||
|
||||
LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = {0};
|
||||
|
||||
start_meas_nr_ue_phy(ue, PHY_PROC_TX);
|
||||
|
||||
nr_ue_ulsch_procedures(ue, frame_tx, slot_tx, phy_data, (c16_t **)&txdataF);
|
||||
nr_ue_ulsch_procedures(ue, frame_tx, slot_tx, phy_data, (c16_t **)&txdataF, was_symbol_used);
|
||||
|
||||
ue_srs_procedures_nr(ue, proc, (c16_t **)&txdataF);
|
||||
ue_srs_procedures_nr(ue, proc, (c16_t **)&txdataF, was_symbol_used);
|
||||
|
||||
pucch_procedures_ue_nr(ue, proc, phy_data, (c16_t **)&txdataF);
|
||||
pucch_procedures_ue_nr(ue, proc, phy_data, (c16_t **)&txdataF, was_symbol_used);
|
||||
|
||||
LOG_D(PHY, "Sending Uplink data \n");
|
||||
|
||||
@@ -304,7 +305,8 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
|
||||
&ue->frame_parms,
|
||||
ue->frame_parms.nb_antennas_tx,
|
||||
(c16_t **)txdataF,
|
||||
link_type_ul);
|
||||
link_type_ul,
|
||||
was_symbol_used);
|
||||
stop_meas_nr_ue_phy(ue, OFDM_MOD_STATS);
|
||||
}
|
||||
|
||||
|
||||
@@ -308,9 +308,12 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc
|
||||
tx_action = 1;
|
||||
}
|
||||
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT];
|
||||
for (int i = 0; i < 14; i++)
|
||||
was_symbol_used[i] = true;
|
||||
if (tx_action) {
|
||||
LOG_D(NR_PHY, "Sending Uplink data \n");
|
||||
nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, fp, fp->nb_antennas_tx, txdataF, link_type_sl);
|
||||
nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, fp, fp->nb_antennas_tx, txdataF, link_type_sl, was_symbol_used);
|
||||
}
|
||||
|
||||
LOG_D(NR_PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
|
||||
|
||||
@@ -132,8 +132,11 @@ binary_search_float_nr(
|
||||
* TS 38.213 9 UE procedure for reporting control information
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txdataF)
|
||||
void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
c16_t **txdataF,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
|
||||
{
|
||||
const int nr_slot_tx = proc->nr_slot_tx;
|
||||
NR_UE_PUCCH *pucch_vars = &phy_data->pucch_vars;
|
||||
@@ -141,6 +144,10 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
|
||||
for (int i=0; i<2; i++) {
|
||||
if(pucch_vars->active[i]) {
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu = &pucch_vars->pucch_pdu[i];
|
||||
for (int symb_idx = 0; symb_idx < pucch_pdu->nr_of_symbols; symb_idx++) {
|
||||
int symb = pucch_pdu->start_symbol_index + symb_idx;
|
||||
was_symbol_used[symb] = true;
|
||||
}
|
||||
uint16_t nb_of_prbs = pucch_pdu->prb_size;
|
||||
/* Generate PUCCH signal according to its format and parameters */
|
||||
|
||||
|
||||
@@ -50,6 +50,6 @@
|
||||
|
||||
/*************** FUNCTIONS ****************************************/
|
||||
|
||||
void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txdataF);
|
||||
void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txdataF, bool was_symbol_used[14]);
|
||||
|
||||
#endif /* PUCCH_UCI_UE_NR_H */
|
||||
|
||||
@@ -1091,11 +1091,16 @@ printf("%d\n", slot);
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
} else {
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT];
|
||||
for (int i = 0; i < 14; i++) {
|
||||
was_symbol_used[i] = true;
|
||||
}
|
||||
nr_normal_prefix_mod(&gNB->common_vars.txdataF[0][aa][txdataF_offset],
|
||||
&txdata[aa][slot_offset],
|
||||
14,
|
||||
frame_parms,
|
||||
slot);
|
||||
slot,
|
||||
was_symbol_used);
|
||||
}
|
||||
}
|
||||
if (n_trials==1) {
|
||||
|
||||
@@ -1525,7 +1525,7 @@ int main(int argc, char *argv[])
|
||||
printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
|
||||
|
||||
printf("\nUE TX\n");
|
||||
for (int i = PHY_PROC_TX; i <= ULSCH_ENCODING_STATS; i++) {
|
||||
for (int i = PHY_PROC_TX; i <= OFDM_MOD_STATS; i++) {
|
||||
printStatIndent(&UE->phy_cpu_stats.cpu_time_stats[i], UE->phy_cpu_stats.cpu_time_stats[i].meas_name);
|
||||
}
|
||||
printStatIndent(&gNB->rx_srs_stats,"RX SRS time");
|
||||
|
||||
Reference in New Issue
Block a user