improvements in RU beamforming handling procedures
This commit is contained in:
@@ -29,31 +29,38 @@
|
||||
|
||||
void init_prach_ru_list(RU_t *ru);
|
||||
|
||||
int nr_phy_init_RU(RU_t *ru) {
|
||||
|
||||
int nr_phy_init_RU(RU_t *ru)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int i,j;
|
||||
int p;
|
||||
int re;
|
||||
|
||||
LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d, nb_rx %d\n",ru_if_types[ru->if_south],ru->nb_tx, ru->nb_rx);
|
||||
|
||||
nfapi_nr_config_request_scf_t *cfg;
|
||||
ru->nb_log_antennas=0;
|
||||
for (int n=0;n<ru->num_gNB;n++) {
|
||||
cfg = &ru->config;
|
||||
if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas) ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->config;
|
||||
ru->nb_log_antennas = 0;
|
||||
for (int n = 0; n < ru->num_gNB; n++) {
|
||||
if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas)
|
||||
ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;
|
||||
}
|
||||
// copy configuration from gNB[0] in to RU, assume that all gNB instances sharing RU use the same configuration (at least the parts that are needed by the RU, numerology and PRACH)
|
||||
|
||||
ru->analog_beamforming = cfg->analog_beamforming_ve.analog_bf_vendor_ext.value;
|
||||
LOG_I(PHY, "RU configured with%s analog beamforming\n", ru->analog_beamforming ? "" : "out");
|
||||
|
||||
// copy configuration from gNB[0] in to RU, assume that all gNB instances sharing RU use the same configuration
|
||||
// (at least the parts that are needed by the RU, numerology and PRACH)
|
||||
|
||||
AssertFatal(ru->nb_log_antennas > 0 && ru->nb_log_antennas < 13, "ru->nb_log_antennas %d ! \n",ru->nb_log_antennas);
|
||||
|
||||
ru->common.beam_id = malloc16_clear(ru->nb_log_antennas * sizeof(uint8_t*));
|
||||
for(int i = 0; i < ru->nb_tx; ++i)
|
||||
ru->common.beam_id[i] = malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(uint8_t));
|
||||
|
||||
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals
|
||||
// Time-domain signals
|
||||
ru->common.txdata = (int32_t**)malloc16(ru->nb_tx*sizeof(int32_t*));
|
||||
ru->common.rxdata = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
|
||||
|
||||
|
||||
for (i=0; i<ru->nb_tx; i++) {
|
||||
for (int i = 0; i < ru->nb_tx; i++) {
|
||||
// Allocate 10 subframes of I/Q TX signal data (time) if not
|
||||
ru->common.txdata[i] = (int32_t*)malloc16_clear((ru->sf_extension + fp->samples_per_frame)*sizeof(int32_t));
|
||||
LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes,sf_extension %d)\n",i,ru->common.txdata[i],
|
||||
@@ -63,7 +70,7 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
LOG_I(PHY,"[INIT] common.txdata[%d] = %p \n",i,ru->common.txdata[i]);
|
||||
|
||||
}
|
||||
for (i=0;i<ru->nb_rx;i++) {
|
||||
for (int i = 0; i < ru->nb_rx; i++) {
|
||||
ru->common.rxdata[i] = (int32_t*)malloc16_clear( fp->samples_per_frame*sizeof(int32_t) );
|
||||
}
|
||||
} // IF5 or local RF
|
||||
@@ -76,7 +83,7 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing
|
||||
LOG_I(PHY,"nb_tx %d\n",ru->nb_tx);
|
||||
ru->common.rxdata_7_5kHz = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
|
||||
for (i=0;i<ru->nb_rx;i++) {
|
||||
for (int i = 0; i < ru->nb_rx; i++) {
|
||||
ru->common.rxdata_7_5kHz[i] = (int32_t*)malloc16_clear( 2*fp->samples_per_subframe*2*sizeof(int32_t) );
|
||||
LOG_I(PHY,"rxdata_7_5kHz[%d] %p for RU %d\n",i,ru->common.rxdata_7_5kHz[i],ru->idx);
|
||||
}
|
||||
@@ -84,31 +91,33 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
|
||||
// allocate precoding input buffers (TX)
|
||||
ru->common.txdataF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
|
||||
for(i=0; i< ru->nb_tx; ++i) ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
|
||||
// [hna] samples_per_frame without CP
|
||||
for(int i = 0; i < ru->nb_tx; ++i)
|
||||
ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
||||
|
||||
// allocate IFFT input buffers (TX)
|
||||
ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
|
||||
LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n",ru->common.txdataF_BF,
|
||||
ru->nb_tx*sizeof(int32_t*));
|
||||
for (i=0; i<ru->nb_tx; i++) {
|
||||
LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n", ru->common.txdataF_BF, ru->nb_tx*sizeof(int32_t*));
|
||||
for (int i = 0; i < ru->nb_tx; i++) {
|
||||
ru->common.txdataF_BF[i] = (int32_t*)malloc16_clear(fp->samples_per_subframe_wCP*sizeof(int32_t) );
|
||||
LOG_I(PHY,"txdataF_BF[%d] %p for RU %d\n",i,ru->common.txdataF_BF[i],ru->idx);
|
||||
}
|
||||
// allocate FFT output buffers (RX)
|
||||
ru->common.rxdataF = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
|
||||
for (i=0; i<ru->nb_rx; i++) {
|
||||
for (int i = 0; i < ru->nb_rx; i++) {
|
||||
// allocate 4 slots of I/Q signal data (frequency)
|
||||
ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(**ru->common.rxdataF)*(RU_RX_SLOT_DEPTH*fp->symbols_per_slot*fp->ofdm_symbol_size) );
|
||||
int size = RU_RX_SLOT_DEPTH * fp->symbols_per_slot * fp->ofdm_symbol_size;
|
||||
ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(**ru->common.rxdataF) * size);
|
||||
LOG_I(PHY,"rxdataF[%d] %p for RU %d\n",i,ru->common.rxdataF[i],ru->idx);
|
||||
}
|
||||
|
||||
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
|
||||
// AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
|
||||
// "nb_antennas_rx too large");
|
||||
for (j=0;j<NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX;j++) {
|
||||
for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) {
|
||||
ru->prach_rxsigF[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
|
||||
|
||||
for (i=0; i<ru->nb_rx; i++) {
|
||||
for (int i = 0; i < ru->nb_rx; i++) {
|
||||
// largest size for PRACH FFT is 4x98304 (16*24576)
|
||||
ru->prach_rxsigF[j][i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) );
|
||||
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[j][i]);
|
||||
@@ -120,44 +129,8 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
|
||||
LOG_I(PHY,"[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB);
|
||||
|
||||
if (ru->do_precoding == 1) {
|
||||
int beam_count = 0;
|
||||
if (ru->nb_tx>1) { //Enable beamforming when nb_tx > 1
|
||||
|
||||
for (p=0;p<ru->nb_log_antennas;p++) {
|
||||
//if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
|
||||
beam_count++;
|
||||
}
|
||||
AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
|
||||
|
||||
for (i=0; i<ru->num_gNB; i++) {
|
||||
int l_ind = 0;
|
||||
for (p=0;p<ru->nb_log_antennas;p++) {
|
||||
//if ((fp->L_ssb >> (63-p)) & 0x01) {
|
||||
ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
|
||||
for (j=0; j<ru->nb_tx; j++) {
|
||||
ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
|
||||
AssertFatal(ru->bw_list[i],"ru->bw_list[%d] is null\n",i);
|
||||
for (re=0; re<fp->ofdm_symbol_size; re++)
|
||||
ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind];
|
||||
//printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j);
|
||||
l_ind++;
|
||||
} // for j
|
||||
//}
|
||||
} // for p
|
||||
} // for i
|
||||
}
|
||||
|
||||
ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*));
|
||||
for(i=0; i< ru->nb_tx; ++i) {
|
||||
ru->common.beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
|
||||
memset(ru->common.beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
|
||||
}
|
||||
}
|
||||
} // !=IF5
|
||||
|
||||
ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_subframe_wCP );
|
||||
|
||||
init_prach_ru_list(ru);
|
||||
|
||||
return(0);
|
||||
@@ -165,56 +138,48 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
|
||||
void nr_phy_free_RU(RU_t *ru)
|
||||
{
|
||||
int i,j;
|
||||
int p;
|
||||
|
||||
LOG_I(PHY, "Freeing RU signal buffers (if_south %s) nb_tx %d\n", ru_if_types[ru->if_south], ru->nb_tx);
|
||||
|
||||
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so free memory for time-domain signals
|
||||
// Hack: undo what is done at allocation
|
||||
for (i = 0; i < ru->nb_tx; i++) {
|
||||
for (int i = 0; i < ru->nb_tx; i++) {
|
||||
int32_t *p = &ru->common.txdata[i][-ru->sf_extension];
|
||||
free_and_zero(p);
|
||||
}
|
||||
free_and_zero(ru->common.txdata);
|
||||
|
||||
for (i = 0; i < ru->nb_rx; i++)
|
||||
for (int i = 0; i < ru->nb_rx; i++)
|
||||
free_and_zero(ru->common.rxdata[i]);
|
||||
free_and_zero(ru->common.rxdata);
|
||||
} // else: IF5 or local RF -> nothing to free()
|
||||
|
||||
if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing
|
||||
for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata_7_5kHz[i]);
|
||||
for (int i = 0; i < ru->nb_rx; i++)
|
||||
free_and_zero(ru->common.rxdata_7_5kHz[i]);
|
||||
free_and_zero(ru->common.rxdata_7_5kHz);
|
||||
|
||||
// free beamforming input buffers (TX)
|
||||
for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF[i]);
|
||||
for (int i = 0; i < ru->nb_tx; i++)
|
||||
free_and_zero(ru->common.txdataF[i]);
|
||||
free_and_zero(ru->common.txdataF);
|
||||
|
||||
// free IFFT input buffers (TX)
|
||||
for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF_BF[i]);
|
||||
for (int i = 0; i < ru->nb_tx; i++)
|
||||
free_and_zero(ru->common.txdataF_BF[i]);
|
||||
free_and_zero(ru->common.txdataF_BF);
|
||||
|
||||
// free FFT output buffers (RX)
|
||||
for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdataF[i]);
|
||||
free_and_zero(ru->common.rxdataF);
|
||||
for (int i = 0; i < ru->nb_rx; i++)
|
||||
free_and_zero(ru->common.rxdataF[i]);
|
||||
free_and_zero(ru->common.rxdataF);
|
||||
|
||||
for (j=0;j<NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX;j++) {
|
||||
for (i = 0; i < ru->nb_rx; i++)
|
||||
for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) {
|
||||
for (int i = 0; i < ru->nb_rx; i++)
|
||||
free_and_zero(ru->prach_rxsigF[j][i]);
|
||||
free_and_zero(ru->prach_rxsigF[j]);
|
||||
}
|
||||
if (ru->do_precoding == 1) {
|
||||
for (i = 0; i < ru->num_gNB; i++) {
|
||||
for (p = 0; p < ru->nb_log_antennas; p++) {
|
||||
for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]);
|
||||
free_and_zero(ru->beam_weights[i][p]);
|
||||
}
|
||||
}
|
||||
for(i=0; i< ru->nb_tx; ++i)
|
||||
free_and_zero(ru->common.beam_id[i]);
|
||||
free_and_zero(ru->common.beam_id);
|
||||
}
|
||||
for(int i = 0; i < ru->nb_log_antennas; ++i)
|
||||
free_and_zero(ru->common.beam_id[i]);
|
||||
free_and_zero(ru->common.beam_id);
|
||||
}
|
||||
free_and_zero(ru->common.sync_corr);
|
||||
}
|
||||
|
||||
@@ -137,32 +137,25 @@ int beam_precoding_one_eNB(int32_t **txdataF,
|
||||
}
|
||||
|
||||
|
||||
int nr_beam_precoding(c16_t **txdataF,
|
||||
c16_t **txdataF_BF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t ***beam_weights,
|
||||
int slot,
|
||||
int symbol,
|
||||
int aa,
|
||||
int nb_antenna_ports,
|
||||
int offset)
|
||||
void nr_beam_precoding(c16_t **txdataF,
|
||||
c16_t **txdataF_BF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t ***beam_weights,
|
||||
int slot,
|
||||
int symbol,
|
||||
int aa,
|
||||
int nb_antenna_ports,
|
||||
int offset)
|
||||
{
|
||||
|
||||
|
||||
uint8_t p;
|
||||
|
||||
// clear txdata_BF[aa][re] for each call of ue_spec_beamforming
|
||||
memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], 0, sizeof(c16_t) *(frame_parms->ofdm_symbol_size));
|
||||
|
||||
for (p=0; p<nb_antenna_ports; p++) {
|
||||
//if ((frame_parms->L_ssb >> (63-p)) & 0x01) {
|
||||
multadd_cpx_vector((int16_t*)&txdataF[p][(symbol*frame_parms->ofdm_symbol_size)+offset],
|
||||
(int16_t*)beam_weights[p][aa],
|
||||
(int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],
|
||||
0,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
15);
|
||||
//}
|
||||
for (int p = 0; p < nb_antenna_ports; p++) {
|
||||
multadd_cpx_vector((int16_t*)&txdataF[p][(symbol*frame_parms->ofdm_symbol_size)+offset],
|
||||
(int16_t*)beam_weights[p][aa],
|
||||
(int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],
|
||||
0,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
15);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -95,16 +95,15 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
|
||||
*/
|
||||
void nr_dft(c16_t *z, c16_t *d, uint32_t Msc_PUSCH);
|
||||
|
||||
int nr_beam_precoding(c16_t **txdataF,
|
||||
c16_t **txdataF_BF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t ***beam_weights,
|
||||
int slot,
|
||||
int symbol,
|
||||
int aa,
|
||||
int nb_antenna_ports,
|
||||
int offset
|
||||
);
|
||||
void nr_beam_precoding(c16_t **txdataF,
|
||||
c16_t **txdataF_BF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t ***beam_weights,
|
||||
int slot,
|
||||
int symbol,
|
||||
int aa,
|
||||
int nb_antenna_ports,
|
||||
int offset);
|
||||
|
||||
void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
|
||||
c16_t *txdataF,
|
||||
|
||||
@@ -663,6 +663,7 @@ typedef struct RU_t_s {
|
||||
/// structure for analyzing high-level RT measurements
|
||||
rt_ru_profiling_t rt_ru_profiling;
|
||||
void* scopeData;
|
||||
bool analog_beamforming;
|
||||
} RU_t;
|
||||
|
||||
|
||||
|
||||
@@ -52,28 +52,37 @@
|
||||
extern int oai_exit;
|
||||
|
||||
// OFDM modulation core routine, generates a first_symbol to first_symbol+num_symbols on a particular slot and TX antenna port
|
||||
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
|
||||
|
||||
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
|
||||
unsigned int slot_offset,slot_offsetF;
|
||||
int slot = tti_tx;
|
||||
|
||||
|
||||
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0) , 1 );
|
||||
|
||||
if (aa==0 && first_symbol == 0) start_meas(&ru->ofdm_mod_stats);
|
||||
slot_offset = fp->get_samples_slot_timestamp(slot,fp,0);
|
||||
slot_offsetF = first_symbol*fp->ofdm_symbol_size;
|
||||
if (aa == 0 && first_symbol == 0)
|
||||
start_meas(&ru->ofdm_mod_stats);
|
||||
slot_offset = fp->get_samples_slot_timestamp(slot, fp, 0);
|
||||
slot_offsetF = first_symbol * fp->ofdm_symbol_size;
|
||||
|
||||
int abs_first_symbol = slot*fp->symbols_per_slot;
|
||||
int abs_first_symbol = slot * fp->symbols_per_slot;
|
||||
|
||||
for (uint16_t idx_sym=abs_first_symbol; idx_sym<abs_first_symbol+first_symbol; idx_sym++)
|
||||
slot_offset += (idx_sym%(0x7<<fp->numerology_index)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
|
||||
for (int idx_sym = abs_first_symbol; idx_sym < abs_first_symbol + first_symbol; idx_sym++)
|
||||
slot_offset += (idx_sym % (0x7 << fp->numerology_index)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
|
||||
|
||||
slot_offset += fp->ofdm_symbol_size*first_symbol;
|
||||
slot_offset += fp->ofdm_symbol_size * first_symbol;
|
||||
|
||||
LOG_D(PHY,"SFN/SF:RU:TX:%d/%d aa %d Generating slot %d (first_symbol %d num_symbols %d) slot_offset %d, slot_offsetF %d\n",ru->proc.frame_tx, ru->proc.tti_tx,aa,slot,first_symbol,num_symbols,slot_offset,slot_offsetF);
|
||||
LOG_D(PHY,
|
||||
"SFN/SF:RU:TX:%d/%d aa %d Generating slot %d (first_symbol %d num_symbols %d) slot_offset %d, slot_offsetF %d\n",
|
||||
ru->proc.frame_tx,
|
||||
ru->proc.tti_tx,
|
||||
aa,
|
||||
slot,
|
||||
first_symbol,
|
||||
num_symbols,
|
||||
slot_offset,
|
||||
slot_offsetF);
|
||||
|
||||
if (fp->Ncp == 1) {
|
||||
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF],
|
||||
@@ -110,8 +119,8 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
|
||||
}
|
||||
} // numerology_index!=0
|
||||
else { //numerology_index == 0
|
||||
for (uint16_t idx_sym=abs_first_symbol; idx_sym<abs_first_symbol+num_symbols; idx_sym++) {
|
||||
if (idx_sym%0x7) {
|
||||
for (int idx_sym = abs_first_symbol; idx_sym < abs_first_symbol+num_symbols; idx_sym++) {
|
||||
if (idx_sym % 0x7) {
|
||||
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF],
|
||||
(int*)&ru->common.txdata[aa][slot_offset],
|
||||
fp->ofdm_symbol_size,
|
||||
@@ -135,7 +144,8 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
|
||||
} // numerology 0
|
||||
}
|
||||
|
||||
if (aa==0 && first_symbol==0) stop_meas(&ru->ofdm_mod_stats);
|
||||
if (aa == 0 && first_symbol == 0)
|
||||
stop_meas(&ru->ofdm_mod_stats);
|
||||
|
||||
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0), 0);
|
||||
}
|
||||
@@ -170,160 +180,158 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) {
|
||||
|
||||
}
|
||||
|
||||
void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) {
|
||||
|
||||
int l,aa;
|
||||
void nr_feptx_prec(RU_t *ru, int frame_tx, int tti_tx)
|
||||
{
|
||||
PHY_VARS_gNB **gNB_list = ru->gNB_list,*gNB;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
int32_t ***bw;
|
||||
int i=0;
|
||||
int slot_tx = tti_tx;
|
||||
int txdataF_offset = (tti_tx*fp->samples_per_slot_wCP);
|
||||
|
||||
start_meas(&ru->precoding_stats);
|
||||
AssertFatal(ru->nb_log_antennas > 0,"ru->nb_log_antennas is 0!\n");
|
||||
if (ru->num_gNB == 1){
|
||||
AssertFatal(ru->nb_log_antennas > 0, "ru->nb_log_antennas is 0!\n");
|
||||
|
||||
if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT)
|
||||
return;
|
||||
|
||||
if (ru->num_gNB == 1) {
|
||||
gNB = gNB_list[0];
|
||||
|
||||
if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT) return;
|
||||
if (ru->config.dbt_config.num_dig_beams != 0) {
|
||||
for(int i = 0; i < ru->nb_log_antennas; ++i) {
|
||||
memcpy((void*) &ru->common.beam_id[i][slot_tx * fp->symbols_per_slot],
|
||||
(void*) &gNB->common_vars.beam_id[i][slot_tx * fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot) * sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
if (!ru->do_precoding || (ru->nb_tx == 1 && ru->nb_log_antennas == 1)) {
|
||||
for (i = 0; i < ru->nb_log_antennas; ++i) {
|
||||
//ru->common.txdataF_BF[i] = (int32_t *)&gNB->common_vars.txdataF[i][txdataF_offset];
|
||||
memcpy(ru->common.txdataF_BF[i],
|
||||
&gNB->common_vars.txdataF[i][txdataF_offset],
|
||||
fp->samples_per_slot_wCP*sizeof(int32_t));
|
||||
}
|
||||
if (ru->config.dbt_config.num_dig_beams == 0 || ru->analog_beamforming) {
|
||||
for (int i = 0; i < ru->nb_log_antennas; ++i)
|
||||
memcpy(ru->common.txdataF_BF[i], &gNB->common_vars.txdataF[i][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t));
|
||||
}
|
||||
else {
|
||||
for(i=0; i<ru->nb_log_antennas; ++i) {
|
||||
for(int i = 0; i < ru->nb_log_antennas; ++i) {
|
||||
memcpy((void*)ru->common.txdataF[i],
|
||||
(void*)&gNB->common_vars.txdataF[i][txdataF_offset],
|
||||
fp->samples_per_slot_wCP*sizeof(int32_t));
|
||||
memcpy((void*)&ru->common.beam_id[i][slot_tx*fp->symbols_per_slot],
|
||||
(void*)&gNB->common_vars.beam_id[i][slot_tx*fp->symbols_per_slot],
|
||||
fp->symbols_per_slot*sizeof(uint8_t));
|
||||
fp->samples_per_slot_wCP * sizeof(int32_t));
|
||||
}
|
||||
bw = ru->beam_weights[0];
|
||||
for (l=0;l<fp->symbols_per_slot;l++) {
|
||||
for (aa=0;aa<ru->nb_tx;aa++) {
|
||||
for (int l = 0; l < fp->symbols_per_slot; l++) {
|
||||
for (int aa = 0; aa < ru->nb_tx; aa++) {
|
||||
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
|
||||
nr_beam_precoding((c16_t **)ru->common.txdataF,
|
||||
(c16_t **)ru->common.txdataF_BF,
|
||||
fp,
|
||||
bw,
|
||||
ru->beam_weights[0],
|
||||
tti_tx,
|
||||
l,
|
||||
aa,
|
||||
ru->nb_log_antennas,
|
||||
0);
|
||||
}// for (aa=0;aa<ru->nb_tx;aa++)
|
||||
}// for (l=0;l<fp->symbols_per_slot;l++)
|
||||
}// ru->do_precoding
|
||||
}// if (ru->num_gNB == 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stop_meas(&ru->precoding_stats);
|
||||
}
|
||||
|
||||
// core routine for FEP TX, called from threads in RU TX thread-pool
|
||||
void nr_feptx(void *arg) {
|
||||
|
||||
void nr_feptx(void *arg)
|
||||
{
|
||||
feptx_cmd_t *feptx = (feptx_cmd_t *)arg;
|
||||
|
||||
RU_t *ru = feptx->ru;
|
||||
int slot = feptx->slot;
|
||||
int aa = feptx->aid;
|
||||
int startSymbol = feptx->startSymbol;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int numSymbols = feptx->numSymbols;
|
||||
int numSamples = feptx->numSymbols*fp->ofdm_symbol_size;
|
||||
int txdataF_offset = (slot*fp->samples_per_slot_wCP) + startSymbol*fp->ofdm_symbol_size;
|
||||
int txdataF_BF_offset = startSymbol*fp->ofdm_symbol_size;
|
||||
RU_t *ru = feptx->ru;
|
||||
int slot = feptx->slot;
|
||||
int aa = feptx->aid;
|
||||
int startSymbol = feptx->startSymbol;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int numSymbols = feptx->numSymbols;
|
||||
int numSamples = feptx->numSymbols * fp->ofdm_symbol_size;
|
||||
int txdataF_offset = (slot * fp->samples_per_slot_wCP) + startSymbol * fp->ofdm_symbol_size;
|
||||
int txdataF_BF_offset = startSymbol * fp->ofdm_symbol_size;
|
||||
|
||||
////////////precoding////////////
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->aid , 1);
|
||||
|
||||
if (aa==0) start_meas(&ru->precoding_stats);
|
||||
|
||||
if (ru->do_precoding == 1) {
|
||||
for(int i=0; i<ru->nb_log_antennas; ++i) {
|
||||
if (aa == 0)
|
||||
start_meas(&ru->precoding_stats);
|
||||
|
||||
if (ru->config.dbt_config.num_dig_beams != 0) {
|
||||
for(int i = 0; i < ru->nb_log_antennas; ++i) {
|
||||
memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot],
|
||||
(void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot)*sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) {
|
||||
memcpy((void*)&ru->common.txdataF_BF[0][txdataF_BF_offset],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset],
|
||||
numSamples*sizeof(int32_t));
|
||||
}
|
||||
else if (ru->do_precoding == 0) {
|
||||
int gNB_tx = ru->gNB_list[0]->frame_parms.nb_antennas_tx;
|
||||
// If there is no digital beamforming we just need to copy the data to RU
|
||||
if (ru->config.dbt_config.num_dig_beams == 0 || ru->analog_beamforming)
|
||||
memcpy((void*)&ru->common.txdataF_BF[aa][txdataF_BF_offset],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[aa%gNB_tx][txdataF_offset],
|
||||
numSamples*sizeof(int32_t));
|
||||
}
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[aa][txdataF_offset],
|
||||
numSamples * sizeof(int32_t));
|
||||
else {
|
||||
AssertFatal(1==0,"This needs to be fixed, do not use beamforming.\n");
|
||||
int32_t ***bw = ru->beam_weights[0];
|
||||
for(int i=0; i<fp->symbols_per_slot; ++i){
|
||||
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
|
||||
for(int i = 0; i < fp->symbols_per_slot; ++i) {
|
||||
nr_beam_precoding((c16_t **)ru->gNB_list[0]->common_vars.txdataF,
|
||||
(c16_t **)ru->common.txdataF_BF,
|
||||
fp,
|
||||
bw,
|
||||
ru->beam_weights[0],
|
||||
slot,
|
||||
i,
|
||||
aa,
|
||||
ru->nb_log_antennas,
|
||||
txdataF_offset);//here
|
||||
txdataF_offset);
|
||||
}
|
||||
}
|
||||
if (aa==0) stop_meas(&ru->precoding_stats);
|
||||
|
||||
if (aa==0)
|
||||
stop_meas(&ru->precoding_stats);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->aid , 0);
|
||||
|
||||
////////////FEPTX////////////
|
||||
nr_feptx0(ru,slot,startSymbol,numSymbols,aa);
|
||||
nr_feptx0(ru, slot, startSymbol, numSymbols, aa);
|
||||
}
|
||||
|
||||
// RU FEP TX using thread-pool
|
||||
void nr_feptx_tp(RU_t *ru, int frame_tx, int slot) {
|
||||
|
||||
void nr_feptx_tp(RU_t *ru, int frame_tx, int slot)
|
||||
{
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
int nbfeptx=0;
|
||||
if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return;
|
||||
// for (int aa=0; aa<ru->nb_tx; aa++) memset(ru->common.txdataF[aa],0,ru->nr_frame_parms->samples_per_slot_wCP*sizeof(int32_t));
|
||||
|
||||
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 1 );
|
||||
int nbfeptx = 0;
|
||||
if (nr_slot_select(cfg, frame_tx, slot) == NR_UPLINK_SLOT)
|
||||
return;
|
||||
if (ru->idx == 0)
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 1);
|
||||
start_meas(&ru->ofdm_total_stats);
|
||||
for (int aid=0;aid<ru->nb_tx;aid++) {
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid,ru->respfeptx,nr_feptx);
|
||||
feptx_cmd_t *feptx_cmd=(feptx_cmd_t*)NotifiedFifoData(req);
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = 0;
|
||||
feptx_cmd->numSymbols = (ru->half_slot_parallelization>0)?ru->nr_frame_parms->symbols_per_slot>>1:ru->nr_frame_parms->symbols_per_slot;
|
||||
pushTpool(ru->threadPool,req);
|
||||
for (int aid = 0; aid < ru->nb_tx; aid++) {
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid, ru->respfeptx, nr_feptx);
|
||||
feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req);
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = 0;
|
||||
feptx_cmd->numSymbols = (ru->half_slot_parallelization > 0) ?
|
||||
ru->nr_frame_parms->symbols_per_slot >> 1 :
|
||||
ru->nr_frame_parms->symbols_per_slot;
|
||||
pushTpool(ru->threadPool, req);
|
||||
nbfeptx++;
|
||||
if (ru->half_slot_parallelization>0) {
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid + ru->nb_tx,ru->respfeptx,nr_feptx);
|
||||
feptx_cmd_t *feptx_cmd=(feptx_cmd_t*)NotifiedFifoData(req);
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot>>1;
|
||||
feptx_cmd->numSymbols = ru->nr_frame_parms->symbols_per_slot>>1;
|
||||
pushTpool(ru->threadPool,req);
|
||||
if (ru->half_slot_parallelization > 0) {
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid + ru->nb_tx, ru->respfeptx, nr_feptx);
|
||||
feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req);
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot >> 1;
|
||||
feptx_cmd->numSymbols = ru->nr_frame_parms->symbols_per_slot >> 1;
|
||||
pushTpool(ru->threadPool, req);
|
||||
nbfeptx++;
|
||||
}
|
||||
}
|
||||
while (nbfeptx>0) {
|
||||
while (nbfeptx > 0) {
|
||||
notifiedFIFO_elt_t *req=pullTpool(ru->respfeptx, ru->threadPool);
|
||||
delNotifiedFIFO_elt(req);
|
||||
nbfeptx--;
|
||||
}
|
||||
stop_meas(&ru->ofdm_total_stats);
|
||||
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 0 );
|
||||
if (ru->idx == 0)
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 0);
|
||||
}
|
||||
|
||||
// core RX FEP routine, called by threads in RU thread-pool
|
||||
|
||||
Reference in New Issue
Block a user