diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 3d9fb87cba007815c3413a8881ad151b15d5f325..f5ede896a78d244e18012732a8ef3cbcf37c5b00 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -252,7 +252,7 @@ case $key in VM_NAME=ci-phy-sim ARCHIVES_LOC=phy_sim LOG_PATTERN=.Rel15.txt - NB_PATTERN_FILES=10 + NB_PATTERN_FILES=11 BUILD_OPTIONS="--phy_simulators" VM_MEMORY=8192 RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" @@ -331,7 +331,7 @@ case $key in VM_NAME=ci-phy-sim ARCHIVES_LOC=phy_sim LOG_PATTERN=.Rel15.txt - NB_PATTERN_FILES=10 + NB_PATTERN_FILES=11 BUILD_OPTIONS="--phy_simulators" VM_MEMORY=8192 RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 4b52a2b2d808abf19adc74fc6adf5504de70606b..4e05552c1a624b542012dbd8c256399344fb9559 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1299,6 +1299,7 @@ set(PHY_SRC_UE ${PHY_POLARSRC} ${PHY_SMALLBLOCKSRC} ${PHY_LDPCSRC} + ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c # added by prasanth ) set(PHY_NR_UE_SRC @@ -2551,6 +2552,14 @@ add_executable(nr_pbchsim ${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) +#PUCCH ---> Prashanth +add_executable(nr_pucchsim + ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c + ${OPENAIR_DIR}/common/utils/backtrace.c + ${T_SOURCE}) +target_link_libraries(nr_pucchsim -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) +#PUCCH ---> Prashanth + add_executable(nr_dlsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c ${OPENAIR_DIR}/common/utils/backtrace.c diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index e99d84a134d1bec38c40d7252e8198f313e532f3..ecd53cc87c9f9ce3081fcb84c196a463fdb5e082 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -684,7 +684,7 @@ function main() { echo_info "Compiling unitary tests simulators" # TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim #simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim" - simlist="dlsim ulsim polartest ldpctest smallblocktest nr_pbchsim nr_dlschsim nr_dlsim nr_ulschsim" + simlist="nr_pucchsim dlsim ulsim polartest ldpctest smallblocktest nr_pbchsim nr_dlschsim nr_dlsim nr_ulschsim" for f in $simlist ; do compilations \ phy_simulators $f \ diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index c0571f2bc5e2eed5603d7555b3a94e195e91c9aa..11c8d57febe357f8bdecadd56516649339be875a 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -135,8 +135,8 @@ 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); +int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx); +int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx); extern PARALLEL_CONF_t get_thread_parallel_conf(void); extern WORKER_CONF_t get_thread_worker_conf(void); @@ -151,20 +151,18 @@ 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_L1_rxtx_proc_t *proc, char *thread_name) { +static inline int rxtx(PHY_VARS_gNB *gNB,int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) { start_meas(&softmodem_stats_rxtx_sf); // ******************************************************************* if (nfapi_mode == 1) { // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick - uint16_t frame = proc->frame_rx; - uint16_t slot = proc->slot_rx; //add_subframe(&frame, &subframe, 4); //oai_subframe_ind(proc->frame_tx, proc->subframe_tx); //LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe); start_meas(&nfapi_meas); - oai_subframe_ind(frame, slot); + oai_subframe_ind(frame_rx, slot_rx); stop_meas(&nfapi_meas); if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus|| @@ -179,15 +177,15 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_ NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles, gNB->UL_INFO.cqi_ind.number_of_cqis, - proc->frame_rx, proc->slot_rx, - proc->frame_tx, proc->slot_tx); + frame_rx, slot_rx, + frame_tx, slot_tx); } } /// NR disabling // **************************************** // Common RX procedures subframe n - T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->slot_tx)); + T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx)); /* // if this is IF5 or 3GPP_gNB if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) { @@ -200,8 +198,8 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_ } */ pthread_mutex_lock(&gNB->UL_INFO_mutex); - gNB->UL_INFO.frame = proc->frame_rx; - gNB->UL_INFO.slot = proc->slot_rx; + gNB->UL_INFO.frame = frame_rx; + gNB->UL_INFO.slot = slot_rx; gNB->UL_INFO.module_id = gNB->Mod_id; gNB->UL_INFO.CC_id = gNB->CC_id; gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); @@ -217,12 +215,12 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_ if (oai_exit) return(-1); - if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) { - phy_procedures_gNB_TX(gNB, proc, 1); + if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) { + phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); } stop_meas( &softmodem_stats_rxtx_sf ); - LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->slot_rx, proc->frame_tx, proc->slot_tx); + LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx); #if 0 LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ", softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now, @@ -268,17 +266,14 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_ static void *gNB_L1_thread_tx(void *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; + gNB_L1_rxtx_proc_t *L1_proc_tx = &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); - //wait_sync("tx_thread"); + sprintf(thread_name,"gNB_L1_thread_tx\n"); 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; + if (wait_on_condition(&L1_proc_tx->mutex,&L1_proc_tx->cond,&L1_proc_tx->instance_cnt,thread_name)<0) break; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 1 ); @@ -289,22 +284,24 @@ static void *gNB_L1_thread_tx(void *param) { // 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) // ***************************************** - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,proc->slot_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB,proc->slot_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 ); - proc->instance_cnt = -1; + int frame_tx = L1_proc_tx->frame_tx; + int slot_tx = L1_proc_tx->slot_tx; + uint64_t timestamp_tx = L1_proc_tx->timestamp_tx; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx); + phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); + pthread_mutex_lock( &L1_proc_tx->mutex ); + L1_proc_tx->instance_cnt = -1; // the thread can now be woken up - if (pthread_cond_signal(&proc->cond) != 0) { + if (pthread_cond_signal(&L1_proc_tx->cond) != 0) { LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n"); exit_fun( "ERROR pthread_cond_signal" ); } + pthread_mutex_unlock(&L1_proc_tx->mutex); - pthread_mutex_unlock( &proc->mutex ); - wakeup_txfh(proc,gNB); + wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 ); } return 0; @@ -320,41 +317,43 @@ static void *gNB_L1_thread( void *param ) { static int gNB_thread_rxtx_status; 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; + gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc; //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; 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); + + sprintf(thread_name,"gNB_L1_thread"); + while (!oai_exit) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 0 ); + if (wait_on_condition(&L1_proc->mutex,&L1_proc->cond,&L1_proc->instance_cnt,thread_name)<0) break; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 ); - if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break; + int frame_rx = L1_proc->frame_rx; + int slot_rx = L1_proc->slot_rx; + int frame_tx = L1_proc->frame_tx; + int slot_tx = L1_proc->slot_tx; + uint64_t timestamp_tx = L1_proc->timestamp_tx; - 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_SLOT_NUMBER_TX0_GNB,proc->slot_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,proc->slot_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); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,slot_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,slot_rx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,frame_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,frame_rx); if (oai_exit) break; if (gNB->CC_id==0) { - 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 (rxtx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,thread_name) < 0) break; } - if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break; + if (release_thread(&L1_proc->mutex,&L1_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); - } + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,timestamp_tx); + else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(gNB,L1_proc,frame_tx,slot_tx,timestamp_tx); } // while !oai_exit LOG_D(PHY, " *** Exiting gNB thread RXn_TXnp4\n"); @@ -402,7 +401,7 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame; - 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); + if (rxtx(gNB,L1_proc->frame_rx,L1_proc->slot_rx,L1_proc->frame_tx,L1_proc->slot_tx,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->tti_tx = L1_proc->slot_tx; @@ -410,92 +409,116 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct } } -int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB) { +int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx) { + RU_t *ru; RU_proc_t *ru_proc; + + int waitret,ret; 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->slot_tx, proc->instance_cnt_RUs); + wait.tv_nsec=10000000L; + - 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->slot_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); +// note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1); + waitret=timedwait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh",1000000); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0); + + AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n"); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); - if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1); + if (waitret == ETIMEDOUT) { + LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 1 slot times (500us)\n",frame_tx,slot_tx); - for(int i=0; inum_RU; i++) { + AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); + gNB->proc.RU_mask_tx = 0; + AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); + AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); + proc->instance_cnt_RUs = 0; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); + AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0); + + return(-1); + } + + for(int i=0; inum_RU; i++) + { ru = gNB->RU_list[i]; ru_proc = &ru->proc; + + AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); if (ru_proc->instance_cnt_gNBs == 0) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1); LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->tti_tx, proc->frame_rx, proc->slot_rx); - return(-1); - } + AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); + gNB->proc.RU_mask_tx = 0; + AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); + AssertFatal((ret=pthread_mutex_unlock( &ru_proc->mutex_gNBs ))==0,"mutex_unlock return %d\n",ret); - 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->tti_rx&1,ru_proc->instance_cnt_gNBs ); - exit_fun( "error locking mutex_gNB" ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0); return(-1); } ru_proc->instance_cnt_gNBs = 0; - ru_proc->timestamp_tx = proc->timestamp_tx; - ru_proc->tti_tx = proc->slot_tx; - ru_proc->frame_tx = proc->frame_tx; - LOG_I(PHY,"Signaling tx_thread_fh for %d.%d\n",ru_proc->frame_tx,ru_proc->tti_tx); + ru_proc->timestamp_tx = timestamp_tx; + ru_proc->tti_tx = slot_tx; + ru_proc->frame_tx = frame_tx; + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, ru_proc->instance_cnt_gNBs); + LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_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); - } + AssertFatal(pthread_cond_signal(&ru_proc->cond_gNBs) == 0, + "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n"); + AssertFatal((ret=pthread_mutex_unlock(&ru_proc->mutex_gNBs))==0,"mutex_unlock returned %d\n",ret); - 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; +int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx) { + + + gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx; + + int ret; + struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; + + + AssertFatal((ret = pthread_mutex_lock(&L1_proc_tx->mutex))==0,"mutex_lock returns %d\n",ret); - 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) { + 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->slot_rx = L1_proc->slot_rx; - L1_proc_tx->frame_rx = L1_proc->frame_rx; - L1_proc_tx->slot_tx = L1_proc->slot_tx; - L1_proc_tx->frame_tx = L1_proc->frame_tx; - L1_proc_tx->timestamp_tx = L1_proc->timestamp_tx; + + L1_proc_tx->slot_rx = slot_rx; + L1_proc_tx->frame_rx = frame_rx; + L1_proc_tx->slot_tx = slot_tx; + L1_proc_tx->frame_tx = frame_tx; + L1_proc_tx->timestamp_tx = timestamp_tx; + + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0); + // 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); - } + AssertFatal(pthread_cond_signal(&L1_proc_tx->cond) == 0, "ERROR pthread_cond_signal for gNB L1 thread\n"); + + AssertFatal((ret=pthread_mutex_unlock(&L1_proc_tx->mutex))==0,"mutex_unlock returns %d\n",ret); - pthread_mutex_unlock( &L1_proc_tx->mutex); return(0); } @@ -504,56 +527,48 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { 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 ret; int i; struct timespec wait; - pthread_mutex_lock(&proc->mutex_RU); - - for (i=0; inum_RU; i++) { + + AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret); + for (i=0;inum_RU;i++) { if (ru == gNB->RU_list[i]) { if ((proc->RU_mask&(1< 0) - LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", - gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask); - + LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", + gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask); proc->RU_mask |= (1<RU_mask != (1<num_RU)-1) { // not all RUs have provided their information so return LOG_E(PHY,"Not all RUs have provided their info\n"); - pthread_mutex_unlock(&proc->mutex_RU); + AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"mutex_unlock returns %d\n",ret); return(0); - } else { // all RUs have provided their information so continue on and wakeup gNB processing + } + else { // all RUs have provided their information so continue on and wakeup gNB processing proc->RU_mask = 0; - pthread_mutex_unlock(&proc->mutex_RU); + AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret); } + wait.tv_sec=0; wait.tv_nsec=5000000L; - /* accept some delay in processing - up to 5ms */ - for (i = 0; i < fp->slots_per_frame && L1_proc->instance_cnt == 0; i++) { - LOG_W( PHY,"[gNB] SFN.SL %d.%d, gNB RXn-TXnp4 thread busy!! (i %d, cnt %i)\n", L1_proc->frame_tx, L1_proc->slot_tx, i,L1_proc->instance_cnt); - usleep(100); - } - - if (L1_proc->instance_cnt == 0) { - exit_fun( "TX thread busy" ); - return(-1); - } - // wake up TX for subframe n+sl_ahead // lock the TX mutex and make sure the thread is ready - 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->slot_rx&1,L1_proc->instance_cnt ); - exit_fun( "error locking mutex" ); - return(-1); - } + AssertFatal((ret=pthread_mutex_lock(&L1_proc->mutex)) == 0,"mutex_lock returns %d\n", ret); + if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe + AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret); + LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx); + } + ++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 + + // 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 // transmitted timestamp of the next TX slot (first). - // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, + // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, // we want to generate subframe (n+sl_ahead), so TS_tx = TX_rx+sl_ahead*samples_per_tti, // and proc->slot_tx = proc->slot_rx+sl_ahead L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot); @@ -561,7 +576,10 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { L1_proc->slot_rx = ru_proc->tti_rx; L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame; - LOG_I(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sl_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sl_ahead); + + LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sl_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sl_ahead); + + pthread_mutex_unlock( &L1_proc->mutex ); // the thread can now be woken up if (pthread_cond_signal(&L1_proc->cond) != 0) { @@ -569,8 +587,7 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { exit_fun( "ERROR pthread_cond_signal" ); return(-1); } - - pthread_mutex_unlock( &L1_proc->mutex ); + return(0); } /* @@ -849,7 +866,7 @@ void init_eNB_afterRU(void) { LOG_I(PHY,"Mapping RX ports from %d RUs to gNB %d\n",gNB->num_RU,gNB->Mod_id); //LOG_I(PHY,"Overwriting gNB->prach_vars.rxsigF[0]:%p\n", gNB->prach_vars.rxsigF[0]); - gNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *)); + // gNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *)); LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU); for (ru_id=0,aa=0; ru_idnum_RU; ru_id++) { @@ -862,7 +879,7 @@ void init_eNB_afterRU(void) { for (i=0; iRU_list[ru_id]->nb_rx; aa++,i++) { LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa); - gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i]; + // gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i]; gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i]; } } diff --git a/executables/nr-ru.c b/executables/nr-ru.c index e6e62ad5532ccf113f05ec21b788a345e53c2f47..58272eeaa0bfc13541b981ba8eea7e7dd7e78a1c 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -297,27 +297,27 @@ int connect_rau(RU_t *ru) { /* Southbound Fronthaul functions, RCC/RAU */ // southbound IF5 fronthaul for 16-bit OAI format -static inline void fh_if5_south_out(RU_t *ru) { +static inline void fh_if5_south_out(RU_t *ru,int frame,int slot,uint64_t timestamp) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); - send_IF5(ru, ru->proc.timestamp_tx, ru->proc.tti_tx, &ru->seqno, IF5_RRH_GW_DL); + send_IF5(ru, timestamp, slot, &ru->seqno, IF5_RRH_GW_DL); } // southbound IF5 fronthaul for Mobipass packet format -static inline void fh_if5_mobipass_south_out(RU_t *ru) { +static inline void fh_if5_mobipass_south_out(RU_t *ru,int frame,int slot,uint64_t timestamp) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); - send_IF5(ru, ru->proc.timestamp_tx, ru->proc.tti_tx, &ru->seqno, IF5_MOBIPASS); + send_IF5(ru, timestamp, slot, &ru->seqno, IF5_MOBIPASS); } // southbound IF4p5 fronthaul -static inline void fh_if4p5_south_out(RU_t *ru) { +static inline void fh_if4p5_south_out(RU_t *ru,int frame,int slot, uint64_t timestamp) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx); if (nr_slot_select(&ru->gNB_list[0]->gNB_config,ru->proc.tti_tx)!=SF_UL) - send_IF4p5(ru,ru->proc.frame_tx, ru->proc.tti_tx, IF4p5_PDLFFT); + send_IF4p5(ru,frame, slot, IF4p5_PDLFFT); } /*************************************************************/ @@ -564,9 +564,9 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot_tx ); } - if (ru->feptx_ofdm) ru->feptx_ofdm(ru); + if (ru->feptx_ofdm) ru->feptx_ofdm(ru,frame_tx,slot_tx); - if (ru->fh_south_out) ru->fh_south_out(ru); + if (ru->fh_south_out) ru->fh_south_out(ru,frame_tx,slot_tx,proc->timestamp_tx); } void fh_if5_north_out(RU_t *ru) { @@ -657,7 +657,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { proc->timestamp_rx = 0; } else { if (proc->timestamp_rx - old_ts != fp->samples_per_slot) { - LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_slot,ru->ts_offset); + LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_slot,ru->ts_offset); ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_slot); proc->timestamp_rx = ts-ru->ts_offset; } @@ -669,7 +669,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { proc->timestamp_tx = proc->timestamp_rx+(sl_ahead*fp->samples_per_slot); proc->tti_tx = (proc->tti_rx+sl_ahead)%fp->slots_per_frame; proc->frame_tx = (proc->tti_rx>(fp->slots_per_frame-1-sl_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx; - LOG_I(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", + LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", ru->idx, 0, (unsigned long long int)proc->timestamp_rx, @@ -707,16 +707,16 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { } -void tx_rf(RU_t *ru) { +void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { RU_proc_t *proc = &ru->proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; void *txp[ru->nb_tx]; unsigned int txs; int i; - T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(proc->frame_tx), T_INT(proc->tti_tx), - T_INT(0), T_BUFFER(&ru->common.txdata[0][proc->tti_tx * fp->samples_per_slot], fp->samples_per_slot * 4)); - nr_subframe_t SF_type = nr_slot_select(cfg,proc->tti_tx%fp->slots_per_frame); + T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot), + T_INT(0), T_BUFFER(&ru->common.txdata[0][slot * fp->samples_per_slot], fp->samples_per_slot * 4)); + nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame); int sf_extension = 0; if ((SF_type == SF_DL) || @@ -742,23 +742,23 @@ 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_TTI_NUMBER_TX0_RU, proc->tti_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot ); for (i=0; inb_tx; i++) - txp[i] = (void *)&ru->common.txdata[i][(proc->tti_tx*fp->samples_per_slot)-sf_extension]; + txp[i] = (void *)&ru->common.txdata[i][(slot*fp->samples_per_slot)-sf_extension]; - 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_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); // prepare tx buffer pointers txs = ru->rfdevice.trx_write_func(&ru->rfdevice, - proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, + timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, txp, siglen+sf_extension, ru->nb_tx, flags); LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, - (long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->tti_tx); + (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen); } @@ -1206,36 +1206,40 @@ static void *ru_thread_tx( void *param ) { char filename[40]; int print_frame = 8; int i = 0; - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - //CPU_SET(5, &cpuset); - //pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - //wait_sync("ru_thread_tx"); + int ret; + + 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) { if (oai_exit) break; - LOG_I(PHY,"ru_thread_tx: Waiting for TX processing\n"); + LOG_D(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"); + AssertFatal((ret=pthread_mutex_lock(&proc->mutex_gNBs))==0,"mutex_lock return %d\n",ret); + int frame_tx=proc->frame_tx; + int tti_tx =proc->tti_tx; + uint64_t timestamp_tx = proc->timestamp_tx; + + AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_gNBs))==0,"mutex_lock returns %d\n",ret); + if (oai_exit) break; - //printf("~~~~~~~~~~~~~~~~start process for ru_thread_tx %d.%d\n", proc->frame_tx, proc->tti_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_TTI_NUMBER_TX0_RU, proc->tti_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx ); // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru); + if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx); // do OFDM if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx); 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_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,tti_tx,timestamp_tx); if (ru->fh_north_out) ru->fh_north_out(ru); } else { @@ -1265,12 +1269,13 @@ static void *ru_thread_tx( void *param ) { }//else emulate_rf release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, proc->instance_cnt_gNBs); 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); + AssertFatal((ret=pthread_mutex_lock(&gNB_proc->mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); for (int j=0; jnum_RU; j++) { if (ru == gNB->RU_list[j]) { @@ -1283,20 +1288,21 @@ static void *ru_thread_tx( void *param ) { } if (gNB_proc->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 + AssertFatal((ret=pthread_mutex_unlock(&gNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); + } else { // all RUs TX are finished so send the ready signal to gNB 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; + AssertFatal((ret=pthread_mutex_unlock(&gNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); + AssertFatal((ret=pthread_mutex_lock(&L1_proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); // 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" ); - } + if (L1_proc->instance_cnt_RUs==-1) { + AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0, + "ERROR pthread_cond_signal for gNB_L1_thread\n"); + } //else AssertFatal(1==0,"gNB TX thread is not ready\n"); + L1_proc->instance_cnt_RUs = 0; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs); + AssertFatal((ret=pthread_mutex_unlock(&L1_proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); - pthread_mutex_unlock( &L1_proc->mutex_RUs ); } } } @@ -1320,6 +1326,8 @@ static void *ru_thread( void *param ) { ru_thread_status = 0; // set default return value sprintf(threadname,"ru_thread %d",ru->idx); + + LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); if(emulate_rf) { @@ -1430,23 +1438,23 @@ static void *ru_thread( void *param ) { if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; // do RX front-end processing (frequency-shift, dft) if needed - if (ru->feprx) ru->feprx(ru); + if (ru->feprx) ru->feprx(ru,proc->tti_rx); // At this point, all information for subframe has been received on FH interface // 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) { + if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD && ru->num_gNB==0) { // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru); + if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx); // do OFDM if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx); 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_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx); if (ru->fh_north_out) ru->fh_north_out(ru); } else { @@ -1580,11 +1588,11 @@ int stop_rf(RU_t *ru) { return 0; } -extern void fep_full(RU_t *ru); -extern void ru_fep_full_2thread(RU_t *ru); -extern void nr_feptx_ofdm(RU_t *ru); -extern void nr_feptx_ofdm_2thread(RU_t *ru); -extern void feptx_prec(RU_t *ru); +extern void fep_full(RU_t *ru,int slot); +extern void ru_fep_full_2thread(RU_t *ru,int slot); +extern void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); +extern void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx); +extern void feptx_prec(RU_t *ru, int frame_tx,int tti_tx); extern void init_fep_thread(RU_t *ru); extern void init_nr_feptx_thread(RU_t *ru); diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 3147284e997b1c01b66a78bb7773817e6d30fa27..93a0b9fc046a9e1d77afd80ba1a8935a1abe7ad9 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -381,13 +381,14 @@ void reset_stats(FL_OBJECT *button, long arg) { phy_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0; phy_vars_gNB->UE_stats[i].dlsch_ACK[k][j]=0; phy_vars_gNB->UE_stats[i].dlsch_trials[k][j]=0; - }*/ + } phy_vars_gNB->UE_stats[i].dlsch_l2_errors[k]=0; phy_vars_gNB->UE_stats[i].ulsch_errors[k]=0; phy_vars_gNB->UE_stats[i].ulsch_consecutive_errors=0; phy_vars_gNB->UE_stats[i].dlsch_sliding_cnt=0; phy_vars_gNB->UE_stats[i].dlsch_NAK_round0=0; phy_vars_gNB->UE_stats[i].dlsch_mcs_offset=0; + */ } } } diff --git a/executables/nr-ue.c b/executables/nr-ue.c index bf0dc9809a21532bbf7047a7982229e208dcb16c..d6946f1ac787d7064a5a8bf6c527fde4e04539d8 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -169,6 +169,7 @@ static void UE_synch(void *arg) { int freq_offset=0; UE->is_synchronized = 0; + if (UE->UE_scan == 0) { get_band(downlink_frequency[CC_id][0], &UE->frame_parms.eutra_band, &uplink_frequency_offset[CC_id][0], &UE->frame_parms.frame_type); LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", @@ -239,7 +240,7 @@ static void UE_synch(void *arg) { case pbch: LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); - if (nr_initial_sync( &syncD->proc, UE, UE->mode ) == 0) { + if (nr_initial_sync( &syncD->proc, UE, UE->mode,2) == 0) { freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_slot; LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", @@ -348,7 +349,7 @@ static void UE_synch(void *arg) { } } -void processSubframeRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { +void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { // Process Rx data for one sub-frame if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) { //clean previous FAPI MESSAGE @@ -376,9 +377,9 @@ void processSubframeRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL ); #else uint64_t a=rdtsc(); - phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode); + phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode, UE_mac->phy_config.config_req.pbch_config); LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_tti_rx, (rdtsc()-a)/3500); - // printf(">>> nr_ue_pdcch_procedures ended\n"); + //printf(">>> nr_ue_pdcch_procedures ended\n"); #endif } @@ -413,7 +414,7 @@ void UE_processing(void *arg) { processingData_t *rxtxD=(processingData_t *) arg; UE_nr_rxtx_proc_t *proc = &rxtxD->proc; PHY_VARS_NR_UE *UE = rxtxD->UE; - processSubframeRX(UE, proc); + processSlotRX(UE, proc); //printf(">>> mac ended\n"); // Prepare the future Tx data #if 0 @@ -447,7 +448,7 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { for (int i=0; iframe_parms.nb_antennas_tx; i++) dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4); - for(int x=0; x<10; x++) { + for(int x=0; x<20; x++) { // two frames for initial sync for (int i=0; iframe_parms.nb_antennas_rx; i++) rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) + 4*x*UE->frame_parms.samples_per_subframe; @@ -613,6 +614,7 @@ void *UE_thread(void *arg) { continue; } + absolute_slot++; // whatever means thread_idx // Fix me: will be wrong when slot 1 is slow, as slot 2 finishes diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 8300f10675946cb91d342a1d8e2280b8c052dff5..c8143879b1c492ae92ac1ac2b580f1b030361dc4 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -393,7 +393,7 @@ static void get_options(void) { uint32_t online_log_messages; uint32_t glog_level, glog_verbosity; uint32_t start_telnetsrv=0; - paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; + paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ; paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 078a8066c3c2c97088e00e2b3b8d624660eef0d4..4d45e08722efbfcb9563f0c31dad473919527a1d 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -150,7 +150,7 @@ /* command line parameters common to eNodeB and UE */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define CMDLINE_PARAMS_DESC { \ +#define CMDLINE_PARAMS_DESC_UE { \ {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \ {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ diff --git a/executables/openairinterface5g_limits.h b/executables/openairinterface5g_limits.h index ca29078758aea5aa68c64dbe4fd135efbd94944f..53ee79a61deb6d1d03d373cb0954af08bf1b00dc 100644 --- a/executables/openairinterface5g_limits.h +++ b/executables/openairinterface5g_limits.h @@ -8,10 +8,10 @@ #define NUMBER_OF_NR_RU_MAX 2 #ifndef PHYSIM #ifndef UE_EXPANSION - #define NUMBER_OF_UE_MAX 4 - #define NUMBER_OF_NR_UE_MAX 4 - #define NUMBER_OF_CONNECTED_eNB_MAX 1 - #define NUMBER_OF_CONNECTED_gNB_MAX 1 + #define NUMBER_OF_UE_MAX 16 + #define NUMBER_OF_NR_UE_MAX 16 + #define NUMBER_OF_CONNECTED_eNB_MAX 3 + #define NUMBER_OF_CONNECTED_gNB_MAX 3 #else #define NUMBER_OF_UE_MAX 256 #define NUMBER_OF_NR_UE_MAX 256 diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 397f20633698fb8f4865381ee041790e86eafa52..c388c4e1e0be9912f777c1775747658b3618651f 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -35,7 +35,6 @@ #include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_REFSIG/nr_refsig.h" -#include "PHY/LTE_REFSIG/lte_refsig.h" #include "SCHED_NR/fapi_nr_l1.h" extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn); @@ -81,11 +80,11 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms; nfapi_nr_config_request_t *cfg = &gNB->gNB_config; NR_gNB_COMMON *const common_vars = &gNB->common_vars; - LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars; + /*LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars; LTE_eNB_SRS *const srs_vars = gNB->srs_vars; - LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars; + LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/ - int i, UE_id; + int i; LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__); gNB->total_dlsch_bitrate = 0; @@ -155,19 +154,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, /// Transport init necessary for NR synchro init_nr_transport(gNB); - /* - lte_gold(fp,gNB->lte_gold_table,fp->Nid_cell); - generate_pcfich_reg_mapping(fp); - generate_phich_reg_mapping(fp);*/ - - for (UE_id=0; UE_idfirst_run_timing_advance[UE_id] = - 1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here. - // clear whole structure - bzero( &gNB->UE_stats[UE_id], sizeof(LTE_eNB_UE_stats) ); - gNB->physicalConfigDedicated[UE_id] = NULL; - } - gNB->first_run_I0_measurements = 1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here. common_vars->rxdata = (int32_t **)NULL; @@ -183,6 +169,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, } // Channel estimates for SRS +/* for (UE_id=0; UE_idofdm_symbol_size*2 ); } } //UE_id - +*/ /*generate_ul_ref_sigs_rx(); init_ulsch_power_LUT();*/ +/* // SRS for (UE_id=0; UE_idofdm_symbol_size*sizeof(int32_t)); @@ -211,8 +199,9 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, prach_vars->rxsigF[0] = (int16_t **)malloc16_clear(64*sizeof(int16_t *)); - for (UE_id=0; UE_idrxdataF_ext = (int32_t **)malloc16( 2*sizeof(int32_t *) ); pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( 2*sizeof(int32_t *) ); @@ -241,6 +230,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, gNB->UE_stats_ptr[UE_id] = &gNB->UE_stats[UE_id]; gNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration +*/ return (0); } /* @@ -291,13 +281,12 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) { //NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms; //nfapi_nr_config_request_t *cfg = &gNB->gNB_config; NR_gNB_COMMON *const common_vars = &gNB->common_vars; - LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars; + /*LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars; LTE_eNB_SRS *const srs_vars = gNB->srs_vars; - LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars; + LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/ uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; - int i, UE_id; - for (i = 0; i < 15; i++) { + for (int i = 0; i < 15; i++) { free_and_zero(common_vars->txdataF[i]); /* rxdataF[i] is not allocated -> don't free */ } @@ -306,7 +295,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) { free_and_zero(common_vars->rxdataF); // PDCCH DMRS sequences free_and_zero(pdcch_dmrs); - +/* // Channel estimates for SRS for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { for (i=0; i<64; i++) { @@ -352,6 +341,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) { } //UE_id for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) gNB->UE_stats_ptr[UE_id] = NULL; +*/ } /* void install_schedule_handlers(IF_Module_t *if_inst) @@ -408,6 +398,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { gNB_config->sch_config.n_ssb_crb.value = (phy_config->cfg->rf_config.dl_carrier_bandwidth.value-20); gNB_config->sch_config.physical_cell_id.value = phy_config->cfg->sch_config.physical_cell_id.value; gNB_config->sch_config.ssb_scg_position_in_burst.value= phy_config->cfg->sch_config.ssb_scg_position_in_burst.value; + gNB_config->sch_config.ssb_periodicity.value = phy_config->cfg->sch_config.ssb_periodicity.value; if (phy_config->cfg->subframe_config.duplex_mode.value == 0) { gNB_config->subframe_config.duplex_mode.value = TDD; @@ -446,9 +437,9 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { nfapi_nr_config_request_t *cfg = &gNB->gNB_config; LOG_I(PHY, "Initialise nr transport\n"); - for (i=0; idlsch[i][j] = new_gNB_dlsch(1,16,NSOFT,0,fp,cfg); @@ -493,8 +484,6 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { LOG_D(PHY,"gNB %d.%d : SI %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_SI); gNB->dlsch_ra = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg); LOG_D(PHY,"gNB %d.%d : RA %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_ra); - gNB->dlsch_MCH = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg); - LOG_D(PHY,"gNB %d.%d : MCH %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_MCH); gNB->rx_total_gain_dB=130; for(i=0; irxdata = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); for (th_id=0; th_idcommon_vars_rx_data_per_thread[th_id].rxdataF = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); } for (i=0; inb_antennas_rx; i++) { - common_vars->rxdata[i] = (int32_t*) malloc16_clear( (fp->samples_per_subframe*10+2048)*sizeof(int32_t) ); + common_vars->rxdata[i] = (int32_t*) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) ); for (th_id=0; th_idcommon_vars_rx_data_per_thread[th_id].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) ); } @@ -905,6 +904,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, ue->decode_MIB = 1; ue->decode_SIB = 1; + ue->ssb_periodicity = 5; // initialization of ssb periodicity to 5ms according to TS38.213 section 4.1 + init_prach_tables(839); diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index c6a6d93c185f64351179c84ede06a4986bbe6a05..7ff88612a1ab036cff3653d47b8ad6ac7fe86511 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -117,8 +117,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, return(-1); } - - for (aa=0; aanb_antennas_rx; aa++) { memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); @@ -135,13 +133,13 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, if (symbol==0) { if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) - memcpy((short *)&common_vars->rxdata[aa][frame_length_samples], - (short *)&common_vars->rxdata[aa][0], + memcpy((short*) &common_vars->rxdata[aa][frame_length_samples], + (short*) &common_vars->rxdata[aa][0], frame_parms->ofdm_symbol_size*sizeof(int)); if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs memcpy((void *)tmp_dft_in, - (void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples], + (void *) &common_vars->rxdata[aa][rx_offset % frame_length_samples], frame_parms->ofdm_symbol_size*sizeof(int)); dft((int16_t *)tmp_dft_in, (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); @@ -150,19 +148,20 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, start_meas(&ue->rx_dft_stats); #endif - dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], + dft((int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); #endif } } else { - rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*symbol;// + - // (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1); + + rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*symbol; + // + (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1); if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) - memcpy((void *)&common_vars->rxdata[aa][frame_length_samples], - (void *)&common_vars->rxdata[aa][0], + memcpy((void *) &common_vars->rxdata[aa][frame_length_samples], + (void *) &common_vars->rxdata[aa][0], frame_parms->ofdm_symbol_size*sizeof(int)); #if UE_TIMING_TRACE start_meas(&ue->rx_dft_stats); @@ -170,13 +169,13 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs memcpy((void *)tmp_dft_in, - (void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], + (void *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], frame_parms->ofdm_symbol_size*sizeof(int)); dft((int16_t *)tmp_dft_in, (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly - dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], + dft((int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } #if UE_TIMING_TRACE @@ -192,6 +191,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, #endif } + #ifdef DEBUG_FEP printf("slot_fep: done\n"); #endif diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h index dc20ab24d7f8bbc9bdd08a597d24d0809529c4ea..a2e66d4e110dce4263b22a42e9c4c513bc3a6a00 100644 --- a/openair1/PHY/NR_REFSIG/pss_nr.h +++ b/openair1/PHY/NR_REFSIG/pss_nr.h @@ -134,10 +134,11 @@ void free_context_synchro_nr(void); void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue); void free_context_pss_nr(void); int set_pss_nr(int ofdm_symbol_size); -int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change); +int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change); int pss_search_time_nr(int **rxdata, ///rx data in time domain NR_DL_FRAME_PARMS *frame_parms, int fo_flag, + int is, int *eNB_id, int *f_off); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 15e31d9728840ba4981e656757e49940716081e4..e59c03b745fb79c26ff96a7123a4efce6e71dc88 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -187,12 +187,12 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, cset_start_symb = pdcch_params.first_symbol; cset_nsymb = pdcch_params.n_symb; dci_idx = 0; - LOG_I(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb); + LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb); // DMRS length is per OFDM symbol uint16_t dmrs_length = (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS)? (pdcch_params.n_rb*6) : (dci_alloc.L*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE) uint16_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE) - LOG_I(PHY, "DMRS length per symbol %d\t DCI encoded length %d\n", dmrs_length, encoded_length); + LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d\n", dmrs_length, encoded_length); /// DMRS QPSK modulation /*There is a need to shift from which index the pregenerated DMRS sequence is used @@ -202,7 +202,7 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, gold_pdcch_dmrs[symb] += (pdcch_params.rb_offset*3)>>5; dmrs_offset = (pdcch_params.rb_offset*3)&0x1f; - LOG_I(PHY, "PDCCH DMRS offset %d\n", dmrs_offset); + LOG_D(PHY, "PDCCH DMRS offset %d\n", dmrs_offset); } for (int symb=cset_start_symb; symbcce_list[cce_idx]; cce->cce_idx = tmp + cce_idx; @@ -120,14 +120,11 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m return ret; }*/ -void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, - int frame, - int subframe, - gNB_L1_rxtx_proc_t *proc, - NR_gNB_DCI_ALLOC_t *dci_alloc, - nfapi_nr_dl_config_dci_dl_pdu *pdcch_pdu, - nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu) -{ +void nr_fill_dci(PHY_VARS_gNB *gNB, + int frame, + int slot, + NR_gNB_DCI_ALLOC_t *dci_alloc, + nfapi_nr_dl_config_dci_dl_pdu *pdcch_pdu) { uint8_t n_shift; @@ -139,13 +136,29 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, nfapi_nr_config_request_t *cfg = &gNB->gNB_config; - NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0]; - NR_DL_gNB_HARQ_t **harq = dlsch->harq_processes; + NR_gNB_DLSCH_t *dlsch; uint16_t N_RB = params_rel15->n_RB_BWP; uint8_t fsize=0, pos=0, cand_idx=0; + + int dlsch_id = find_nr_dlsch(params_rel15->rnti,gNB,SEARCH_EXIST_OR_FREE); + if( (dlsch_id<0) || (dlsch_id>=NUMBER_OF_NR_DLSCH_MAX) ){ + LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",params_rel15->rnti,dlsch_id); + return; + } + + dlsch = gNB->dlsch[dlsch_id][0]; + + dlsch->slot_tx[slot] = 1; + dlsch->harq_ids[frame%2][slot] = pdu_rel15->harq_pid; + AssertFatal(pdu_rel15->harq_pid < 8 && pdu_rel15->harq_pid >= 0, + "illegal harq_pid %d\n",pdu_rel15->harq_pid); + + dlsch->harq_mask |= (1<harq_pid); + dlsch->rnti = params_rel15->rnti; + dci_alloc->L = 8; memcpy((void*)&dci_alloc->pdcch_params, (void*)params_rel15, sizeof(nfapi_nr_dl_config_pdcch_parameters_rel15_t)); dci_alloc->size = nr_get_dci_size(dci_alloc->pdcch_params.dci_format, @@ -400,7 +413,7 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, *dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++); - // LOG_I(PHY, "DCI PDU: [0]->0x%08llx \t [1]->0x%08llx \t [2]->0x%08llx \t [3]->0x%08llx\n", + // LOG_D(PHY, "DCI PDU: [0]->0x%08llx \t [1]->0x%08llx \t [2]->0x%08llx \t [3]->0x%08llx\n", // dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]); @@ -495,10 +508,7 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, break; } - LOG_I(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]); - LOG_I(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx); - - /// DLSCH struct - memcpy((void*)&harq[dci_alloc->harq_pid]->dlsch_pdu, (void*)dlsch_pdu, sizeof(nfapi_nr_dl_config_dlsch_pdu)); + LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]); + LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 48cd97809a882ae61df7b782a3b37edd8a24854d..7b10404fc9994beb1ac83d265995349cf8e336c9 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -196,6 +196,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch, uint32_t ***pdsch_dmrs, int32_t** txdataF, int16_t amp, + int frame, uint8_t slot, NR_DL_FRAME_PARMS frame_parms, nfapi_nr_config_request_t config) { @@ -212,7 +213,8 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch, uint16_t encoded_length = nb_symbols*Qm; /// CRC, coding, interleaving and rate matching - nr_dlsch_encoding(harq->pdu, slot, &dlsch, &frame_parms); + AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n"); + nr_dlsch_encoding(harq->pdu, frame,slot, &dlsch, &frame_parms); #ifdef DEBUG_DLSCH printf("PDSCH encoding:\nPayload:\n"); for (int i=0; iB>>7; i++) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index f5f1ba3d0a451b35ba46a73718f74a94af021b85..a2de3a231af2169a2f985c5d34b5004f25c612a3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -82,12 +82,19 @@ void nr_pdsch_layer_mapping(int16_t **mod_symbs, uint16_t n_symbs, int16_t **tx_layers); +void nr_fill_dlsch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, + unsigned char *sdu); + uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch, NR_gNB_DCI_ALLOC_t dci_alloc, uint32_t ***pdsch_dmrs, int32_t** txdataF, int16_t amp, - uint8_t subframe, + int frame, + uint8_t slot, NR_DL_FRAME_PARMS frame_parms, nfapi_nr_config_request_t config); @@ -103,10 +110,13 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); -int nr_dlsch_encoding(unsigned char *a, - uint8_t subframe, +int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type); + +int nr_dlsch_encoding(unsigned char *a,int frame, + uint8_t slot, NR_gNB_DLSCH_t *dlsch, NR_DL_FRAME_PARMS* frame_parms); + void nr_emulate_dlsch_payload(uint8_t* payload, uint16_t size); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 0a2927d881d5d79bc2af6f5e5de78ceb063e2239..c8a602e8d04bf6cf7d005e6659a0f21eaece2dce 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -163,9 +163,10 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, } - for (i=0; i<10; i++) - dlsch->harq_ids[i] = 0; - + for (i=0; i<20; i++) { + dlsch->harq_ids[0][i] = 0; + dlsch->harq_ids[1][i] = 0; + } for (i=0; iharq_processes[i] = (NR_DL_gNB_HARQ_t *)malloc16(sizeof(NR_DL_gNB_HARQ_t)); @@ -248,9 +249,10 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) dlsch->rnti = 0; dlsch->active = 0; - for (i=0; i<10; i++) - dlsch->harq_ids[i] = Mdlharq; - + for (i=0; i<10; i++) { + dlsch->harq_ids[0][i] = Mdlharq; + dlsch->harq_ids[1][i] = Mdlharq; + } for (i=0; iharq_processes[i]) { // dlsch->harq_processes[i]->Ndi = 0; @@ -267,7 +269,7 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) } } -int nr_dlsch_encoding(unsigned char *a, +int nr_dlsch_encoding(unsigned char *a,int frame, uint8_t slot, NR_gNB_DLSCH_t *dlsch, NR_DL_FRAME_PARMS* frame_parms) @@ -275,7 +277,8 @@ int nr_dlsch_encoding(unsigned char *a, unsigned int G; unsigned int crc=1; - uint8_t harq_pid = dlsch->harq_ids[slot]; + uint8_t harq_pid = dlsch->harq_ids[frame&2][slot]; + AssertFatal(harq_pid<8 && harq_pid>=0,"illegal harq_pid %d\b",harq_pid); nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; uint16_t nb_rb = rel15.n_prb; uint8_t nb_symb_sch = rel15.nb_symbols; @@ -332,7 +335,9 @@ int nr_dlsch_encoding(unsigned char *a, dlsch->harq_processes[harq_pid]->B = A+24; // dlsch->harq_processes[harq_pid]->b = a; - + + AssertFatal((A/8)+4 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_DLSCH_PAYLOAD_BYTES); + memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); nr_segmentation(dlsch->harq_processes[harq_pid]->b, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c index c1ac34075a5efcd944bf110b9e1550a21935a3bd..ac87a8194b2edf67a8a7fe374861b66d508a8a4e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c @@ -248,3 +248,45 @@ void nr_emulate_dlsch_payload(uint8_t* pdu, uint16_t size) { for (int i=0; idlsch[i]!=NULL,"gNB->dlsch[%d] is null\n",i); + AssertFatal(gNB->dlsch[i]!=NULL,"gNB->dlsch[%d][0] is null\n",i); + LOG_D(PHY,"searching for rnti %x : dlsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->dlsch[i][0]->harq_mask,gNB->dlsch[i][0]->rnti,first_free_index); + if ((gNB->dlsch[i][0]->harq_mask >0) && + (gNB->dlsch[i][0]->rnti==rnti)) return i; + else if ((gNB->dlsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i; + } + if (type == SEARCH_EXIST) return -1; + if (first_free_index != -1) + gNB->dlsch[first_free_index][0]->rnti = 0; + return first_free_index; +} + +void nr_fill_dlsch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, + uint8_t *sdu) { + + nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch_pdu->dlsch_pdu_rel15; + + int dlsch_id = find_nr_dlsch(rel15->rnti,gNB,SEARCH_EXIST); + AssertFatal( (dlsch_id>=0) && (dlsch_idrnti,dlsch_id); + NR_gNB_DLSCH_t *dlsch = gNB->dlsch[dlsch_id][0]; + NR_DL_gNB_HARQ_t **harq = dlsch->harq_processes; + /// DLSCH struct + memcpy((void*)&harq[dlsch->harq_ids[frame%2][slot]]->dlsch_pdu, (void*)dlsch_pdu, sizeof(nfapi_nr_dl_config_dlsch_pdu)); + AssertFatal(sdu!=NULL,"sdu is null\n"); + harq[dlsch->harq_ids[frame%2][slot]]->pdu = sdu; + + +} + diff --git a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c index 83d0d72b2857d3fd1f0bd550959052ab02fd19c3..79fe3817a88109c7b4aa6bba9bb00e09724395f8 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c @@ -107,7 +107,7 @@ void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, nfapi_nr_dl_config_dci_dl_pdu dci_pdu, nfapi_nr_config_request_t config) { - LOG_I(MAC, "TBS calculation\n"); + LOG_D(MAC, "TBS calculation\n"); nfapi_nr_dl_config_pdcch_parameters_rel15_t params_rel15 = dci_pdu.pdcch_params_rel15; nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_rel15 = &dlsch_pdu->dlsch_pdu_rel15; @@ -118,7 +118,7 @@ void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, uint8_t N_sh_symb = dlsch_rel15->nb_symbols; uint8_t Imcs = dlsch_rel15->mcs_idx; uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh; - LOG_I(MAC, "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n", N_RE_prime, N_sh_symb, N_PRB_DMRS, N_PRB_oh); + LOG_D(MAC, "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n", N_RE_prime, N_sh_symb, N_PRB_DMRS, N_PRB_oh); uint16_t N_RE, Ninfo, Ninfo_prime, C, TBS=0, R; uint8_t table_idx, Qm, n, scale; @@ -168,7 +168,7 @@ void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, dlsch_rel15->nb_re_dmrs = N_PRB_DMRS; dlsch_rel15->nb_mod_symbols = N_RE_prime*dlsch_rel15->n_prb*dlsch_rel15->nb_codewords; - LOG_I(MAC, "TBS %d : N_RE %d N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d Ninfo %d Ninfo_prime %d R %d Qm %d table %d scale %d nb_symbols %d\n", + LOG_D(MAC, "TBS %d : N_RE %d N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d Ninfo %d Ninfo_prime %d R %d Qm %d table %d scale %d nb_symbols %d\n", TBS, N_RE, N_PRB_DMRS, N_sh_symb, N_PRB_oh, Ninfo, Ninfo_prime, R, Qm, table_idx, scale, dlsch_rel15->nb_mod_symbols); } diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c new file mode 100644 index 0000000000000000000000000000000000000000..3513c198cbc87325556560cea23beffc1c9d3687 --- /dev/null +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "PHY/impl_defs_nr.h" +#include "PHY/defs_nr_common.h" +#include "PHY/defs_nr_UE.h" +#include "PHY/NR_UE_TRANSPORT/pucch_nr.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" + +#include "common/utils/LOG/log.h" +#include "common/utils/LOG/vcd_signal_dumper.h" + +#include "T.h" + + +void nr_decode_pucch0( int32_t **rxdataF, + pucch_GroupHopping_t pucch_GroupHopping, + uint32_t n_id, // hoppingID higher layer parameter + uint8_t *payload, + NR_DL_FRAME_PARMS *frame_parms, + int16_t amp, + int nr_tti_tx, + uint8_t m0, // should come from resource set + uint8_t nrofSymbols, // should come from resource set + uint8_t startingSymbolIndex, // should come from resource set + uint16_t startingPRB, // should come from resource set + uint8_t nr_bit) { // is number of UCI bits to be decoded + int nr_sequences; + const uint8_t *mcs; + if(nr_bit==1){ + mcs=table1_mcs; + nr_sequences=4; + } + else{ + mcs=table2_mcs; + nr_sequences=8; + } + /* + * Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation + * + */ + /* + * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 + */ + // alpha is cyclic shift + double alpha; + // lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission + //uint8_t lnormal; + // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] + //uint8_t lprime; + // mcs is provided by TC 38.213 subclauses 9.2.3, 9.2.4, 9.2.5 FIXME! + //uint8_t mcs; + + /* + * in TS 38.213 Subclause 9.2.1 it is said that: + * for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift + * is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift + */ + + /* + * Implementing TS 38.211 Subclause 6.3.2.3.1, the sequence x(n) shall be generated according to: + * x(l*12+n) = r_u_v_alpha_delta(n) + */ + // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1 + uint8_t u=0,v=0;//,delta=0; + // if frequency hopping is disabled by the higher-layer parameter PUCCH-frequency-hopping + // n_hop = 0 + // if frequency hopping is enabled by the higher-layer parameter PUCCH-frequency-hopping + // n_hop = 0 for first hop + // n_hop = 1 for second hop + uint8_t n_hop = 0; + //uint8_t PUCCH_Frequency_Hopping; // from higher layers FIXME!! + + // x_n contains the sequence r_u_v_alpha_delta(n) + int16_t x_n_re[nr_sequences][24],x_n_im[nr_sequences][24]; + int n,i,l; + for(i=0;i>15) + - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))>>15); // Re part of base sequence shifted by alpha + x_n_im[i][(12*l)+n] =(int16_t)((int32_t)(amp)* (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) + + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))>>15); // Im part of base sequence shifted by alpha + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d)\n", + u,v,alpha,l,n,x_n_re[(12*l)+n],x_n_im[(12*l)+n]); + #endif + } + } + } + int16_t r_re[24],r_im[24]; + /* + * Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources FIXME! + */ + uint32_t re_offset=0; + for (l=0; lN_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))); + } + if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6; + } + if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + for (n=0; n<12; n++){ + if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { + // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); + } + r_re[(12*l)+n]=((int16_t *)&rxdataF[0][re_offset])[0]; + r_im[(12*l)+n]=((int16_t *)&rxdataF[0][re_offset])[1]; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,re_offset, + l,n,((int16_t *)&rxdataF[0][re_offset])[0],((int16_t *)&rxdataF[0][re_offset])[1]); + #endif + re_offset++; + } + } + double corr[nr_sequences],corr_re[nr_sequences],corr_im[nr_sequences]; + memset(corr,0,nr_sequences*sizeof(double)); + memset(corr_re,0,nr_sequences*sizeof(double)); + memset(corr_im,0,nr_sequences*sizeof(double)); + for(i=0;imax_corr){ + index= i; + max_corr=corr[i]; + } + } + *payload=(uint8_t)index; // payload bits 00..b3b2b0, b0 is the SR bit and b3b2 are HARQ bits +} + diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 0ab83712d8e44863415a722f80a03bf140045cc0..1728d93b695930ab280c2216b0502e465d41b4dd 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -65,7 +65,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, k = nushift; #ifdef DEBUG_CH - printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,ue->frame_parms.ofdm_symbol_size, + printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -324,6 +324,9 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + #ifdef DEBUG_CH printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif @@ -441,8 +444,8 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, k = coreset_start_subcarrier; #ifdef DEBUG_PDCCH - printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, - ue->frame_parms.Ncp,l,Ns,k, symbol); + printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, + ue->frame_parms.Ncp,Ns,k, symbol); #endif fl = filt16a_l1; @@ -638,6 +641,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned short bwp_start_subcarrier, unsigned short nb_rb_pdsch) { + int pilot[1320] __attribute__((aligned(16))); unsigned char aarx; unsigned short k; @@ -665,8 +669,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int re_offset = k; #ifdef DEBUG_CH - printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size, - ue->frame_parms.Ncp,l,Ns,k, symbol); + printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size, + ue->frame_parms.Ncp,Ns,k, symbol); #endif switch (nushift) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 50c7bafbadc687826a4d88b7edefcc428ea9576e..fc4fff1c40915b15686657019eab2e16d3616ffd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -201,13 +201,14 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini char duplex_string[2][4] = {"FDD","TDD"}; char prefix_string[2][9] = {"NORMAL","EXTENDED"}; -int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode) +int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode, int n_frames) { int32_t sync_pos, sync_pos_frame; // k_ssb, N_ssb_crb, sync_pos2, int32_t metric_tdd_ncp=0; uint8_t phase_tdd_ncp; double im, re; + int is; NR_DL_FRAME_PARMS *fp = &ue->frame_parms; int ret=-1; @@ -222,10 +223,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode) nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,fp->N_RB_DL,n_ssb_crb,0); LOG_D(PHY,"nr_initial sync ue RB_DL %d\n", fp->N_RB_DL); - /* - write_output("rxdata0.m","rxd0",ue->common_vars.rxdata[0],10*fp->samples_per_subframe,1,1); - exit(-1); - */ + /* Initial synchronisation * @@ -242,26 +240,27 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode) cnt++; if (1){ // (cnt>100) - cnt =0; + cnt =0; - /* process pss search on received buffer */ - sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE); + // initial sync performed on two successive frames, if pbch passes on first frame, no need to process second frame + // only one frame is used for symulation tools + for(is=0; is= fp->nb_prefix_samples) - ue->ssb_offset = sync_pos - fp->nb_prefix_samples; - else - ue->ssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples; + /* process pss search on received buffer */ + sync_pos = pss_synchro_nr(ue, is, NO_RATE_CHANGE); - - //write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*fp->samples_per_subframe,1,1); + if (sync_pos >= fp->nb_prefix_samples) + ue->ssb_offset = sync_pos - fp->nb_prefix_samples; + else + ue->ssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples; #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos,ue->common_vars.eNb_id); - LOG_I(PHY,"sync_pos %d ssb_offset %d \n",sync_pos,ue->ssb_offset); + LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos,ue->common_vars.eNb_id); + LOG_I(PHY,"sync_pos %d ssb_offset %d \n",sync_pos,ue->ssb_offset); #endif - // digital compensation of FFO for SSB symbols - if (ue->UE_fo_compensation){ + // digital compensation of FFO for SSB symbols + if (ue->UE_fo_compensation){ double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time double off_angle = -2*M_PI*s_time*(ue->common_vars.freq_offset); // offset rotation angle compensation per sample @@ -276,11 +275,10 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode) ((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle))); } } - } - + } - /* check that SSS/PBCH block is continuous inside the received buffer */ - if (sync_pos < (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe - (NB_SYMBOLS_PBCH * fp->ofdm_symbol_size))) { + /* check that SSS/PBCH block is continuous inside the received buffer */ + if (sync_pos < (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe - (NB_SYMBOLS_PBCH * fp->ofdm_symbol_size))) { /* slop_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */ /* for NR this is not the case but slot_fep is still used for computing FFT of samples */ @@ -291,33 +289,33 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode) /* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */ /* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */ - for(int i=0; i<4;i++) - nr_slot_fep(ue, - i, - 0, - ue->ssb_offset, - 0); + for(int i=0; i<4;i++) + nr_slot_fep(ue, + i, + 0, + ue->ssb_offset, + 0); #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"Calling sss detection (normal CP)\n"); + LOG_I(PHY,"Calling sss detection (normal CP)\n"); #endif - rx_sss_nr(ue,&metric_tdd_ncp,&phase_tdd_ncp); + rx_sss_nr(ue,&metric_tdd_ncp,&phase_tdd_ncp); - //FK: why do we need to do this again here? - //nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0); + //FK: why do we need to do this again here? + //nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0); - nr_gold_pbch(ue); - ret = nr_pbch_detection(proc, ue,1,mode); // start pbch detection at first symbol after pss + nr_gold_pbch(ue); + ret = nr_pbch_detection(proc, ue,1,mode); // start pbch detection at first symbol after pss - if (ret == 0) { - // sync at symbol ue->symbol_offset - // computing the offset wrt the beginning of the frame - sync_pos_frame = (fp->ofdm_symbol_size + fp->nb_prefix_samples0)+((ue->symbol_offset)-1)*(fp->ofdm_symbol_size + fp->nb_prefix_samples); - ue->rx_offset = ue->ssb_offset - sync_pos_frame; - } + if (ret == 0) { + // sync at symbol ue->symbol_offset + // computing the offset wrt the beginning of the frame + sync_pos_frame = (fp->ofdm_symbol_size + fp->nb_prefix_samples0)+((ue->symbol_offset)-1)*(fp->ofdm_symbol_size + fp->nb_prefix_samples); + ue->rx_offset = ue->ssb_offset - sync_pos_frame; + } - nr_gold_pdcch(ue,0, 2); + nr_gold_pdcch(ue,0, 2); /* int nb_prefix_samples0 = fp->nb_prefix_samples0; fp->nb_prefix_samples0 = fp->nb_prefix_samples; @@ -333,16 +331,20 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode) ue->common_vars.freq_offset ); */ + #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, pbch %d\n", - fp->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,ret); + LOG_I(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, pbch %d\n", + fp->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,ret); #endif - } - else { + + } + else { #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"TDD Normal prefix: SSS error condition: sync_pos %d\n", sync_pos); + LOG_I(PHY,"TDD Normal prefix: SSS error condition: sync_pos %d\n", sync_pos); #endif - } + } + if (ret == 0) break; + } } else { ret = -1; @@ -370,6 +372,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode) #endif //#endif + ue->is_synchronized_on_frame = is; // to notify on which of the two frames sync was successful + if (ue->UE_scan_carrier == 0) { #if UE_AUTOTEST_TRACE diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index d23f1645345aa2633df8a750a2bd16727bc719b5..b56573f2b3c25ecece9968fac93cf053f502f0a7 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -417,6 +417,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, uint8_t i_ssb, MIMO_mode_t mimo_mode, uint32_t high_speed_flag) { + + int Ns = proc->nr_tti_rx; NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars; int max_h=0; int symbol; @@ -443,19 +445,21 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, int symbol_offset=1; if (ue->is_synchronized > 0) - symbol_offset=ue->symbol_offset; + symbol_offset=(ue->symbol_offset)%(frame_parms->symbols_per_slot); else symbol_offset=0; + #ifdef DEBUG_PBCH - //printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[proc->subframe_rx]].rxdataF); + //printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF); write_output("rxdataF0_pbch.m","rxF0pbch", - &nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[proc->subframe_rx]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1); + &nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1); #endif // symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot for (symbol=1; symbol<4; symbol++) { - nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[proc->subframe_rx]].rxdataF, + + nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF, nr_ue_pbch_vars->dl_ch_estimates, nr_ue_pbch_vars->rxdataF_ext, nr_ue_pbch_vars->dl_ch_estimates_ext, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index e7af6323277b05b70cc85096775e69e869b8c9ef..6e588acd1d73b014f75aae5b15efb2b44b4c4fb1 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1480,7 +1480,9 @@ void generate_RIV_tables(void); @param mode current running mode */ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, - PHY_VARS_NR_UE *phy_vars_ue, runmode_t mode); + PHY_VARS_NR_UE *phy_vars_ue, + runmode_t mode, + int n_frames); /*! diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index 40945bebef14712683461d0d356c168e132f5753..a88095986478a2becf0a723001f99d58d44e4c08 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -402,7 +402,7 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue) assert(0); } - size = NR_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int64_t)*frame_parms_ue->samples_per_subframe; + size = sizeof(int64_t)*(frame_parms_ue->samples_per_frame + (2*ofdm_symbol_size)); q = (int64_t*)malloc16(size); if (q != NULL) { pss_corr_ue[i] = q; @@ -611,7 +611,7 @@ void restore_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_ch void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **rxdata) { NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); - int samples_for_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti; + int samples_for_frame = 2*frame_parms->samples_per_frame; AssertFatal(frame_parms->samples_per_tti > 3839,"Illegal samples_per_tti %d\n",frame_parms->samples_per_tti); @@ -658,7 +658,7 @@ void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **r * *********************************************************************/ -int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) +int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change) { NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); int synchro_position; @@ -667,9 +667,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) #ifdef DBG_PSS_NR - int samples_for_frame = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; - - LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], samples_for_frame, 1, 1); + LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], frame_parms->samples_per_frame, 1, 1); #endif @@ -678,7 +676,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*)); for (int aa=0; aa < frame_parms->nb_antennas_rx; aa++) { - rxdata[aa] = (int32_t*) malloc16_clear( (frame_parms->samples_per_subframe*10+8192)*sizeof(int32_t)); + rxdata[aa] = (int32_t*) malloc16_clear( (frame_parms->samples_per_frame+8192)*sizeof(int32_t)); } #ifdef SYNCHRO_DECIMAT @@ -693,7 +691,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) #ifdef DBG_PSS_NR - LOG_M("rxdata0_des.m","rxd0_des", &rxdata[0][0], samples_for_frame,1,1); + LOG_M("rxdata0_des.m","rxd0_des", &rxdata[0][0], frame_parms->samples_per_frame,1,1); #endif @@ -708,6 +706,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) synchro_position = pss_search_time_nr(rxdata, frame_parms, fo_flag, + is, (int *)&PHY_vars_UE->common_vars.eNb_id, (int *)&PHY_vars_UE->common_vars.freq_offset); @@ -746,6 +745,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) return synchro_position; } + static inline int abs32(int x) { return (((int)((short*)&x)[0])*((int)((short*)&x)[0]) + ((int)((short*)&x)[1])*((int)((short*)&x)[1])); @@ -820,6 +820,7 @@ static inline double angle64(int64_t x) int pss_search_time_nr(int **rxdata, ///rx data in time domain NR_DL_FRAME_PARMS *frame_parms, int fo_flag, + int is, int *eNB_id, int *f_off) { @@ -829,13 +830,17 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain int64_t avg[NUMBER_PSS_SEQUENCE]; double ffo_est=0; - - unsigned int length = (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe); /* 1 frame for now, it should be 2 TODO_NR */ + // performing the correlation on a frame length plus one symbol for the first of the two frame + // to take into account the possibility of PSS in between the two frames + unsigned int length; + if (is==0) + length = frame_parms->samples_per_frame + (2*frame_parms->ofdm_symbol_size); + else + length = frame_parms->samples_per_frame; AssertFatal(length>0,"illegal length %d\n",length); for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) AssertFatal(pss_corr_ue[i] != NULL,"pss_corr_ue[%d] not yet allocated! Exiting.\n", i); - peak_value = 0; peak_position = 0; pss_source = 0; @@ -871,7 +876,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain /* perform correlation of rx data and pss sequence ie it is a dot product */ result = dot_product64((short*)primary_synchro_time_nr[pss_index], - (short*) &(rxdata[ar][n]), + (short*) &(rxdata[ar][n])+(is*frame_parms->samples_per_frame), frame_parms->ofdm_symbol_size, shift); pss_corr_ue[pss_index][n] += abs64(result); @@ -905,13 +910,13 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain int64_t result1,result2; // Computing cross-correlation at peak on half the symbol size for first half of data result1 = dot_product64((short*)primary_synchro_time_nr[pss_source], - (short*) &(rxdata[0][peak_position]), + (short*) &(rxdata[0][peak_position])+(is*frame_parms->samples_per_frame), frame_parms->ofdm_symbol_size>>1, shift); // Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size // as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift result2 = dot_product64((short*)primary_synchro_time_nr[pss_source]+(frame_parms->ofdm_symbol_size), - (short*) &(rxdata[0][peak_position])+(frame_parms->ofdm_symbol_size), + (short*) &(rxdata[0][peak_position])+(frame_parms->ofdm_symbol_size+(is*frame_parms->samples_per_frame)), frame_parms->ofdm_symbol_size>>1, shift); @@ -950,7 +955,10 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain LOG_M("pss_corr_ue0.m","pss_corr_ue0",pss_corr_ue[0],length,1,6); LOG_M("pss_corr_ue1.m","pss_corr_ue1",pss_corr_ue[1],length,1,6); LOG_M("pss_corr_ue2.m","pss_corr_ue2",pss_corr_ue[2],length,1,6); - LOG_M("rxdata0.m","rxd0",rxdata[0],length,1,1); + if (is) + LOG_M("rxdata1.m","rxd0",rxdata[frame_parms->samples_per_frame],length,1,1); + else + LOG_M("rxdata0.m","rxd0",rxdata[0],length,1,1); } else { debug_cnt++; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index 41b055a7ff84d890c1cb64de67afc2ff6b87d3f4..2771874bd3f66d83f7c88bbfdf479afcc676a576 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -48,14 +48,12 @@ #endif //#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) -void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_nr.puch_GroupHopping, - //uint8_t PUCCH_GroupHopping, - PHY_VARS_NR_UE *ue, - //uint32_t n_id, - uint8_t n_hop, - int nr_tti_tx, - uint8_t *u, - uint8_t *v) { +void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, + uint32_t n_id, + uint8_t n_hop, + int nr_tti_tx, + uint8_t *u, + uint8_t *v) { /* * Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping * The following variables are set by higher layers: @@ -69,12 +67,12 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n * n_hop=1 for the second hop */ // depending on the value of the PUCCH_GroupHopping, we will obtain different values for u,v - pucch_GroupHopping_t PUCCH_GroupHopping = ue->pucch_config_common_nr->pucch_GroupHopping; // from higher layers FIXME!!! + //pucch_GroupHopping_t PUCCH_GroupHopping = ue->pucch_config_common_nr->pucch_GroupHopping; // from higher layers FIXME!!! // n_id defined as per TS 38.211 subclause 6.3.2.2.1 (is given by the higher-layer parameter hoppingId) // it is hoppingId from PUCCH-ConfigCommon: // Cell-Specific scrambling ID for group hoppping and sequence hopping if enabled // Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2) BIT STRING (SIZE (10)) - uint16_t n_id = ue->pucch_config_common_nr->hoppingId; // from higher layers FIXME!!! + //uint16_t n_id = ue->pucch_config_common_nr->hoppingId; // from higher layers FIXME!!! #ifdef DEBUG_NR_PUCCH_TX // initialization to be removed PUCCH_GroupHopping=neither; @@ -84,8 +82,8 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n uint8_t f_ss=0,f_gh=0; *u=0; *v=0; - uint32_t c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v - uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 + uint32_t c_init = 0; + uint32_t x1,s; // TS 38.211 Subclause 5.2.1 int l = 32, minShift = ((2*nr_tti_tx+n_hop)<<3); int tmpShift =0; #ifdef DEBUG_NR_PUCCH_TX @@ -97,6 +95,8 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n } if (PUCCH_GroupHopping == enable) { // PUCCH_GroupHopping 'enabled' + c_init = floor(n_id/30); // we initialize c_init to calculate u,v according to 6.3.2.2.1 of 38.211 + s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 for (int m=0; m<8; m++) { while(minShift >= l) { s = lte_gold_generic(&x1, &c_init, 0); @@ -118,6 +118,8 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n } if (PUCCH_GroupHopping == disable) { // PUCCH_GroupHopping 'disabled' + c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v + s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 f_ss = n_id%30; l = 32, minShift = (2*nr_tti_tx+n_hop); @@ -137,7 +139,7 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n #endif } -double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue, +double nr_cyclic_shift_hopping(uint32_t n_id, uint8_t m0, uint8_t mcs, uint8_t lnormal, @@ -153,7 +155,7 @@ double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue, */ // alpha_init initialized to 2*PI/12=0.5235987756 double alpha = 0.5235987756; - uint32_t c_init = ue->pucch_config_common_nr->hoppingId; // we initialize c_init again to calculate n_cs + uint32_t c_init = n_id; // we initialize c_init again to calculate n_cs #ifdef DEBUG_NR_PUCCH_TX // initialization to be remo.ved c_init=10; @@ -246,8 +248,8 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, for (int l=0; lpucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,startingSymbolIndex,nr_tti_tx); #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u,v,alpha,l); #endif @@ -435,8 +437,8 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", n_hop,nr_tti_tx); #endif - nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value - alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,lprime,nr_tti_tx); + nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,lprime,nr_tti_tx); for (int n=0; n<12; n++) { r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) @@ -753,8 +755,8 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", n_hop,nr_tti_tx); #endif - nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value - alpha = nr_cyclic_shift_hopping(ue,m0,mcs,lnormal,lprime,nr_tti_tx); + nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,lnormal,lprime,nr_tti_tx); for (int n=0; n<12; n++) { r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) @@ -1571,7 +1573,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, for (int l=0; l= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop - nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value // Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33 if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies @@ -1617,7 +1619,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, } uint16_t j=0; - alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,startingSymbolIndex,nr_tti_tx); + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,startingSymbolIndex,nr_tti_tx); for (int rb=0; rbpucch_config_common_nr.puch_GroupHopping, - //uint8_t PUCCH_GroupHopping, - PHY_VARS_NR_UE *ue, - //uint32_t n_id, +void nr_decode_pucch0( int32_t **rxdataF, + pucch_GroupHopping_t PUCCH_GroupHopping, + uint32_t n_id, //PHY_VARS_gNB *gNB, generally rxdataf is in gNB->common_vars + uint8_t *payload, + NR_DL_FRAME_PARMS *frame_parms, + int16_t amp, + int nr_tti_tx, + uint8_t m0, // should come from resource set + uint8_t nrofSymbols, // should come from resource set + uint8_t startingSymbolIndex, // should come from resource set + uint16_t startingPRB, // should come from resource set + uint8_t nr_bit); + +void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, + uint32_t n_id, uint8_t n_hop, int nr_tti_tx, uint8_t *u, uint8_t *v); -double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue, +double nr_cyclic_shift_hopping(uint32_t n_id, uint8_t m0, uint8_t mcs, uint8_t lnormal, @@ -111,6 +122,11 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, uint8_t nr_bit, uint8_t occ_length_format4, uint8_t occ_index_format4); + +// tables for mcs values for different payloads + static const uint8_t table1_mcs[]={0,3,6,9}; + static const uint8_t table2_mcs[]={0,1,3,4,6,7,9,10}; + /* * The following tables implement TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (rows->u {0,1,..,29} / columns->n {0,1,...,M_ZC-1) * Where base sequence r_u_v(n)=exp[j*phi(n)*pi/4] 0<=n<=M_ZC-1 and M_ZC={6,12,18,24} diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index f8c0aad3f29bf6b19bff029a7d53fdd672823c18..c342fb73b1006b2a9369846d1fe7e192334b6376 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -159,13 +159,13 @@ void phy_scope_gNB(FD_phy_scope_gnb *form, uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; uint8_t nb_antennas_tx = 1; // frame_parms->nb_antennas_tx; // in LTE Rel. 8 and 9 only a single transmit antenna is assumed at the UE int16_t **rxsig_t; - int16_t **chest_t; - int16_t **chest_f; - int16_t *pusch_llr; - int32_t *pusch_comp; - int32_t *pucch1_comp; - int32_t *pucch1_thres; - int32_t *pucch1ab_comp; + int16_t **chest_t=NULL; + int16_t **chest_f=NULL; + int16_t *pusch_llr=NULL; + int32_t *pusch_comp=NULL; + int32_t *pucch1_comp=NULL; + int32_t *pucch1_thres=NULL; + int32_t *pucch1ab_comp=NULL; float Re,Im,ymax; float *llr, *bit; float I[nsymb_ce*2], Q[nsymb_ce*2]; @@ -199,13 +199,14 @@ void phy_scope_gNB(FD_phy_scope_gnb *form, rxsig_t = (int16_t**) phy_vars_gnb->common_vars.rxdata; //chest_t = (int16_t**) phy_vars_gnb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id]; - chest_t = (int16_t**) phy_vars_gnb->srs_vars[UE_id].srs_ch_estimates; + /* chest_t = (int16_t**) phy_vars_gnb->srs_vars[UE_id].srs_ch_estimates; chest_f = (int16_t**) phy_vars_gnb->pusch_vars[UE_id]->drs_ch_estimates; pusch_llr = (int16_t*) phy_vars_gnb->pusch_vars[UE_id]->llr; pusch_comp = (int32_t*) phy_vars_gnb->pusch_vars[UE_id]->rxdataF_comp; pucch1_comp = (int32_t*) phy_vars_gnb->pucch1_stats[UE_id]; pucch1_thres = (int32_t*) phy_vars_gnb->pucch1_stats_thres[UE_id]; pucch1ab_comp = (int32_t*) phy_vars_gnb->pucch1ab_stats[UE_id]; + */ // Received signal in time domain of receive antenna 0 if (rxsig_t != NULL) { @@ -861,13 +862,13 @@ void reset_stats_gNB(FL_OBJECT *button, long arg) { phy_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0; phy_vars_gNB->UE_stats[i].dlsch_ACK[k][j]=0; phy_vars_gNB->UE_stats[i].dlsch_trials[k][j]=0; - }*/ + } phy_vars_gNB->UE_stats[i].dlsch_l2_errors[k]=0; phy_vars_gNB->UE_stats[i].ulsch_errors[k]=0; phy_vars_gNB->UE_stats[i].ulsch_consecutive_errors=0; phy_vars_gNB->UE_stats[i].dlsch_sliding_cnt=0; phy_vars_gNB->UE_stats[i].dlsch_NAK_round0=0; - phy_vars_gNB->UE_stats[i].dlsch_mcs_offset=0; + phy_vars_gNB->UE_stats[i].dlsch_mcs_offset=0;*/ } } } diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 76769ed4db3866767b88eae7226f99eb94ec3fbb..83982fe5beab1c0c3dd4f9fa816b221c3c0854a4 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -124,6 +124,8 @@ typedef struct RU_proc_t_s { int tti_rx; /// subframe (LTE) / slot (NR) to act upon for transmission int tti_tx; + /// slot to pass to feptx worker thread + int slot_feptx; /// subframe to act upon for reception of prach int subframe_prach; #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -385,7 +387,7 @@ typedef struct RU_t_s{ /// function pointer to synchronous RX fronthaul function (RRU,3GPP_eNB/3GPP_gNB) void (*fh_south_in)(struct RU_t_s *ru,int *frame, int *subframe); /// function pointer to synchronous TX fronthaul function - void (*fh_south_out)(struct RU_t_s *ru); + void (*fh_south_out)(struct RU_t_s *ru,int frame_tx,int tti_tx, uint64_t timestamp_tx); /// function pointer to synchronous RX fronthaul function (RRU) void (*fh_north_in)(struct RU_t_s *ru,int *frame, int *subframe); /// function pointer to synchronous RX fronthaul function (RRU) @@ -401,11 +403,11 @@ typedef struct RU_t_s{ /// function pointer to initialization function for radio interface int (*start_if)(struct RU_t_s *ru,struct PHY_VARS_gNB_s *gNB); /// function pointer to RX front-end processing routine (DFTs/prefix removal or NULL) - void (*feprx)(struct RU_t_s *ru); + void (*feprx)(struct RU_t_s *ru,int subframe); /// function pointer to TX front-end processing routine (IDFTs and prefix removal or NULL) - void (*feptx_ofdm)(struct RU_t_s *ru); + void (*feptx_ofdm)(struct RU_t_s *ru,int frame_tx,int tti_tx); /// function pointer to TX front-end processing routine (PRECODING) - void (*feptx_prec)(struct RU_t_s *ru); + void (*feptx_prec)(struct RU_t_s *ru,int frame_tx,int tti_tx); /// function pointer to wakeup routine in lte-enb/nr-gnb. int (*wakeup_rxtx)(struct PHY_VARS_eNB_s *eNB, struct RU_t_s *ru); int (*nr_wakeup_rxtx)(struct PHY_VARS_gNB_s *gNB, struct RU_t_s *ru); diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 503e8cdc03e92b0732f56f44ba6ba01fcb05e19a..3216297f59f122f9674fbb3011d3382508eb854d 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -1016,6 +1016,35 @@ static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond, return(0); } +static inline int timedwait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name,uint32_t time_ns) { + int rc; + int waitret=0; + if ((rc = pthread_mutex_lock(mutex)) != 0) { + LOG_E(PHY, "[SCHED][eNB] wait_on_condition(): error locking mutex for %s (%d %s, %p)\n", + name, rc, strerror(rc), (void *)mutex); + exit_fun("nothing to add"); + return(-1); + } + + struct timespec now,abstime; + + while (*instance_cnt < 0) { + clock_gettime(CLOCK_REALTIME,&now); + // most of the time the thread is waiting here + // proc->instance_cnt_rxtx is -1 + abstime.tv_sec=now.tv_sec; + abstime.tv_nsec = now.tv_nsec + time_ns; + if ((waitret = pthread_cond_timedwait(cond,mutex,&abstime))==ETIMEDOUT) break; // this unlocks mutex_rxtx while waiting and then locks it again + + } + + if (pthread_mutex_unlock(mutex) != 0) { + LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name); + exit_fun("nothing to add"); + return(-1); + } + return(waitret); +} static inline int wait_on_busy_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { int rc; if ((rc = pthread_mutex_lock(mutex)) != 0) { @@ -1048,7 +1077,7 @@ static inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char * return(-1); } - *instance_cnt=*instance_cnt-1; + *instance_cnt=-1; if (pthread_mutex_unlock(mutex) != 0) { LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for %s\n",name); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 24be9688dc08039c2df802b1e234b5568288dd29..731c64b4704272f0c1f43cf669393a7d48202848 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -144,11 +144,11 @@ typedef struct { /// HARQ process mask, indicates which processes are currently active uint16_t harq_mask; /// Indicator of TX activation per subframe. Used during PUCCH detection for ACK/NAK. - uint8_t subframe_tx[10]; + uint8_t slot_tx[80]; /// First CCE of last PDSCH scheduling per subframe. Again used during PUCCH detection for ACK/NAK. uint8_t nCCE[10]; /// Process ID's per subframe. Used to associate received ACKs on PUSCH/PUCCH to DLSCH harq process ids - uint8_t harq_ids[10]; + uint8_t harq_ids[2][80]; /// Window size (in outgoing transport blocks) for fine-grain rate adaptation uint8_t ra_window_size; /// First-round error threshold for fine-grain rate adaptation @@ -382,12 +382,14 @@ typedef struct { /// scheduling parameters for RXn-TXnp4 thread struct sched_param sched_param_rxtx; - /// \internal This variable is protected by \ref mutex_RUs. + /// \internal This variable is protected by \ref mutex_RUs_tx. int instance_cnt_RUs; /// condition variable for tx processing thread pthread_cond_t cond_RUs; - /// mutex for RXn-TXnp4 processing thread + /// mutex for L1 RXTX processing thread pthread_mutex_t mutex_RUs; + /// mutex for L1 TX FH synchronization + pthread_mutex_t mutex_RUs_tx; } gNB_L1_rxtx_proc_t; @@ -497,30 +499,30 @@ typedef struct { short n0_subband_power_tot_dBm[100]; // gNB measurements (per user) //! estimated received spatial signal power (linear) - unsigned int rx_spatial_power[NUMBER_OF_UE_MAX][2][2]; + unsigned int rx_spatial_power[NUMBER_OF_NR_DLSCH_MAX][2][2]; //! estimated received spatial signal power (dB) - unsigned short rx_spatial_power_dB[NUMBER_OF_UE_MAX][2][2]; + unsigned short rx_spatial_power_dB[NUMBER_OF_NR_DLSCH_MAX][2][2]; //! estimated rssi (dBm) - short rx_rssi_dBm[NUMBER_OF_UE_MAX]; + short rx_rssi_dBm[NUMBER_OF_NR_DLSCH_MAX]; //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) - int rx_correlation[NUMBER_OF_UE_MAX][2]; + int rx_correlation[NUMBER_OF_NR_DLSCH_MAX][2]; //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) - int rx_correlation_dB[NUMBER_OF_UE_MAX][2]; + int rx_correlation_dB[NUMBER_OF_NR_DLSCH_MAX][2]; /// Wideband CQI (= SINR) - int wideband_cqi[NUMBER_OF_UE_MAX][MAX_NUM_RU_PER_gNB]; + int wideband_cqi[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB]; /// Wideband CQI in dB (= SINR dB) - int wideband_cqi_dB[NUMBER_OF_UE_MAX][MAX_NUM_RU_PER_gNB]; + int wideband_cqi_dB[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB]; /// Wideband CQI (sum of all RX antennas, in dB) - char wideband_cqi_tot[NUMBER_OF_UE_MAX]; + char wideband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX]; /// Subband CQI per RX antenna and RB (= SINR) - int subband_cqi[NUMBER_OF_UE_MAX][MAX_NUM_RU_PER_gNB][100]; + int subband_cqi[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][100]; /// Total Subband CQI and RB (= SINR) - int subband_cqi_tot[NUMBER_OF_UE_MAX][100]; + int subband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX][100]; /// Subband CQI in dB and RB (= SINR dB) - int subband_cqi_dB[NUMBER_OF_UE_MAX][MAX_NUM_RU_PER_gNB][100]; + int subband_cqi_dB[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][100]; /// Total Subband CQI and RB - int subband_cqi_tot_dB[NUMBER_OF_UE_MAX][100]; + int subband_cqi_tot_dB[NUMBER_OF_NR_DLSCH_MAX][100]; /// PRACH background noise level int prach_I0; } PHY_MEASUREMENTS_gNB; @@ -570,19 +572,19 @@ typedef struct PHY_VARS_gNB_s { LTE_eNB_PHICH phich_vars[2]; NR_gNB_COMMON common_vars; - LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX]; +/* LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX]; LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX]; LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX]; - LTE_eNB_PRACH prach_vars; - NR_gNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX][2]; // Nusers times two spatial streams - NR_gNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1][2]; // [Nusers times + number of RA][2 codewords], index 0 in [NUMBER_OF_UE_MAX+1] is for RA + LTE_eNB_PRACH prach_vars;*/ + NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2]; // Nusers times two spatial streams + NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX+1][2]; // [Nusers times + number of RA][2 codewords], index 0 in [NUMBER_OF_UE_MAX+1] is for RA // LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p; - NR_gNB_DLSCH_t *dlsch_MCH; NR_gNB_DLSCH_t *dlsch_PCH; +/* LTE_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX]; LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX]; - +*/ uint8_t pbch_configured; uint8_t pbch_pdu[4]; //PBCH_PDU_SIZE char gNB_generate_rar; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 8f463b59b54de0618dfd6d6493c585cad5094645..cb2200898c497d7f77cd2410ac9ef94360f69646 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -292,7 +292,7 @@ typedef struct { /// \brief Holds the received data in time domain. /// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES+2048[ + /// - second index: sample [0..2*FRAME_LENGTH_COMPLEX_SAMPLES+2048[ int32_t **rxdata; NR_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[RX_NB_TH_MAX]; @@ -880,8 +880,10 @@ typedef struct { int UE_scan_carrier; /// \brief Indicator that UE should enable estimation and compensation of frequency offset int UE_fo_compensation; - /// \brief Indicator that UE is synchronized to an eNB + /// \brief Indicator that UE is synchronized to a gNB int is_synchronized; + /// \brief Indicates on which frame is synchronized in a two frame synchronization + int is_synchronized_on_frame; /// Data structure for UE process scheduling UE_nr_proc_t proc; /// Flag to indicate the UE shouldn't do timing correction at all @@ -1038,6 +1040,7 @@ typedef struct { // uint8_t prach_timer; uint8_t decode_SIB; uint8_t decode_MIB; + uint8_t ssb_periodicity; /// temporary offset during cell search prior to MIB decoding int ssb_offset; uint16_t symbol_offset; // offset in terms of symbols for detected ssb in sync diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index 2724567f4b9a94a2a36fb3c2076df72cd1166cd5..2591a914a59c168bbbe4966af5efeafbe31fe7fb 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -60,23 +60,23 @@ void feptx0(RU_t *ru,int slot) { unsigned int aa,slot_offset; int slot_sizeF = (fp->ofdm_symbol_size)* ((fp->Ncp==1) ? 6 : 7); - int subframe = ru->proc.tti_tx; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+slot , 1 ); - slot_offset = subframe*fp->samples_per_tti + (slot*(fp->samples_per_tti>>1)); + slot_offset = slot*(fp->samples_per_tti>>1); //LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d\n",ru->proc.frame_tx, ru->proc.subframe_tx,slot); for (aa=0; aanb_tx; aa++) { - if (fp->Ncp == EXTENDED) PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF], + if (fp->Ncp == EXTENDED) PHY_ofdm_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF], (int*)&ru->common.txdata[aa][slot_offset], fp->ofdm_symbol_size, 6, fp->nb_prefix_samples, CYCLIC_PREFIX); - else normal_prefix_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF], + else normal_prefix_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF], (int*)&ru->common.txdata[aa][slot_offset], 7, fp); @@ -123,7 +123,7 @@ void feptx0(RU_t *ru,int slot) { } }*/ } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+slot , 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(slot&1) , 0); } static void *feptx_thread(void *param) { @@ -136,9 +136,13 @@ static void *feptx_thread(void *param) { while (!oai_exit) { if (wait_on_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+1 , 1 ); + if (oai_exit) break; //stop_meas(&ru->ofdm_mod_wakeup_stats); - feptx0(ru,1); + feptx0(ru,proc->slot_feptx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+1 , 0 ); + if (release_thread(&proc->mutex_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break; if (pthread_cond_signal(&proc->cond_feptx) != 0) { @@ -155,16 +159,14 @@ static void *feptx_thread(void *param) { return(NULL); } -void feptx_ofdm_2thread(RU_t *ru) { +void feptx_ofdm_2thread(RU_t *ru,int frame,int subframe) { LTE_DL_FRAME_PARMS *fp=ru->frame_parms; RU_proc_t *proc = &ru->proc; struct timespec wait; - int subframe = ru->proc.tti_tx; wait.tv_sec=0; wait.tv_nsec=5000000L; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); start_meas(&ru->ofdm_mod_stats); if (subframe_select(fp,subframe) == SF_UL) return; @@ -185,7 +187,8 @@ void feptx_ofdm_2thread(RU_t *ru) { pthread_mutex_unlock( &proc->mutex_feptx ); return; } - + + proc->slot_feptx=1+(subframe<<1); ++proc->instance_cnt_feptx; @@ -200,7 +203,7 @@ void feptx_ofdm_2thread(RU_t *ru) { } // call first slot in this thread - feptx0(ru,0); + feptx0(ru,(subframe<<1)); start_meas(&ru->ofdm_mod_wait_stats); wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread"); stop_meas(&ru->ofdm_mod_wait_stats); @@ -209,14 +212,13 @@ void feptx_ofdm_2thread(RU_t *ru) { printf("delay in feptx wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_tx,proc->subframe_tx); }*/ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); stop_meas(&ru->ofdm_mod_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); } -void feptx_ofdm(RU_t *ru) { +void feptx_ofdm(RU_t *ru,int frame,int subframe) { LTE_DL_FRAME_PARMS *fp=ru->frame_parms; @@ -227,7 +229,6 @@ void feptx_ofdm(RU_t *ru) { ((fp->Ncp==1) ? 6 : 7); int len,len2; int16_t *txdata; - int subframe = ru->proc.tti_tx; // int CC_id = ru->proc.CC_id; @@ -356,13 +357,12 @@ void feptx_ofdm(RU_t *ru) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); } -void feptx_prec(RU_t *ru) { +void feptx_prec(RU_t *ru,int frame,int subframe) { int l,i,aa; PHY_VARS_eNB **eNB_list = ru->eNB_list,*eNB; LTE_DL_FRAME_PARMS *fp; int32_t ***bw; - int subframe = ru->proc.tti_tx; if (ru->num_eNB == 1) { eNB = eNB_list[0]; @@ -506,7 +506,7 @@ extern void kill_feptx_thread(RU_t *ru) pthread_cond_destroy( &proc->cond_feptx ); } -void ru_fep_full_2thread(RU_t *ru) { +void ru_fep_full_2thread(RU_t *ru,int subframe) { RU_proc_t *proc = &ru->proc; @@ -515,7 +515,7 @@ void ru_fep_full_2thread(RU_t *ru) { LTE_DL_FRAME_PARMS *fp=ru->frame_parms; if ((fp->frame_type == TDD) && - (subframe_select(fp,proc->tti_rx) != SF_UL)) return; + (subframe_select(fp,subframe) != SF_UL)) return; if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); @@ -567,20 +567,19 @@ void ru_fep_full_2thread(RU_t *ru) { -void fep_full(RU_t *ru) { +void fep_full(RU_t *ru,int subframe) { - RU_proc_t *proc = &ru->proc; int l; LTE_DL_FRAME_PARMS *fp=ru->frame_parms; if ((fp->frame_type == TDD) && - (subframe_select(fp,proc->tti_rx) != SF_UL)) return; + (subframe_select(fp,subframe) != SF_UL)) return; start_meas(&ru->ofdm_demod_stats); if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); - remove_7_5_kHz(ru,proc->tti_rx<<1); - remove_7_5_kHz(ru,1+(proc->tti_rx<<1)); + remove_7_5_kHz(ru,subframe<<1); + remove_7_5_kHz(ru,1+(subframe<<1)); for (l=0; lsymbols_per_tti/2; l++) { slot_fep_ul(ru, diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index d663a95c358c0da965b11aa41c7ff318a7904e28..fffd8140ba2bb076ffb647e0c8d76f885bba58ca 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -30,6 +30,8 @@ * \warning */ #include "fapi_nr_l1.h" +#include "PHY/NR_TRANSPORT/nr_dlsch.h" +#include "PHY/NR_TRANSPORT/nr_dci.h" int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req); int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req); @@ -37,7 +39,6 @@ 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_L1_rxtx_proc_t *proc, nfapi_nr_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu) { @@ -45,7 +46,7 @@ void handle_nr_nfapi_bch_pdu(PHY_VARS_gNB *gNB, AssertFatal(dl_config_pdu->bch_pdu_rel15.length == 3, "BCH PDU has length %d != 3\n", dl_config_pdu->bch_pdu_rel15.length); - LOG_I(PHY,"pbch_pdu[0]: %x,pbch_pdu[1]: %x,gNB->pbch_pdu[2]: %x\n",sdu[0],sdu[1],sdu[2]); + LOG_D(PHY,"pbch_pdu[0]: %x,pbch_pdu[1]: %x,gNB->pbch_pdu[2]: %x\n",sdu[0],sdu[1],sdu[2]); gNB->pbch_pdu[0] = sdu[2]; gNB->pbch_pdu[1] = sdu[1]; gNB->pbch_pdu[2] = sdu[0]; @@ -56,25 +57,33 @@ void handle_nr_nfapi_bch_pdu(PHY_VARS_gNB *gNB, void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB, int frame, int slot, - gNB_L1_rxtx_proc_t *proc, - nfapi_nr_dl_config_request_pdu_t *dl_config_pdu, - nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu) -{ + nfapi_nr_dl_config_dci_dl_pdu *dci_dl_pdu) { int idx = slot&1; NR_gNB_PDCCH *pdcch_vars = &gNB->pdcch_vars; - LOG_I(PHY,"Frame %d, Slot %d: DCI processing - populating pdcch_vars->dci_alloc[%d] proc:slot_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,slot, pdcch_vars->num_dci, proc->slot_tx, idx, pdcch_vars->num_dci); + LOG_D(PHY,"Frame %d, Slot %d: DCI processing - populating pdcch_vars->dci_alloc[%d] proc:slot_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,slot, pdcch_vars->num_dci, slot, idx, pdcch_vars->num_dci); // copy dci configuration into gNB structure - nr_fill_dci_and_dlsch(gNB,frame,slot,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],&dl_config_pdu->dci_dl_pdu,&dl_config_dlsch_pdu->dlsch_pdu); + nr_fill_dci(gNB,frame,slot,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],dci_dl_pdu); + - LOG_I(PHY,"Frame %d, Slot %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:slot_tx:%d idx:%d pdcch_vars->num_dci:%d\n",proc->frame_tx,proc->slot_tx, pdcch_vars->num_dci, proc->slot_tx, idx, pdcch_vars->num_dci); + LOG_D(PHY,"Frame %d, Slot %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:slot_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,slot, pdcch_vars->num_dci, slot, idx, pdcch_vars->num_dci); } +void handle_nr_nfapi_dlsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, + nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, + uint8_t *sdu) +{ + + + nr_fill_dlsch(gNB,frame,slot,dlsch_pdu,sdu); + +} + void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ + PHY_VARS_gNB *gNB; - 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; @@ -88,12 +97,10 @@ 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.L1_proc; uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu; nfapi_nr_dl_config_request_pdu_t *dl_config_pdu; - nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu; int i; @@ -112,7 +119,6 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ for (i=0;idl_config_request_body.dl_config_pdu_list[i]; LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type); - printf("NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type); switch (dl_config_pdu->pdu_type) { case NFAPI_NR_DL_CONFIG_BCH_PDU_TYPE: AssertFatal(dl_config_pdu->bch_pdu_rel15.pdu_index < TX_req->tx_request_body.number_of_pdus, @@ -123,22 +129,31 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ do_oai=1; handle_nr_nfapi_bch_pdu(gNB, - proc, dl_config_pdu, TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu_rel15.pdu_index].segments[0].segment_data); break; case NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE: - dl_config_dlsch_pdu = &DL_req->dl_config_request_body.dl_config_pdu_list[++i]; handle_nfapi_nr_dci_dl_pdu(gNB, frame, slot, - proc, - dl_config_pdu, - dl_config_dlsch_pdu); + &dl_config_pdu->dci_dl_pdu); gNB->pdcch_vars.num_dci++; gNB->pdcch_vars.num_pdsch_rnti++; do_oai=1; break; + case NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE: + + { + nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu_rel15 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel15; + uint16_t pdu_index = dlsch_pdu_rel15->pdu_index; + uint16_t tx_pdus = TX_req->tx_request_body.number_of_pdus; + uint16_t invalid_pdu = pdu_index == -1; + uint8_t *sdu = invalid_pdu ? NULL : pdu_index >= tx_pdus ? NULL : TX_req->tx_request_body.tx_pdu_list[pdu_index].segments[0].segment_data; + + AssertFatal(sdu!=NULL,"sdu is null, pdu_index %d, tx_pdus %d\n",pdu_index,tx_pdus); + handle_nr_nfapi_dlsch_pdu(gNB,frame,slot,&dl_config_pdu->dlsch_pdu, sdu); + do_oai=1; + } } } diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h index 71ef6039f3a06a2e8c54ba1516273abdd1ed71fe..9157ca1632e834b77164924bf4bdc3a94b20bc32 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.h +++ b/openair1/SCHED_NR/fapi_nr_l1.h @@ -38,6 +38,8 @@ 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_L1_rxtx_proc_t *proc, - nfapi_nr_dl_config_request_pdu_t *dl_config_pdu, - nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu); + nfapi_nr_dl_config_dci_dl_pdu *dcl_dl_pdu); +void handle_nr_nfapi_dlsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, + nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, + uint8_t *sdu); + diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 653e9632b5072e7d8cbb82b272182e711f4fbd5e..544a8ef1dd700e9573897abf4e59f7a66f851713 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -56,12 +56,12 @@ extern openair0_config_t openair0_cfg[MAX_CARDS]; extern int oai_exit; -void nr_feptx0(RU_t *ru,int first_symbol, int num_symbols) { +void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols) { NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; unsigned int aa,slot_offset,slot_offsetF; - int slot = ru->proc.tti_tx; + int slot = tti_tx; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0) , 1 ); @@ -110,13 +110,13 @@ void nr_feptx0(RU_t *ru,int first_symbol, int num_symbols) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0), 0); } -void nr_feptx_ofdm_2thread(RU_t *ru) { +void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; RU_proc_t *proc = &ru->proc; struct timespec wait; - int slot = ru->proc.tti_tx; + int slot = tti_tx; wait.tv_sec=0; wait.tv_nsec=5000000L; @@ -149,7 +149,10 @@ void nr_feptx_ofdm_2thread(RU_t *ru) { } ++proc->instance_cnt_feptx; - + // slot to pass to worker thread + proc->slot_feptx = slot; + pthread_mutex_unlock( &proc->mutex_feptx ); + if (pthread_cond_signal(&proc->cond_feptx) != 0) { printf("[RU] ERROR pthread_cond_signal for feptx thread\n"); @@ -157,11 +160,10 @@ void nr_feptx_ofdm_2thread(RU_t *ru) { return; } - pthread_mutex_unlock( &proc->mutex_feptx ); } // call first half-slot in this thread - nr_feptx0(ru,0,fp->symbols_per_slot>>1); + nr_feptx0(ru,slot,0,fp->symbols_per_slot>>1); wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"NR feptx thread"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); @@ -181,11 +183,13 @@ static void *nr_feptx_thread(void *param) { while (!oai_exit) { if (wait_on_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"NR feptx thread")<0) break; - nr_feptx0(ru,ru->nr_frame_parms->symbols_per_slot>>1,ru->nr_frame_parms->symbols_per_slot>>1); + int slot=proc->slot_feptx; if (release_thread(&proc->mutex_feptx,&proc->instance_cnt_feptx,"NR feptx thread")<0) break; + nr_feptx0(ru,slot,ru->nr_frame_parms->symbols_per_slot>>1,ru->nr_frame_parms->symbols_per_slot>>1); + if (pthread_cond_signal(&proc->cond_feptx) != 0) { - printf("[gNB] ERROR pthread_cond_signal for NR feptx thread exit\n"); + LOG_E(PHY,"[gNB] ERROR pthread_cond_signal for NR feptx thread exit\n"); exit_fun( "ERROR pthread_cond_signal" ); return NULL; } @@ -209,7 +213,7 @@ void nr_init_feptx_thread(RU_t *ru) { // is this supposed to generate a slot or a subframe??? // seems to be hardcoded to numerology 1 (2 slots=1 subframe) -void nr_feptx_ofdm(RU_t *ru) { +void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; @@ -217,7 +221,7 @@ void nr_feptx_ofdm(RU_t *ru) { unsigned int aa=0; int slot_sizeF = (fp->ofdm_symbol_size)* ((cfg->subframe_config.dl_cyclic_prefix_type.value == 1) ? 12 : 14); - int slot = ru->proc.tti_tx; + int slot = tti_tx; int *txdata = &ru->common.txdata[aa][slot*fp->samples_per_slot]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); @@ -232,7 +236,7 @@ void nr_feptx_ofdm(RU_t *ru) { ((nr_slot_select(cfg,slot)==SF_S))) { // LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot); - nr_feptx0(ru,0,fp->symbols_per_slot); + nr_feptx0(ru,slot,0,fp->symbols_per_slot); } @@ -240,7 +244,7 @@ void nr_feptx_ofdm(RU_t *ru) { stop_meas(&ru->ofdm_mod_stats); LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, slot %d: txp (time %p) %d dB, txp (freq) %d dB\n", - ru->proc.frame_tx,slot,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->samples_per_slot)), + frame_tx,slot,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->samples_per_slot)), dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF))); } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index aeda4b354985087070a86d1eb63590f71b12e51d..53c6f3acc0cf8310c2a6f52aa1dc9abac174f610 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -93,10 +93,18 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { int ssb_start_symbol, rel_slot; n_hf = cfg->sch_config.half_frame_index.value; + + // if SSB periodicity is 5ms, they are transmitted in both half frames + if ( cfg->sch_config.ssb_periodicity.value == 5) { + if (slot<10) + n_hf=0; + else + n_hf=1; + } + // to set a effective slot number between 0 to 9 in the half frame where the SSB is supposed to be rel_slot = (n_hf)? (slot-10) : slot; - LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot); if(rel_slot<10 && rel_slot>=0) { @@ -114,7 +122,10 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { nr_generate_pss(gNB->d_pss, txdataF[0], AMP, ssb_start_symbol, cfg, fp); nr_generate_sss(gNB->d_sss, txdataF[0], AMP, ssb_start_symbol, cfg, fp); - nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp); + if (fp->Lmax == 4) + nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp); + else + nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp); nr_generate_pbch(&gNB->pbch, pbch_pdu, @@ -130,15 +141,19 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { } void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, - gNB_L1_rxtx_proc_t *proc, + int frame,int slot, int do_meas) { int aa; - int frame=proc->frame_tx; - int slot=proc->slot_tx; uint8_t num_dci=0,num_pdsch_rnti; NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; nfapi_nr_config_request_t *cfg = &gNB->gNB_config; int offset = gNB->CC_id; + uint8_t ssb_frame_periodicity; // every how many frames SSB are generated + + if (cfg->sch_config.ssb_periodicity.value < 20) + ssb_frame_periodicity = 1; + else + ssb_frame_periodicity = (cfg->sch_config.ssb_periodicity.value)/10 ; // 10ms is the frame length if ((cfg->subframe_config.duplex_mode.value == TDD) && (nr_slot_select(cfg,slot)==SF_UL)) return; @@ -151,32 +166,34 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, memset(gNB->common_vars.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t)); } - if (nfapi_mode == 0 || nfapi_mode == 1) { - nr_common_signal_procedures(gNB,frame, slot); - //if (frame == 9) - //write_output("txdataF.m","txdataF",gNB->common_vars.txdataF[aa],fp->samples_per_frame_wCP, 1, 1); + if (nfapi_mode == 0 || nfapi_mode == 1) { + if (!(frame%ssb_frame_periodicity)) // generate SSB only for given frames according to SSB periodicity + nr_common_signal_procedures(gNB,frame, slot); } num_dci = gNB->pdcch_vars.num_dci; num_pdsch_rnti = gNB->pdcch_vars.num_pdsch_rnti; if (num_dci) { - LOG_I(PHY, "[gNB %d] Frame %d slot %d \ + LOG_D(PHY, "[gNB %d] Frame %d slot %d \ Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, slot, num_dci); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1); if (nfapi_mode == 0 || nfapi_mode == 1) { nr_generate_dci_top(gNB->pdcch_vars, gNB->nr_gold_pdcch_dmrs[slot], gNB->common_vars.txdataF[0], AMP, *fp, *cfg); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); if (num_pdsch_rnti) { - LOG_I(PHY, "PDSCH generation started (%d)\n", num_pdsch_rnti); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1); + LOG_D(PHY, "PDSCH generation started (%d)\n", num_pdsch_rnti); nr_generate_pdsch(*gNB->dlsch[0][0], gNB->pdcch_vars.dci_alloc[0], gNB->nr_gold_pdsch_dmrs[slot], gNB->common_vars.txdataF, - AMP, slot, *fp, *cfg); + AMP, frame,slot, *fp, *cfg); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0); } } } diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 7c5a5d0146301793a7e8ca4bc8d4297e6336ff2f..9d290742bf2c9ef33813e07ebbcc8355ee1d07d8 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -36,14 +36,14 @@ nr_slot_t nr_slot_select (nfapi_nr_config_request_t *cfg, unsigned char slot); 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_L1_rxtx_proc_t *proc, int do_meas); +void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx,int slot_tx, int do_meas); void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot); +void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); +void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx); +void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols); void nr_init_feptx_thread(RU_t *ru); -void nr_feptx_ofdm(RU_t *ru); -void nr_feptx_ofdm_2thread(RU_t *ru); -void nr_feptx0(RU_t *ru,int first_symbol, int num_symbols); -void fep_full(RU_t *ru); -void feptx_prec(RU_t *ru); +void fep_full(RU_t *ru,int slot); +void feptx_prec(RU_t *ru,int frame_tx,int tti_tx); int nr_phy_init_RU(RU_t *ru); void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params, diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 5a8dc96fab08e6c53b524a78490df751af18687d..ad065437188663467bc27f97be96e58584a8418a 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -123,7 +123,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t e @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying @param phy_vars_rn pointer to RN variables */ -int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t do_pdcch_flag,runmode_t mode); +int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t do_pdcch_flag,runmode_t mode,fapi_nr_pbch_config_t pbch_config); int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 0a087d5b8b9c4efdc8365286ff4ebc896bf05309..72747b03dd3b980addaca2d7bbd380aceaab9276 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -2823,6 +2823,7 @@ void nr_ue_pbch_procedures(uint8_t eNB_id, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN); //LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id); + ret = nr_rx_pbch(ue, proc, ue->pbch_vars[eNB_id], &ue->frame_parms, @@ -2832,6 +2833,7 @@ void nr_ue_pbch_procedures(uint8_t eNB_id, ue->high_speed_flag); if (ret==0) { + ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0; @@ -4330,21 +4332,45 @@ void *UE_thread_slot1_dl_processing(void *arg) { #endif +int is_pbch_in_slot(fapi_nr_pbch_config_t pbch_config, int frame, int slot, int periodicity, uint16_t slots_per_frame) { -int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - uint8_t eNB_id, - uint8_t do_pdcch_flag, - runmode_t mode) -{ + int ssb_slot_decoded = (pbch_config.ssb_index)/2; + + if (periodicity == 5) { + // check for pbch in corresponding slot each half frame + if (pbch_config.half_frame_bit) + return(slot == ssb_slot_decoded || slot == ssb_slot_decoded - slots_per_frame/2); + else + return(slot == ssb_slot_decoded || slot == ssb_slot_decoded + slots_per_frame/2); + } + else { + // if the current frame is supposed to contain ssb + if (!((frame-(pbch_config.system_frame_number))%(periodicity/10))) + return(slot == ssb_slot_decoded); + else + return 0; + } +} + + +int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id, + uint8_t do_pdcch_flag,runmode_t mode, + fapi_nr_pbch_config_t pbch_config) { + + + + int l,l2; + int pilot1; int frame_rx = proc->frame_rx; int nr_tti_rx = proc->nr_tti_rx; + int slot_pbch; NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0]; NR_UE_DLSCH_t **dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id]; uint8_t harq_pid = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid; NR_DL_UE_HARQ_t *dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; uint16_t nb_symb_sch = dlsch0_harq->nb_symbols; uint8_t nb_symb_pdcch = pdcch_vars->coreset[0].duration; + uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE) uint8_t dci_cnt = 0; LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx); @@ -4510,18 +4536,17 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); } + slot_pbch = is_pbch_in_slot(pbch_config, frame_rx, nr_tti_rx, ssb_periodicity, ue->frame_parms.slots_per_frame); - - if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1)) + // looking for pbch only in slot where it is supposed to be + if ((ue->decode_MIB == 1) && slot_pbch) { LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); - uint8_t i_ssb = ue->rx_ind.rx_indication_body[0].mib_pdu.ssb_index; - uint8_t n_hf = (((ue->rx_ind.rx_indication_body[0].mib_pdu.additional_bits)>>4)&0x01); - for (int i=1; i<4; i++) { + nr_slot_fep(ue, - (ue->symbol_offset+i), //mu=1 case B + (ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot), nr_tti_rx, 0, 0); @@ -4529,7 +4554,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, #if UE_TIMING_TRACE start_meas(&ue->dlsch_channel_estimation_stats); #endif - nr_pbch_channel_estimation(ue,0,0,ue->symbol_offset+i,i-1,i_ssb,n_hf); + nr_pbch_channel_estimation(ue,0,nr_tti_rx,(ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot),i-1,(pbch_config.ssb_index)&7,pbch_config.half_frame_bit); #if UE_TIMING_TRACE stop_meas(&ue->dlsch_channel_estimation_stats); #endif diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 3807c51b96a5069014967d38ad7f276c92597a4a..5e3f7e2df68504af26937437ba218c8a7504453e 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -68,8 +68,8 @@ #include "PHY/INIT/phy_init.h" -void feptx_ofdm(RU_t *ru); -void feptx_prec(RU_t *ru); +void feptx_ofdm(RU_t *ru,int frame,int subframe); +void feptx_prec(RU_t *ru,int frame,int subframe); double cpuf; @@ -1440,6 +1440,7 @@ int main(int argc, char **argv) } eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[0];//UE->current_thread_id[subframe]]; + proc_eNB->frame_tx = 0; if (input_fd==NULL) { @@ -1652,8 +1653,8 @@ int main(int argc, char **argv) ru->proc.tti_tx=subframe; memcpy((void*)ru->frame_parms,(void*)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); - feptx_prec(ru); - feptx_ofdm(ru); + feptx_prec(ru,proc_eNB->frame_tx,subframe); + feptx_ofdm(ru,proc_eNB->frame_tx,subframe); stop_meas(&eNB->ofdm_mod_stats); @@ -1671,8 +1672,8 @@ int main(int argc, char **argv) ru->proc.tti_tx=(subframe+1)%10; - feptx_prec(ru); - feptx_ofdm(ru); + feptx_prec(ru,proc_eNB->frame_tx,subframe+1); + feptx_ofdm(ru,proc_eNB->frame_tx,subframe+1); proc_eNB->frame_tx++; diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 8d963b91867ae6f235ac473f3937acc5066c5555..0a1603e00dd90e9360e573d61637385b90d77b2c 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -108,8 +108,8 @@ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ int nfapi_mode = 0; -extern void fep_full(RU_t *ru); -extern void ru_fep_full_2thread(RU_t *ru); +extern void fep_full(RU_t *ru,int); +extern void ru_fep_full_2thread(RU_t *ru,int); extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); @@ -1283,7 +1283,7 @@ int main(int argc, char **argv) { start_meas(&eNB->phy_proc_rx); ru->feprx = (parallel_flag == 1) ? ru_fep_full_2thread : fep_full; eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - ru->feprx(ru); + ru->feprx(ru,subframe); phy_procedures_eNB_uespec_RX(eNB,proc_rxtx); stop_meas(&eNB->phy_proc_rx); diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index 0eed21c446e0262181872f098d966bae55d91618..8e250cd2165a51e2e692d5d0ae8c154badff5f18 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -149,7 +149,7 @@ int main(int argc, char **argv) { uint16_t N_RB_DL = 106, mu = 1; //unsigned char frame_type = 0; unsigned char pbch_phase = 0; - int frame = 0, subframe = 0; + int frame = 0, slot = 0; int frame_length_complex_samples; //int frame_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; @@ -528,7 +528,7 @@ int main(int argc, char **argv) { //printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32)); // generate signal if (input_fd == NULL) { - nr_dlsch_encoding(test_input, subframe, dlsch, frame_parms); + nr_dlsch_encoding(test_input, frame, slot, dlsch, frame_parms); } for (SNR = snr0; SNR < snr1; SNR += snr_step) { @@ -583,7 +583,7 @@ int main(int argc, char **argv) { #endif ret = nr_dlsch_decoding(UE, channel_output_fixed, &UE->frame_parms, dlsch0_ue, dlsch0_ue->harq_processes[0], frame, nb_symb_sch, - subframe, harq_pid, is_crnti, llr8_flag); + slot,harq_pid, is_crnti, llr8_flag); if (ret > dlsch0_ue->max_ldpc_iterations) n_errors++; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 771b6ba7c631677d1183ca9c4cba8d2d1e28702d..a968df8da50e42a6f1a64b882f0078d2bf9bf767 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -113,7 +113,8 @@ void config_common(int Mod_idP, int CC_idP, int Nid_cell, int nr_bandP, - uint64_t ssb_pattern, + uint64_t SSB_positions, + uint16_t ssb_periodicity, uint64_t dl_CarrierFreqP, uint32_t dl_BandwidthP ); @@ -166,7 +167,7 @@ int main(int argc, char **argv) //int pbch_tx_ant; int N_RB_DL=273,mu=1; - uint64_t ssb_pattern = 0x01; + uint16_t ssb_periodicity = 10; //unsigned char frame_type = 0; unsigned char pbch_phase = 0; @@ -177,7 +178,6 @@ int main(int argc, char **argv) int slot_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; @@ -520,7 +520,7 @@ int main(int argc, char **argv) mac_top_init_gNB(); gNB_mac = RC.nrmac[0]; - config_common(0,0,Nid_cell,78,ssb_pattern,(uint64_t)3640000000L,N_RB_DL); + config_common(0,0,Nid_cell,78,SSB_positions,ssb_periodicity,(uint64_t)3640000000L,N_RB_DL); config_nr_mib(0,0,1,kHz30,0,0,0,0,0); nr_l2_init_ue(); @@ -554,9 +554,7 @@ int main(int argc, char **argv) Sched_INFO.TX_req = &gNB_mac->TX_req[0]; nr_schedule_response(&Sched_INFO); - gNB_proc.frame_tx = frame; - gNB_proc.slot_tx = slot; - phy_procedures_gNB_TX(gNB,&gNB_proc,0); + phy_procedures_gNB_TX(gNB,frame,slot,0); //nr_common_signal_procedures (gNB,frame,subframe); @@ -681,6 +679,10 @@ int main(int argc, char **argv) UE_mac->scheduled_response.frame = frame; UE_mac->scheduled_response.slot = slot; + UE_mac->phy_config.config_req.pbch_config.system_frame_number = frame; + UE_mac->phy_config.config_req.pbch_config.ssb_index = 0; + UE_mac->phy_config.config_req.pbch_config.half_frame_bit = 0; + for (SNR=snr0; SNRis_synchronized == 0) { UE_nr_rxtx_proc_t proc={0}; - ret = nr_initial_sync(&proc, UE, normal_txrx); + ret = nr_initial_sync(&proc, UE, normal_txrx,1); printf("nr_initial_sync1 returns %d\n",ret); if (ret<0) n_errors++; } @@ -731,7 +733,8 @@ int main(int argc, char **argv) &UE_proc, 0, do_pdcch_flag, - normal_txrx); + normal_txrx, + UE_mac->phy_config.config_req.pbch_config); if (n_trials==1) { LOG_M("rxsigF0.m","rxsF0", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0],slot_length_complex_samples_no_prefix,1,1); diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 847fac3213f2ea29232f2279ba99245de9a245d0..775710bb6029eb19cb59d26eadaea6af47758507 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -479,8 +479,7 @@ int main(int argc, char **argv) if(eps!=0.0) UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation - if (init_nr_ue_signal(UE, 1, 0) != 0) - { + if (init_nr_ue_signal(UE, 1, 0) != 0) { printf("Error at UE NR initialisation\n"); exit(-1); } @@ -601,25 +600,25 @@ int main(int argc, char **argv) if (UE->is_synchronized == 0) { UE_nr_rxtx_proc_t proc={0}; - ret = nr_initial_sync(&proc, UE, normal_txrx); + ret = nr_initial_sync(&proc, UE, normal_txrx,1); printf("nr_initial_sync1 returns %d\n",ret); if (ret<0) n_errors++; } else { UE->rx_offset=0; - uint8_t ssb_index = 0; while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb - UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms, ssb_index, n_hf); + int ssb_slot = (ssb_index/2)+(n_hf*frame_parms->slots_per_frame); for (int i=UE->symbol_offset+1; isymbol_offset+4; i++) { nr_slot_fep(UE, - i, - 0, + i%frame_parms->symbols_per_slot, + ssb_slot, 0, 0); - nr_pbch_channel_estimation(UE,0,0,i,i-(UE->symbol_offset+1),ssb_index%8,n_hf); + nr_pbch_channel_estimation(UE,0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf); + } UE_nr_rxtx_proc_t proc={0}; diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c new file mode 100644 index 0000000000000000000000000000000000000000..19e0e7dc25af48217c833b64cb9e2cbf29215644 --- /dev/null +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -0,0 +1,542 @@ +/* + * 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/NR_REFSIG/nr_mod_table.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 "PHY/NR_UE_TRANSPORT/pucch_nr.h" + + +PHY_VARS_gNB *gNB; +PHY_VARS_NR_UE *UE; +RAN_CONTEXT_t RC; +openair0_config_t openair0_cfg[MAX_CARDS]; + +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_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn) {return(0);} +int32_t get_uldl_offset(int nr_bandP) {return(0);} + +NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);} + +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); +} + +// needed for some functions +PHY_VARS_NR_UE * PHY_vars_UE_g[1][1]={{NULL}}; + +int main(int argc, char **argv) +{ + + char c; + + int i,aa;//,l; + double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0; + double cfo=0; + uint8_t snr1set=0; + int **txdata; + double **s_re,**s_im,**r_re,**r_im; + // 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=0; + uint8_t transmission_mode = 1,n_tx=1,n_rx=1; + uint16_t Nid_cell=0; + uint64_t SSB_positions=0x01; + + channel_desc_t *gNB2UE; + + uint8_t extended_prefix_flag=0; + int8_t interf1=-21,interf2=-21; + + FILE *input_fd=NULL,*pbch_file_fd=NULL; + + //uint32_t nsymb,tx_lev,tx_lev1 = 0,tx_lev2 = 0; + //char input_val_str[50],input_val_str2[50]; + //uint8_t frame_mod4,num_pdcch_symbols = 0; + //double pbch_sinr; + //int pbch_tx_ant; + + SCM_t channel_model=AWGN;//Rayleigh1_anticorr; + + + int N_RB_DL=273,mu=1; + + unsigned char frame_type = 0; + unsigned char pbch_phase = 0; + + int frame=0,subframe=0; + 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; + + int loglvl=OAILOG_WARNING; + + 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:o: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 'o': + cfo = atof(optarg); + msg("Setting CFO to %f Hz\n",cfo); + 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 '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("-o Carrier frequency offset in Hz\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; + frame_parms->Nid_cell = Nid_cell; + + nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); + phy_init_nr_gNB(gNB,0,0); + + double fs,bw,scs,eps; + + if (mu == 1 && N_RB_DL == 217) { + fs = 122.88e6; + bw = 80e6; + scs = 30000; + } + else if (mu == 1 && N_RB_DL == 245) { + fs = 122.88e6; + bw = 90e6; + scs = 30000; + } + else if (mu == 1 && N_RB_DL == 273) { + fs = 122.88e6; + bw = 100e6; + scs = 30000; + } + else if (mu == 1 && N_RB_DL == 106) { + fs = 61.44e6; + bw = 40e6; + scs = 30000; + } + else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); + + // cfo with respect to sub-carrier spacing + eps = cfo/scs; + + // computation of integer and fractional FO to compare with estimation results + int IFO; + if(eps!=0.0){ + printf("Introducing a CFO of %lf relative to SCS of %d kHz\n",eps,(int)(scs/1000)); + if (eps>0) + IFO=(int)(eps+0.5); + else + IFO=(int)(eps-0.5); + printf("FFO = %lf; IFO = %d\n",eps-IFO,IFO); + } + + 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)); + memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); + //phy_init_nr_top(UE); //called from init_nr_ue_signal + + UE->perfect_ce = 0; + + if(eps!=0.0) + UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation + + if (init_nr_ue_signal(UE, 1, 0) != 0) + { + printf("Error at UE NR initialisation\n"); + exit(-1); + } + int16_t amp=0x1FFF; + int nr_tti_tx=0; //According to standards it is Slot number within a frame for subcarrier spacing configuration μ but not sure why he made the variable name so 4.3.2,38.211 + nr_gold_pbch(UE); + // generate signal +// pucch_config_common_nr should assign values for this if not done before structure in ue being used by functions + uint8_t actual_payload=0,payload_received;//payload bits b7b6...b2b1b0 where b7..b3=0 b2b1=HARQ b0 is SR. payload maximum value is 7 + uint8_t mcs; + int nr_bit=1; // maximum value possible is 2 +/*if(nr_bit==1){ + mcs=table1_mcs[actual_payload]; + } + else{ + mcs=table2_mcs[actual_payload]; + }*/ + uint8_t m0=0;// higher layer paramater initial cyclic shift + uint8_t nrofSymbols=1; //number of OFDM symbols can be 1-2 for format 1 + uint8_t startingSymbolIndex=0; // resource allocated see 9.2.1, 38.213 for more info.should be actually present in the resource set provided + uint16_t startingPRB=5; //PRB number not sure see 9.2.1, 38.213 for more info. Should be actually present in the resource set provided + pucch_GroupHopping_t PUCCH_GroupHopping=UE->pucch_config_common_nr->pucch_GroupHopping; + uint32_t n_id=UE->pucch_config_common_nr->hoppingId; + printf("\nsnr1=%f\n",snr1); + for(SNR=snr0;SNR<=snr1;SNR=SNR+1){ + n_errors = 0; + sigma2_dB = 20*log10((double)amp/32767)-SNR; + sigma2 = pow(10,sigma2_dB/10); + printf("entering SNR value %f\n",SNR); + for (trial=0; trialpucch_config_dedicated,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB); + + for (i=0; i1) + r_re[0][i]=1; + if(r_im[0][i]<-1) + r_im[0][i]=-1; + else if(r_im[0][i]>1) + r_im[0][0]=1; + ((int16_t *)txdata[0])[(i<<1)] = (int16_t)round(r_re[0][i]*32767); + ((int16_t *)txdata[0])[(i<<1)+1] =(int16_t)round(r_im[0][i]*32767); + + } + nr_decode_pucch0(txdata,PUCCH_GroupHopping,n_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,nr_bit); + n_errors=((actual_payload^payload_received)&1)+(((actual_payload^payload_received)&2)>>1)+(((actual_payload^payload_received)&4)>>2)+n_errors; + //printf("actual_payload=%x,payload_received=%x",actual_payload,payload_received); + } + printf("SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,n_errors); + } + 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/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index 9fb7066bde818150bac91494a781e584bfa2e9f8..8e67e96f616baf38f0bf53d03575342708ced96c 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -89,6 +89,8 @@ # define MAX_gNB 2 #endif +#define NUMBER_OF_NR_DLSCH_MAX 16 +#define NUMBER_OF_NR_ULSCH_MAX 16 #define MAX_MANAGED_ENB_PER_MOBILE 2 #define MAX_MANAGED_GNB_PER_MOBILE 2 diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 2675e4454c8d549a6a6bcf38da84f6f2bf88f518..c595ea1d990866901db2e72613c211812c8b3f19 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -60,7 +60,6 @@ #include "RRC_config_tools.h" #include "enb_paramdef.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); @@ -263,7 +262,6 @@ void RCconfig_L1(void) { } if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) { - sf_ahead = 4; // Need 4 subframe gap between RX and TX } else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { RC.eNB[j][0]->eth_params_n.local_if_name = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); RC.eNB[j][0]->eth_params_n.my_addr = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); @@ -273,7 +271,6 @@ void RCconfig_L1(void) { RC.eNB[j][0]->eth_params_n.my_portd = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr); RC.eNB[j][0]->eth_params_n.remote_portd = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); RC.eNB[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 RC.nb_macrlc_inst = 1; // This is used by mac_top_init_eNB() // This is used by init_eNB_afterRU() RC.nb_CC = (int *)malloc((1+RC.nb_inst)*sizeof(int)); @@ -359,7 +356,6 @@ void RCconfig_macrlc() { RC.mac[j]->eth_params_s.my_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTD_IDX].iptr); RC.mac[j]->eth_params_s.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); RC.mac[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 printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); configure_nfapi_vnf(RC.mac[j]->eth_params_s.my_addr, RC.mac[j]->eth_params_s.my_portc); printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 6954b9507d171326d08ead63a856592de5c9a347..81e59a7dd2c32ff760af8e39025370ad44397cff 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -83,9 +83,9 @@ void config_common(int Mod_idP, int cellid, int nr_bandP, uint64_t ssb_pattern, + uint16_t ssb_periodicity, uint64_t dl_CarrierFreqP, - uint32_t dl_BandwidthP - ){ + uint32_t dl_BandwidthP){ nfapi_nr_config_request_t *cfg = &RC.nrmac[Mod_idP]->config[CC_idP]; @@ -93,6 +93,7 @@ void config_common(int Mod_idP, cfg->sch_config.physical_cell_id.value = cellid; cfg->sch_config.ssb_scg_position_in_burst.value = ssb_pattern; + cfg->sch_config.ssb_periodicity.value = ssb_periodicity; // FDD cfg->subframe_config.duplex_mode.value = 1; @@ -137,6 +138,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, int p_gNB, int nr_bandP, uint64_t ssb_pattern, + uint16_t ssb_enum_periodicity, uint64_t dl_CarrierFreqP, int dl_BandwidthP, NR_BCCH_BCH_Message_t *mib, @@ -144,6 +146,30 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, ){ + uint16_t ssb_periodicity; + + switch (ssb_enum_periodicity) { + case 0: + ssb_periodicity = 5; + break; + case 1: + ssb_periodicity = 10; + break; + case 2: + ssb_periodicity = 20; + break; + case 3: + ssb_periodicity = 40; + break; + case 4: + ssb_periodicity = 80; + break; + case 5: + ssb_periodicity = 160; + break; + + } + if( mib != NULL ){ config_nr_mib(Mod_idP, CC_idP, @@ -168,6 +194,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, cellid, nr_bandP, ssb_pattern, + ssb_periodicity, dl_CarrierFreqP, dl_BandwidthP ); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index ce18158f186dd59c186b0c9d7ad89de37965531e..b6b0a41924187bd0959e2348fd685dbcc9b7589a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -45,7 +45,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, uint8_t CC_id; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; - //NR_COMMON_channels_t *cc = nr_mac->common_channels; + NR_COMMON_channels_t *cc = nr_mac->common_channels; nfapi_nr_dl_config_request_body_t *dl_req; nfapi_nr_dl_config_request_pdu_t *dl_config_dci_pdu; nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu; @@ -61,7 +61,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, int scs = get_dlscs(cfg); int slots_per_frame = get_spf(cfg); for (CC_id=0; CC_idDL_req[CC_id].dl_config_request_body; @@ -115,7 +115,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, pdu_rel15->pucch_resource_indicator = 7; pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7; - LOG_I(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", + LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", pdu_rel15->frequency_domain_assignment, pdu_rel15->time_domain_assignment, pdu_rel15->vrb_to_prb_mapping, @@ -145,7 +145,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, params_rel15->sfn_mod2, params_rel15->first_slot); nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg); - LOG_I(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d\n", + LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d\n", dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, dlsch_pdu_rel15->start_symbol, @@ -163,20 +163,12 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, TX_req->pdu_index = nr_mac->pdu_index[CC_id]++; TX_req->num_segments = 1; TX_req->segments[0].segment_length = 8; + TX_req->segments[0].segment_data = &cc[CC_id].RAR_pdu.payload[0]; nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus+1]; - TX_req->pdu_length = dlsch_pdu_rel15->transport_block_size; - TX_req->pdu_index = nr_mac->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = 8; - nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; - nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; - nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; } } @@ -206,7 +198,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, //int scs = get_dlscs(cfg); //int slots_per_frame = get_spf(cfg); for (CC_id=0; CC_idcoreset[CC_id][1]; nfapi_nr_search_space_t* search_space = &nr_mac->search_space[CC_id][1]; @@ -259,7 +251,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, pdu_rel15->pucch_resource_indicator = 7; pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7; - LOG_I(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", + LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", pdu_rel15->frequency_domain_assignment, pdu_rel15->time_domain_assignment, pdu_rel15->vrb_to_prb_mapping, @@ -273,7 +265,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, params_rel15->dci_format = NFAPI_NR_DL_DCI_FORMAT_1_0; //params_rel15->aggregation_level = 1; - LOG_I(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d, config type %d\n \ + LOG_D(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d, config type %d\n \ coreset params: mux_pattern %d, n_rb %d, n_symb %d, rb_offset %d \n \ ss params : first symb %d, ss type %d\n", params_rel15->rnti, @@ -287,7 +279,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, params_rel15->first_symbol, params_rel15->search_space_type); nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg); - LOG_I(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d\n", + LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d\n", dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, dlsch_pdu_rel15->start_symbol, @@ -301,20 +293,12 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, dl_req->number_pdu+=2; TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = 6; - TX_req->pdu_index = nr_mac->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = 8; - nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; - nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; - nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - - TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus+1]; TX_req->pdu_length = dlsch_pdu_rel15->transport_block_size; TX_req->pdu_index = nr_mac->pdu_index[CC_id]++; TX_req->num_segments = 1; - TX_req->segments[0].segment_length = 8; + TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0]; + + TX_req->segments[0].segment_length = dlsch_pdu_rel15->transport_block_size+2; nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 9e70ae7025ac90c8ebab85a0cf692d16829da3ae..4f5e3b593801a8eb641e0906f895341afa9f85a7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -38,18 +38,20 @@ void mac_top_init_gNB(void); void config_common(int Mod_idP, int CC_idP, - int Nid_cell, + int Nid_cell, int nr_bandP, - uint64_t ssb_pattern, + uint64_t ssb_pattern, + uint16_t ssb_periodicity, uint64_t dl_CarrierFreqP, uint32_t dl_BandwidthP); int rrc_mac_config_req_gNB(module_id_t Mod_idP, int CC_id, - int cellid, + int cellid, int p_gNB, int nr_bandP, uint64_t ssb_pattern, + uint16_t ssb_periodicity, uint64_t dl_CarrierFreqP, int dl_BandwidthP, NR_BCCH_BCH_Message_t *mib, diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 92409d96dcfc4f0eb877a33af061f87480a0440a..c7b500007d59dadffde995eed4bef71705837a4f 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -1181,7 +1181,7 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) ctxt_pP->subframe, ctxt_pP->module_id); - for (dst_id = 0; dst_id>4)&0x3f); #ifdef DEBUG_RRC - LOG_I(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); + LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); #endif gNB_RRC_INST *rrc; @@ -76,11 +76,11 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP, (void *)mib, carrier->MIB, 24); - LOG_I(NR_RRC,"Encoded MIB for frame %d sfn_msb %d (%p), bits %lu\n",frameP,sfn_msb,carrier->MIB,enc_rval.encoded); + LOG_D(NR_RRC,"Encoded MIB for frame %d sfn_msb %d (%p), bits %lu\n",frameP,sfn_msb,carrier->MIB,enc_rval.encoded); buffer_pP[0]=carrier->MIB[0]; buffer_pP[1]=carrier->MIB[1]; buffer_pP[2]=carrier->MIB[2]; - LOG_I(NR_RRC,"MIB PDU buffer_pP[0]=%x , buffer_pP[1]=%x, buffer_pP[2]=%x\n",buffer_pP[0],buffer_pP[1],buffer_pP[2]); + LOG_D(NR_RRC,"MIB PDU buffer_pP[0]=%x , buffer_pP[1]=%x, buffer_pP[2]=%x\n",buffer_pP[0],buffer_pP[1],buffer_pP[2]); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); return(3); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 749320b3572662a1c4cb7754b7046f4010211603..2b2e48bc9105fe1c623171e98106fe0dbf772aaf 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -258,7 +258,6 @@ static void init_NR_SI(const protocol_ctxt_t* const ctxt_pP, ); LOG_I(NR_RRC,"Done init_NR_SI\n"); - rrc_mac_config_req_gNB(ctxt_pP->module_id, CC_id, @@ -266,6 +265,7 @@ static void init_NR_SI(const protocol_ctxt_t* const ctxt_pP, RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].p_gNB, configuration->nr_band[CC_id], configuration->ServingCellConfigCommon_ssb_PositionsInBurst_PR[CC_id], + configuration->ServingCellConfigCommon_ssb_periodicityServingCell[CC_id], RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq, configuration->N_RB_DL[CC_id], (NR_BCCH_BCH_Message_t *)&RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].mib, diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 890561f385995140ade691d2dc8e9151421b23bb..a698ab872bb925402e81a8976c9ace1dd028a715 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -98,6 +98,7 @@ typedef struct { int64_t rx_count; int wait_for_first_pps; int use_gps; + int first_tx; //! timestamp of RX packet openair0_timestamp rx_timestamp; @@ -323,10 +324,10 @@ static int trx_usrp_start(openair0_device *device) { cmd.stream_now = false; // start at constant delay s->rx_stream->issue_stream_cmd(cmd); - s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); + /*s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); s->tx_md.has_time_spec = true; s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false; + s->tx_md.end_of_burst = false;*/ s->rx_count = 0; s->tx_count = 0; s->rx_timestamp = 0; @@ -435,6 +436,7 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, if (u_sf_mode != 2) { // not replay mode #endif usrp_state_t *s = (usrp_state_t *)device->priv; + int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ @@ -464,47 +466,54 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, } } - s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); - s->tx_md.has_time_spec = flags; - - if(flags>0) - s->tx_md.has_time_spec = true; - else - s->tx_md.has_time_spec = false; + boolean_t first_packet_state=false,last_packet_state=false; if (flags == 2) { // start of burst - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false; + // s->tx_md.start_of_burst = true; + // s->tx_md.end_of_burst = false; + first_packet_state = true; + last_packet_state = false; } else if (flags == 3) { // end of burst - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = true; + //s->tx_md.start_of_burst = false; + //s->tx_md.end_of_burst = true; + first_packet_state = false; + last_packet_state - true; } else if (flags == 4) { // start and end - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = true; + // s->tx_md.start_of_burst = true; + // s->tx_md.end_of_burst = true; + first_packet_state = true; + last_packet_state = true; } else if (flags==1) { // middle of burst - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = false; + // s->tx_md.start_of_burst = false; + // s->tx_md.end_of_burst = false; + first_packet_state = false; + last_packet_state = false; } - - if(flags==10) { // fail safe mode - s->tx_md.has_time_spec = false; - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = true; + else if (flags==10) { // fail safe mode + // s->tx_md.has_time_spec = false; + // s->tx_md.start_of_burst = false; + // s->tx_md.end_of_burst = true; + first_packet_state=false; + last_packet_state=true; } + s->tx_md.has_time_spec = true; + s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet_state; + s->tx_md.end_of_burst = last_packet_state; + s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); - if (cc>1) { - std::vector buff_ptrs; + s->tx_count++; - for (int i=0; i1) { + std::vector buff_ptrs; - ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); - } else - ret = (int)s->tx_stream->send(buff_tx[0], nsamps, s->tx_md,1e-3); + for (int i=0; itx_stream->send(buff_ptrs, nsamps, s->tx_md); + } else ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md); + if (ret != nsamps) LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps); + #if defined(USRP_REC_PLAY) } else { struct timespec req; @@ -1087,7 +1096,7 @@ extern "C" { device->type = USRP_B200_DEV; usrp_master_clock = 30.72e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); - args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; + args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=7680, recv_frame_size=7680" ; } if (device_adds[0].get("type") == "n3xx") { @@ -1095,6 +1104,7 @@ extern "C" { device->type=USRP_X300_DEV; //treat it as X300 for now usrp_master_clock = 122.88e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); + //args += ", send_buff_size=33554432"; } if (device_adds[0].get("type") == "x300") { @@ -1115,6 +1125,7 @@ extern "C" { else s->usrp->set_clock_source("external"); + if (device->type==USRP_X300_DEV) { openair0_cfg[0].rx_gain_calib_table = calib_table_x310; #if defined(USRP_REC_PLAY) @@ -1335,6 +1346,7 @@ extern "C" { LOG_I(PHY," Actual TX gain: %f...\n", s->usrp->get_tx_gain(i)); LOG_I(PHY," Actual TX bandwidth: %fM...\n", s->usrp->get_tx_bandwidth(i)/1e6); LOG_I(PHY," Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str()); + LOG_I(PHY," Actual TX packet size: %lu\n",s->tx_stream->get_max_num_samps()); } LOG_I(PHY,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 099e1c190aa42996bf696ffad4575a2060d19735..b1a6644e5ede48722718c3e9f3ae46ab7ae49b95 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -3,6 +3,12 @@ copyleft: OpenAirInterface Software Alliance and it's licence */ +/* + * Open issues and limitations + * The read and write should be called in the same thread, that is not new USRP UHD design + * When the opposite side switch from passive reading to active R+Write, the synchro is not fully deterministic + */ + #include #include #include @@ -28,7 +34,7 @@ #define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t)) #define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b))) -#define sample_t uint32_t // 2*16 bits complex number +#define sample_t uint32_t //2*16 bits complex number typedef struct buffer_s { int conn_sock; @@ -111,7 +117,7 @@ void setblocking(int sock, enum blocking_t active) { AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, ""); } -static bool flushInput(rfsimulator_state_t *t); +static bool flushInput(rfsimulator_state_t *t, int timeout); void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { if (t->saveIQfile != -1) { @@ -134,7 +140,9 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { continue; if(errno==EAGAIN) { - flushInput(t); + // The opposite side is saturated + // we read incoming sockets meawhile waiting + flushInput(t, 5); continue; } else return; @@ -229,14 +237,17 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi lastW=timestamp; LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n", nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) ); + // Let's verify we don't have incoming data + // This is mandatory when the opposite side don't transmit + flushInput(t, 0); return nsamps; } -static bool flushInput(rfsimulator_state_t *t) { +static bool flushInput(rfsimulator_state_t *t, int timeout) { // Process all incoming events on sockets // store the data in lists struct epoll_event events[FD_SETSIZE]= {0}; - int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, 20); + int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, timeout); if ( nfds==-1 ) { if ( errno==EINTR || errno==EAGAIN ) @@ -356,7 +367,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo if ( first_sock == FD_SETSIZE ) { // no connected device (we are eNB, no UE is connected) - if (!flushInput(t)) { + if (!flushInput(t, 10)) { for (int x=0; x < nbAnt; x++) memset(samplesVoid[x],0,sampleToByte(nsamps,1)); @@ -385,7 +396,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ptr->lastReceivedTS, t->nextTimestamp+nsamps); */ - flushInput(t); + flushInput(t, 3); } while (have_to_wait); } diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index 9b4ee23dc8bc1e179cfa95616b3703a235d68bec..92e89eb1da998298682ee7fb2b133863cffe99bf 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -6,6 +6,8 @@ # define NUMBER_OF_gNB_MAX 1 # define NUMBER_OF_RU_MAX 2 # define NUMBER_OF_NR_RU_MAX 2 +# define NUMBER_OF_NR_DLSCH_MAX 16 +# define NUMBER_OF_NR_ULSCH_MAX 16 # ifndef PHYSIM # ifndef UE_EXPANSION # define NUMBER_OF_UE_MAX 4 diff --git a/targets/RT/USER/eNB_usrp.gtkw b/targets/RT/USER/eNB_usrp.gtkw index 2f448dc680fe9e3c612e2cc12fd9214cebfb3fe7..074e3b1324a7082b57390d368aa123b341ecfc7d 100644 --- a/targets/RT/USER/eNB_usrp.gtkw +++ b/targets/RT/USER/eNB_usrp.gtkw @@ -1,13 +1,13 @@ [*] [*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI -[*] Mon Oct 29 17:36:13 2018 +[*] Sun May 19 21:39:57 2019 [*] -[dumpfile] "/mnt/hgfs/Documents/Devel/openair_dump_eNB.vcd" -[dumpfile_mtime] "Mon Oct 29 17:34:25 2018" -[dumpfile_size] 4559568 -[savefile] "/home/kaltenbe/Devel/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw" -[timestart] 7635200000 -[size] 1535 780 +[dumpfile] "/tmp/openair_dump_eNB.vcd" +[dumpfile_mtime] "Sun May 19 21:30:25 2019" +[dumpfile_size] 11590554 +[savefile] "/home/sphex/raymond/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw" +[timestart] 7629910000 +[size] 1840 795 [pos] -1 -1 *-21.832302 7639830000 -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 @@ -24,9 +24,11 @@ variables.trx_tst[63:0] functions.eNB_thread_rxtx0 @24 variables.frame_number_RX0_RU[63:0] -variables.subframe_number_RX0_RU[63:0] +@25 +variables.tti_number_RX0_RU[63:0] +@24 variables.frame_number_TX0_RU[63:0] -variables.subframe_number_TX0_RU[63:0] +variables.tti_number_TX0_RU[63:0] @28 functions.mac_schedule_dlsch functions.macxface_eNB_dlsch_ulsch_scheduler @@ -54,9 +56,7 @@ functions.phy_procedures_eNb_rx_uespec1 functions.phy_enb_sfgen functions.phy_procedures_eNb_tx0 functions.phy_procedures_eNb_tx1 -@29 functions.phy_procedures_ru_feprx0 -@28 functions.phy_procedures_ru_feprx1 functions.phy_procedures_ru_feptx_ofdm0 functions.phy_procedures_ru_feptx_ofdm1 diff --git a/targets/RT/USER/gNB_usrp.gtkw b/targets/RT/USER/gNB_usrp.gtkw index b40f946bc19ac1da645896460832fdf6d710f897..069d1765a95358b9f4875addcac6bb9277a712e4 100644 --- a/targets/RT/USER/gNB_usrp.gtkw +++ b/targets/RT/USER/gNB_usrp.gtkw @@ -1,28 +1,34 @@ [*] -[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI -[*] Tue Nov 6 14:54:14 2018 +[*] GTKWave Analyzer v3.3.61 (w)1999-2014 BSI +[*] Sat May 18 17:25:11 2019 [*] -[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 +[dumpfile] "/tmp/openair_dump_gNB40.vcd" +[dumpfile_mtime] "Sat May 18 17:11:31 2019" +[dumpfile_size] 53148516 +[savefile] "/home/caracal/raymond/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw" +[timestart] 11552775390 +[size] 1840 795 +[pos] -1 -1 +*-13.848083 11552814436 -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 +[sst_vpaned_height] 197 @28 functions.trx_read functions.trx_write +@420 +variables.frame_number_TX0_UE[63:0] +variables.frame_number_TX1_UE[63:0] +@28 +functions.ue_gain_control +@420 +variables.frame_number_RX1_UE[63:0] +@25 +variables.trx_ts_ue[63:0] @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.tti_number_RX0_RU[63:0] variables.frame_number_TX0_RU[63:0] @@ -30,8 +36,6 @@ variables.tti_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.slot_number_RX0_gNB[63:0] @@ -46,7 +50,13 @@ variables.frame_number_TX1_gNB[63:0] variables.slot_number_TX1_gNB[63:0] @28 functions.gNB_thread_rxtx1 -functions.phy_procedures_ru_feprx0 +functions.phy_enb_pdcch_tx +functions.phy_eNB_dlsch_encoding +functions.phy_eNB_dlsch_encoding_w +functions.generate_dlsch +@420 +variables.frame_number_RX0_UE[63:0] +@28 functions.phy_procedures_ru_feprx0 functions.phy_procedures_ru_feprx1 functions.phy_procedures_ru_feptx_ofdm0 diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index a35c22f4eb244bcf89c44d9687ba916c8f609005..1531d0ffd8c205fc349349712a61931e3ab737d4 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -309,23 +309,23 @@ int connect_rau(RU_t *ru) { /* Southbound Fronthaul functions, RCC/RAU */ // southbound IF5 fronthaul for 16-bit OAI format -static inline void fh_if5_south_out(RU_t *ru) { +static inline void fh_if5_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); - send_IF5(ru, ru->proc.timestamp_tx, ru->proc.tti_tx, &ru->seqno, IF5_RRH_GW_DL); + send_IF5(ru, timestamp, subframe, &ru->seqno, IF5_RRH_GW_DL); } // southbound IF5 fronthaul for Mobipass packet format -static inline void fh_if5_mobipass_south_out(RU_t *ru) { +static inline void fh_if5_mobipass_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); - send_IF5(ru, ru->proc.timestamp_tx, ru->proc.tti_tx, &ru->seqno, IF5_MOBIPASS); + send_IF5(ru, timestamp, subframe, &ru->seqno, IF5_MOBIPASS); } // southbound IF4p5 fronthaul -static inline void fh_if4p5_south_out(RU_t *ru) { +static inline void fh_if4p5_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx); - if (subframe_select(ru->frame_parms,ru->proc.tti_tx)!=SF_UL) - send_IF4p5(ru,ru->proc.frame_tx, ru->proc.tti_tx, IF4p5_PDLFFT); + if (subframe_select(ru->frame_parms,subframe)!=SF_UL) + send_IF4p5(ru,frame, subframe, IF4p5_PDLFFT); } /*************************************************************/ @@ -646,8 +646,8 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx ); } - if (ru->feptx_ofdm) ru->feptx_ofdm(ru); - if (ru->fh_south_out) ru->fh_south_out(ru); + if (ru->feptx_ofdm) ru->feptx_ofdm(ru,frame_tx,tti_tx); + if (ru->fh_south_out) ru->fh_south_out(ru,frame_tx,tti_tx,proc->timestamp_tx); } void fh_if5_north_out(RU_t *ru) { @@ -841,7 +841,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { } -void tx_rf(RU_t *ru) { +void tx_rf(RU_t *ru,int frame,int subframe,uint64_t timestamp) { RU_proc_t *proc = &ru->proc; LTE_DL_FRAME_PARMS *fp = ru->frame_parms; @@ -849,12 +849,12 @@ void tx_rf(RU_t *ru) { unsigned int txs; int i; - T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(proc->frame_tx), T_INT(proc->tti_tx), - T_INT(0), T_BUFFER(&ru->common.txdata[0][proc->tti_tx * fp->samples_per_tti], fp->samples_per_tti * 4)); + T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(subframe), + T_INT(0), T_BUFFER(&ru->common.txdata[0][subframe * fp->samples_per_tti], fp->samples_per_tti * 4)); - lte_subframe_t SF_type = subframe_select(fp,proc->tti_tx%10); - lte_subframe_t prevSF_type = subframe_select(fp,(proc->tti_tx+9)%10); - lte_subframe_t nextSF_type = subframe_select(fp,(proc->tti_tx+1)%10); + lte_subframe_t SF_type = subframe_select(fp,subframe%10); + lte_subframe_t prevSF_type = subframe_select(fp,(subframe+9)%10); + lte_subframe_t nextSF_type = subframe_select(fp,(subframe+1)%10); int sf_extension = 0; if ((SF_type == SF_DL) || @@ -892,7 +892,7 @@ void tx_rf(RU_t *ru) { #endif for (i=0; inb_tx; i++) - txp[i] = (void*)&ru->common.txdata[i][(proc->tti_tx*fp->samples_per_tti)-sf_extension]; + txp[i] = (void*)&ru->common.txdata[i][(subframe*fp->samples_per_tti)-sf_extension]; /* add fail safe for late command */ if(late_control!=STATE_BURST_NORMAL){//stop burst @@ -925,22 +925,22 @@ void tx_rf(RU_t *ru) { } /* add fail safe for late command end */ - 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_TTI_NUMBER_TX0_RU, proc->tti_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, subframe); - 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_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); // prepare tx buffer pointers txs = ru->rfdevice.trx_write_func(&ru->rfdevice, - proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, + timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, txp, siglen+sf_extension, ru->nb_tx, flags); LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, - (long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->tti_tx); + (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,subframe); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); @@ -1558,13 +1558,13 @@ static void* ru_thread_tx( void* param ) { if (oai_exit) break; // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru); + if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx); // do OFDM if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx); 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_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx); if (ru->fh_north_out) ru->fh_north_out(ru); } @@ -1764,7 +1764,7 @@ static void* ru_thread( void* param ) { // do RX front-end processing (frequency-shift, dft) if needed - if (ru->feprx) ru->feprx(ru); + if (ru->feprx) ru->feprx(ru,proc->tti_rx); // At this point, all information for subframe has been received on FH interface // If this proc is to provide synchronization, do so @@ -1804,13 +1804,13 @@ static void* ru_thread( void* param ) { #ifndef PHY_TX_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); + if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx); // do OFDM if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx); 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_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx); if (ru->fh_north_out) ru->fh_north_out(ru); } @@ -2074,10 +2074,10 @@ static void* rf_tx( void* param ) { // 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 ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx); 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_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx); if (ru->fh_north_out) ru->fh_north_out(ru); } @@ -2112,13 +2112,13 @@ int stop_rf(RU_t *ru) return 0; } -extern void fep_full(RU_t *ru); -extern void ru_fep_full_2thread(RU_t *ru); -extern void feptx_ofdm(RU_t *ru); -extern void feptx_ofdm_2thread(RU_t *ru); -extern void feptx_prec(RU_t *ru); -extern void init_fep_thread(RU_t *ru,pthread_attr_t *attr); -extern void init_feptx_thread(RU_t *ru,pthread_attr_t *attr); +extern void fep_full(RU_t *ru,int subframe); +extern void ru_fep_full_2thread(RU_t *ru,int subframe); +extern void feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); +extern void feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx); +extern void feptx_prec(RU_t *ru,int frame_tx,int tti_tx); +extern void init_fep_thread(RU_t *ru); +extern void init_feptx_thread(RU_t *ru); extern void kill_fep_thread(RU_t *ru); extern void kill_feptx_thread(RU_t *ru); @@ -2256,8 +2256,8 @@ void init_RU_proc(RU_t *ru) { } if (get_thread_worker_conf() == WORKER_ENABLE) { - init_fep_thread(ru,NULL); - init_feptx_thread(ru,NULL); + init_fep_thread(ru); + init_feptx_thread(ru); } if (opp_enabled == 1) pthread_create(&ru->ru_stats_thread,NULL,ru_stats_thread,(void*)ru); diff --git a/targets/RT/USER/nr-gnb.c b/targets/RT/USER/nr-gnb.c index 5d8c98d64512124d13ee70cc9aef9e9436fa76f7..77d4dea5e7f6a6b734205c40c75e6320aad9c4f3 100644 --- a/targets/RT/USER/nr-gnb.c +++ b/targets/RT/USER/nr-gnb.c @@ -1,4 +1,4 @@ -/* +/*/* * 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. @@ -143,8 +143,8 @@ 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); +int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx); +int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx); extern PARALLEL_CONF_t get_thread_parallel_conf(void); extern WORKER_CONF_t get_thread_worker_conf(void); @@ -159,7 +159,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_L1_rxtx_proc_t *proc, char *thread_name) { +static inline int rxtx(PHY_VARS_gNB *gNB,int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) { start_meas(&softmodem_stats_rxtx_sf); // ******************************************************************* @@ -167,15 +167,11 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_ if (nfapi_mode == 1) { // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick - uint16_t frame = proc->frame_rx; - uint16_t slot = proc->slot_rx; //add_subframe(&frame, &subframe, 4); - //oai_subframe_ind(proc->frame_tx, proc->subframe_tx); - //LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe); start_meas(&nfapi_meas); - oai_subframe_ind(frame, slot); + oai_subframe_ind(frame_rx, slot_rx); stop_meas(&nfapi_meas); if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus|| @@ -184,14 +180,13 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_ gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles || gNB->UL_INFO.cqi_ind.number_of_cqis ) { - LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d \n", + LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d \n", NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs, NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles, gNB->UL_INFO.cqi_ind.number_of_cqis, - proc->frame_rx, proc->slot_rx, - proc->frame_tx, proc->slot_tx); + frame_rx, slot_rx); } } @@ -200,22 +195,22 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_ // **************************************** // Common RX procedures subframe n - T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->slot_tx)); + T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx)); /* // if this is IF5 or 3GPP_gNB if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) { - wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx); + wakeup_prach_gNB(gNB,NULL,frame_rx,slot_rx); } // UE-specific RX processing for subframe n if (nfapi_mode == 0 || nfapi_mode == 1) { - phy_procedures_gNB_uespec_RX(gNB, proc, no_relay ); + phy_procedures_gNB_uespec_RX(gNB, frame_rx,slot_rx, no_relay ); } */ pthread_mutex_lock(&gNB->UL_INFO_mutex); - gNB->UL_INFO.frame = proc->frame_rx; - gNB->UL_INFO.slot = proc->slot_rx; + gNB->UL_INFO.frame = frame_rx; + gNB->UL_INFO.slot = slot_rx; gNB->UL_INFO.module_id = gNB->Mod_id; gNB->UL_INFO.CC_id = gNB->CC_id; @@ -232,77 +227,40 @@ 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); - if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD){ - phy_procedures_gNB_TX(gNB, proc, 1); - } + if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); stop_meas( &softmodem_stats_rxtx_sf ); - LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->slot_rx, proc->frame_tx, proc->slot_tx); - -#if 0 - LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ", - softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now, - TICK_TO_US(gNB->phy_proc), - TICK_TO_US(gNB->phy_proc_tx), - TICK_TO_US(gNB->phy_proc_rx), - TICK_TO_US(gNB->rx_prach), - TICK_TO_US(gNB->ofdm_mod_stats), - softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now); - LOG_D(PHY, - "dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ", - TICK_TO_US(gNB->dlsch_encoding_stats), - TICK_TO_US(gNB->dlsch_modulation_stats), - TICK_TO_US(gNB->dlsch_scrambling_stats), - TICK_TO_US(gNB->dlsch_rate_matching_stats), - TICK_TO_US(gNB->dlsch_turbo_encoding_stats), - TICK_TO_US(gNB->dlsch_interleaving_stats), - TICK_TO_US(gNB->rx_dft_stats)); - - LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ", - TICK_TO_US(gNB->ulsch_channel_estimation_stats), - TICK_TO_US(gNB->ulsch_freq_offset_estimation_stats), - TICK_TO_US(gNB->ulsch_decoding_stats), - TICK_TO_US(gNB->ulsch_demodulation_stats), - TICK_TO_US(gNB->ulsch_rate_unmatching_stats)); - - LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ", - TICK_TO_US(gNB->ulsch_turbo_decoding_stats), - TICK_TO_US(gNB->ulsch_deinterleaving_stats), - TICK_TO_US(gNB->ulsch_demultiplexing_stats), - TICK_TO_US(gNB->ulsch_llr_stats), - TICK_TO_US(gNB->ulsch_tc_init_stats)); - LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n", - TICK_TO_US(gNB->ulsch_tc_alpha_stats), - TICK_TO_US(gNB->ulsch_tc_beta_stats), - TICK_TO_US(gNB->ulsch_tc_gamma_stats), - TICK_TO_US(gNB->ulsch_tc_ext_stats), - TICK_TO_US(gNB->ulsch_tc_intl1_stats), - TICK_TO_US(gNB->ulsch_tc_intl2_stats) - ); -#endif + LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx); + return(0); } static void* gNB_L1_thread_tx(void* 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 = (PHY_VARS_gNB*)param; + gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx; 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"); - + + // This tells L1_thread (RX) that L1_thread_tx is not ready yet + pthread_mutex_lock(&L1_proc_tx->mutex); + L1_proc_tx->instance_cnt = -2; + pthread_mutex_unlock(&L1_proc_tx->mutex); + + sprintf(thread_name,"gNB_L1_thread_tx\n"); + + thread_top_init(thread_name,1,870000L,1000000L,1000000L); + + pthread_mutex_lock(&L1_proc_tx->mutex); + L1_proc_tx->instance_cnt++; + pthread_mutex_unlock(&L1_proc_tx->mutex); + 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; + if (wait_on_condition(&L1_proc_tx->mutex,&L1_proc_tx->cond,&L1_proc_tx->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; // ***************************************** @@ -310,23 +268,25 @@ static void* gNB_L1_thread_tx(void* param) { // 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) // ***************************************** - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,proc->slot_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB,proc->slot_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); + int frame_tx = L1_proc_tx->frame_tx; + int slot_tx = L1_proc_tx->slot_tx; + uint64_t timestamp_tx = L1_proc_tx->timestamp_tx; + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx); - phy_procedures_gNB_TX(gNB, proc, 1); + phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); - pthread_mutex_lock( &proc->mutex ); - proc->instance_cnt = -1; + pthread_mutex_lock( &L1_proc_tx->mutex ); + L1_proc_tx->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"); + if (pthread_cond_signal(&L1_proc_tx->cond) != 0) { + LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for L1_threa_tx\n"); exit_fun( "ERROR pthread_cond_signal" ); } - pthread_mutex_unlock( &proc->mutex ); - wakeup_txfh(proc,gNB); + pthread_mutex_unlock( &L1_proc_tx->mutex ); + wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 ); } return 0; @@ -343,49 +303,58 @@ static void* gNB_L1_thread( void* param ) { static int gNB_thread_rxtx_status; 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]; + gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc; char thread_name[100]; - + // This tells ru_thread that L1_thread is not ready + pthread_mutex_lock(&L1_proc->mutex); + L1_proc->instance_cnt = -2; + pthread_mutex_unlock(&L1_proc->mutex); // 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); + sprintf(thread_name,"gNB_L1_thread"); + + thread_top_init(thread_name,1,870000L,1000000L,1000000L); + + // This tells ru_thread that L1_thread is ready + pthread_mutex_lock(&L1_proc->mutex); + L1_proc->instance_cnt++; + pthread_mutex_unlock(&L1_proc->mutex); 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; + if (wait_on_condition(&L1_proc->mutex,&L1_proc->cond,&L1_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_SLOT_NUMBER_TX0_GNB,proc->slot_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,proc->slot_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); + int frame_rx = L1_proc->frame_rx; + int slot_rx = L1_proc->slot_rx; + int frame_tx = L1_proc->frame_tx; + int slot_tx = L1_proc->slot_tx; + uint64_t timestamp_tx = L1_proc->timestamp_tx; + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,slot_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,slot_rx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,frame_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,frame_rx); if (oai_exit) break; if (gNB->CC_id==0) { - if (rxtx(gNB,proc,thread_name) < 0) break; + if (rxtx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,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); - } + if (release_thread(&L1_proc->mutex,&L1_proc->instance_cnt,thread_name)<0) break; + + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,timestamp_tx); + else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(gNB,L1_proc,frame_tx,slot_tx,timestamp_tx); + } // while !oai_exit @@ -439,72 +408,83 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame; - 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); + if (rxtx(gNB,L1_proc->frame_rx,L1_proc->slot_rx,L1_proc->frame_tx,L1_proc->slot_tx,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->tti_tx = L1_proc->slot_tx; ru_proc->frame_tx = L1_proc->frame_tx; } } -int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB) { +int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx) { RU_t *ru; RU_proc_t *ru_proc; - + int waitret; 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->slot_tx, proc->instance_cnt_RUs); + wait.tv_nsec=10000000L; + - 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->slot_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); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); +// note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time + waitret=timedwait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh",500000); + + if (waitret == ETIMEDOUT) { + LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 2 slot times (1000us)\n",frame_tx,slot_tx); + + pthread_mutex_lock(&gNB->proc.mutex_RU_tx); + gNB->proc.RU_mask_tx = 0; + pthread_mutex_unlock(&gNB->proc.mutex_RU_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0); + + return(-1); + } + else if (release_thread(&proc->mutex_RUs_tx,&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->tti_tx, proc->frame_rx, proc->slot_rx); + pthread_mutex_lock(&gNB->proc.mutex_RU_tx); + gNB->proc.RU_mask_tx = 0; + pthread_mutex_unlock(&gNB->proc.mutex_RU_tx); 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->tti_rx&1,ru_proc->instance_cnt_gNBs ); - exit_fun( "error locking mutex_gNB" ); + if ((waitret = pthread_mutex_timedlock(&ru_proc->mutex_gNBs,&wait)) == ETIMEDOUT) { + LOG_W( PHY, "[eNB] ERROR pthread_mutex_lock timed out on mutex_gNBs L1_thread_tx (timeout)\n"); return(-1); } + else AssertFatal(waitret==0,"pthread_mutex_timedlock returned %d\n",waitret); ru_proc->instance_cnt_gNBs = 0; - ru_proc->timestamp_tx = proc->timestamp_tx; - ru_proc->tti_tx = proc->slot_tx; - ru_proc->frame_tx = proc->frame_tx; + ru_proc->timestamp_tx = timestamp_tx; + ru_proc->tti_tx = slot_tx; + ru_proc->frame_tx = frame_tx; - LOG_I(PHY,"Signaling tx_thread_fh for %d.%d\n",ru_proc->frame_tx,ru_proc->tti_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, ru_proc->instance_cnt_gNBs); + pthread_mutex_unlock( &ru_proc->mutex_gNBs ); + + LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_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) { +int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx) { - 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; + gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx; struct timespec wait; @@ -517,6 +497,11 @@ int wakeup_tx(PHY_VARS_gNB *gNB) { exit_fun("ERROR pthread_lock"); return(-1); } + if (L1_proc_tx->instance_cnt == -2) { // L1_thread_tx isn't ready yet so return + pthread_mutex_unlock( &L1_proc_tx->mutex); + return(0); + } + while(L1_proc_tx->instance_cnt == 0){ pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex); } @@ -524,12 +509,17 @@ int wakeup_tx(PHY_VARS_gNB *gNB) { L1_proc_tx->instance_cnt = 0; - L1_proc_tx->slot_rx = L1_proc->slot_rx; - L1_proc_tx->frame_rx = L1_proc->frame_rx; - L1_proc_tx->slot_tx = L1_proc->slot_tx; - L1_proc_tx->frame_tx = L1_proc->frame_tx; - L1_proc_tx->timestamp_tx = L1_proc->timestamp_tx; - + L1_proc_tx->slot_rx = slot_rx; + L1_proc_tx->frame_rx = frame_rx; + L1_proc_tx->slot_tx = slot_tx; + L1_proc_tx->frame_tx = frame_tx; + L1_proc_tx->timestamp_tx = timestamp_tx; + + pthread_mutex_unlock( &L1_proc_tx->mutex); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0); + // 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"); @@ -537,7 +527,6 @@ int wakeup_tx(PHY_VARS_gNB *gNB) { return(-1); } - pthread_mutex_unlock( &L1_proc_tx->mutex); return(0); } @@ -575,24 +564,24 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { wait.tv_sec=0; wait.tv_nsec=5000000L; - /* accept some delay in processing - up to 5ms */ - for (i = 0; i < fp->slots_per_frame && L1_proc->instance_cnt == 0; i++) { - LOG_W( PHY,"[gNB] SFN.SL %d.%d, gNB RXn-TXnp4 thread busy!! (i %d, cnt %i)\n", L1_proc->frame_tx, L1_proc->slot_tx, i,L1_proc->instance_cnt); - usleep(100); - } - if (L1_proc->instance_cnt == 0) { - exit_fun( "TX thread busy" ); - return(-1); - } - // wake up TX for subframe n+sl_ahead // lock the TX mutex and make sure the thread is ready 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->slot_rx&1,L1_proc->instance_cnt ); + LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB L1 thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt ); exit_fun( "error locking mutex" ); return(-1); } - + + if (L1_proc->instance_cnt==-2) { // L1_thread isn't ready yet so return + pthread_mutex_unlock( &L1_proc->mutex ); + return(0); + } + + if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe + pthread_mutex_unlock( &L1_proc->mutex ); + LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx); + } + ++L1_proc->instance_cnt; // We have just received and processed the common part of a subframe, say n. @@ -607,7 +596,9 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame; - LOG_I(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sl_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sl_ahead); + LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sl_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sl_ahead); + + pthread_mutex_unlock( &L1_proc->mutex ); // the thread can now be woken up if (pthread_cond_signal(&L1_proc->cond) != 0) { @@ -616,8 +607,6 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { return(-1); } - pthread_mutex_unlock( &L1_proc->mutex ); - return(0); } /* @@ -747,8 +736,8 @@ void init_gNB_proc(int inst) { 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 = -2; + L1_proc_tx->instance_cnt = -2; L1_proc->instance_cnt_RUs = 0; L1_proc_tx->instance_cnt_RUs = 0; proc->instance_cnt_prach = -1; @@ -928,7 +917,7 @@ void init_eNB_afterRU(void) { //LOG_I(PHY,"Overwriting gNB->prach_vars.rxsigF[0]:%p\n", gNB->prach_vars.rxsigF[0]); - gNB->prach_vars.rxsigF[0] = (int16_t**)malloc16(64*sizeof(int16_t*)); + //gNB->prach_vars.rxsigF[0] = (int16_t**)malloc16(64*sizeof(int16_t*)); LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU); @@ -944,7 +933,7 @@ void init_eNB_afterRU(void) { for (i=0;iRU_list[ru_id]->nb_rx;aa++,i++) { LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa); - gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i]; +// gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i]; gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i]; } } diff --git a/targets/RT/USER/nr-ru.c b/targets/RT/USER/nr-ru.c index c0598b9144d188bce1fd9ba3d7ab1029c1227204..bad5adf9e67de84afd8e86e0dae1890ea13e8cfd 100644 --- a/targets/RT/USER/nr-ru.c +++ b/targets/RT/USER/nr-ru.c @@ -580,8 +580,8 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot_tx ); } - if (ru->feptx_ofdm) ru->feptx_ofdm(ru); - if (ru->fh_south_out) ru->fh_south_out(ru); + if (ru->feptx_ofdm) ru->feptx_ofdm(ru,frame_tx,slot_tx); + if (ru->fh_south_out) ru->fh_south_out(ru,frame_tx,slot_tx,proc->timestamp_tx); } void fh_if5_north_out(RU_t *ru) { @@ -661,7 +661,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { old_ts = proc->timestamp_rx; - LOG_I(PHY,"Reading %d samples for slot %d (%p)\n",fp->samples_per_slot,*slot,rxp[0]); + LOG_D(PHY,"Reading %d samples for slot %d (%p)\n",fp->samples_per_slot,*slot,rxp[0]); if(emulate_rf){ wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread"); @@ -691,7 +691,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { } else { if (proc->timestamp_rx - old_ts != fp->samples_per_slot) { - LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_slot,ru->ts_offset); + LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_slot,ru->ts_offset); ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_slot); proc->timestamp_rx = ts-ru->ts_offset; } @@ -701,15 +701,6 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { proc->tti_rx = (proc->timestamp_rx / fp->samples_per_slot)%fp->slots_per_frame; // synchronize first reception to frame 0 subframe 0 - proc->timestamp_tx = proc->timestamp_rx+(sl_ahead*fp->samples_per_slot); - proc->tti_tx = (proc->tti_rx+sl_ahead)%fp->slots_per_frame; - proc->frame_tx = (proc->tti_rx>(fp->slots_per_frame-1-sl_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx; - - LOG_I(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", - ru->idx, - 0, - (unsigned long long int)proc->timestamp_rx, - (int)ru->ts_offset,proc->frame_rx,proc->tti_rx,proc->tti_tx,fp->slots_per_frame); // dump VCD output for first RU in list if (ru == RC.ru[0]) { @@ -745,7 +736,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { } -void tx_rf(RU_t *ru) { +void tx_rf(RU_t *ru,int frame_tx,int tti_tx,uint64_t timestamp_tx) { RU_proc_t *proc = &ru->proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; @@ -754,10 +745,10 @@ void tx_rf(RU_t *ru) { unsigned int txs; int i; - T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(proc->frame_tx), T_INT(proc->tti_tx), - T_INT(0), T_BUFFER(&ru->common.txdata[0][proc->tti_tx * fp->samples_per_slot], fp->samples_per_slot * 4)); + T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame_tx), T_INT(tti_tx), + T_INT(0), T_BUFFER(&ru->common.txdata[0][tti_tx * fp->samples_per_slot], fp->samples_per_slot * 4)); - nr_subframe_t SF_type = nr_slot_select(cfg,proc->tti_tx%fp->slots_per_frame); + nr_subframe_t SF_type = nr_slot_select(cfg,tti_tx%fp->slots_per_frame); int sf_extension = 0; if ((SF_type == SF_DL) || @@ -785,29 +776,28 @@ 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_TTI_NUMBER_TX0_RU, proc->tti_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU,tti_tx ); for (i=0; inb_tx; i++) - txp[i] = (void*)&ru->common.txdata[i][(proc->tti_tx*fp->samples_per_slot)-sf_extension]; + txp[i] = (void*)&ru->common.txdata[i][(tti_tx*fp->samples_per_slot)-sf_extension]; - 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_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); // prepare tx buffer pointers txs = ru->rfdevice.trx_write_func(&ru->rfdevice, - proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, + timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, txp, siglen+sf_extension, ru->nb_tx, - flags); - + 4);//flags); LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, - (long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->tti_tx); + (long long unsigned int)timestamp_tx,frame_tx,proc->frame_tx_unwrap,tti_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen); + AssertFatal(txs == (siglen+sf_extension),"TX : Timeout (sent %d/%d)\n",txs, siglen); } } @@ -1084,7 +1074,7 @@ static inline int wakeup_prach_ru(RU_t *ru) { ru->gNB_list[0]->proc.frame_prach = ru->proc.frame_rx; ru->gNB_list[0]->proc.slot_prach = ru->proc.tti_rx; } - LOG_I(PHY,"RU %d: waking up PRACH thread\n",ru->idx); + LOG_D(PHY,"RU %d: waking up PRACH thread\n",ru->idx); // the thread can now be woken up AssertFatal(pthread_cond_signal(&ru->proc.cond_prach) == 0, "ERROR pthread_cond_signal for RU prach thread\n"); } @@ -1289,47 +1279,49 @@ static void* ru_thread_tx( void* param ) { int print_frame = 8; 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"); + thread_top_init("ru_thread_tx",0,400000,500000,500000); 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) { if (oai_exit) break; - LOG_I(PHY,"ru_thread_tx: Waiting for TX processing\n"); + LOG_D(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"); + + + pthread_mutex_lock(&proc->mutex_gNBs); + int frame_tx=proc->frame_tx; + int tti_tx =proc->tti_tx; + uint64_t timestamp_tx = proc->timestamp_tx; + + pthread_mutex_unlock(&proc->mutex_gNBs); + if (oai_exit) break; //printf("~~~~~~~~~~~~~~~~start process for ru_thread_tx %d.%d\n", proc->frame_tx, proc->tti_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_TTI_NUMBER_TX0_RU, proc->tti_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx ); // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru); + if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx); // do OFDM if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx); 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_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,tti_tx,timestamp_tx); if (ru->fh_north_out) ru->fh_north_out(ru); } else { - if(proc->frame_tx == print_frame) + if(frame_tx == print_frame) { for (i=0; inb_tx; i++) { @@ -1356,6 +1348,8 @@ static void* ru_thread_tx( void* param ) { }//if(proc->frame_tx == print_frame) }//else emulate_rf release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, proc->instance_cnt_gNBs); + for(i = 0; inum_gNB; i++) { gNB = ru->gNB_list[i]; @@ -1377,14 +1371,16 @@ static void* ru_thread_tx( void* param ) { gNB_proc->RU_mask_tx = 0; pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); - pthread_mutex_lock( &L1_proc->mutex_RUs); + pthread_mutex_lock(&L1_proc->mutex_RUs_tx); L1_proc->instance_cnt_RUs = 0; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs); + pthread_mutex_unlock( &L1_proc->mutex_RUs_tx ); + // 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"); + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB L1 TX thread\n"); exit_fun( "ERROR pthread_cond_signal" ); } - pthread_mutex_unlock( &L1_proc->mutex_RUs ); } } } @@ -1414,7 +1410,7 @@ static void* ru_thread( void* param ) { sprintf(threadname,"ru_thread %d",ru->idx); thread_top_init(threadname,0,870000,1000000,1000000); - LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); + LOG_D(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); if(emulate_rf){ fill_rf_config(ru,ru->rf_config_file); @@ -1505,7 +1501,7 @@ static void* ru_thread( void* param ) { if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot); else AssertFatal(1==0, "No fronthaul interface at south port"); - LOG_I(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0][0]:[RX:%d%d TX(SFN):%d]\n", + LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0][0]:[RX:%d%d TX(SFN):%d]\n", frame,slot, proc->frame_rx,proc->tti_rx, proc->frame_tx,proc->tti_tx, @@ -1534,17 +1530,17 @@ static void* ru_thread( void* param ) { // 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) + if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD && ru->num_gNB==0) { // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru); + if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx); // do OFDM if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx); 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_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx); if (ru->fh_north_out) ru->fh_north_out(ru); } @@ -1685,12 +1681,6 @@ int stop_rf(RU_t *ru) return 0; } -extern void fep_full(RU_t *ru); -extern void ru_fep_full_2thread(RU_t *ru); -extern void nr_feptx_ofdm(RU_t *ru); -extern void nr_feptx_ofdm_2thread(RU_t *ru); -extern void feptx_prec(RU_t *ru); -extern void init_fep_thread(RU_t *ru,pthread_attr_t *attr); extern void init_nr_feptx_thread(RU_t *ru,pthread_attr_t *attr); void init_RU_proc(RU_t *ru) { diff --git a/targets/RT/USER/nr-softmodem.c b/targets/RT/USER/nr-softmodem.c index 40d4758847f59eff0d516a4155a4ddca63bd676f..3aafb821a0dbcca64a7f106d26ff9f13f06f4dd6 100644 --- a/targets/RT/USER/nr-softmodem.c +++ b/targets/RT/USER/nr-softmodem.c @@ -389,7 +389,7 @@ void reset_stats(FL_OBJECT *button, long arg) phy_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0; phy_vars_gNB->UE_stats[i].dlsch_ACK[k][j]=0; phy_vars_gNB->UE_stats[i].dlsch_trials[k][j]=0; - }*/ + } phy_vars_gNB->UE_stats[i].dlsch_l2_errors[k]=0; phy_vars_gNB->UE_stats[i].ulsch_errors[k]=0; @@ -399,6 +399,7 @@ void reset_stats(FL_OBJECT *button, long arg) phy_vars_gNB->UE_stats[i].dlsch_sliding_cnt=0; phy_vars_gNB->UE_stats[i].dlsch_NAK_round0=0; phy_vars_gNB->UE_stats[i].dlsch_mcs_offset=0; +*/ } } }