From 818b27c1f802d106ddbbe0e6c514f10adce4f2bb Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Wed, 31 Oct 2018 18:18:51 +0100 Subject: [PATCH 01/14] renaming for gNB --- openair1/PHY/NR_TRANSPORT/nr_dci.h | 2 +- openair1/PHY/NR_TRANSPORT/nr_dci_tools.c | 2 +- openair1/PHY/defs_gNB.h | 31 ++-- openair1/SCHED_NR/fapi_nr_l1.c | 8 +- openair1/SCHED_NR/fapi_nr_l1.h | 2 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- openair1/SCHED_NR/sched_nr.h | 2 +- targets/RT/USER/nr-gnb.c | 170 ++++++++++++---------- targets/RT/USER/nr-ru.c | 2 +- 9 files changed, 123 insertions(+), 98 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index 62236eff32..8d79311f35 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -49,7 +49,7 @@ void nr_pdcch_scrambling(uint32_t *in, void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, int frame, int subframe, - gNB_rxtx_proc_t *proc, + gNB_L1_rxtx_proc_t *proc, NR_gNB_DCI_ALLOC_t *dci_alloc, nfapi_nr_dl_config_request_pdu_t *pdu); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c index aafafb6d7d..c1a17e6da7 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c @@ -108,7 +108,7 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, int frame, int subframe, - gNB_rxtx_proc_t *proc, + gNB_L1_rxtx_proc_t *proc, NR_gNB_DCI_ALLOC_t *dci_alloc, nfapi_nr_dl_config_request_pdu_t *pdu) { diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 18c2ba5cce..6afed9518d 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -99,22 +99,29 @@ typedef struct { int frame_rx; /// \brief Instance count for RXn-TXnp4 processing thread. /// \internal This variable is protected by \ref mutex_rxtx. - int instance_cnt_rxtx; + int instance_cnt; /// pthread structure for RXn-TXnp4 processing thread - pthread_t pthread_rxtx; + pthread_t pthread; /// pthread attributes for RXn-TXnp4 processing thread - pthread_attr_t attr_rxtx; + pthread_attr_t attr; /// condition variable for tx processing thread - pthread_cond_t cond_rxtx; + pthread_cond_t cond; /// mutex for RXn-TXnp4 processing thread - pthread_mutex_t mutex_rxtx; + pthread_mutex_t mutex; /// scheduling parameters for RXn-TXnp4 thread struct sched_param sched_param_rxtx; -} gNB_rxtx_proc_t; + + /// \internal This variable is protected by \ref mutex_RUs. + int instance_cnt_RUs; + /// condition variable for tx processing thread + pthread_cond_t cond_RUs; + /// mutex for RXn-TXnp4 processing thread + pthread_mutex_t mutex_RUs; +} gNB_L1_rxtx_proc_t; /// Context data structure for eNB subframe processing -typedef struct gNB_proc_t_s { +typedef struct gNB_L1_proc_t_s { /// Component Carrier index uint8_t CC_id; /// thread index @@ -181,17 +188,19 @@ typedef struct gNB_proc_t_s { pthread_mutex_t mutex_asynch_rxtx; /// mutex for RU access to eNB processing (PDSCH/PUSCH) pthread_mutex_t mutex_RU; + /// mutex for RU_tx access to eNB_tx processing (PDSCH/PUSCH) + pthread_mutex_t mutex_RU_tx; /// mutex for RU access to eNB processing (PRACH) pthread_mutex_t mutex_RU_PRACH; /// mutex for RU access to eNB processing (PRACH BR) pthread_mutex_t mutex_RU_PRACH_br; /// mask for RUs serving eNB (PDSCH/PUSCH) - int RU_mask; + int RU_mask, RU_mask_tx; /// mask for RUs serving eNB (PRACH) int RU_mask_prach; /// set of scheduling variables RXn-TXnp4 threads - gNB_rxtx_proc_t proc_rxtx[2]; -} gNB_proc_t; + gNB_L1_rxtx_proc_t L1_proc, L1_proc_tx; +} gNB_L1_proc_t; @@ -251,7 +260,7 @@ typedef struct PHY_VARS_gNB_s { module_id_t Mod_id; uint8_t CC_id; uint8_t configured; - gNB_proc_t proc; + gNB_L1_proc_t proc; int single_thread_flag; int abstraction_flag; int num_RU; diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index e6fda71d39..99c8ab3037 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -37,7 +37,7 @@ int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req); extern uint8_t nfapi_mode; void handle_nr_nfapi_bch_pdu(PHY_VARS_gNB *gNB, - gNB_rxtx_proc_t *proc, + gNB_L1_rxtx_proc_t *proc, nfapi_nr_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu) { @@ -56,7 +56,7 @@ void handle_nr_nfapi_bch_pdu(PHY_VARS_gNB *gNB, void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB, int frame, int subframe, - gNB_rxtx_proc_t *proc, + gNB_L1_rxtx_proc_t *proc, nfapi_nr_dl_config_request_pdu_t *dl_config_pdu) { int idx = subframe&1; @@ -73,7 +73,7 @@ void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB, void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ PHY_VARS_gNB *gNB; - gNB_rxtx_proc_t *proc; + gNB_L1_rxtx_proc_t *proc; // copy data from L2 interface into L1 structures module_id_t Mod_id = Sched_INFO->module_id; uint8_t CC_id = Sched_INFO->CC_id; @@ -87,7 +87,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ AssertFatal(RC.gNB[Mod_id][CC_id]!=NULL,"RC.gNB[%d][%d] is null\n",Mod_id,CC_id); gNB = RC.gNB[Mod_id][CC_id]; - proc = &gNB->proc.proc_rxtx[0]; + proc = &gNB->proc.L1_proc; uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu; diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h index 2dd47ad806..4c6b25e969 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.h +++ b/openair1/SCHED_NR/fapi_nr_l1.h @@ -41,5 +41,5 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO); void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB, int frame, int subframe, - gNB_rxtx_proc_t *proc, + gNB_L1_rxtx_proc_t *proc, nfapi_nr_dl_config_request_pdu_t *dl_config_pdu); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 36c441db26..86c49cd6d9 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -152,7 +152,7 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) { } void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, - gNB_rxtx_proc_t *proc, + gNB_L1_rxtx_proc_t *proc, int do_meas) { int aa; diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index f962575a2a..17354d4fb3 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -36,7 +36,7 @@ lte_subframe_t nr_subframe_select (nfapi_nr_config_request_t *cfg, unsigned char subframe); void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp); -void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, gNB_rxtx_proc_t *proc, int do_meas); +void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int do_meas); void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe); void nr_init_feptx_thread(RU_t *ru,pthread_attr_t *attr_feptx); void nr_feptx_ofdm(RU_t *ru); diff --git a/targets/RT/USER/nr-gnb.c b/targets/RT/USER/nr-gnb.c index 41e14aaaa5..0f2866cdca 100644 --- a/targets/RT/USER/nr-gnb.c +++ b/targets/RT/USER/nr-gnb.c @@ -154,7 +154,7 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); #define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials) -static inline int rxtx(PHY_VARS_gNB *gNB,gNB_rxtx_proc_t *proc, char *thread_name) { +static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_name) { start_meas(&softmodem_stats_rxtx_sf); // ******************************************************************* @@ -281,7 +281,7 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_rxtx_proc_t *proc, char *thread_nam /*! * \brief The RX UE-specific and TX thread of gNB. - * \param param is a \ref gNB_proc_t structure which contains the info what to process. + * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ @@ -289,7 +289,7 @@ static void* gNB_thread_rxtx( void* param ) { static int gNB_thread_rxtx_status; - gNB_rxtx_proc_t *proc = (gNB_rxtx_proc_t*)param; + gNB_L1_rxtx_proc_t *proc = (gNB_L1_rxtx_proc_t*)param; PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; char thread_name[100]; @@ -299,13 +299,13 @@ static void* gNB_thread_rxtx( void* param ) { gNB_thread_rxtx_status = 0; - sprintf(thread_name,"RXn_TXnp4_%d",&gNB->proc.proc_rxtx[0] == proc ? 0 : 1); + sprintf(thread_name,"RXn_TXnp4_%d",&gNB->proc.L1_proc == proc ? 0 : 1); thread_top_init(thread_name,1,850000L,1000000L,2000000L); while (!oai_exit) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); - if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; + if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 ); @@ -317,7 +317,7 @@ static void* gNB_thread_rxtx( void* param ) { } - if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; + if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break; } // while !oai_exit @@ -355,8 +355,8 @@ static void wait_system_ready (char *message, volatile int *start_flag) { void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int subframe_rx, char *string, struct RU_t_s *ru) { - gNB_proc_t *proc = &gNB->proc; - gNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0]; + gNB_L1_proc_t *proc = &gNB->proc; + gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; RU_proc_t *ru_proc=&ru->proc; @@ -366,25 +366,25 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int subframe_rx, char *string, str if (!oai_exit) { T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx)); - proc_rxtx->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); - proc_rxtx->frame_rx = ru_proc->frame_rx; - proc_rxtx->subframe_rx = ru_proc->subframe_rx; - proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > (9-sf_ahead)) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx; - proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + sf_ahead)%10; + L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); + L1_proc->frame_rx = ru_proc->frame_rx; + L1_proc->subframe_rx = ru_proc->subframe_rx; + L1_proc->frame_tx = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; + L1_proc->subframe_tx = (L1_proc->subframe_rx + sf_ahead)%10; - if (rxtx(gNB,proc_rxtx,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id); - ru_proc->timestamp_tx = proc_rxtx->timestamp_tx; - ru_proc->subframe_tx = proc_rxtx->subframe_tx; - ru_proc->frame_tx = proc_rxtx->frame_tx; + if (rxtx(gNB,L1_proc,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id); + ru_proc->timestamp_tx = L1_proc->timestamp_tx; + ru_proc->subframe_tx = L1_proc->subframe_tx; + ru_proc->frame_tx = L1_proc->frame_tx; } } int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { - gNB_proc_t *proc=&gNB->proc; + gNB_L1_proc_t *proc=&gNB->proc; - gNB_rxtx_proc_t *proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1]; + gNB_L1_rxtx_proc_t *L1_proc=&proc->L1_proc; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; @@ -415,24 +415,24 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { wait.tv_nsec=5000000L; /* accept some delay in processing - up to 5ms */ - for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) { - LOG_W( PHY,"[gNB] Frame %d Subframe %d, gNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx); + for (i = 0; i < 10 && L1_proc->instance_cnt == 0; i++) { + LOG_W( PHY,"[gNB] Frame %d Subframe %d, gNB RXn-TXnp4 thread busy!! (cnt %i)\n", L1_proc->frame_tx, L1_proc->subframe_tx, L1_proc->instance_cnt); usleep(500); } - if (proc_rxtx->instance_cnt_rxtx == 0) { + if (L1_proc->instance_cnt == 0) { exit_fun( "TX thread busy" ); return(-1); } // wake up TX for subframe n+sf_ahead // lock the TX mutex and make sure the thread is ready - if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx ); - exit_fun( "error locking mutex_rxtx" ); + if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) { + LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx&1,L1_proc->instance_cnt ); + exit_fun( "error locking mutex" ); return(-1); } - ++proc_rxtx->instance_cnt_rxtx; + ++L1_proc->instance_cnt; // We have just received and processed the common part of a subframe, say n. // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired @@ -440,27 +440,27 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti, // and proc->subframe_tx = proc->subframe_rx+sf_ahead - proc_rxtx->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); - proc_rxtx->frame_rx = proc->frame_rx; - proc_rxtx->subframe_rx = proc->subframe_rx; - proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > (9-sf_ahead)) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx; - proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + sf_ahead)%10; + L1_proc->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); + L1_proc->frame_rx = proc->frame_rx; + L1_proc->subframe_rx = proc->subframe_rx; + L1_proc->frame_tx = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; + L1_proc->subframe_tx = (L1_proc->subframe_rx + sf_ahead)%10; // the thread can now be woken up - if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) { + if (pthread_cond_signal(&L1_proc->cond) != 0) { LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n"); exit_fun( "ERROR pthread_cond_signal" ); return(-1); } - pthread_mutex_unlock( &proc_rxtx->mutex_rxtx ); + pthread_mutex_unlock( &L1_proc->mutex ); return(0); } /* void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe) { - gNB_proc_t *proc = &gNB->proc; + gNB_L1_proc_t *proc = &gNB->proc; LTE_DL_FRAME_PARMS *fp=&gNB->frame_parms; int i; @@ -519,7 +519,7 @@ void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe) { /*! * \brief The prach receive thread of gNB. - * \param param is a \ref gNB_proc_t structure which contains the info what to process. + * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ /* @@ -528,7 +528,7 @@ static void* gNB_thread_prach( void* param ) { PHY_VARS_gNB *gNB= (PHY_VARS_gNB *)param; - gNB_proc_t *proc = &gNB->proc; + gNB_L1_proc_t *proc = &gNB->proc; // set default return value gNB_thread_prach_status = 0; @@ -568,8 +568,8 @@ void init_gNB_proc(int inst) { int i=0; int CC_id; PHY_VARS_gNB *gNB; - gNB_proc_t *proc; - gNB_rxtx_proc_t *proc_rxtx; + gNB_L1_proc_t *proc; + gNB_L1_rxtx_proc_t *L1_proc,*L1_proc_tx; pthread_attr_t *attr0=NULL,*attr1=NULL; //*attr_prach=NULL; @@ -582,27 +582,32 @@ void init_gNB_proc(int inst) { #endif proc = &gNB->proc; - proc_rxtx = proc->proc_rxtx; - proc_rxtx[0].instance_cnt_rxtx = -1; - proc_rxtx[1].instance_cnt_rxtx = -1; + 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_prach=0; + proc->first_rx =1; + proc->first_tx =1; + proc->RU_mask =0; + proc->RU_mask_tx = (1<num_RU)-1; + proc->RU_mask_prach =0; pthread_mutex_init( &gNB->UL_INFO_mutex, NULL); - pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); - pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); - pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); - pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); + pthread_mutex_init( &L1_proc->mutex, NULL); + pthread_mutex_init( &L1_proc_tx->mutex, NULL); + pthread_cond_init( &L1_proc->cond, NULL); + pthread_cond_init( &L1_proc_tx->cond, NULL); pthread_mutex_init( &proc->mutex_prach, NULL); pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init( &proc->mutex_RU,NULL); + pthread_mutex_init( &proc->mutex_RU_tx,NULL); pthread_mutex_init( &proc->mutex_RU_PRACH,NULL); pthread_cond_init( &proc->cond_prach, NULL); @@ -612,23 +617,23 @@ void init_gNB_proc(int inst) { pthread_attr_init( &proc->attr_asynch_rxtx); // pthread_attr_init( &proc->attr_td); // pthread_attr_init( &proc->attr_te); - pthread_attr_init( &proc_rxtx[0].attr_rxtx); - pthread_attr_init( &proc_rxtx[1].attr_rxtx); + pthread_attr_init( &L1_proc->attr); + pthread_attr_init( &L1_proc_tx->attr); LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag); - if (gNB->single_thread_flag==0) { - pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, gNB_thread_rxtx, &proc_rxtx[0] ); - pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, gNB_thread_rxtx, &proc_rxtx[1] ); - } + /*if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { + pthread_create( &L1_proc->pthread, attr0, L1_thread, proc ); + pthread_create( &L1_proc_tx->pthread, attr1, L1_thread_tx, proc); + }*/ //pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB ); char name[16]; if (gNB->single_thread_flag==0) { - snprintf( name, sizeof(name), "RXTX0 %d", i ); - pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); - snprintf( name, sizeof(name), "RXTX1 %d", i ); - pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); + snprintf( name, sizeof(name), "L1 %d", i ); + pthread_setname_np( L1_proc->pthread, name ); + snprintf( name, sizeof(name), "L1TX %d", i ); + pthread_setname_np( L1_proc_tx->pthread, name ); } AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); @@ -651,23 +656,27 @@ void kill_gNB_proc(int inst) { int *status; PHY_VARS_gNB *gNB; - gNB_proc_t *proc; - gNB_rxtx_proc_t *proc_rxtx; + gNB_L1_proc_t *proc; + gNB_L1_rxtx_proc_t *L1_proc, *L1_proc_tx; for (int CC_id=0; CC_idproc; - proc_rxtx = &proc->proc_rxtx[0]; + L1_proc = &proc->L1_proc; + L1_proc_tx = &proc->L1_proc_tx; LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst ); - if (gNB->single_thread_flag==0) { - pthread_mutex_lock(&proc_rxtx[0].mutex_rxtx); - proc_rxtx[0].instance_cnt_rxtx = 0; - pthread_mutex_unlock(&proc_rxtx[0].mutex_rxtx); - pthread_mutex_lock(&proc_rxtx[1].mutex_rxtx); - proc_rxtx[1].instance_cnt_rxtx = 0; - pthread_mutex_unlock(&proc_rxtx[1].mutex_rxtx); + if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { + pthread_mutex_lock(&L1_proc->mutex); + L1_proc->instance_cnt = 0; + pthread_cond_signal(&L1_proc->cond); + pthread_mutex_unlock(&L1_proc->mutex); + + pthread_mutex_lock(&L1_proc_tx->mutex); + L1_proc_tx->instance_cnt = 0; + pthread_cond_signal(&L1_proc_tx->cond); + pthread_mutex_unlock(&L1_proc_tx->mutex); } proc->instance_cnt_prach = 0; pthread_cond_signal( &proc->cond_prach ); @@ -685,15 +694,22 @@ void kill_gNB_proc(int inst) { LOG_I(PHY, "Destroying UL_INFO mutex\n"); pthread_mutex_destroy(&gNB->UL_INFO_mutex); int i; - if (gNB->single_thread_flag==0) { - for (i=0;i<2;i++) { - LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n",i); - pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status ); - LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n",i); - pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); - pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); - } + if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) { + LOG_I(PHY, "Joining L1_proc mutex/cond\n"); + pthread_join( L1_proc->pthread, (void**)&status ); + LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n"); + pthread_join( L1_proc_tx->pthread, (void**)&status ); } + LOG_I(PHY, "Destroying L1_proc mutex/cond\n"); + pthread_mutex_destroy( &L1_proc->mutex ); + pthread_cond_destroy( &L1_proc->cond ); + LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n"); + pthread_mutex_destroy( &L1_proc_tx->mutex ); + pthread_cond_destroy( &L1_proc_tx->cond ); + + + pthread_mutex_destroy( &proc->mutex_RU ); + pthread_mutex_destroy( &proc->mutex_RU_tx ); } } diff --git a/targets/RT/USER/nr-ru.c b/targets/RT/USER/nr-ru.c index 04f2f3cdd4..e11b8ee781 100644 --- a/targets/RT/USER/nr-ru.c +++ b/targets/RT/USER/nr-ru.c @@ -874,7 +874,7 @@ void tx_rf(RU_t *ru) { /*! * \brief The Asynchronous RX/TX FH thread of RAU/RCC/gNB/RRU. * This handles the RX FH for an asynchronous RRU/UE - * \param param is a \ref gNB_proc_t structure which contains the info what to process. + * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ static void* ru_thread_asynch_rxtx( void* param ) { From b1a4d4ead4ad82abb0d157ff913f29261c888bba Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Mon, 5 Nov 2018 15:04:32 +0100 Subject: [PATCH 02/14] adding parallel structure --- openair1/PHY/defs_RU.h | 2 - openair2/GNB_APP/gnb_config.c | 36 ++++- openair2/GNB_APP/gnb_paramdef.h | 26 ++++ targets/RT/USER/nr-gnb.c | 174 ++++++++++++++++++++++-- targets/RT/USER/nr-ru.c | 234 +++++++++++++++++++++++++------- 5 files changed, 408 insertions(+), 64 deletions(-) diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 3ad007813e..6f68ee0fb4 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -304,8 +304,6 @@ typedef struct RU_proc_t_s { int instance_pre_scd; #endif /// pipeline ready state - int ru_rx_ready; - int ru_tx_ready; int emulate_rf_busy; } RU_proc_t; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index ac5c8e8b5a..db1bc52090 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -77,6 +77,10 @@ #include "NR_EUTRA-MBSFN-SubframeConfig.h" extern uint16_t sf_ahead; +extern void set_parallel_conf(char *parallel_conf); +extern void set_worker_conf(char *worker_conf); +extern PARALLEL_CONF_t get_thread_parallel_conf(void); +extern WORKER_CONF_t get_thread_worker_conf(void); void RCconfig_nr_flexran() { @@ -2976,6 +2980,36 @@ int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) { return 0; } +int RCconfig_nr_parallel(void) { + char *parallel_conf = NULL; + char *worker_conf = NULL; + extern char *parallel_config; + extern char *worker_config; + paramdef_t ThreadParams[] = THREAD_CONF_DESC; + paramlist_def_t THREADParamList = {THREAD_CONFIG_STRING_THREAD_STRUCT,NULL,0}; + config_getlist( &THREADParamList,NULL,0,NULL); + + if(THREADParamList.numelt>0) { + config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); + parallel_conf = strdup(*(THREADParamList.paramarray[0][THREAD_PARALLEL_IDX].strptr)); + } else { + parallel_conf = strdup("PARALLEL_RU_L1_TRX_SPLIT"); + } + + if(THREADParamList.numelt>0) { + config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); + worker_conf = strdup(*(THREADParamList.paramarray[0][THREAD_WORKER_IDX].strptr)); + } else { + worker_conf = strdup("WORKER_ENABLE"); + } + + if(parallel_config == NULL) set_parallel_conf(parallel_conf); + + if(worker_config == NULL) set_worker_conf(worker_conf); + + return 0; +} + void NRRCConfig(void) { paramlist_def_t MACRLCParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0}; @@ -3016,7 +3050,7 @@ void NRRCConfig(void) { config_getlist( &RUParamList,NULL,0, NULL); RC.nb_RU = RUParamList.numelt; - RCconfig_parallel(); + RCconfig_nr_parallel(); } diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index fd59f83097..a457a3b1a4 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -1099,3 +1099,29 @@ typedef enum { #define MACRLC_REMOTE_S_PORTD_IDX 16 #define MACRLC_SCHED_MODE_IDX 17 #define MACRLC_PHY_TEST_IDX 18 + + +/* thread configuration parameters section name */ +#define THREAD_CONFIG_STRING_THREAD_STRUCT "THREAD_STRUCT" + +/* thread configuration parameters names */ +#define THREAD_CONFIG_STRING_PARALLEL "parallel_config" +#define THREAD_CONFIG_STRING_WORKER "worker_config" + + +#define THREAD_PARALLEL_IDX 0 +#define THREAD_WORKER_IDX 1 + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* thread configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define THREAD_CONF_DESC { \ +{THREAD_CONFIG_STRING_PARALLEL, CONFIG_HLP_PARALLEL, 0, strptr:NULL, defstrval:"PARALLEL_RU_L1_TRX_SPLIT", TYPE_STRING, 0}, \ +{THREAD_CONFIG_STRING_WORKER, CONFIG_HLP_WORKER, 0, strptr:NULL, defstrval:"WORKER_ENABLE", TYPE_STRING, 0} \ +} + + +#define CONFIG_HLP_WORKER "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n" +#define CONFIG_HLP_PARALLEL "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n" +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/targets/RT/USER/nr-gnb.c b/targets/RT/USER/nr-gnb.c index 0f2866cdca..34e9f295fd 100644 --- a/targets/RT/USER/nr-gnb.c +++ b/targets/RT/USER/nr-gnb.c @@ -143,6 +143,11 @@ extern double cpuf; void init_gNB(int,int); void stop_gNB(int nb_inst); +int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB); +int wakeup_tx(PHY_VARS_gNB *gNB); +extern PARALLEL_CONF_t get_thread_parallel_conf(void); +extern WORKER_CONF_t get_thread_worker_conf(void); + void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe); @@ -227,7 +232,9 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_ //if (wait_CCs(proc)<0) return(-1); if (oai_exit) return(-1); - phy_procedures_gNB_TX(gNB, proc, 1); + if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD){ + phy_procedures_gNB_TX(gNB, proc, 1); + } stop_meas( &softmodem_stats_rxtx_sf ); @@ -278,6 +285,44 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_ return(0); } +static void* gNB_L1_thread_tx(void* param) { + + gNB_L1_proc_t *gNB_proc = (gNB_L1_proc_t*)param; + gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc_tx; + PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; + + char thread_name[100]; + sprintf(thread_name,"TXnp4_%d\n",&gNB->proc.L1_proc == proc ? 0 : 1); + thread_top_init(thread_name,1,470000,500000,500000); + + //wait_sync("tx_thread"); + + while (!oai_exit) { + + + if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break; + if (oai_exit) break; + // ***************************************** + // TX processing for subframe n+4 + // 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) + // ***************************************** + + phy_procedures_gNB_TX(gNB, proc, 1); + + pthread_mutex_lock( &proc->mutex ); + proc->instance_cnt = -1; + // the thread can now be woken up + if (pthread_cond_signal(&proc->cond) != 0) { + LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + } + pthread_mutex_unlock( &proc->mutex ); + wakeup_txfh(proc,gNB); + } + + return 0; +} /*! * \brief The RX UE-specific and TX thread of gNB. @@ -285,11 +330,11 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_ * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void* gNB_thread_rxtx( void* param ) { +static void* gNB_L1_thread( void* param ) { static int gNB_thread_rxtx_status; - - gNB_L1_rxtx_proc_t *proc = (gNB_L1_rxtx_proc_t*)param; + gNB_L1_proc_t *gNB_proc = (gNB_L1_proc_t*)param; + gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc; PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; char thread_name[100]; @@ -303,11 +348,9 @@ static void* gNB_thread_rxtx( void* param ) { thread_top_init(thread_name,1,850000L,1000000L,2000000L); while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 ); if (oai_exit) break; @@ -316,12 +359,19 @@ static void* gNB_thread_rxtx( void* param ) { if (rxtx(gNB,proc,thread_name) < 0) break; } - + if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT){ + phy_procedures_gNB_TX(gNB, proc, 1); + } if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break; + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT){ + wakeup_tx(gNB); + } + else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT){ + wakeup_txfh(proc,gNB); + } } // while !oai_exit - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); LOG_D(PHY, " *** Exiting gNB thread RXn_TXnp4\n"); @@ -379,6 +429,101 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int subframe_rx, char *string, str } } +int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB) { + + RU_t *ru; + RU_proc_t *ru_proc; + + + struct timespec wait; + wait.tv_sec=0; + wait.tv_nsec=5000000L; +//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs); + + if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) { + LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->subframe_tx); + return(-1); + } + pthread_mutex_lock(&gNB->proc.mutex_RU_tx); + gNB->proc.RU_mask_tx = 0; + pthread_mutex_unlock(&gNB->proc.mutex_RU_tx); + if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1); + + for(int i=0; inum_RU; i++) + { + ru = gNB->RU_list[i]; + ru_proc = &ru->proc; + if (ru_proc->instance_cnt_gNBs == 0) { + LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx); + return(-1); + } + if (pthread_mutex_timedlock(&ru_proc->mutex_gNBs,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_gNBs ); + exit_fun( "error locking mutex_gNB" ); + return(-1); + } + + ru_proc->instance_cnt_gNBs = 0; + ru_proc->timestamp_tx = proc->timestamp_tx; + ru_proc->subframe_tx = proc->subframe_tx; + ru_proc->frame_tx = proc->frame_tx; + + + // the thread can now be woken up + if (pthread_cond_signal(&ru_proc->cond_gNBs) != 0) { + LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return(-1); + } + + pthread_mutex_unlock( &ru_proc->mutex_gNBs ); + } + + return(0); +} + +int wakeup_tx(PHY_VARS_gNB *gNB) { + + gNB_L1_proc_t *proc=&gNB->proc; + + gNB_L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx; + gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc; + + + struct timespec wait; + wait.tv_sec=0; + wait.tv_nsec=5000000L; + + + if (pthread_mutex_timedlock(&L1_proc_tx->mutex,&wait) != 0) { + LOG_E(PHY, "[SCHED][eNB] ERROR locking mutex for eNB L1_thread_tx\n"); + exit_fun("ERROR pthread_lock"); + return(-1); + } + while(L1_proc_tx->instance_cnt == 0){ + pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex); + } + + L1_proc_tx->instance_cnt = 0; + + + L1_proc_tx->subframe_rx = L1_proc->subframe_rx; + L1_proc_tx->frame_rx = L1_proc->frame_rx; + L1_proc_tx->subframe_tx = L1_proc->subframe_tx; + L1_proc_tx->frame_tx = L1_proc->frame_tx; + L1_proc_tx->timestamp_tx = L1_proc->timestamp_tx; + + // the thread can now be woken up + if (pthread_cond_signal(&L1_proc_tx->cond) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return(-1); + } + + pthread_mutex_unlock( &L1_proc_tx->mutex); + + return(0); +} int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { @@ -619,13 +764,15 @@ void init_gNB_proc(int inst) { // pthread_attr_init( &proc->attr_te); pthread_attr_init( &L1_proc->attr); pthread_attr_init( &L1_proc_tx->attr); + attr0 = &L1_proc->attr; + attr1 = &L1_proc_tx->attr; LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag); - /*if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { - pthread_create( &L1_proc->pthread, attr0, L1_thread, proc ); - pthread_create( &L1_proc_tx->pthread, attr1, L1_thread_tx, proc); - }*/ + if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { + pthread_create( &L1_proc->pthread, attr0, gNB_L1_thread, proc ); + pthread_create( &L1_proc_tx->pthread, attr1, gNB_L1_thread_tx, proc); + } //pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB ); char name[16]; @@ -693,8 +840,7 @@ void kill_gNB_proc(int inst) { LOG_I(PHY, "Destroying UL_INFO mutex\n"); pthread_mutex_destroy(&gNB->UL_INFO_mutex); - int i; - if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) { + if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { LOG_I(PHY, "Joining L1_proc mutex/cond\n"); pthread_join( L1_proc->pthread, (void**)&status ); LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n"); diff --git a/targets/RT/USER/nr-ru.c b/targets/RT/USER/nr-ru.c index e11b8ee781..83410608e6 100644 --- a/targets/RT/USER/nr-ru.c +++ b/targets/RT/USER/nr-ru.c @@ -118,6 +118,9 @@ extern void nr_phy_init_RU(RU_t*); extern void nr_phy_free_RU(RU_t*); extern void nr_phy_config_request(NR_PHY_Config_t *gNB); +extern PARALLEL_CONF_t get_thread_parallel_conf(void); +extern WORKER_CONF_t get_thread_worker_conf(void); + void init_RU(char*); void stop_RU(int nb_ru); void do_ru_sync(RU_t *ru); @@ -1131,12 +1134,12 @@ void do_ru_synch(RU_t *ru) { -void wakeup_gNBs(RU_t *ru) { +void wakeup_gNB_L1s(RU_t *ru) { int i; PHY_VARS_gNB **gNB_list = ru->gNB_list; - LOG_D(PHY,"wakeup_gNBs (num %d) for RU %d ru->gNB_top:%p\n",ru->num_gNB,ru->idx, ru->gNB_top); + LOG_D(PHY,"wakeup_gNB_L1s (num %d) for RU %d ru->gNB_top:%p\n",ru->num_gNB,ru->idx, ru->gNB_top); if (ru->num_gNB==1 && ru->gNB_top!=0) { // call gNB function directly @@ -1378,6 +1381,118 @@ static void* ru_stats_thread(void* param) { return(NULL); } +static void* ru_thread_tx( void* param ) { + RU_t *ru = (RU_t*)param; + RU_proc_t *proc = &ru->proc; + PHY_VARS_gNB *gNB; + gNB_L1_proc_t *gNB_proc; + gNB_L1_rxtx_proc_t *L1_proc; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + char filename[40]; + int print_frame = 2; + int i = 0; + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + + + thread_top_init("ru_thread_tx",1,400000,500000,500000); + + //CPU_SET(5, &cpuset); + //pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + //wait_sync("ru_thread_tx"); + + wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); + + + printf( "ru_thread_tx ready\n"); + while (!oai_exit) { + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD_TX,sched_getcpu()); + if (oai_exit) break; + + + LOG_I(PHY,"ru_thread_tx: Waiting for TX processing\n"); + // wait until eNBs are finished subframe RX n and TX n+4 + wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); + if (oai_exit) break; + + // do TX front-end processing if needed (precoding and/or IDFTs) + if (ru->feptx_prec) ru->feptx_prec(ru); + + // do OFDM if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + if(!emulate_rf){ + // do outgoing fronthaul (south) if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); + + if (ru->fh_north_out) ru->fh_north_out(ru); + } + else + { + if(proc->frame_tx == print_frame) + { + for (i=0; inb_tx; i++) + { + sprintf(filename,"tx%ddataF_frame%d_sf%d.m", i, print_frame, proc->subframe_tx); + LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); + if(proc->subframe_tx == 9) + { + sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); + LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1); + sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame); + FILE *output_fd = fopen(filename,"w"); + if (output_fd) { + fwrite(&ru->common.txdata[i][0], + sizeof(int32_t), + fp->samples_per_frame, + output_fd); + fclose(output_fd); + } + else { + LOG_E(PHY,"Cannot write to file %s\n",filename); + } + }//if(proc->subframe_tx == 9) + }//for (i=0; inb_tx; i++) + }//if(proc->frame_tx == print_frame) + }//else emulate_rf + release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); + for(i = 0; inum_gNB; i++) + { + gNB = ru->gNB_list[i]; + gNB_proc = &gNB->proc; + L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &gNB_proc->L1_proc_tx : &gNB_proc->L1_proc; + pthread_mutex_lock(&gNB_proc->mutex_RU_tx); + for (int j=0;jnum_RU;j++) { + if (ru == gNB->RU_list[j]) { + if ((gNB_proc->RU_mask_tx&(1< 0) + LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n", + gNB->Mod_id,gNB_proc->frame_rx,gNB_proc->subframe_rx,ru->idx,gNB->num_RU,gNB_proc->RU_mask_tx); + gNB_proc->RU_mask_tx |= (1<RU_mask_tx != (1<num_RU)-1) { // not all RUs have provided their information so return + pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); + } + else { // all RUs TX are finished so send the ready signal to eNB processing + gNB_proc->RU_mask_tx = 0; + pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); + + pthread_mutex_lock( &L1_proc->mutex_RUs); + L1_proc->instance_cnt_RUs = 0; + // the thread can now be woken up + if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + } + pthread_mutex_unlock( &L1_proc->mutex_RUs ); + } + } + } + release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); + return 0; +} + static void* ru_thread( void* param ) { static int ru_thread_status; @@ -1440,6 +1555,11 @@ static void* ru_thread( void* param ) { RC.ru_mask &= ~(1<idx); pthread_cond_signal(&RC.ru_cond); pthread_mutex_unlock(&RC.ru_mutex); + + pthread_mutex_lock(&proc->mutex_FH1); + proc->instance_cnt_FH1 = 0; + pthread_mutex_unlock(&proc->mutex_FH1); + pthread_cond_signal(&proc->cond_FH1); wait_sync("ru_thread"); @@ -1514,53 +1634,66 @@ static void* ru_thread( void* param ) { wakeup_slaves(proc); // wakeup all gNB processes waiting for this RU - if (ru->num_gNB>0) wakeup_gNBs(ru); + if (ru->num_gNB>0) wakeup_gNB_L1s(ru); - // wait until gNBs are finished subframe RX n and TX n+sf_ahead - wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread"); - - - // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru); - - // do OFDM if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); - if(!emulate_rf) - { - // do outgoing fronthaul (south) if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); - - if (ru->fh_north_out) ru->fh_north_out(ru); - } - else - { - if(proc->frame_tx == print_frame) - { - for (i=0; inb_tx; i++) - { - sprintf(filename,"tx%ddataF_frame%d_sf%d.m", i, print_frame, proc->subframe_tx); - LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); - if(proc->subframe_tx == 9) - { - sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); - LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1); - sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame); - FILE *output_fd = fopen(filename,"w"); - if (output_fd) { - fwrite(&ru->common.txdata[i][0], - sizeof(int32_t), - fp->samples_per_frame, - output_fd); - fclose(output_fd); - } - else { - LOG_E(PHY,"Cannot write to file %s\n",filename); - } - } - } + if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0){ + // do TX front-end processing if needed (precoding and/or IDFTs) + if (ru->feptx_prec) ru->feptx_prec(ru); + + // do OFDM if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + if(!emulate_rf){ + // do outgoing fronthaul (south) if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); + + if (ru->fh_north_out) ru->fh_north_out(ru); } - //else if (proc->frame_tx > print_frame) oai_exit = 1; + proc->emulate_rf_busy = 0; } + + if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) + { + // do TX front-end processing if needed (precoding and/or IDFTs) + if (ru->feptx_prec) ru->feptx_prec(ru); + + // do OFDM if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + if(!emulate_rf) + { + // do outgoing fronthaul (south) if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); + + if (ru->fh_north_out) ru->fh_north_out(ru); + } + else + { + if(proc->frame_tx == print_frame) + { + for (i=0; inb_tx; i++) + { + sprintf(filename,"tx%ddataF_frame%d_sf%d.m", i, print_frame, proc->subframe_tx); + LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); + if(proc->subframe_tx == 9) + { + sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); + LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1); + sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame); + FILE *output_fd = fopen(filename,"w"); + if (output_fd) { + fwrite(&ru->common.txdata[i][0], + sizeof(int32_t), + fp->samples_per_frame, + output_fd); + fclose(output_fd); + } + else { + LOG_E(PHY,"Cannot write to file %s\n",filename); + } + }//if(proc->subframe_tx == 9) + }//for (i=0; inb_tx; i++) + }//if(proc->frame_tx == print_frame) + }//else emulate_rf + }//if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) } @@ -1680,7 +1813,7 @@ void init_RU_proc(RU_t *ru) { int i=0; RU_proc_t *proc; - pthread_attr_t *attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL, *attr_emulateRF=NULL;// *attr_synch=NULL; + pthread_attr_t *attr_FH=NULL, *attr_FH1=NULL,*attr_prach=NULL,*attr_asynch=NULL, *attr_emulateRF=NULL;// *attr_synch=NULL; //pthread_attr_t *attr_fep=NULL; #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) //pthread_attr_t *attr_prach_br=NULL; @@ -1697,6 +1830,7 @@ void init_RU_proc(RU_t *ru) { proc->instance_cnt_prach = -1; proc->instance_cnt_synch = -1; ; proc->instance_cnt_FH = -1; + proc->instance_cnt_FH1 = -1; proc->instance_cnt_asynch_rxtx = -1; proc->instance_cnt_emulateRF = -1; proc->first_rx = 1; @@ -1711,17 +1845,20 @@ void init_RU_proc(RU_t *ru) { pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init( &proc->mutex_synch,NULL); pthread_mutex_init( &proc->mutex_FH,NULL); + pthread_mutex_init( &proc->mutex_FH1,NULL); pthread_mutex_init( &proc->mutex_emulateRF,NULL); pthread_mutex_init( &proc->mutex_gNBs, NULL); pthread_cond_init( &proc->cond_prach, NULL); pthread_cond_init( &proc->cond_FH, NULL); + pthread_cond_init( &proc->cond_FH1, NULL); pthread_cond_init( &proc->cond_emulateRF, NULL); pthread_cond_init( &proc->cond_asynch_rxtx, NULL); pthread_cond_init( &proc->cond_synch,NULL); pthread_cond_init( &proc->cond_gNBs, NULL); pthread_attr_init( &proc->attr_FH); + pthread_attr_init( &proc->attr_FH1); pthread_attr_init( &proc->attr_emulateRF); pthread_attr_init( &proc->attr_prach); pthread_attr_init( &proc->attr_synch); @@ -1731,6 +1868,7 @@ void init_RU_proc(RU_t *ru) { #ifndef DEADLINE_SCHEDULER attr_FH = &proc->attr_FH; + attr_FH1 = &proc->attr_FH1; attr_emulateRF = &proc->attr_emulateRF; attr_prach = &proc->attr_prach; //attr_synch = &proc->attr_synch; @@ -1738,6 +1876,8 @@ void init_RU_proc(RU_t *ru) { #endif pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru ); + if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) + pthread_create( &proc->pthread_FH1, attr_FH1, ru_thread_tx, (void*)ru ); if(emulate_rf) pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void*)proc ); if (ru->function == NGFI_RRU_IF4p5) { From aa232879a32243ab1ccee10ac13f796161eb2a49 Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Tue, 6 Nov 2018 15:15:56 +0100 Subject: [PATCH 03/14] adding VCD log in file --- common/utils/LOG/vcd_signal_dumper.c | 16 +++++- common/utils/LOG/vcd_signal_dumper.h | 15 ++++++ common/utils/T/T_defs.h | 4 +- common/utils/T/T_messages.txt | 54 +++++++++++++++++++ openair2/GNB_APP/gnb_config.c | 2 + .../CONF/gnb.band78.tm1.106PRB.usrpx300.conf | 9 ++++ targets/RT/USER/nr-gnb.c | 21 +++++++- targets/RT/USER/nr-ru.c | 7 ++- targets/RT/USER/nr-uesoftmodem.h | 4 +- 9 files changed, 122 insertions(+), 10 deletions(-) diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index 666bf46d44..cb28be8550 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -189,7 +189,17 @@ const char* eurecomVariablesNames[] = { "ue0_trx_write_ns_missing", "enb_thread_rxtx_CPUID", "ru_thread_CPUID", - "ru_thread_tx_CPUID" + "ru_thread_tx_CPUID", + + /*signal for NR*/ + "frame_number_TX0_gNB", + "frame_number_TX1_gNB", + "frame_number_RX0_gNB", + "frame_number_RX1_gNB", + "subframe_number_TX0_gNB", + "subframe_number_TX1_gNB", + "subframe_number_RX0_gNB", + "subframe_number_RX1_gNB" }; const char* eurecomFunctionsNames[] = { @@ -408,6 +418,10 @@ const char* eurecomFunctionsNames[] = { "pdcch_interleaving", "pdcch_tx", + /*NR softmodem signal*/ + "gNB_thread_rxtx0", + "gNB_thread_rxtx1" + }; struct vcd_module_s vcd_modules[] = { diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index 749978bb48..5c1ba9e7fe 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -167,6 +167,17 @@ typedef enum { VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX, VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD, VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD_TX, + + /*signal for NR*/ + VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB, + VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB, + VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB, + VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_GNB, + VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_GNB, + VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX1_GNB, + VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_GNB, + VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX1_GNB, + VCD_SIGNAL_DUMPER_VARIABLES_END } vcd_signal_dump_variables; @@ -389,6 +400,10 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_INTERLEAVING, VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX, + /*NR softmodem signal*/ + VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, + VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, + VCD_SIGNAL_DUMPER_FUNCTIONS_END } vcd_signal_dump_functions; diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 83a380662d..5300237178 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -41,10 +41,10 @@ typedef struct { } T_cache_t; /* number of VCD functions (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_FUNCTIONS 190 +#define VCD_NUM_FUNCTIONS 192//190 /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_VARIABLES 128 +#define VCD_NUM_VARIABLES 136//128 /* first VCD function (to be kept up to date! see in T_messages.txt) */ #define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index ec0585c799..6057c09f1c 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1680,6 +1680,48 @@ ID = VCD_VARIABLE_CPUID_RU_THREAD_TX FORMAT = ulong,value VCD_NAME = ru_thread_tx_CPUID + #variable for gNB +ID = VCD_VARIABLE_FRAME_NUMBER_TX0_GNB + DESC = VCD variable FRAME_NUMBER_TX0_GNB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = frame_number_TX0_gNB +ID = VCD_VARIABLE_FRAME_NUMBER_TX1_GNB + DESC = VCD variable FRAME_NUMBER_TX1_GNB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = frame_number_TX1_gNB +ID = VCD_VARIABLE_FRAME_NUMBER_RX0_GNB + DESC = VCD variable FRAME_NUMBER_RX0_GNB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = frame_number_RX0_gNB +ID = VCD_VARIABLE_FRAME_NUMBER_RX1_GNB + DESC = VCD variable FRAME_NUMBER_RX1_GNB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = frame_number_RX1_gNB +ID = VCD_VARIABLE_SUBFRAME_NUMBER_TX0_GNB + DESC = VCD variable SUBFRAME_NUMBER_TX0_GNB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = subframe_number_TX0_gNB +ID = VCD_VARIABLE_SUBFRAME_NUMBER_TX1_GNB + DESC = VCD variable SUBFRAME_NUMBER_TX1_GNB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = subframe_number_TX1_gNB +ID = VCD_VARIABLE_SUBFRAME_NUMBER_RX0_GNB + DESC = VCD variable SUBFRAME_NUMBER_RX0_GNB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = subframe_number_RX0_gNB +ID = VCD_VARIABLE_SUBFRAME_NUMBER_RX1_GNB + DESC = VCD variable SUBFRAME_NUMBER_RX1_GNB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = subframe_number_RX1_gNB + #functions ID = VCD_FUNCTION_RT_SLEEP @@ -2637,3 +2679,15 @@ ID = VCD_FUNCTION_PDCCH_TX GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value VCD_NAME = pdcch_tx + + #function for gNB +ID = VCD_FUNCTION_gNB_PROC_RXTX0 + DESC = VCD function gNB_PROC_RXTX0 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = gNB_thread_rxtx0 +ID = VCD_FUNCTION_gNB_PROC_RXTX1 + DESC = VCD function gNB_PROC_RXTX1 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = gNB_thread_rxtx1 diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index db1bc52090..7270ce9258 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -3004,8 +3004,10 @@ int RCconfig_nr_parallel(void) { } if(parallel_config == NULL) set_parallel_conf(parallel_conf); +if(parallel_config == NULL)printf("~~~~~~~~~~~~~~~~~~~~parallel_conf = %s\n",parallel_conf); if(worker_config == NULL) set_worker_conf(worker_conf); +if(worker_config == NULL)printf("~~~~~~~~~~~~~~~~~~~~worker_conf = %s\n",worker_conf); return 0; } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index cd85fe7a33..721c307f71 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -259,6 +259,15 @@ RUs = ( } ); +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_DISABLE"; + } +); + NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; diff --git a/targets/RT/USER/nr-gnb.c b/targets/RT/USER/nr-gnb.c index 34e9f295fd..58e9be4a9e 100644 --- a/targets/RT/USER/nr-gnb.c +++ b/targets/RT/USER/nr-gnb.c @@ -290,6 +290,8 @@ static void* gNB_L1_thread_tx(void* param) { gNB_L1_proc_t *gNB_proc = (gNB_L1_proc_t*)param; gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc_tx; PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; + +printf("~~~~~~~~~~~~~~~~~~~~gNB_L1_thread_tx is created\n"); char thread_name[100]; sprintf(thread_name,"TXnp4_%d\n",&gNB->proc.L1_proc == proc ? 0 : 1); @@ -299,8 +301,9 @@ static void* gNB_L1_thread_tx(void* param) { while (!oai_exit) { - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 ); if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 1 ); if (oai_exit) break; // ***************************************** // TX processing for subframe n+4 @@ -308,6 +311,11 @@ static void* gNB_L1_thread_tx(void* param) { // (may be relaxed in the future for performance reasons) // ***************************************** + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX1_GNB,proc->subframe_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX1_GNB,proc->subframe_rx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,proc->frame_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_GNB,proc->frame_rx); + phy_procedures_gNB_TX(gNB, proc, 1); pthread_mutex_lock( &proc->mutex ); @@ -337,6 +345,8 @@ static void* gNB_L1_thread( void* param ) { gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc; PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; +printf("~~~~~~~~~~~~~~~~~~~~gNB_L1_thread_tx is created\n"); + char thread_name[100]; @@ -349,8 +359,14 @@ static void* gNB_L1_thread( void* param ) { while (!oai_exit) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 0 ); if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_GNB,proc->subframe_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_GNB,proc->subframe_rx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,proc->frame_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,proc->frame_rx); if (oai_exit) break; @@ -769,7 +785,9 @@ void init_gNB_proc(int inst) { LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag); +printf("~~~~~~~~~~~~~~~~~~~thread_parallel = %d",get_thread_parallel_conf()); if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { +printf("~~~~~~~~~~~~~~~~~~~~~~~creating gNB_L1_thread and gNB_L1_thread_tx \n"); pthread_create( &L1_proc->pthread, attr0, gNB_L1_thread, proc ); pthread_create( &L1_proc_tx->pthread, attr1, gNB_L1_thread_tx, proc); } @@ -1046,6 +1064,7 @@ void init_eNB_afterRU(void) { //init_transport(gNB); //init_precoding_weights(RC.gNB[inst][CC_id]); } +printf("~~~~~~~~~~~~~~~~~~~~~~~start init gNB proc\n"); init_gNB_proc(inst); } diff --git a/targets/RT/USER/nr-ru.c b/targets/RT/USER/nr-ru.c index 83410608e6..f4481dcbf6 100644 --- a/targets/RT/USER/nr-ru.c +++ b/targets/RT/USER/nr-ru.c @@ -1407,8 +1407,7 @@ static void* ru_thread_tx( void* param ) { printf( "ru_thread_tx ready\n"); while (!oai_exit) { - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD_TX,sched_getcpu()); + if (oai_exit) break; @@ -1430,7 +1429,7 @@ static void* ru_thread_tx( void* param ) { } else { - if(proc->frame_tx == print_frame) + /*if(proc->frame_tx == print_frame) { for (i=0; inb_tx; i++) { @@ -1454,7 +1453,7 @@ static void* ru_thread_tx( void* param ) { } }//if(proc->subframe_tx == 9) }//for (i=0; inb_tx; i++) - }//if(proc->frame_tx == print_frame) + }//if(proc->frame_tx == print_frame)*/ }//else emulate_rf release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); for(i = 0; inum_gNB; i++) diff --git a/targets/RT/USER/nr-uesoftmodem.h b/targets/RT/USER/nr-uesoftmodem.h index 90887fe128..dd74adc014 100644 --- a/targets/RT/USER/nr-uesoftmodem.h +++ b/targets/RT/USER/nr-uesoftmodem.h @@ -179,8 +179,8 @@ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ -{"codingw" , CONFIG_HLP_CODINGW, PARAMFLAG_BOOL, iptr:&codingw, defintval:0, TYPE_INT, 0}, \ -{"fepw" , CONFIG_HLP_FEPW, PARAMFLAG_BOOL, iptr:&fepw, defintval:0, TYPE_INT, 0}, \ +{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ +{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \ } From 8273680d7dcf424d785a00211d776b1efb493432 Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Wed, 7 Nov 2018 17:40:08 +0100 Subject: [PATCH 04/14] bug fix for initialization --- openair2/GNB_APP/gnb_config.c | 3 --- targets/RT/USER/nr-gnb.c | 28 ++++++++++++++-------------- targets/RT/USER/nr-ru.c | 17 ++++++++--------- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 7270ce9258..e9cc6df079 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -3004,10 +3004,7 @@ int RCconfig_nr_parallel(void) { } if(parallel_config == NULL) set_parallel_conf(parallel_conf); -if(parallel_config == NULL)printf("~~~~~~~~~~~~~~~~~~~~parallel_conf = %s\n",parallel_conf); - if(worker_config == NULL) set_worker_conf(worker_conf); -if(worker_config == NULL)printf("~~~~~~~~~~~~~~~~~~~~worker_conf = %s\n",worker_conf); return 0; } diff --git a/targets/RT/USER/nr-gnb.c b/targets/RT/USER/nr-gnb.c index 58e9be4a9e..d5ea712ad9 100644 --- a/targets/RT/USER/nr-gnb.c +++ b/targets/RT/USER/nr-gnb.c @@ -287,15 +287,15 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_ static void* gNB_L1_thread_tx(void* param) { - gNB_L1_proc_t *gNB_proc = (gNB_L1_proc_t*)param; + PHY_VARS_gNB *gNB = (PHY_VARS_gNB*)param; + gNB_L1_proc_t *gNB_proc = &gNB->proc; gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc_tx; - PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; + //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; -printf("~~~~~~~~~~~~~~~~~~~~gNB_L1_thread_tx is created\n"); char thread_name[100]; sprintf(thread_name,"TXnp4_%d\n",&gNB->proc.L1_proc == proc ? 0 : 1); - thread_top_init(thread_name,1,470000,500000,500000); + //thread_top_init(thread_name,1,470000,500000,500000); //wait_sync("tx_thread"); @@ -341,21 +341,22 @@ printf("~~~~~~~~~~~~~~~~~~~~gNB_L1_thread_tx is created\n"); static void* gNB_L1_thread( void* param ) { static int gNB_thread_rxtx_status; - gNB_L1_proc_t *gNB_proc = (gNB_L1_proc_t*)param; + PHY_VARS_gNB *gNB = (PHY_VARS_gNB*)param; + gNB_L1_proc_t *gNB_proc = &gNB->proc; gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc; - PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; + //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; -printf("~~~~~~~~~~~~~~~~~~~~gNB_L1_thread_tx is created\n"); char thread_name[100]; + // set default return value gNB_thread_rxtx_status = 0; sprintf(thread_name,"RXn_TXnp4_%d",&gNB->proc.L1_proc == proc ? 0 : 1); - thread_top_init(thread_name,1,850000L,1000000L,2000000L); + //thread_top_init(thread_name,1,850000L,1000000L,2000000L); while (!oai_exit) { @@ -454,7 +455,7 @@ int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB) { struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; -//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs); +printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs); if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) { LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->subframe_tx); @@ -607,6 +608,8 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { L1_proc->frame_tx = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; L1_proc->subframe_tx = (L1_proc->subframe_rx + sf_ahead)%10; +printf("~~~~~~~~~~~~~~~~~~~~~~passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sf_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->subframe_rx, L1_proc->frame_tx, L1_proc->subframe_tx, sf_ahead); + // the thread can now be woken up if (pthread_cond_signal(&L1_proc->cond) != 0) { LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n"); @@ -785,11 +788,9 @@ void init_gNB_proc(int inst) { LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag); -printf("~~~~~~~~~~~~~~~~~~~thread_parallel = %d",get_thread_parallel_conf()); if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { -printf("~~~~~~~~~~~~~~~~~~~~~~~creating gNB_L1_thread and gNB_L1_thread_tx \n"); - pthread_create( &L1_proc->pthread, attr0, gNB_L1_thread, proc ); - pthread_create( &L1_proc_tx->pthread, attr1, gNB_L1_thread_tx, proc); + pthread_create( &L1_proc->pthread, attr0, gNB_L1_thread, gNB ); + pthread_create( &L1_proc_tx->pthread, attr1, gNB_L1_thread_tx, gNB); } //pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB ); @@ -1064,7 +1065,6 @@ void init_eNB_afterRU(void) { //init_transport(gNB); //init_precoding_weights(RC.gNB[inst][CC_id]); } -printf("~~~~~~~~~~~~~~~~~~~~~~~start init gNB proc\n"); init_gNB_proc(inst); } diff --git a/targets/RT/USER/nr-ru.c b/targets/RT/USER/nr-ru.c index f4481dcbf6..83843a03c6 100644 --- a/targets/RT/USER/nr-ru.c +++ b/targets/RT/USER/nr-ru.c @@ -1141,7 +1141,7 @@ void wakeup_gNB_L1s(RU_t *ru) { LOG_D(PHY,"wakeup_gNB_L1s (num %d) for RU %d ru->gNB_top:%p\n",ru->num_gNB,ru->idx, ru->gNB_top); - if (ru->num_gNB==1 && ru->gNB_top!=0) { + if (ru->num_gNB==1 && ru->gNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) { // call gNB function directly char string[20]; @@ -1156,7 +1156,6 @@ void wakeup_gNB_L1s(RU_t *ru) { for (i=0;inum_gNB;i++) { LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->nr_wakeup_rxtx); - if (ru->nr_wakeup_rxtx!=0 && ru->nr_wakeup_rxtx(gNB_list[i],ru) < 0) { LOG_E(PHY,"could not wakeup gNB rxtx process for subframe %d\n", ru->proc.subframe_rx); @@ -1429,7 +1428,7 @@ static void* ru_thread_tx( void* param ) { } else { - /*if(proc->frame_tx == print_frame) + if(proc->frame_tx == print_frame) { for (i=0; inb_tx; i++) { @@ -1453,7 +1452,7 @@ static void* ru_thread_tx( void* param ) { } }//if(proc->subframe_tx == 9) }//for (i=0; inb_tx; i++) - }//if(proc->frame_tx == print_frame)*/ + }//if(proc->frame_tx == print_frame) }//else emulate_rf release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); for(i = 0; inum_gNB; i++) @@ -1554,11 +1553,6 @@ static void* ru_thread( void* param ) { RC.ru_mask &= ~(1<idx); pthread_cond_signal(&RC.ru_cond); pthread_mutex_unlock(&RC.ru_mutex); - - pthread_mutex_lock(&proc->mutex_FH1); - proc->instance_cnt_FH1 = 0; - pthread_mutex_unlock(&proc->mutex_FH1); - pthread_cond_signal(&proc->cond_FH1); wait_sync("ru_thread"); @@ -1587,6 +1581,10 @@ static void* ru_thread( void* param ) { if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru); } + pthread_mutex_lock(&proc->mutex_FH1); + proc->instance_cnt_FH1 = 0; + pthread_mutex_unlock(&proc->mutex_FH1); + pthread_cond_signal(&proc->cond_FH1); // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices while (!oai_exit) { @@ -1830,6 +1828,7 @@ void init_RU_proc(RU_t *ru) { proc->instance_cnt_synch = -1; ; proc->instance_cnt_FH = -1; proc->instance_cnt_FH1 = -1; + proc->instance_cnt_gNBs = -1; proc->instance_cnt_asynch_rxtx = -1; proc->instance_cnt_emulateRF = -1; proc->first_rx = 1; From 5c9b76f1e9f50bf826ba4a5924c27a3a75ac29b7 Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Thu, 8 Nov 2018 11:09:58 +0100 Subject: [PATCH 05/14] bugfix for parameter passing --- targets/RT/USER/nr-gnb.c | 9 ++++----- targets/RT/USER/nr-ru.c | 1 + 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/targets/RT/USER/nr-gnb.c b/targets/RT/USER/nr-gnb.c index d5ea712ad9..037e5b3d73 100644 --- a/targets/RT/USER/nr-gnb.c +++ b/targets/RT/USER/nr-gnb.c @@ -545,10 +545,9 @@ int wakeup_tx(PHY_VARS_gNB *gNB) { int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { gNB_L1_proc_t *proc=&gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc=&proc->L1_proc; - NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + RU_proc_t *ru_proc=&ru->proc; int i; struct timespec wait; @@ -602,9 +601,9 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti, // and proc->subframe_tx = proc->subframe_rx+sf_ahead - L1_proc->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); - L1_proc->frame_rx = proc->frame_rx; - L1_proc->subframe_rx = proc->subframe_rx; + L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); + L1_proc->frame_rx = ru_proc->frame_rx; + L1_proc->subframe_rx = ru_proc->subframe_rx; L1_proc->frame_tx = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; L1_proc->subframe_tx = (L1_proc->subframe_rx + sf_ahead)%10; diff --git a/targets/RT/USER/nr-ru.c b/targets/RT/USER/nr-ru.c index 83843a03c6..044fce188a 100644 --- a/targets/RT/USER/nr-ru.c +++ b/targets/RT/USER/nr-ru.c @@ -1620,6 +1620,7 @@ static void* ru_thread( void* param ) { }*/ // adjust for timing offset between RU +printf("~~~~~~~~~~~~~~~~~~~~~~~~~~%d.%d in ru_thread is in process\n", proc->frame_rx, proc->subframe_rx); if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; From a0844822d40c844289590faaf3d9efe96ea7343c Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Thu, 8 Nov 2018 15:16:25 +0100 Subject: [PATCH 06/14] fix for multiple RU_TX process --- targets/RT/USER/nr-ru.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/targets/RT/USER/nr-ru.c b/targets/RT/USER/nr-ru.c index 044fce188a..bd6216d707 100644 --- a/targets/RT/USER/nr-ru.c +++ b/targets/RT/USER/nr-ru.c @@ -771,8 +771,6 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { if (ru == RC.ru[0]) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, proc->frame_rx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_RU, proc->subframe_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx ); } if (proc->first_rx == 0) { @@ -844,6 +842,8 @@ void tx_rf(RU_t *ru) { flags = 4; // start of burst and end of burst (only one DL SF between two UL) sf_extension = ru->N_TA_offset<<1; } */ + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx ); for (i=0; inb_tx; i++) txp[i] = (void*)&ru->common.txdata[i][(proc->subframe_tx*fp->samples_per_subframe)-sf_extension]; @@ -1415,6 +1415,9 @@ static void* ru_thread_tx( void* param ) { wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); if (oai_exit) break; +printf("~~~~~~~~~~~~~~~~start process for ru_thread_tx %d.%d\n", proc->frame_tx, proc->subframe_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx ); // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru); @@ -1634,22 +1637,7 @@ printf("~~~~~~~~~~~~~~~~~~~~~~~~~~%d.%d in ru_thread is in process\n", proc->fra // wakeup all gNB processes waiting for this RU if (ru->num_gNB>0) wakeup_gNB_L1s(ru); - if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0){ - // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru); - - // do OFDM if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); - if(!emulate_rf){ - // do outgoing fronthaul (south) if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); - - if (ru->fh_north_out) ru->fh_north_out(ru); - } - proc->emulate_rf_busy = 0; - } - - if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) + if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD && ru->num_eNB==0) { // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru); @@ -1691,6 +1679,7 @@ printf("~~~~~~~~~~~~~~~~~~~~~~~~~~%d.%d in ru_thread is in process\n", proc->fra }//for (i=0; inb_tx; i++) }//if(proc->frame_tx == print_frame) }//else emulate_rf + proc->emulate_rf_busy = 0; }//if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) } From e498a37e0d474701cc153b9df8f0f0d3edbb3c6a Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Thu, 8 Nov 2018 15:23:58 +0100 Subject: [PATCH 07/14] print mark out and adding gtkw file for gnb --- targets/RT/USER/gNB_usrp.gtkw | 57 +++++++++++++++++++++++++++++++++++ targets/RT/USER/nr-gnb.c | 4 +-- targets/RT/USER/nr-ru.c | 4 +-- 3 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 targets/RT/USER/gNB_usrp.gtkw diff --git a/targets/RT/USER/gNB_usrp.gtkw b/targets/RT/USER/gNB_usrp.gtkw new file mode 100644 index 0000000000..f7ca2c291a --- /dev/null +++ b/targets/RT/USER/gNB_usrp.gtkw @@ -0,0 +1,57 @@ +[*] +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Tue Nov 6 14:54:14 2018 +[*] +[dumpfile] "/tmp/openair_dump_eNB.vcd" +[dumpfile_mtime] "Tue Nov 6 14:50:45 2018" +[dumpfile_size] 1894074 +[savefile] "/homes/wangts/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw" +[timestart] 1238454000 +[size] 1920 1018 +[pos] -159 -155 +*-20.848083 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[sst_width] 386 +[signals_width] 344 +[sst_expanded] 1 +[sst_vpaned_height] 421 +@28 +functions.trx_read +functions.trx_write +@24 +variables.trx_ts[63:0] +variables.trx_tst[63:0] +@28 +functions.eNB_thread_rxtx0 +@24 +variables.frame_number_RX0_RU[63:0] +variables.subframe_number_RX0_RU[63:0] +variables.frame_number_TX0_RU[63:0] +variables.subframe_number_TX0_RU[63:0] +@28 +functions.mac_schedule_dlsch +functions.macxface_eNB_dlsch_ulsch_scheduler +functions.macxface_ue_scheduler +functions.phy_eNB_ofdm_mod_l +@24 +variables.frame_number_RX0_gNB[63:0] +variables.subframe_number_RX0_gNB[63:0] +variables.frame_number_TX0_gNB[63:0] +variables.subframe_number_TX0_gNB[63:0] +@28 +functions.gNB_thread_rxtx0 +@24 +variables.frame_number_RX1_gNB[63:0] +variables.subframe_number_RX1_gNB[63:0] +variables.frame_number_TX1_gNB[63:0] +variables.subframe_number_TX1_gNB[63:0] +@28 +functions.gNB_thread_rxtx1 +functions.phy_procedures_ru_feprx0 +functions.phy_procedures_ru_feprx0 +functions.phy_procedures_ru_feprx1 +functions.phy_procedures_ru_feptx_ofdm0 +functions.phy_procedures_ru_feptx_ofdm1 +functions.phy_procedures_ru_feptx_prec0 +functions.phy_procedures_ru_feptx_prec1 +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/targets/RT/USER/nr-gnb.c b/targets/RT/USER/nr-gnb.c index 037e5b3d73..eae095b936 100644 --- a/targets/RT/USER/nr-gnb.c +++ b/targets/RT/USER/nr-gnb.c @@ -455,7 +455,7 @@ int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB) { struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; -printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs); +//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs); if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) { LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->subframe_tx); @@ -607,7 +607,7 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { L1_proc->frame_tx = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; L1_proc->subframe_tx = (L1_proc->subframe_rx + sf_ahead)%10; -printf("~~~~~~~~~~~~~~~~~~~~~~passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sf_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->subframe_rx, L1_proc->frame_tx, L1_proc->subframe_tx, sf_ahead); +//printf("~~~~~~~~~~~~~~~~~~~~~~passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sf_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->subframe_rx, L1_proc->frame_tx, L1_proc->subframe_tx, sf_ahead); // the thread can now be woken up if (pthread_cond_signal(&L1_proc->cond) != 0) { diff --git a/targets/RT/USER/nr-ru.c b/targets/RT/USER/nr-ru.c index bd6216d707..d329e467be 100644 --- a/targets/RT/USER/nr-ru.c +++ b/targets/RT/USER/nr-ru.c @@ -1415,7 +1415,7 @@ static void* ru_thread_tx( void* param ) { wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); if (oai_exit) break; -printf("~~~~~~~~~~~~~~~~start process for ru_thread_tx %d.%d\n", proc->frame_tx, proc->subframe_tx); +//printf("~~~~~~~~~~~~~~~~start process for ru_thread_tx %d.%d\n", proc->frame_tx, proc->subframe_tx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx ); // do TX front-end processing if needed (precoding and/or IDFTs) @@ -1623,7 +1623,7 @@ static void* ru_thread( void* param ) { }*/ // adjust for timing offset between RU -printf("~~~~~~~~~~~~~~~~~~~~~~~~~~%d.%d in ru_thread is in process\n", proc->frame_rx, proc->subframe_rx); +//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~%d.%d in ru_thread is in process\n", proc->frame_rx, proc->subframe_rx); if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; From 48e7b9be452ba2cc5e480b8e2fd480fe7f0cfe76 Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Fri, 9 Nov 2018 16:41:59 +0100 Subject: [PATCH 08/14] adding adjustable sf_ahead --- openair2/GNB_APP/gnb_config.c | 10 +++++++--- targets/RT/USER/nr-ru.c | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index e9cc6df079..d695833ed3 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -294,7 +294,7 @@ void RCconfig_NR_L1(void) { } if(strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) { - sf_ahead = 2; // Need 4 subframe gap between RX and TX + //sf_ahead = 2; // Need 4 subframe gap between RX and TX }else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { RC.gNB[j][0]->eth_params_n.local_if_name = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); RC.gNB[j][0]->eth_params_n.my_addr = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); @@ -305,7 +305,7 @@ void RCconfig_NR_L1(void) { RC.gNB[j][0]->eth_params_n.remote_portd = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); RC.gNB[j][0]->eth_params_n.transp_preference = ETH_UDP_MODE; - sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2 + //sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2 RC.nb_nr_macrlc_inst = 1; // This is used by mac_top_init_gNB() @@ -404,7 +404,7 @@ void RCconfig_nr_macrlc() { RC.nrmac[j]->eth_params_s.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); RC.nrmac[j]->eth_params_s.transp_preference = ETH_UDP_MODE; - sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2 + //sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2 printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); configure_nfapi_vnf(RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc); @@ -799,6 +799,10 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { } NRRRC_CONFIGURATION_REQ (msg_p).N_RB_DL[j]= N_RB_DL; + if(N_RB_DL == 217) sf_ahead = 2; + else if(N_RB_DL == 106) sf_ahead = 4; + else AssertFatal (0,"Failed to parse gNB configuration file %s, gnb %d unknown value \"%d\" for N_RB_DL choice: 106, 217 !\n", + RC.config_file_name, i, N_RB_DL); /* if ((N_RB_DL!=6) && (N_RB_DL!=15) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=75) && (N_RB_DL!=100)) { diff --git a/targets/RT/USER/nr-ru.c b/targets/RT/USER/nr-ru.c index d329e467be..0aac90b840 100644 --- a/targets/RT/USER/nr-ru.c +++ b/targets/RT/USER/nr-ru.c @@ -848,10 +848,10 @@ void tx_rf(RU_t *ru) { for (i=0; inb_tx; i++) txp[i] = (void*)&ru->common.txdata[i][(proc->subframe_tx*fp->samples_per_subframe)-sf_extension]; - if (proc->subframe_tx == 0){ + /*if (proc->subframe_tx == 0){ write_output("txdataF_frame.m","txdataF_frame",&ru->common.txdataF_BF[i],fp->samples_per_subframe_wCP, 1, 1); write_output("txdata_frame.m","txdata_frame",&ru->common.txdata[i],fp->samples_per_subframe, 1, 1); - } + }*/ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); From b6dc14f4e8901ccb51bf70cc979b42f43d196239 Mon Sep 17 00:00:00 2001 From: WANG Tsu-Han Date: Fri, 9 Nov 2018 16:52:43 +0100 Subject: [PATCH 09/14] adding config file for 80MHz --- .../CONF/gnb.band78.tm1.217PRB.usrpn300.conf | 288 ++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf new file mode 100644 index 0000000000..a604feabec --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -0,0 +1,288 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_gNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + DL_prefix_type = "NORMAL"; + UL_prefix_type = "NORMAL"; + eutra_band = 22; + downlink_frequency = 3510000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 217; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + MIB_subCarrierSpacingCommon = 30; + MIB_ssb_SubcarrierOffset = 0; + MIB_dmrs_TypeA_Position = 2; + pdcch_ConfigSIB1 = 0; + SIB1_frequencyOffsetSSB = "khz5"; + SIB1_ssb_PeriodicityServingCell = 5; + SIB1_ss_PBCH_BlockPower = -60; + absoluteFrequencySSB = 0; + DL_FreqBandIndicatorNR = 15; + DL_absoluteFrequencyPointA = 15; + DL_offsetToCarrier = 15; + DL_SCS_SubcarrierSpacing = "kHz30"; + DL_SCS_SpecificCarrier_k0 = 0; + DL_carrierBandwidth = 15; + DL_locationAndBandwidth = 15; + DL_BWP_SubcarrierSpacing = "kHz30"; + DL_BWP_prefix_type = "NORMAL"; + UL_FreqBandIndicatorNR = 15; + UL_absoluteFrequencyPointA = 13; + UL_additionalSpectrumEmission = 3; + UL_p_Max = -1; + UL_frequencyShift7p5khz = "TRUE"; + UL_offsetToCarrier = 10; + UL_SCS_SubcarrierSpacing = "kHz30"; + UL_SCS_SpecificCarrier_k0 = 0; + UL_carrierBandwidth = 15; + UL_locationAndBandwidth = 15; + UL_BWP_SubcarrierSpacing = "kHz30"; + UL_BWP_prefix_type = "NORMAL"; + UL_timeAlignmentTimerCommon = "infinity"; + ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" + ServingCellConfigCommon_ssb_PositionsInBurst_PR = "shortBitmap"; + ServingCellConfigCommon_ssb_periodicityServingCell = 10; + ServingCellConfigCommon_dmrs_TypeA_Position = 2; + NIA_SubcarrierSpacing = "kHz15"; + ServingCellConfigCommon_ss_PBCH_BlockPower = -60; + referenceSubcarrierSpacing = "kHz15"; + dl_UL_TransmissionPeriodicity = "ms0p5"; + nrofDownlinkSlots = 10; + nrofDownlinkSymbols = 10; + nrofUplinkSlots = 10; + nrofUplinkSymbols = 10; + rach_totalNumberOfRA_Preambles = 63; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_choice = "oneEighth"; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneEighth = 4; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneFourth = 8; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneHalf = 16; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_one = 24; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_two = 32; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_four = 8; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_eight = 4; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_sixteen = 2; + rach_groupBconfigured = "ENABLE"; + rach_ra_Msg3SizeGroupA = 56; + rach_messagePowerOffsetGroupB = "dB0"; + rach_numberOfRA_PreamblesGroupA = 32; + rach_ra_ContentionResolutionTimer = 8; + rsrp_ThresholdSSB = 64; + rsrp_ThresholdSSB_SUL = 64; + prach_RootSequenceIndex_choice = "l839"; + prach_RootSequenceIndex_l839 = 0; + prach_RootSequenceIndex_l139 = 0; + prach_msg1_SubcarrierSpacing = "kHz30"; + restrictedSetConfig = "unrestrictedSet"; + msg3_transformPrecoding = "ENABLE"; + prach_ConfigurationIndex = 10; + prach_msg1_FDM = "one"; + prach_msg1_FrequencyStart = 10; + zeroCorrelationZoneConfig = 10; + preambleReceivedTargetPower = -150; + preambleTransMax = 6; + powerRampingStep = "dB0"; + ra_ResponseWindow = 8; + groupHoppingEnabledTransformPrecoding = "ENABLE"; + msg3_DeltaPreamble = 0; + p0_NominalWithGrant = 0; + PUSCH_TimeDomainResourceAllocation_k2 = 0; + PUSCH_TimeDomainResourceAllocation_mappingType = "typeA"; + PUSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; + pucch_ResourceCommon = 0; + pucch_GroupHopping = "neither"; + hoppingId = 0; + p0_nominal = -30; + PDSCH_TimeDomainResourceAllocation_k0 = 2; + PDSCH_TimeDomainResourceAllocation_mappingType = "typeA"; + PDSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; + rateMatchPatternId = 0; + RateMatchPattern_patternType = "bitmaps"; + symbolsInResourceBlock = "oneSlot"; + periodicityAndPattern = 2; + RateMatchPattern_controlResourceSet = 5; + RateMatchPattern_subcarrierSpacing = "kHz30"; + RateMatchPattern_mode = "dynamic"; + controlResourceSetZero = 0; + searchSpaceZero = 0; + searchSpaceSIB1 = 10; + searchSpaceOtherSystemInformation = 10; + pagingSearchSpace = 10; + ra_SearchSpace = 10; + PDCCH_common_controlResourceSetId = 5; + PDCCH_common_ControlResourceSet_duration = 2; + PDCCH_cce_REG_MappingType = "nonInterleaved"; + PDCCH_reg_BundleSize = 3; + PDCCH_interleaverSize = 3; + PDCCH_shiftIndex = 10; + PDCCH_precoderGranularity = "sameAsREG-bundle"; + PDCCH_TCI_StateId = 32; + tci_PresentInDCI = "ENABLE"; + PDCCH_DMRS_ScramblingID = 0; + SearchSpaceId = 10; + commonSearchSpaces_controlResourceSetId = 5; + SearchSpace_monitoringSlotPeriodicityAndOffset_choice = "sl1"; + SearchSpace_monitoringSlotPeriodicityAndOffset_value = 0; + SearchSpace_duration = 2; + SearchSpace_nrofCandidates_aggregationLevel1 = 0; + SearchSpace_nrofCandidates_aggregationLevel2 = 0; + SearchSpace_nrofCandidates_aggregationLevel4 = 0; + SearchSpace_nrofCandidates_aggregationLevel8 = 0; + SearchSpace_nrofCandidates_aggregationLevel16 = 0; + SearchSpace_searchSpaceType = "common"; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1 = 1; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2 = 1; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4 = 1; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8 = 1; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16 = 1; + Common_dci_Format2_3_monitoringPeriodicity = 1; + Common_dci_Format2_3_nrofPDCCH_Candidates = 1; + ue_Specific__dci_Formats = "formats0-0-And-1-0"; + RateMatchPatternLTE_CRS_carrierFreqDL = 6; + RateMatchPatternLTE_CRS_carrierBandwidthDL = 6; + RateMatchPatternLTE_CRS_nrofCRS_Ports = 1; + RateMatchPatternLTE_CRS_v_Shift = 0; + RateMatchPatternLTE_CRS_radioframeAllocationPeriod = 1; + RateMatchPatternLTE_CRS_radioframeAllocationOffset = 0; + RateMatchPatternLTE_CRS_subframeAllocation_choice = "oneFrame"; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.100.8"; + clock_src = "external"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + From a272960353e9f2b41fef3e646687b79c1630a3e5 Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Mon, 12 Nov 2018 15:22:38 +0100 Subject: [PATCH 10/14] adding parallel function for nrUE and fixes for commenadline option --- targets/RT/USER/nr-softmodem.h | 9 +++++++-- targets/RT/USER/nr-uesoftmodem.c | 26 ++++++++++++++++++++++++-- targets/RT/USER/nr-uesoftmodem.h | 4 ++-- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/targets/RT/USER/nr-softmodem.h b/targets/RT/USER/nr-softmodem.h index 426d124b26..9dce5f34bd 100644 --- a/targets/RT/USER/nr-softmodem.h +++ b/targets/RT/USER/nr-softmodem.h @@ -86,7 +86,10 @@ #define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" +#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n" #define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n" +#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n" +#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n" /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument @@ -167,8 +170,10 @@ {"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ -{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ -{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ +{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ +{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ +{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ +{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT,PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \ } diff --git a/targets/RT/USER/nr-uesoftmodem.c b/targets/RT/USER/nr-uesoftmodem.c index 75eacb829a..02db7d1a02 100644 --- a/targets/RT/USER/nr-uesoftmodem.c +++ b/targets/RT/USER/nr-uesoftmodem.c @@ -165,9 +165,31 @@ uint8_t nb_antenna_rx = 1; char ref[128] = "internal"; char channels[128] = "0"; -int codingw = 0; -int fepw = 0; +char *parallel_config = NULL; +char *worker_config = NULL; +static THREAD_STRUCT thread_struct; +void set_parallel_conf(char *parallel_conf) +{ + if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; + printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); +} +void set_worker_conf(char *worker_conf) +{ + if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; + else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; + printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); +} +PARALLEL_CONF_t get_thread_parallel_conf(void) +{ + return thread_struct.parallel_conf; +} +WORKER_CONF_t get_thread_worker_conf(void) +{ + return thread_struct.worker_conf; +} int rx_input_level_dBm; //static int online_log_messages=0; diff --git a/targets/RT/USER/nr-uesoftmodem.h b/targets/RT/USER/nr-uesoftmodem.h index 1beab9bb64..ff3ec107de 100644 --- a/targets/RT/USER/nr-uesoftmodem.h +++ b/targets/RT/USER/nr-uesoftmodem.h @@ -85,9 +85,9 @@ #define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" #define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n" -#define CONFIG_HLP_CODINGW "coding worker thread enable(disable by defult)\n" -#define CONFIG_HLP_FEPW "FEP worker thread enabled(disable by defult)\n" #define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n" +#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n" +#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" From d849dbd053e0984ad62860cf466fba4e02f530f7 Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Mon, 12 Nov 2018 17:12:45 +0100 Subject: [PATCH 11/14] putting back variable needed for eNB --- openair1/PHY/defs_RU.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 6f68ee0fb4..3ad007813e 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -304,6 +304,8 @@ typedef struct RU_proc_t_s { int instance_pre_scd; #endif /// pipeline ready state + int ru_rx_ready; + int ru_tx_ready; int emulate_rf_busy; } RU_proc_t; From e2fceb52e7674a9205df590b44b4fb29d16d5e60 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 15 Nov 2018 22:25:53 +0100 Subject: [PATCH 12/14] adding nr_dlsim (doing pdcch for the moment only) --- cmake_targets/CMakeLists.txt | 12 +- openair1/PHY/phy_vars_ue.h | 4 - openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 6 +- openair1/SCHED_UE/phy_procedures_lte_ue.c | 2 + openair1/SIMULATION/NR_PHY/dlsim.c | 701 ++++++++++++++++++ openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h | 2 + .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 9 + 7 files changed, 729 insertions(+), 7 deletions(-) create mode 100644 openair1/SIMULATION/NR_PHY/dlsim.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index cc6b7a434e..ca646d2bff 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1602,7 +1602,14 @@ add_library(L2 ${MAC_SRC} ${ENB_APP_SRC} ) -# ${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c) + +add_library(MAC_NR + ${MAC_NR_SRC} + ) + +add_library(MAC_UE_NR + ${MAC_NR_SRC_UE} + ) add_library(L2_NR ${L2_NR_SRC} @@ -2550,6 +2557,9 @@ target_link_libraries(ldpctest SIMU PHY PHY_NR m ${ATLAS_LIBRARIES}) add_executable(nr_pbchsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c ${T_SOURCE}) target_link_libraries(nr_pbchsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl) +add_executable(nr_dlsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c ${T_SOURCE}) +target_link_libraries(nr_dlsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl) + foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim) diff --git a/openair1/PHY/phy_vars_ue.h b/openair1/PHY/phy_vars_ue.h index 79448164d3..e00b302dd7 100644 --- a/openair1/PHY/phy_vars_ue.h +++ b/openair1/PHY/phy_vars_ue.h @@ -54,10 +54,6 @@ unsigned short rev[2048],rev_times4[8192],rev_half[1024]; unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192]; -char mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"}; - - - #include "SIMULATION/ETH_TRANSPORT/vars.h" diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index f3fa4ed55b..16d7f152c3 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -87,6 +87,8 @@ fifo_dump_emos_UE emos_dump_UE; #define NS_PER_SLOT 500000 +char mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"}; + extern double cpuf; int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, @@ -6137,10 +6139,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); - /*if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1)) + if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1)) { ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag); - }*/ + } // do procedures for C-RNTI LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 4b1ceca403..3ace8ee79a 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -71,6 +71,8 @@ #define NS_PER_SLOT 500000 +char mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"}; + extern double cpuf; void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c new file mode 100644 index 0000000000..cc89f245fc --- /dev/null +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -0,0 +1,701 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include +#include +#include +#include + +#include "common/config/config_userapi.h" +#include "common/utils/LOG/log.h" +#include "common/ran_context.h" + +#include "SIMULATION/TOOLS/sim.h" +#include "SIMULATION/RF/rf.h" +#include "PHY/types.h" +#include "PHY/defs_nr_common.h" +#include "PHY/defs_nr_UE.h" +#include "PHY/defs_gNB.h" +#include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "PHY/MODULATION/modulation_eNB.h" +#include "PHY/MODULATION/modulation_UE.h" +#include "PHY/INIT/phy_init.h" +#include "PHY/NR_TRANSPORT/nr_transport.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" + +#include "SCHED_NR/sched_nr.h" +#include "SCHED_NR_UE/fapi_nr_ue_l1.h" + +#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" +#include "LAYER2/NR_MAC_UE/mac_defs.h" +#include "LAYER2/NR_MAC_UE/mac_extern.h" + +#include "NR_PHY_INTERFACE/NR_IF_Module.h" +#include "NR_UE_PHY_INTERFACE/NR_IF_Module.h" + +PHY_VARS_gNB *gNB; +PHY_VARS_NR_UE *UE; +RAN_CONTEXT_t RC; + + +double cpuf; + +// dummy functions +int nfapi_mode=0; +int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);} +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } + +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } + +int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } + +int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) {return(0);} + +uint32_t from_earfcn(int eutra_bandP,uint32_t dl_earfcn) {return(0);} +int32_t get_uldl_offset(int eutra_bandP) {return(0);} + +NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);} + +int8_t dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info){return(0);} +int8_t dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info){return(0);} + +void exit_function(const char* file, const char* function, const int line,const char *s) { + const char * msg= s==NULL ? "no comment": s; + printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); + exit(-1); +} + +int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, + const int CC_id, + const uint8_t gNB_index, + const int8_t channel, + const uint8_t* pduP, + const sdu_size_t pdu_len) +{return(0);} +int rlc_module_init (void) {return(0);} +void pdcp_layer_init(void) {} +int rrc_init_nr_global_param(void){return(0);} + + + +// needed for some functions +PHY_VARS_NR_UE ***PHY_vars_UE_g; +uint16_t conjugate[8]__attribute__((aligned(32))) = {-1,1,-1,1,-1,1,-1,1}; + +int main(int argc, char **argv) +{ + + char c; + + int i,l,aa; + double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0; + uint8_t snr1set=0; + int **txdata; + double **s_re,**s_im,**r_re,**r_im; + double iqim = 0.0; + unsigned char pbch_pdu[6]; + // int sync_pos, sync_pos_slot; + // FILE *rx_frame_file; + FILE *output_fd = NULL; + uint8_t write_output_file=0; + //int result; + int freq_offset; + // int subframe_offset; + // char fname[40], vname[40]; + int trial,n_trials=1,n_errors,n_errors2,n_alamouti; + uint8_t transmission_mode = 1,n_tx=1,n_rx=1; + uint16_t Nid_cell=0; + + channel_desc_t *gNB2UE; + uint32_t nsymb,tx_lev,tx_lev1 = 0,tx_lev2 = 0; + uint8_t extended_prefix_flag=0; + int8_t interf1=-21,interf2=-21; + + FILE *input_fd=NULL,*pbch_file_fd=NULL; + char input_val_str[50],input_val_str2[50]; + + uint8_t frame_mod4,num_pdcch_symbols = 0; + + SCM_t channel_model=AWGN;//Rayleigh1_anticorr; + + double pbch_sinr; + int pbch_tx_ant; + int N_RB_DL=273,mu=1; + + unsigned char frame_type = 0; + unsigned char pbch_phase = 0; + + int frame=0,subframe=1; + int frame_length_complex_samples; + int frame_length_complex_samples_no_prefix; + NR_DL_FRAME_PARMS *frame_parms; + nfapi_nr_config_request_t *gNB_config; + gNB_L1_rxtx_proc_t gNB_proc; + UE_nr_rxtx_proc_t UE_proc; + NR_Sched_Rsp_t Sched_INFO; + gNB_MAC_INST *gNB_mac; + NR_UE_MAC_INST_t *UE_mac; + + int ret; + int run_initial_sync=0; + int do_pdcch_flag=1; + + int loglvl=OAILOG_WARNING; + + float target_error_rate = 0.01; + + cpuf = get_cpu_freq_GHz(); + + if ( load_configmodule(argc,argv) == 0) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + + randominit(0); + + while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:N:F:GR:dP:IL:")) != -1) { + switch (c) { + case 'f': + write_output_file=1; + output_fd = fopen(optarg,"w"); + + if (output_fd==NULL) { + printf("Error opening %s\n",optarg); + exit(-1); + } + + break; + + case 'd': + frame_type = 1; + break; + + case 'g': + switch((char)*optarg) { + case 'A': + channel_model=SCM_A; + break; + + case 'B': + channel_model=SCM_B; + break; + + case 'C': + channel_model=SCM_C; + break; + + case 'D': + channel_model=SCM_D; + break; + + case 'E': + channel_model=EPA; + break; + + case 'F': + channel_model=EVA; + break; + + case 'G': + channel_model=ETU; + break; + + default: + msg("Unsupported channel model!\n"); + exit(-1); + } + + break; + + case 'i': + interf1=atoi(optarg); + break; + + case 'j': + interf2=atoi(optarg); + break; + + case 'n': + n_trials = atoi(optarg); + break; + + case 's': + snr0 = atof(optarg); + msg("Setting SNR0 to %f\n",snr0); + break; + + case 'S': + snr1 = atof(optarg); + snr1set=1; + msg("Setting SNR1 to %f\n",snr1); + break; + + /* + case 't': + Td= atof(optarg); + break; + */ + case 'p': + extended_prefix_flag=1; + break; + + /* + case 'r': + ricean_factor = pow(10,-.1*atof(optarg)); + if (ricean_factor>1) { + printf("Ricean factor must be between 0 and 1\n"); + exit(-1); + } + break; + */ + case 'x': + transmission_mode=atoi(optarg); + + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=6)) { + msg("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } + + break; + + case 'y': + n_tx=atoi(optarg); + + if ((n_tx==0) || (n_tx>2)) { + msg("Unsupported number of tx antennas %d\n",n_tx); + exit(-1); + } + + break; + + case 'z': + n_rx=atoi(optarg); + + if ((n_rx==0) || (n_rx>2)) { + msg("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } + + break; + + case 'N': + Nid_cell = atoi(optarg); + break; + + case 'R': + N_RB_DL = atoi(optarg); + break; + + case 'F': + input_fd = fopen(optarg,"r"); + + if (input_fd==NULL) { + printf("Problem with filename %s\n",optarg); + exit(-1); + } + + break; + + case 'P': + pbch_phase = atoi(optarg); + + if (pbch_phase>3) + printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); + + break; + + case 'I': + run_initial_sync=1; + target_error_rate=0.1; + break; + + case 'L': + loglvl = atoi(optarg); + break; + + default: + case 'h': + printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", + argv[0]); + printf("-h This message\n"); + printf("-p Use extended prefix mode\n"); + printf("-d Use TDD\n"); + printf("-n Number of frames to simulate\n"); + printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); + printf("-t Delay spread for multipath channel\n"); + printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); + printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); + printf("-N Nid_cell\n"); + printf("-R N_RB_DL\n"); + printf("-O oversampling factor (1,2,4,8,16)\n"); + printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); + // printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); + printf("-f Output filename (.txt format) for Pe/SNR results\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); + exit (-1); + break; + } + } + + logInit(); + set_glog(loglvl); + T_stdout = 1; + + if (snr1set==0) + snr1 = snr0+10; + + printf("Initializing gNodeB for mu %d, N_RB_DL %d\n",mu,N_RB_DL); + + RC.gNB = (PHY_VARS_gNB***) malloc(sizeof(PHY_VARS_gNB **)); + RC.gNB[0] = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *)); + RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB)); + gNB = RC.gNB[0][0]; + gNB_config = &gNB->gNB_config; + frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) + frame_parms->nb_antennas_tx = n_tx; + frame_parms->nb_antennas_rx = n_rx; + frame_parms->N_RB_DL = N_RB_DL; + frame_parms->N_RB_UL = N_RB_DL; + + nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu); + phy_init_nr_gNB(gNB,0,0); + + double fs,bw; + + if (mu == 1 && N_RB_DL == 217) { + fs = 122.88e6; + bw = 80e6; + } + else if (mu == 1 && N_RB_DL == 245) { + fs = 122.88e6; + bw = 90e6; + } + else if (mu == 1 && N_RB_DL == 273) { + fs = 122.88e6; + bw = 100e6; + } + else if (mu == 1 && N_RB_DL == 106) { + fs = 61.44e6; + bw = 40e6; + } + else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); + + gNB2UE = new_channel_desc_scm(n_tx, + n_rx, + channel_model, + fs, + bw, + 0, + 0, + 0); + + if (gNB2UE==NULL) { + msg("Problem generating channel model. Exiting.\n"); + exit(-1); + } + + 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; + + s_re = malloc(2*sizeof(double*)); + s_im = malloc(2*sizeof(double*)); + r_re = malloc(2*sizeof(double*)); + r_im = malloc(2*sizeof(double*)); + txdata = malloc(2*sizeof(int*)); + + for (i=0; i<2; i++) { + + s_re[i] = malloc(frame_length_complex_samples*sizeof(double)); + bzero(s_re[i],frame_length_complex_samples*sizeof(double)); + s_im[i] = malloc(frame_length_complex_samples*sizeof(double)); + bzero(s_im[i],frame_length_complex_samples*sizeof(double)); + + r_re[i] = malloc(frame_length_complex_samples*sizeof(double)); + bzero(r_re[i],frame_length_complex_samples*sizeof(double)); + r_im[i] = malloc(frame_length_complex_samples*sizeof(double)); + bzero(r_im[i],frame_length_complex_samples*sizeof(double)); + + printf("Allocating %d samples for txdata\n",frame_length_complex_samples); + txdata[i] = malloc(frame_length_complex_samples*sizeof(int)); + bzero(r_re[i],frame_length_complex_samples*sizeof(int)); + + } + + if (pbch_file_fd!=NULL) { + load_pbch_desc(pbch_file_fd); + } + + + //configure UE + UE = malloc(sizeof(PHY_VARS_NR_UE)); + PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE**)); + PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE*)); + PHY_vars_UE_g[0][0] = UE; + memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); + phy_init_nr_top(UE); + if (run_initial_sync==1) UE->is_synchronized = 0; + else UE->is_synchronized = 1; + + UE->perfect_ce = 0; + + if (init_nr_ue_signal(UE, 1, 0) != 0) + { + printf("Error at UE NR initialisation\n"); + exit(-1); + } + + nr_gold_pbch(UE); + + RC.nb_nr_macrlc_inst = 1; + mac_top_init_gNB(); + gNB_mac = RC.nrmac[0]; + + nr_l2_init_ue(); + UE_mac = get_mac_inst(0); + + UE->if_inst = nr_ue_if_module_init(0); + UE->if_inst->scheduled_response = nr_ue_scheduled_response; + UE->if_inst->phy_config_request = nr_ue_phy_config_request; + UE->if_inst->dl_indication = dummy_nr_ue_dl_indication; + UE->if_inst->ul_indication = dummy_nr_ue_ul_indication; + + + //mac->if_module = nr_ue_if_module_init(0); + + + // generate signal + if (input_fd==NULL) { + gNB->pbch_configured = 1; + for (int i=0;i<4;i++) gNB->pbch_pdu[i]=i+1; + + nr_schedule_css_dlsch_phytest(0,frame,subframe); + Sched_INFO.module_id = 0; + Sched_INFO.CC_id = 0; + Sched_INFO.frame = frame; + Sched_INFO.subframe = subframe; + Sched_INFO.DL_req = &gNB_mac->DL_req[0]; + Sched_INFO.UL_req = NULL; + Sched_INFO.HI_DCI0_req = NULL; + Sched_INFO.TX_req = &gNB_mac->TX_req[0]; + nr_schedule_response(&Sched_INFO); + + gNB_proc.frame_tx = frame; + gNB_proc.subframe_tx = subframe; + phy_procedures_gNB_TX(gNB,&gNB_proc,0); + + //nr_common_signal_procedures (gNB,frame,subframe); + + LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); + if (gNB->frame_parms.nb_antennas_tx>1) + LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1); + + //TODO: loop over slots + for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { + if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) { + PHY_ofdm_mod(gNB->common_vars.txdataF[aa], + txdata[aa], + frame_parms->ofdm_symbol_size, + 12, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); + } else { + nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], + txdata[aa], + 14, + frame_parms); + } + } + } else { + printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0); + + if (fread(txdata[0], + sizeof(int32_t), + frame_length_complex_samples, + input_fd) != frame_length_complex_samples) { + printf("error reading from file\n"); + exit(-1); + } + } + + LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1); + if (gNB->frame_parms.nb_antennas_tx>1) + LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1); + + if (output_fd) + fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd); + + int txlev = signal_energy(&txdata[0][5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); + + // printf("txlev %d (%f)\n",txlev,10*log10(txlev)); + + for (i=0; inb_antennas_tx; aa++) { + r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); + r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); + } + } + + //Configure UE + fapi_nr_dl_config_request_t dl_config; + // Type0 PDCCH search space + dl_config.number_pdus = 1; + dl_config.dl_config_list[0].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI; + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.rnti = 3; // to be set + + uint64_t mask = 0x0; + uint16_t num_rbs=24; + uint16_t rb_offset=0; + uint16_t cell_id=0; + uint16_t num_symbols=2; + for(i=0; i<(num_rbs/6); ++i){ // 38.331 Each bit corresponds a group of 6 RBs + mask = mask >> 1; + mask = mask | 0x100000000000; + } + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.frequency_domain_resource = mask; + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.rb_offset = rb_offset; // additional parameter other than coreset + + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.duration = num_symbols; + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_mapping_type =CCE_REG_MAPPING_TYPE_INTERLEAVED; + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_reg_bundle_size = 6; // L 38.211 7.3.2.2 + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_interleaver_size = 2; // R 38.211 7.3.2.2 + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_shift_index = cell_id; + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.precoder_granularity = PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE; + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.pdcch_dmrs_scrambling_id = cell_id; + + uint32_t number_of_search_space_per_slot=1; + uint32_t first_symbol_index=0; + uint32_t search_space_duration; // element of search space + uint32_t coreset_duration; // element of coreset + + coreset_duration = num_symbols * number_of_search_space_per_slot; + + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.number_of_candidates[0] = table_38213_10_1_1_c2[0]; + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.number_of_candidates[1] = table_38213_10_1_1_c2[1]; + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.number_of_candidates[2] = table_38213_10_1_1_c2[2]; // CCE aggregation level = 4 + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.number_of_candidates[3] = table_38213_10_1_1_c2[3]; // CCE aggregation level = 8 + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.number_of_candidates[4] = table_38213_10_1_1_c2[4]; // CCE aggregation level = 16 + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.duration = search_space_duration; + dl_config.dl_config_list[0].dci_config_pdu.dci_config_rel15.monitoring_symbols_within_slot = (0x3fff << first_symbol_index) & (0x3fff >> (14-coreset_duration-first_symbol_index)) & 0x3fff; + + + for (SNR=snr0; SNRnb_antennas_rx; aa++) { + + ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + } + } + + if (n_trials==1) { + LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0],frame_length_complex_samples,1,1); + if (gNB->frame_parms.nb_antennas_tx>1) + LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_length_complex_samples,1,1); + } + if (UE->is_synchronized == 0) { + ret = nr_initial_sync(UE, normal_txrx); + printf("nr_initial_sync1 returns %d\n",ret); + if (ret<0) n_errors++; + } + else { + UE->rx_offset=0; + + UE_proc.frame_rx = frame; + UE_proc.nr_tti_rx= subframe; + UE_proc.subframe_rx = subframe; + + UE_mac->scheduled_response.dl_config = &dl_config; + nr_ue_scheduled_response(&UE_mac->scheduled_response); + + phy_procedures_nrUE_RX(UE, + &UE_proc, + 0, + 0, + do_pdcch_flag, + normal_txrx, + no_relay); + + if (UE->dci_ind.number_of_dcis==0) n_errors++; + } + } //noise trials + + printf("SNR %f : n_errors (negative CRC) = %d/%d\n", SNR,n_errors,n_trials); + + if ((float)n_errors/(float)n_trials <= target_error_rate) { + printf("PDCCH test OK\n"); + break; + } + + if (n_trials==1) + break; + + } // NSR + + for (i=0; i<2; i++) { + free(s_re[i]); + free(s_im[i]); + free(r_re[i]); + free(r_im[i]); + free(txdata[i]); + } + + free(s_re); + free(s_im); + free(r_re); + free(r_im); + free(txdata); + + if (output_fd) + fclose(output_fd); + + if (input_fd) + fclose(input_fd); + + return(n_errors); + +} + + + diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index 4c252dc652..a9b385d878 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -181,6 +181,8 @@ int8_t nr_ue_if_module_kill(uint32_t module_id); \param dl_info including dci_ind and rx_request messages*/ int8_t nr_ue_dl_indication(nr_downlink_indication_t *dl_info); +int8_t nr_ue_ul_indication(nr_uplink_indication_t *ul_info); + // TODO check /**\brief handle BCCH-BCH message from dl_indication \param pduP pointer to bch pdu diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 258d6c5f03..b197ea7576 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -259,6 +259,15 @@ RUs = ( } ); +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_DISABLE"; + } +); + NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; From 5daf21683cf68fd183d5e5b85f17c10f82eca677 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 16 Nov 2018 15:54:34 +0100 Subject: [PATCH 13/14] making things compile again --- openair1/PHY/phy_vars.h | 3 --- openair1/PHY/phy_vars_nr_ue.h | 3 --- 2 files changed, 6 deletions(-) diff --git a/openair1/PHY/phy_vars.h b/openair1/PHY/phy_vars.h index ebc6fc1c9f..e8588ce0b8 100644 --- a/openair1/PHY/phy_vars.h +++ b/openair1/PHY/phy_vars.h @@ -59,9 +59,6 @@ unsigned short rev[2048],rev_times4[8192],rev_half[1024]; unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192]; -char mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"}; - - #include "SIMULATION/ETH_TRANSPORT/vars.h" diff --git a/openair1/PHY/phy_vars_nr_ue.h b/openair1/PHY/phy_vars_nr_ue.h index 05afddf798..93a489178a 100644 --- a/openair1/PHY/phy_vars_nr_ue.h +++ b/openair1/PHY/phy_vars_nr_ue.h @@ -55,9 +55,6 @@ unsigned short rev[2048],rev_times4[8192],rev_half[1024]; unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192]; -char mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"}; - - #include "SIMULATION/ETH_TRANSPORT/vars.h" From fd1ca9cff7d45b0c8aa5d0011d461b3a59592e57 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 16 Nov 2018 17:15:07 +0100 Subject: [PATCH 14/14] fixing a bug in nr_pbch_extract --- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index d30b5badf3..42ad8e08cf 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -91,7 +91,7 @@ uint16_t nr_pbch_extract(int **rxdataF, for (rb=0; rb<20; rb++) { j=0; - if (symbol==1 || symbol==7) { + if (symbol==1 || symbol==3) { for (i=0; i<12; i++) { if ((i!=nushiftmod4) && (i!=(nushiftmod4+4)) && @@ -147,7 +147,7 @@ uint16_t nr_pbch_extract(int **rxdataF, for (rb=0; rb<20; rb++) { j=0; - if (symbol==1 || symbol==7) { + if (symbol==1 || symbol==3) { for (i=0; i<12; i++) { if ((i!=nushiftmod4) && (i!=(nushiftmod4+4)) &&