merge, compile ok, regular exe ok, ocp-gnb not
This commit is contained in:
+248
-247
@@ -77,9 +77,14 @@ int nfapi_sync_var=-1;
|
||||
uint8_t nfapi_mode = NFAPI_MONOLITHIC; // Default to monolithic mode
|
||||
double cpuf;
|
||||
|
||||
uint32_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
pthread_cond_t sync_cond;
|
||||
pthread_mutex_t sync_mutex;
|
||||
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
|
||||
|
||||
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
time_stats_t softmodem_stats_mt; // main thread
|
||||
time_stats_t softmodem_stats_hw; // hw acquisition
|
||||
time_stats_t softmodem_stats_rxtx_sf; // total tx time
|
||||
@@ -111,6 +116,8 @@ extern double cpuf;
|
||||
short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655};
|
||||
|
||||
static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx) {
|
||||
sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
start_meas(&softmodem_stats_rxtx_sf);
|
||||
|
||||
// *******************************************************************
|
||||
@@ -151,10 +158,27 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
|
||||
gNB->UL_INFO.CC_id = gNB->CC_id;
|
||||
gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
|
||||
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
|
||||
// RX processing
|
||||
int tx_slot_type = nr_slot_select(cfg,frame_tx,slot_tx);
|
||||
int rx_slot_type = nr_slot_select(cfg,frame_rx,slot_rx);
|
||||
|
||||
//if (slot_rx == NR_UPLINK_SLOT || gNB->frame_parms.frame_type == FDD)
|
||||
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
|
||||
phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
|
||||
if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) {
|
||||
// UE-specific RX processing for subframe n
|
||||
// TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT
|
||||
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
|
||||
}
|
||||
|
||||
if (oai_exit) return(-1);
|
||||
|
||||
// *****************************************
|
||||
// TX processing for subframe n+sf_ahead
|
||||
// run PHY TX procedures the one after the other for all CCs to avoid race conditions
|
||||
// (may be relaxed in the future for performance reasons)
|
||||
// *****************************************
|
||||
|
||||
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
|
||||
phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
|
||||
}
|
||||
|
||||
stop_meas( &softmodem_stats_rxtx_sf );
|
||||
LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
|
||||
@@ -168,15 +192,14 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, struct RU_t_s *ru) {
|
||||
RU_proc_t *ru_proc=&ru->proc;
|
||||
proc->frame_rx = frame_rx;
|
||||
proc->slot_rx = slot_rx;
|
||||
sl_ahead = sf_ahead*fp->slots_per_subframe;
|
||||
|
||||
if (!oai_exit) {
|
||||
L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot);
|
||||
L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe);
|
||||
L1_proc->frame_rx = ru_proc->frame_rx;
|
||||
L1_proc->slot_rx = ru_proc->tti_rx;
|
||||
L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ?
|
||||
(L1_proc->frame_rx+1)&1023 :
|
||||
L1_proc->frame_rx;
|
||||
L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame;
|
||||
L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
|
||||
L1_proc->slot_tx = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame;
|
||||
|
||||
if (rxtx(gNB,L1_proc->frame_rx,L1_proc->slot_rx,L1_proc->frame_tx,L1_proc->slot_tx) < 0)
|
||||
LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id);
|
||||
@@ -189,141 +212,107 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, struct RU_t_s *ru) {
|
||||
|
||||
static void *process_stats_thread(void *param) {
|
||||
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
|
||||
RU_t *ru = (RU_t *)NULL;
|
||||
reset_meas(&gNB->dlsch_encoding_stats);
|
||||
reset_meas(&gNB->dlsch_scrambling_stats);
|
||||
reset_meas(&gNB->dlsch_modulation_stats);
|
||||
reset_meas(&softmodem_stats_mt);
|
||||
reset_meas(&softmodem_stats_hw);
|
||||
for (int sfn=0; sfn < 10; sfn++) {
|
||||
reset_meas(&softmodem_stats_rxtx_sf);
|
||||
reset_meas(&softmodem_stats_rx_sf);
|
||||
}
|
||||
wait_sync("process_stats_thread");
|
||||
|
||||
while(!oai_exit) {
|
||||
sleep(1);
|
||||
print_meas(&gNB->dlsch_encoding_stats, "pdsch_encoding", NULL, NULL);
|
||||
print_meas(&gNB->dlsch_scrambling_stats, "pdsch_scrambling", NULL, NULL);
|
||||
print_meas(&gNB->dlsch_modulation_stats, "pdsch_modulation", NULL, NULL);
|
||||
print_meas(&softmodem_stats_mt, "Main gNB Thread", NULL, NULL);
|
||||
print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL);
|
||||
print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL);
|
||||
print_meas(&ru->precoding_stats,"feptx_prec",NULL,NULL);
|
||||
print_meas(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL);
|
||||
print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL);
|
||||
print_meas(&ru->ofdm_total_stats,"feptx_total",NULL,NULL);
|
||||
print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL);
|
||||
print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL);
|
||||
print_meas(&ru->compression,"compression",NULL,NULL);
|
||||
print_meas(&ru->transport,"transport",NULL,NULL);
|
||||
for (int sfn=0; sfn < 10; sfn++) {
|
||||
print_meas(&softmodem_stats_rxtx_sf,"[gNB][total_phy_proc_rxtx]",NULL, NULL);
|
||||
print_meas(&softmodem_stats_rx_sf,"[gNB][total_phy_proc_rx]",NULL,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void init_gNB_proc(int inst) {
|
||||
int CC_id;
|
||||
PHY_VARS_gNB *gNB;
|
||||
gNB_L1_proc_t *proc;
|
||||
gNB_L1_rxtx_proc_t *L1_proc,*L1_proc_tx;
|
||||
|
||||
for (CC_id=0; CC_id<RC.nb_nr_CC[inst]; CC_id++) {
|
||||
gNB = RC.gNB[inst][CC_id];
|
||||
proc = &gNB->proc;
|
||||
L1_proc = &proc->L1_proc;
|
||||
L1_proc_tx = &proc->L1_proc_tx;
|
||||
L1_proc->instance_cnt = -1;
|
||||
L1_proc_tx->instance_cnt = -1;
|
||||
L1_proc->instance_cnt_RUs = 0;
|
||||
L1_proc_tx->instance_cnt_RUs = 0;
|
||||
proc->instance_cnt_prach = -1;
|
||||
proc->instance_cnt_asynch_rxtx = -1;
|
||||
proc->CC_id = CC_id;
|
||||
proc->first_rx =1;
|
||||
proc->first_tx =1;
|
||||
proc->RU_mask =0;
|
||||
proc->RU_mask_tx = (1<<gNB->num_RU)-1;
|
||||
proc->RU_mask_prach =0;
|
||||
pthread_mutex_init( &gNB->UL_INFO_mutex, NULL);
|
||||
}
|
||||
PHY_VARS_gNB *gNB = RC.gNB[inst];
|
||||
gNB_L1_proc_t *proc = &gNB->proc;
|
||||
gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
|
||||
gNB_L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx;
|
||||
L1_proc->instance_cnt = -1;
|
||||
L1_proc_tx->instance_cnt = -1;
|
||||
L1_proc->instance_cnt_RUs = 0;
|
||||
L1_proc_tx->instance_cnt_RUs = 0;
|
||||
proc->instance_cnt_prach = -1;
|
||||
proc->instance_cnt_asynch_rxtx = -1;
|
||||
proc->CC_id = 0;
|
||||
proc->first_rx =1;
|
||||
proc->first_tx =1;
|
||||
proc->RU_mask =0;
|
||||
proc->RU_mask_tx = (1<<gNB->num_RU)-1;
|
||||
proc->RU_mask_prach =0;
|
||||
pthread_mutex_init( &gNB->UL_INFO_mutex, NULL);
|
||||
}
|
||||
|
||||
/// eNB kept in function name for nffapi calls, TO FIX
|
||||
void init_eNB_afterRU(void) {
|
||||
int inst,CC_id,ru_id,i,aa;
|
||||
int inst,ru_id,i,aa;
|
||||
PHY_VARS_gNB *gNB;
|
||||
LOG_I(PHY,"%s() RC.nb_nr_inst:%d\n", __FUNCTION__, RC.nb_nr_inst);
|
||||
|
||||
for (inst=0; inst<RC.nb_nr_inst; inst++) {
|
||||
LOG_I(PHY,"RC.nb_nr_CC[inst]:%d\n", RC.nb_nr_CC[inst]);
|
||||
LOG_I(PHY,"RC.nb_nr_CC[inst:%d]:%p\n", inst, RC.gNB[inst]);
|
||||
gNB = RC.gNB[inst];
|
||||
phy_init_nr_gNB(gNB,0,0);
|
||||
LOG_I(PHY,"Mapping RX ports from %d RUs to gNB %d\n",gNB->num_RU,gNB->Mod_id);
|
||||
//LOG_I(PHY,"Overwriting gNB->prach_vars.rxsigF[0]:%p\n", gNB->prach_vars.rxsigF[0]);
|
||||
// gNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *));
|
||||
LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU);
|
||||
|
||||
for (CC_id=0; CC_id<RC.nb_nr_CC[inst]; CC_id++) {
|
||||
LOG_I(PHY,"RC.nb_nr_CC[inst:%d][CC_id:%d]:%p\n", inst, CC_id, RC.gNB[inst][CC_id]);
|
||||
gNB = RC.gNB[inst][CC_id];
|
||||
phy_init_nr_gNB(gNB,0,0);
|
||||
for (ru_id=0,aa=0; ru_id<gNB->num_RU; ru_id++) {
|
||||
AssertFatal(gNB->RU_list[ru_id]->common.rxdataF!=NULL,
|
||||
"RU %d : common.rxdataF is NULL\n",
|
||||
gNB->RU_list[ru_id]->idx);
|
||||
AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF!=NULL,
|
||||
"RU %d : prach_rxsigF is NULL\n",
|
||||
gNB->RU_list[ru_id]->idx);
|
||||
|
||||
LOG_I(PHY,"Mapping RX ports from %d RUs to gNB %d\n",gNB->num_RU,gNB->Mod_id);
|
||||
//LOG_I(PHY,"Overwriting gNB->prach_vars.rxsigF[0]:%p\n", gNB->prach_vars.rxsigF[0]);
|
||||
// gNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *));
|
||||
LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU);
|
||||
|
||||
for (ru_id=0,aa=0; ru_id<gNB->num_RU; ru_id++) {
|
||||
AssertFatal(gNB->RU_list[ru_id]->common.rxdataF!=NULL,
|
||||
"RU %d : common.rxdataF is NULL\n",
|
||||
gNB->RU_list[ru_id]->idx);
|
||||
AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF!=NULL,
|
||||
"RU %d : prach_rxsigF is NULL\n",
|
||||
gNB->RU_list[ru_id]->idx);
|
||||
|
||||
for (i=0; i<gNB->RU_list[ru_id]->nb_rx; aa++,i++) {
|
||||
LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
|
||||
// gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i];
|
||||
gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i];
|
||||
}
|
||||
for (i=0; i<gNB->RU_list[ru_id]->nb_rx; aa++,i++) {
|
||||
LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
|
||||
gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[i];
|
||||
gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i];
|
||||
}
|
||||
//init_precoding_weights(RC.gNB[inst][CC_id]);
|
||||
}
|
||||
}
|
||||
|
||||
//init_precoding_weights(RC.gNB[inst][CC_id]);
|
||||
}
|
||||
}
|
||||
|
||||
void init_gNB(int single_thread_flag,int wait_for_sync) {
|
||||
int CC_id;
|
||||
int inst;
|
||||
PHY_VARS_gNB *gNB;
|
||||
LOG_I(PHY,"[nr-softmodem.c] gNB structure about to be allocated RC.nb_nr_L1_inst:%d RC.nb_nr_L1_CC[0]:%d\n",RC.nb_nr_L1_inst,RC.nb_nr_L1_CC[0]);
|
||||
if (RC.gNB == NULL)
|
||||
RC.gNB = (PHY_VARS_gNB **) calloc(1,(1+RC.nb_nr_L1_inst)*sizeof(PHY_VARS_gNB *));
|
||||
|
||||
AssertFatal(RC.gNB != NULL,"");
|
||||
for (inst=0; inst<RC.nb_nr_L1_inst; inst++) {
|
||||
AssertFatal(RC.gNB[inst] != NULL,"");
|
||||
for (int inst=0; inst<RC.nb_nr_L1_inst; inst++) {
|
||||
if (RC.gNB[inst] == NULL )
|
||||
RC.gNB[inst] = (PHY_VARS_gNB *) calloc(1,sizeof(PHY_VARS_gNB));
|
||||
|
||||
for (CC_id=0; CC_id<RC.nb_nr_L1_CC[inst]; CC_id++) {
|
||||
AssertFatal(RC.gNB[inst][CC_id] != NULL,"");
|
||||
gNB = RC.gNB[inst][CC_id];
|
||||
gNB->abstraction_flag = false;
|
||||
gNB->single_thread_flag = true;
|
||||
/*nr_polar_init(&gNB->nrPolar_params,
|
||||
NR_POLAR_PBCH_MESSAGE_TYPE,
|
||||
NR_POLAR_PBCH_PAYLOAD_BITS,
|
||||
NR_POLAR_PBCH_AGGREGATION_LEVEL);*/
|
||||
LOG_I(PHY,"Registering with MAC interface module\n");
|
||||
AssertFatal((gNB->if_inst = NR_IF_Module_init(inst))!=NULL,"Cannot register interface");
|
||||
gNB->if_inst->NR_Schedule_response = nr_schedule_response;
|
||||
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
|
||||
memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
|
||||
memset((void *)&gNB->UL_tti_req,0,sizeof(nfapi_nr_ul_tti_request_t));
|
||||
//memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO));
|
||||
LOG_I(PHY,"Setting indication lists\n");
|
||||
gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list;
|
||||
gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list;
|
||||
gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list;
|
||||
gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list;
|
||||
gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list;
|
||||
gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;
|
||||
gNB->prach_energy_counter = 0;
|
||||
}
|
||||
PHY_VARS_gNB *gNB= RC.gNB[inst];
|
||||
gNB->abstraction_flag = false;
|
||||
gNB->single_thread_flag = true;
|
||||
/*nr_polar_init(&gNB->nrPolar_params,
|
||||
NR_POLAR_PBCH_MESSAGE_TYPE,
|
||||
NR_POLAR_PBCH_PAYLOAD_BITS,
|
||||
NR_POLAR_PBCH_AGGREGATION_LEVEL);*/
|
||||
LOG_I(PHY,"Registering with MAC interface module\n");
|
||||
AssertFatal((gNB->if_inst = NR_IF_Module_init(inst))!=NULL,"Cannot register interface");
|
||||
gNB->if_inst->NR_Schedule_response = nr_schedule_response;
|
||||
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
|
||||
memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
|
||||
memset((void *)&gNB->UL_tti_req,0,sizeof(nfapi_nr_ul_tti_request_t));
|
||||
//memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO));
|
||||
LOG_I(PHY,"Setting indication lists\n");
|
||||
gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list;
|
||||
gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list;
|
||||
gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list;
|
||||
gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list;
|
||||
gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list;
|
||||
gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;
|
||||
gNB->prach_energy_counter = 0;
|
||||
}
|
||||
|
||||
LOG_I(PHY,"[nr-softmodem.c] gNB structure allocated\n");
|
||||
}
|
||||
|
||||
@@ -385,19 +374,16 @@ static void init_pdcp(void) {
|
||||
void init_main_gNB(void) {
|
||||
RCconfig_NR_L1();
|
||||
RCconfig_nr_macrlc();
|
||||
|
||||
if (RC.nb_nr_L1_inst>0) AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n");
|
||||
|
||||
|
||||
LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst);
|
||||
|
||||
RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *));
|
||||
LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc);
|
||||
|
||||
int gnb_id=0; // only 1 gnb per process, index 0 for now
|
||||
|
||||
RC.nrrrc[gnb_id] = (gNB_RRC_INST*)malloc(sizeof(gNB_RRC_INST));
|
||||
RC.nrrrc[gnb_id] = (gNB_RRC_INST *)malloc(sizeof(gNB_RRC_INST));
|
||||
memset((void *)RC.nrrrc[gnb_id],0,sizeof(gNB_RRC_INST));
|
||||
MessageDef *msg_p = itti_alloc_new_message (TASK_GNB_APP, NRRRC_CONFIGURATION_REQ);
|
||||
|
||||
RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]);
|
||||
openair_rrc_gNB_configuration(GNB_INSTANCE_TO_MODULE_ID(ITTI_MSG_INSTANCE(msg_p)), &NRRRC_CONFIGURATION_REQ(msg_p));
|
||||
}
|
||||
@@ -414,7 +400,6 @@ static void wait_nfapi_init(char *thread_name) {
|
||||
}
|
||||
|
||||
void wait_gNBs(void) {
|
||||
int i,j;
|
||||
int waiting=1;
|
||||
|
||||
while (waiting==1) {
|
||||
@@ -422,14 +407,10 @@ void wait_gNBs(void) {
|
||||
usleep(50*1000);
|
||||
waiting=0;
|
||||
|
||||
for (i=0; i<RC.nb_nr_L1_inst; i++) {
|
||||
printf("RC.nb_nr_L1_CC[%d]:%d\n", i, RC.nb_nr_L1_CC[i]);
|
||||
|
||||
for (j=0; j<RC.nb_nr_L1_CC[i]; j++) {
|
||||
if (RC.gNB[i][j]->configured==0) {
|
||||
waiting=1;
|
||||
break;
|
||||
}
|
||||
for (int i=0; i<RC.nb_nr_L1_inst; i++) {
|
||||
if (RC.gNB[i]->configured==0) {
|
||||
waiting=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -493,7 +474,7 @@ void RCconfig_RU(void) {
|
||||
else
|
||||
RC.ru[j]->num_gNB = 0;
|
||||
|
||||
for (i=0; i<RC.ru[j]->num_gNB; i++) RC.ru[j]->gNB_list[i] = RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0];
|
||||
for (i=0; i<RC.ru[j]->num_gNB; i++) RC.ru[j]->gNB_list[i] = &RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0];
|
||||
|
||||
if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) {
|
||||
RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr));
|
||||
@@ -561,132 +542,145 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
|
||||
void *rxp[ru->nb_rx];
|
||||
unsigned int rxs;
|
||||
int i;
|
||||
uint32_t samples_per_slot = fp->get_samples_per_slot(*slot,fp);
|
||||
openair0_timestamp ts,old_ts;
|
||||
AssertFatal(*slot<fp->slots_per_frame && *slot>=0, "slot %d is illegal (%d)\n",*slot,fp->slots_per_frame);
|
||||
|
||||
for (i=0; i<ru->nb_rx; i++)
|
||||
rxp[i] = (void *)&ru->common.rxdata[i][*slot*fp->samples_per_slot];
|
||||
rxp[i] = (void *)&ru->common.rxdata[i][fp->get_samples_slot_timestamp(*slot,fp,0)];
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
|
||||
old_ts = proc->timestamp_rx;
|
||||
LOG_D(PHY,"Reading %d samples for slot %d (%p)\n",fp->samples_per_slot,*slot,rxp[0]);
|
||||
|
||||
LOG_D(PHY,"Reading %d samples for slot %d (%p)\n",samples_per_slot,*slot,rxp[0]);
|
||||
rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
|
||||
&ts,
|
||||
rxp,
|
||||
fp->samples_per_slot,
|
||||
ru->nb_rx);
|
||||
|
||||
&ts,
|
||||
rxp,
|
||||
samples_per_slot,
|
||||
ru->nb_rx);
|
||||
proc->timestamp_rx = ts-ru->ts_offset;
|
||||
|
||||
|
||||
//AssertFatal(rxs == fp->samples_per_subframe,
|
||||
//"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_subframe,rxs);
|
||||
if (rxs != fp->samples_per_slot)
|
||||
LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_slot,rxs);
|
||||
|
||||
if (rxs != samples_per_slot) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",samples_per_slot,rxs);
|
||||
|
||||
if (proc->first_rx == 1) {
|
||||
ru->ts_offset = proc->timestamp_rx;
|
||||
proc->timestamp_rx = 0;
|
||||
AssertFatal(proc->tti_rx == *slot && proc->frame_rx == *frame ,
|
||||
"Received Timestamp (%llu) doesn't correspond to the time we think it is \n\
|
||||
(proc->tti_rx %d, subframe %d, proc->frame_rx %d frame %d)\n",
|
||||
(long long unsigned int)proc->timestamp_rx,proc->tti_rx,*slot, proc->frame_rx,*frame);
|
||||
} else {
|
||||
if (proc->timestamp_rx - old_ts != fp->samples_per_slot) {
|
||||
LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",
|
||||
proc->timestamp_rx - old_ts - fp->samples_per_slot,ru->ts_offset);
|
||||
ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_slot);
|
||||
if (proc->timestamp_rx - old_ts != fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp)) {
|
||||
LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - samples_per_slot,ru->ts_offset);
|
||||
ru->ts_offset += (proc->timestamp_rx - old_ts - samples_per_slot);
|
||||
proc->timestamp_rx = ts-ru->ts_offset;
|
||||
}
|
||||
}
|
||||
|
||||
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_slot*fp->slots_per_frame))&1023;
|
||||
proc->tti_rx = (proc->timestamp_rx / fp->samples_per_slot)%fp->slots_per_frame;
|
||||
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023;
|
||||
uint32_t idx_sf = proc->timestamp_rx / fp->samples_per_subframe;
|
||||
proc->tti_rx = (idx_sf * fp->slots_per_subframe + (int)round((float)(proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame);
|
||||
*frame = proc->frame_rx;
|
||||
*slot = proc->tti_rx;
|
||||
proc->first_rx = 0;
|
||||
|
||||
if (rxs != fp->samples_per_slot)
|
||||
LOG_E(PHY, "problem receiving samples\n");
|
||||
}
|
||||
|
||||
if (rxs != samples_per_slot) {
|
||||
LOG_E(PHY, "problem receiving samples\n");
|
||||
}
|
||||
}
|
||||
void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
//nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
void *txp[ru->nb_tx];
|
||||
unsigned int txs;
|
||||
int i;
|
||||
int i,txsymb;
|
||||
T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot),
|
||||
T_INT(0), T_BUFFER(&ru->common.txdata[0][slot * fp->samples_per_slot], fp->samples_per_slot * 4));
|
||||
int sf_extension = 0;
|
||||
//nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame,frame);
|
||||
T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp,0)], fp->samples_per_subframe * 4));
|
||||
int slot_type = nr_slot_select(cfg,frame,slot%fp->slots_per_frame);
|
||||
int prevslot_type = nr_slot_select(cfg,frame,(slot+(fp->slots_per_frame-1))%fp->slots_per_frame);
|
||||
int nextslot_type = nr_slot_select(cfg,frame,(slot+1)%fp->slots_per_frame);
|
||||
int sf_extension = 0; //sf_extension = ru->sf_extension;
|
||||
int siglen=fp->get_samples_per_slot(slot,fp);
|
||||
int flags=1;
|
||||
|
||||
if ((slot == 0) ||
|
||||
(slot == 1) || IS_SOFTMODEM_RFSIM ) {
|
||||
int siglen=fp->samples_per_slot;
|
||||
int flags;
|
||||
//nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame);
|
||||
if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT || IS_SOFTMODEM_RFSIM) {
|
||||
if(slot_type == NR_MIXED_SLOT) {
|
||||
txsymb = 0;
|
||||
|
||||
if (slot==0)
|
||||
flags = 2;
|
||||
else if (slot==1)
|
||||
flags=3;
|
||||
else
|
||||
flags=4;
|
||||
for(int symbol_count =0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
|
||||
if (cfg->tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0)
|
||||
txsymb++;
|
||||
}
|
||||
|
||||
/*
|
||||
if (SF_type == SF_S) {
|
||||
siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0);
|
||||
flags=3; // end of burst
|
||||
}
|
||||
if ((fp->frame_type == TDD) &&
|
||||
(SF_type == SF_DL)&&
|
||||
(prevSF_type == SF_UL) &&
|
||||
(nextSF_type == SF_DL)) {
|
||||
flags = 2; // start of burst
|
||||
sf_extension = ru->N_TA_offset<<1;
|
||||
}
|
||||
AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb);
|
||||
|
||||
if ((cfg->subframe_config.duplex_mode == TDD) &&
|
||||
(SF_type == SF_DL)&&
|
||||
(prevSF_type == SF_UL) &&
|
||||
(nextSF_type == SF_UL)) {
|
||||
flags = 4; // start of burst and end of burst (only one DL SF between two UL)
|
||||
sf_extension = ru->N_TA_offset<<1;
|
||||
} */
|
||||
if(slot%(fp->slots_per_subframe/2))
|
||||
siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
|
||||
else
|
||||
siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
|
||||
|
||||
//+ ru->end_of_burst_delay;
|
||||
flags=3; // end of burst
|
||||
}
|
||||
|
||||
if (cfg->cell_config.frame_duplex_type.value == TDD &&
|
||||
slot_type == NR_DOWNLINK_SLOT &&
|
||||
prevslot_type == NR_UPLINK_SLOT) {
|
||||
flags = 2; // start of burst
|
||||
}
|
||||
|
||||
if (cfg->cell_config.frame_duplex_type.value == TDD &&
|
||||
slot_type == NR_DOWNLINK_SLOT &&
|
||||
nextslot_type == NR_UPLINK_SLOT) {
|
||||
flags = 3; // end of burst
|
||||
}
|
||||
|
||||
if (fp->freq_range==nr_FR2) {
|
||||
// the beam index is written in bits 8-10 of the flags
|
||||
// bit 11 enables the gpio programming
|
||||
int beam=0;
|
||||
|
||||
if (slot==0) beam = 11; //3 for boresight & 8 to enable
|
||||
|
||||
/*
|
||||
if (slot==0 || slot==40) beam=0&8;
|
||||
if (slot==10 || slot==50) beam=1&8;
|
||||
if (slot==20 || slot==60) beam=2&8;
|
||||
if (slot==30 || slot==70) beam=3&8;
|
||||
*/
|
||||
flags |= beam<<8;
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame );
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot );
|
||||
|
||||
for (i=0; i<ru->nb_tx; i++) {
|
||||
txp[i] = (void *)&ru->common.txdata[i][(slot*fp->samples_per_slot)-sf_extension];
|
||||
}
|
||||
for (i=0; i<ru->nb_tx; i++)
|
||||
txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot,fp,0)-sf_extension];
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
|
||||
// prepare tx buffer pointers
|
||||
start_meas(&ru->tx_fhaul);
|
||||
txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
|
||||
timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
|
||||
txp,
|
||||
siglen+sf_extension,
|
||||
ru->nb_tx,
|
||||
flags);
|
||||
stop_meas(&ru->tx_fhaul);
|
||||
LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx,
|
||||
LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, slot %d\n",ru->idx,
|
||||
(long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
|
||||
AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %u/%d)\n", txs, siglen);
|
||||
}
|
||||
}
|
||||
|
||||
// this is for RU with local RF unit
|
||||
void fill_rf_config(RU_t *ru, char *rf_config_file) {
|
||||
int i;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index
|
||||
nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index
|
||||
openair0_config_t *cfg = &ru->openair0_cfg;
|
||||
int N_RB = gNB_config->rf_config.dl_carrier_bandwidth.value;
|
||||
int mu = gNB_config->subframe_config.numerology_index_mu.value;
|
||||
int mu = gNB_config->ssb_config.scs_common.value;
|
||||
int N_RB = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
|
||||
fp->threequarter_fs=threequarter_fs;
|
||||
|
||||
if (mu == NR_MU_0) { //or if LTE
|
||||
if(N_RB == 100) {
|
||||
@@ -754,11 +748,23 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
|
||||
} else {
|
||||
AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu);
|
||||
}
|
||||
} else if (mu == NR_MU_3) {
|
||||
if (N_RB == 66) {
|
||||
cfg->sample_rate = 122.88e6;
|
||||
cfg->samples_per_frame = 1228800;
|
||||
cfg->tx_bw = 100e6;
|
||||
cfg->rx_bw = 100e6;
|
||||
} else if(N_RB == 32) {
|
||||
cfg->sample_rate=61.44e6;
|
||||
cfg->samples_per_frame = 614400;
|
||||
cfg->tx_bw = 50e6;
|
||||
cfg->rx_bw = 50e6;
|
||||
}
|
||||
} else {
|
||||
AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu);
|
||||
}
|
||||
|
||||
if (gNB_config->subframe_config.duplex_mode.value==TDD)
|
||||
if (gNB_config->cell_config.frame_duplex_type.value==TDD)
|
||||
cfg->duplex_mode = duplex_mode_TDD;
|
||||
else //FDD
|
||||
cfg->duplex_mode = duplex_mode_FDD;
|
||||
@@ -769,8 +775,14 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
|
||||
cfg->rx_num_channels=ru->nb_rx;
|
||||
|
||||
for (i=0; i<ru->nb_tx; i++) {
|
||||
cfg->tx_freq[i] = (double)fp->dl_CarrierFreq;
|
||||
cfg->rx_freq[i] = (double)fp->ul_CarrierFreq;
|
||||
if (ru->if_frequency == 0) {
|
||||
cfg->tx_freq[i] = (double)fp->dl_CarrierFreq;
|
||||
cfg->rx_freq[i] = (double)fp->ul_CarrierFreq;
|
||||
} else {
|
||||
cfg->tx_freq[i] = (double)ru->if_frequency;
|
||||
cfg->rx_freq[i] = (double)(ru->if_frequency+fp->ul_CarrierFreq-fp->dl_CarrierFreq);
|
||||
}
|
||||
|
||||
cfg->tx_gain[i] = ru->att_tx;
|
||||
cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx;
|
||||
cfg->configFilename = rf_config_file;
|
||||
@@ -781,24 +793,21 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
|
||||
cfg->rx_freq[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void *ru_thread( void *param ) {
|
||||
RU_t *ru = (RU_t *)param;
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int slot = fp->slots_per_frame-1;
|
||||
int frame = 1023;
|
||||
|
||||
LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]);
|
||||
|
||||
fp->threequarter_fs=threequarter_fs;
|
||||
nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp);
|
||||
nr_dump_frame_parms(fp);
|
||||
fill_rf_config(ru,ru->rf_config_file);
|
||||
nr_phy_init_RU(ru);
|
||||
|
||||
AssertFatal(openair0_device_load(&ru->rfdevice,&ru->openair0_cfg)==0,"Cannot connect to local radio\n");
|
||||
AssertFatal(openair0_device_load(&ru->rfdevice,&ru->openair0_cfg)==0,"Cannot connect to local radio\n");
|
||||
AssertFatal(ru->rfdevice.trx_start_func(&ru->rfdevice) == 0,"Could not start the RF device\n");
|
||||
|
||||
|
||||
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
|
||||
while (!oai_exit) {
|
||||
// these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
|
||||
@@ -814,13 +823,12 @@ static void *ru_thread( void *param ) {
|
||||
// synchronization on input FH interface, acquire signals/data and block
|
||||
LOG_D(PHY,"[RU_thread] read data: frame_rx = %d, tti_rx = %d\n", frame, slot);
|
||||
rx_rf(ru,&frame,&slot);
|
||||
|
||||
LOG_D(PHY,"AFTER rx_rf - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0][0]:[RX:%d%d TX(SFN):%d]\n",
|
||||
frame,slot,
|
||||
proc->frame_rx,proc->tti_rx,
|
||||
proc->frame_tx,proc->tti_tx,
|
||||
RC.gNB[0][0]->proc.frame_rx,RC.gNB[0][0]->proc.slot_rx,
|
||||
RC.gNB[0][0]->proc.frame_tx);
|
||||
RC.gNB[0][0].proc.frame_rx,RC.gNB[0][0].proc.slot_rx,
|
||||
RC.gNB[0][0].proc.frame_tx);
|
||||
/*
|
||||
LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n",
|
||||
ru->do_prach,
|
||||
@@ -835,81 +843,76 @@ static void *ru_thread( void *param ) {
|
||||
//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~%d.%d in ru_thread is in process\n", proc->frame_rx, proc->tti_rx);
|
||||
if (ru->idx!=0)
|
||||
proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023;
|
||||
|
||||
|
||||
// do RX front-end processing (frequency-shift, dft) if needed
|
||||
|
||||
|
||||
if (proc->tti_rx == NR_UPLINK_SLOT || fp->frame_type == FDD) {
|
||||
nr_fep_full(ru,proc->tti_rx);
|
||||
}
|
||||
|
||||
gNB_top(RC.gNB[0][0], frame, slot, ru);
|
||||
|
||||
gNB_top(&RC.gNB[0][0], frame, slot, ru);
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
//ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx);
|
||||
nr_feptx_prec(ru,proc->frame_tx,proc->tti_tx);
|
||||
// do OFDM with/without TX front-end processing if needed
|
||||
//ru->feptx_ofdm
|
||||
nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
if (nr_slot_select(cfg,proc->tti_tx,proc->frame_tx ) != SF_UL) {
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
|
||||
if (nr_slot_select(cfg,proc->frame_tx, proc->tti_tx ) != SF_UL) {
|
||||
int aa=0; // antenna 0 hardcoded
|
||||
NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms;
|
||||
nr_feptx0(ru,proc->tti_tx,0,fp->symbols_per_slot,aa);
|
||||
}
|
||||
|
||||
|
||||
// do outgoing fronthaul (south) if needed
|
||||
tx_rf(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx);
|
||||
}
|
||||
|
||||
|
||||
printf( "Exiting ru_thread \n");
|
||||
ru->rfdevice.trx_end_func(&ru->rfdevice);
|
||||
|
||||
static int ru_thread_status = 0;
|
||||
return &ru_thread_status;
|
||||
}
|
||||
|
||||
void launch_NR_RU(char *rf_config_file) {
|
||||
printf("configuring RU from file\n");
|
||||
RCconfig_RU();
|
||||
LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",
|
||||
RC.nb_nr_L1_inst,RC.nb_RU,get_nprocs());
|
||||
|
||||
RC.nb_nr_L1_inst,RC.nb_RU,get_nprocs());
|
||||
LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU);
|
||||
|
||||
for (int ru_id=0; ru_id<RC.nb_RU; ru_id++) {
|
||||
LOG_D(PHY,"Process RC.ru[%d]\n",ru_id);
|
||||
RU_t *ru = RC.ru[ru_id];
|
||||
RU_t *ru = RC.ru[ru_id];
|
||||
ru->rf_config_file = rf_config_file;
|
||||
ru->idx = ru_id;
|
||||
ru->ts_offset = 0;
|
||||
// use gNB_list[0] as a reference for RU frame parameters
|
||||
// NOTE: multiple CC_id are not handled here yet!
|
||||
|
||||
LOG_D(PHY, "%s() RC.ru[%d].num_gNB:%d ru->gNB_list[0]:%p RC.gNB[0][0]:%p rf_config_file:%s\n",
|
||||
__FUNCTION__, ru_id, ru->num_gNB, ru->gNB_list[0], RC.gNB[0][0], ru->rf_config_file);
|
||||
LOG_D(PHY, "%s() RC.ru[%d].num_gNB:%d ru->gNB_list[0]:%p rf_config_file:%s\n",
|
||||
__FUNCTION__, ru_id, ru->num_gNB, ru->gNB_list[0], ru->rf_config_file);
|
||||
LOG_E(PHY,"ru->gNB_list ru->num_gNB hardcoded: one RU connected to carrier 0 of gNB 0\n");
|
||||
ru->gNB_list[0] = RC.gNB[0][0];
|
||||
ru->gNB_list[0] = &RC.gNB[0][0];
|
||||
ru->num_gNB=1;
|
||||
LOG_I(PHY,"Copying frame parms from gNB in RC to ru %d and frame_parms in ru\n",ru->idx);
|
||||
memcpy((void *)ru->nr_frame_parms,&RC.gNB[0][0]->frame_parms,sizeof(NR_DL_FRAME_PARMS));
|
||||
memcpy((void *)ru->nr_frame_parms,&RC.gNB[0][0].frame_parms,sizeof(NR_DL_FRAME_PARMS));
|
||||
|
||||
for (int i=0; i<ru->num_gNB; i++) {
|
||||
PHY_VARS_gNB *gNB0 = ru->gNB_list[i];
|
||||
PHY_VARS_gNB *gNB0 = ru->gNB_list[i];
|
||||
gNB0->RU_list[gNB0->num_RU++] = ru;
|
||||
}
|
||||
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "thread_FH", -1, OAI_PRIORITY_RT_MAX );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
int main( int argc, char **argv ) {
|
||||
|
||||
AssertFatal(load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY),
|
||||
"[SOFTMODEM] Error, configuration module init failed\n");
|
||||
"[SOFTMODEM] Error, configuration module init failed\n");
|
||||
logInit();
|
||||
#ifndef PACKAGE_VERSION
|
||||
# define PACKAGE_VERSION "UNKNOWN"
|
||||
#endif
|
||||
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
|
||||
|
||||
configure_linux();
|
||||
get_options ();
|
||||
get_common_options(SOFTMODEM_GNB_BIT );
|
||||
@@ -918,46 +921,43 @@ int main( int argc, char **argv ) {
|
||||
fprintf(stderr,"Getting configuration failed\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
cpuf=get_cpu_freq_GHz();
|
||||
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
|
||||
set_taus_seed (0);
|
||||
|
||||
init_opt();
|
||||
|
||||
if(IS_SOFTMODEM_NOS1)
|
||||
init_pdcp();
|
||||
|
||||
init_main_gNB();
|
||||
|
||||
/* Start the agent. If it is turned off in the configuration, it won't start */
|
||||
RCconfig_nr_flexran();
|
||||
|
||||
for (int i = 0; i < RC.nb_nr_L1_inst; i++) {
|
||||
flexran_agent_start(i);
|
||||
}
|
||||
|
||||
// init UE_PF_PO and mutex lock (paging from S1AP)
|
||||
pthread_mutex_init(&ue_pf_po_mutex, NULL);
|
||||
|
||||
printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
|
||||
pthread_cond_init(&nfapi_sync_cond,NULL);
|
||||
pthread_mutex_init(&nfapi_sync_mutex, NULL);
|
||||
|
||||
const char *nfapi_mode_str[] = {
|
||||
"MONOLITHIC", "PNF", "VNF", };
|
||||
"MONOLITHIC", "PNF", "VNF",
|
||||
};
|
||||
AssertFatal(nfapi_mode < 3,"");
|
||||
printf("NFAPI MODE:%s\n", nfapi_mode_str[nfapi_mode]);
|
||||
|
||||
|
||||
if (nfapi_mode==NFAPI_MODE_VNF) // VNF
|
||||
wait_nfapi_init("main?");
|
||||
|
||||
number_of_cards = 1;
|
||||
LOG_I(PHY,"Initializing gNB threads\n");
|
||||
init_gNB(single_thread_flag,wait_for_sync);
|
||||
|
||||
printf("wait_gNBs()\n");
|
||||
wait_gNBs();
|
||||
printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU);
|
||||
|
||||
config_sync_var=0;
|
||||
|
||||
if (nfapi_mode==NFAPI_MODE_PNF) { // PNF
|
||||
@@ -978,6 +978,7 @@ int main( int argc, char **argv ) {
|
||||
}
|
||||
|
||||
init_gNB_proc(0); // only instance 0 (one gNB per process)
|
||||
|
||||
if (RC.nb_RU >0) {
|
||||
printf("Initializing RU threads\n");
|
||||
launch_NR_RU(get_softmodem_params()->rf_config_file);
|
||||
@@ -986,17 +987,17 @@ int main( int argc, char **argv ) {
|
||||
if (opp_enabled ==1) {
|
||||
pthread_t t;
|
||||
threadCreate(&t, process_stats_thread,
|
||||
(void *)NULL, "time_meas", -1, OAI_PRIORITY_RT_LOW);
|
||||
(void *)NULL, "time_meas", -1, OAI_PRIORITY_RT_LOW);
|
||||
}
|
||||
|
||||
if (do_forms==1) {
|
||||
scopeParms_t tmp={&argc, argv};
|
||||
scopeParms_t tmp= {&argc, argv};
|
||||
startScope(&tmp);
|
||||
}
|
||||
|
||||
while(!oai_exit)
|
||||
sleep(1);
|
||||
|
||||
|
||||
for(int ru_id=0; ru_id<NB_RU; ru_id++) {
|
||||
if (RC.ru[ru_id]->rfdevice.trx_end_func)
|
||||
RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);
|
||||
|
||||
Reference in New Issue
Block a user