diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 35d02f8842e80e4d566198a03759f9c4dd4a1ea1..cecdf623efd466d47e127da78532acd2489214e5 100755 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -59,6 +59,7 @@ #include "sctp_default_values.h" #include "SystemInformationBlockType2.h" #include "LAYER2/MAC/extern.h" +#include "PHY/extern.h" #define ENB_CONFIG_STRING_ACTIVE_ENBS "Active_eNBs" @@ -321,8 +322,8 @@ void enb_config_display(void) for (j=0; j< enb_properties.properties[i]->nb_cc; j++) { // CC_ID node function/timing - printf( "\n\tnode_function for CC %d: \t%d:\n",j,enb_properties.properties[i]->cc_node_function[j]); - printf( "\tnode_timing for CC %d: \t%d:\n",j,enb_properties.properties[i]->cc_node_timing[j]); + printf( "\n\tnode_function for CC %d: \t%s:\n",j,eNB_functions[enb_properties.properties[i]->cc_node_function[j]]); + printf( "\tnode_timing for CC %d: \t%s:\n",j,eNB_timing[enb_properties.properties[i]->cc_node_timing[j]]); printf( "\tnode_synch_ref for CC %d: \t%d:\n",j,enb_properties.properties[i]->cc_node_synch_ref[j]); printf( "\teutra band for CC %d: \t%"PRId16":\n",j,enb_properties.properties[i]->eutra_band[j]); diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h index c47cc8e8c7a3dde20ba2a7edc5b960471024b410..55b55c7e5f89eb23c2ac5855396afefd3436752c 100644 --- a/openair2/UTIL/OCG/OCG.h +++ b/openair2/UTIL/OCG/OCG.h @@ -44,6 +44,7 @@ #ifndef __OCG_H__ #define __OCG_H__ +#include "PHY/defs.h" #include "PHY/impl_defs_top.h" #include "platform_types.h" @@ -707,8 +708,8 @@ typedef struct { // phy related params unsigned int n_frames; unsigned int n_frames_flag; // if set, then let the emulation goes to infinity - node_function_t node_function[MAX_NUM_CCs]; - node_timing_t node_timing[MAX_NUM_CCS]; + eNB_func_t node_function[MAX_NUM_CCs]; + eNB_timing_t node_timing[MAX_NUM_CCs]; unsigned char frame_type[MAX_NUM_CCs]; //! LTE frame type (TDD=1, FDD=0). \note this should be converted to \ref lte_frame_type_t (header file reorganization needed) char * frame_type_name[MAX_NUM_CCs]; unsigned char tdd_config[MAX_NUM_CCs]; diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 70f098217a8d7ce44da4243c8576c3f323208063..17d1f7b1800a9e0c703318585da8df656ec9693c 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -248,6 +248,9 @@ typedef struct { struct openair0_device_t { /*!brief Module ID of this device */ int Mod_id; + + /*!brief Component Carrier ID of this device */ + int CC_id; /*!brief Type of this device */ dev_type_t type; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf index 3ec8ea01da7c99e050b0340706a181ad6db6683e..ad3bcfcf92beaaf894deb03256a89ee2d48c635c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf @@ -24,7 +24,8 @@ eNBs = component_carriers = ( { node_function = "eNodeB_3GPP"; - node_timing = "SYNCH_TO_OTHER"; + node_timing = "synch_to_other"; + node_synch_ref = 0; frame_type = "FDD"; tdd_config = 3; tdd_config_s = 0; @@ -37,8 +38,8 @@ eNBs = Nid_cell_mbsfn = 0; nb_antennas_tx = 1; nb_antennas_rx = 1; - tx_gain = 25; - rx_gain = 20; + tx_gain = 25; + rx_gain = 20; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 2ec507e4c326a1c0542aaa4914f39763e37e2b75..177291596ba2229d27c38a6967b56a0094edce3e 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -157,8 +157,8 @@ static struct { void exit_fun(const char* s); -void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[]); -void stop_eNB(void); +void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst); +void stop_eNB(int nb_inst); void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) { @@ -647,6 +647,8 @@ static void* eNB_thread_asynch_rx( void* param ) { uint32_t symbol_number=0; uint32_t symbol_mask, symbol_mask_full; int prach_rx; + int dummy_rx[fp->nb_antennas_rx][fp->samples_per_tti]; + int rxs; #ifdef DEADLINE_SCHEDULER struct sched_attr attr; @@ -739,7 +741,34 @@ static void* eNB_thread_asynch_rx( void* param ) { #endif // DEADLINE_SCHEDULER - if (eNB->node_function == eNodeB_3GPP_BBU) { // acquisition from IF + + mlockall(MCL_CURRENT | MCL_FUTURE); + + // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe + printf( "waiting for sync (eNB_thread_asynch_rx)\n"); + pthread_mutex_lock( &sync_mutex ); + + while (sync_var<0) + pthread_cond_wait( &sync_cond, &sync_mutex ); + + pthread_mutex_unlock(&sync_mutex); + + printf( "got sync (eNB_thread_asynch_rx)\n" ); + + if (eNB->node_function == eNodeB_3GPP) { // acquisition from RF + + if (eNB->rfdevice.trx_read_func) + rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, + &proc->timestamp_rx, + (void**)dummy_rx, + fp->samples_per_tti, + fp->nb_antennas_rx); + else { + printf("eNB asynch RX\n"); + sleep(1); + } + } + else if (eNB->node_function == eNodeB_3GPP_BBU) { // acquisition from IF /// **** recv_IF5 of rxdata from RRH **** /// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 ); recv_IF5(eNB, ×tamp_rx, subframe_rx++, IF5_RRH_GW_UL); @@ -938,7 +967,7 @@ static void* eNB_thread_FH( void* param ) { pthread_mutex_unlock(&sync_mutex); - printf( "got sync (eNB_thread)\n" ); + printf( "got sync (eNB_thread FH)\n" ); #if defined(ENABLE_ITTI) wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB); @@ -1394,108 +1423,106 @@ static void* eNB_thread_prach( void* param ) { } -void init_eNB_proc(int nb_inst) { +void init_eNB_proc(int inst) { int i; int CC_id; PHY_VARS_eNB *eNB; eNB_proc_t *proc; eNB_rxtx_proc_t *proc_rxtx; - int inst; - - for (inst = 0; inst < nb_inst; inst++) { - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - eNB = PHY_vars_eNB_g[inst][CC_id]; - LOG_I(PHY,"Initializing eNB %d CC_id %d (%s,%s),\n",inst,CC_id,eNB_functions[eNB->node_function],eNB_timing[eNB->node_timing]); - proc = &eNB->proc; - proc_rxtx = proc->proc_rxtx; + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + eNB = PHY_vars_eNB_g[inst][CC_id]; + LOG_I(PHY,"Initializing eNB %d CC_id %d (%s,%s),\n",inst,CC_id,eNB_functions[eNB->node_function],eNB_timing[eNB->node_timing]); + proc = &eNB->proc; + proc_rxtx = proc->proc_rxtx; #ifndef DEADLINE_SCHEDULER - /* - pthread_attr_init( &attr_eNB_proc_tx[CC_id][i] ); - if (pthread_attr_setstacksize( &attr_eNB_proc_tx[CC_id][i], 64 *PTHREAD_STACK_MIN ) != 0) - perror("[ENB_PROC_TX] setting thread stack size failed\n"); - - pthread_attr_init( &attr_eNB_proc_rx[CC_id][i] ); - if (pthread_attr_setstacksize( &attr_eNB_proc_rx[CC_id][i], 64 * PTHREAD_STACK_MIN ) != 0) - perror("[ENB_PROC_RX] setting thread stack size failed\n"); - */ - // set the kernel scheduling policy and priority - proc_rxtx[0].sched_param_rxtx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&proc_rxtx[0].attr_rxtx, &proc_rxtx[0].sched_param_rxtx); - pthread_attr_setschedpolicy (&proc_rxtx[0].attr_rxtx, SCHED_FIFO); - proc_rxtx[1].sched_param_rxtx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&proc_rxtx[1].attr_rxtx, &proc_rxtx[1].sched_param_rxtx); - pthread_attr_setschedpolicy (&proc_rxtx[1].attr_rxtx, SCHED_FIFO); - - proc->sched_param_FH.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&proc->attr_FH, &proc->sched_param_FH); - pthread_attr_setschedpolicy (&proc->attr_FH, SCHED_FIFO); - - proc->sched_param_prach.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&proc->attr_prach, &proc->sched_param_prach); - pthread_attr_setschedpolicy (&proc->attr_prach, SCHED_FIFO); - - printf("Setting OS scheduler to SCHED_FIFO for eNB [cc%d][thread%d] \n",CC_id, i); + /* + pthread_attr_init( &attr_eNB_proc_tx[CC_id][i] ); + if (pthread_attr_setstacksize( &attr_eNB_proc_tx[CC_id][i], 64 *PTHREAD_STACK_MIN ) != 0) + perror("[ENB_PROC_TX] setting thread stack size failed\n"); + + pthread_attr_init( &attr_eNB_proc_rx[CC_id][i] ); + if (pthread_attr_setstacksize( &attr_eNB_proc_rx[CC_id][i], 64 * PTHREAD_STACK_MIN ) != 0) + perror("[ENB_PROC_RX] setting thread stack size failed\n"); + */ + // set the kernel scheduling policy and priority + proc_rxtx[0].sched_param_rxtx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; + pthread_attr_setschedparam (&proc_rxtx[0].attr_rxtx, &proc_rxtx[0].sched_param_rxtx); + pthread_attr_setschedpolicy (&proc_rxtx[0].attr_rxtx, SCHED_FIFO); + proc_rxtx[1].sched_param_rxtx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; + pthread_attr_setschedparam (&proc_rxtx[1].attr_rxtx, &proc_rxtx[1].sched_param_rxtx); + pthread_attr_setschedpolicy (&proc_rxtx[1].attr_rxtx, SCHED_FIFO); + + proc->sched_param_FH.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY; + pthread_attr_setschedparam (&proc->attr_FH, &proc->sched_param_FH); + pthread_attr_setschedpolicy (&proc->attr_FH, SCHED_FIFO); + + proc->sched_param_prach.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; + pthread_attr_setschedparam (&proc->attr_prach, &proc->sched_param_prach); + pthread_attr_setschedpolicy (&proc->attr_prach, SCHED_FIFO); + + printf("Setting OS scheduler to SCHED_FIFO for eNB [cc%d][thread%d] \n",CC_id, i); #endif - proc_rxtx[0].instance_cnt_rxtx = -1; - proc_rxtx[1].instance_cnt_rxtx = -1; - proc->instance_cnt_prach = -1; - proc->instance_cnt_FH = -1; - proc->CC_id = CC_id; - - proc->first_rx=4; - - pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); - pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); - pthread_mutex_init( &proc->mutex_prach, NULL); - pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); - pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); - pthread_cond_init( &proc->cond_prach, NULL); - pthread_cond_init( &proc->cond_FH, NULL); + proc_rxtx[0].instance_cnt_rxtx = -1; + proc_rxtx[1].instance_cnt_rxtx = -1; + proc->instance_cnt_prach = -1; + proc->instance_cnt_FH = -1; + proc->CC_id = CC_id; + + proc->first_rx=4; + + pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); + pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); + pthread_mutex_init( &proc->mutex_prach, NULL); + pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); + pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); + pthread_cond_init( &proc->cond_prach, NULL); + pthread_cond_init( &proc->cond_FH, NULL); #ifndef DEADLINE_SCHEDULER - pthread_create( &proc_rxtx[0].pthread_rxtx, &proc_rxtx[0].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[0] ); - pthread_create( &proc_rxtx[1].pthread_rxtx, &proc_rxtx[1].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[1] ); - pthread_create( &proc->pthread_FH, &proc->attr_FH, eNB_thread_FH, &eNB->proc ); - pthread_create( &proc->pthread_prach, &proc->attr_prach, eNB_thread_prach, &eNB->proc ); - if (eNB->node_timing == synch_to_other) - pthread_create( &proc->pthread_asynch_rx, &proc->attr_asynch_rx, eNB_thread_asynch_rx, &eNB->proc ); + pthread_create( &proc_rxtx[0].pthread_rxtx, &proc_rxtx[0].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[0] ); + pthread_create( &proc_rxtx[1].pthread_rxtx, &proc_rxtx[1].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[1] ); + pthread_create( &proc->pthread_FH, &proc->attr_FH, eNB_thread_FH, &eNB->proc ); + pthread_create( &proc->pthread_prach, &proc->attr_prach, eNB_thread_prach, &eNB->proc ); + if (eNB->node_timing == synch_to_other) + pthread_create( &proc->pthread_asynch_rx, &proc->attr_asynch_rx, eNB_thread_asynch_rx, &eNB->proc ); #else - pthread_create( &proc_rxtx[0].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[0] ); - pthread_create( &proc_rxtx[1].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[1] ); - pthread_create( &proc->pthread_FH, NULL, eNB_thread_FH, &eNB->proc ); - pthread_create( &proc->pthread_prach, NULL, eNB_thread_prach, &eNB->proc ); - if (eNB->node_timing == synch_to_other) - pthread_create( &proc->pthread_asynch_rx, NULL, eNB_thread_asynch_rx, &eNB->proc ); - -#endif - char name[16]; - snprintf( name, sizeof(name), "RXTX0 %d", i ); - pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); - snprintf( name, sizeof(name), "RXTX1 %d", i ); - pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); - snprintf( name, sizeof(name), "FH %d", i ); - pthread_setname_np( proc->pthread_FH, name ); - } + pthread_create( &proc_rxtx[0].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[0] ); + pthread_create( &proc_rxtx[1].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[1] ); + pthread_create( &proc->pthread_FH, NULL, eNB_thread_FH, &eNB->proc ); + pthread_create( &proc->pthread_prach, NULL, eNB_thread_prach, &eNB->proc ); + if (eNB->node_timing == synch_to_other) + pthread_create( &proc->pthread_asynch_rx, NULL, eNB_thread_asynch_rx, &eNB->proc ); - /* setup PHY proc TX sync mechanism */ - pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); - pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); - sync_phy_proc.phy_proc_CC_id = 0; +#endif + char name[16]; + snprintf( name, sizeof(name), "RXTX0 %d", i ); + pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); + snprintf( name, sizeof(name), "RXTX1 %d", i ); + pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); + snprintf( name, sizeof(name), "FH %d", i ); + pthread_setname_np( proc->pthread_FH, name ); } + + /* setup PHY proc TX sync mechanism */ + pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); + pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); + sync_phy_proc.phy_proc_CC_id = 0; } + /*! * \brief Terminate eNB TX and RX threads. */ -void kill_eNB_proc(void) { +void kill_eNB_proc(int inst) { int *status; PHY_VARS_eNB *eNB; eNB_proc_t *proc; eNB_rxtx_proc_t *proc_rxtx; for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - eNB=PHY_vars_eNB_g[0][CC_id]; + eNB=PHY_vars_eNB_g[inst][CC_id]; proc = &eNB->proc; proc_rxtx = &proc->proc_rxtx[0]; @@ -1650,16 +1677,21 @@ void print_opp_meas(void) { } -void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[]) { + void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst) { int CC_id; + int inst; + + for (inst=0;inst<nb_inst;inst++) { + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + PHY_vars_eNB_g[inst][CC_id]->node_function = node_function[CC_id]; + PHY_vars_eNB_g[inst][CC_id]->node_timing = node_timing[CC_id]; + LOG_I(PHY,"Initializing eNB %d CC_id %d : (%s,%s)\n",inst,CC_id,eNB_functions[node_function[CC_id]],eNB_timing[node_timing[CC_id]]); + } - for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { - PHY_vars_eNB_g[0][CC_id]->node_function = node_function[CC_id]; - PHY_vars_eNB_g[0][CC_id]->node_timing = node_timing[CC_id]; + init_eNB_proc(inst); } - - init_eNB_proc(); + sleep(1); LOG_D(HW,"[lte-softmodem.c] eNB threads created\n"); @@ -1677,7 +1709,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[]) { } -void stop_eNB() { +void stop_eNB(int nb_inst) { /* #ifdef DEBUG_THREADS @@ -1702,6 +1734,8 @@ void stop_eNB() { #endif // DEBUG_THREADS */ - printf("Killing eNB processing threads\n"); - kill_eNB_proc(); + for (int inst=0;inst<nb_inst;inst++) { + printf("Killing eNB %d processing threads\n",inst); + kill_eNB_proc(inst); + } } diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 297286687eb5977b5869c2689039f524a8d77749..ad89a4604d42edcdd2d7112246cf81ba8414f536 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -119,8 +119,8 @@ unsigned short config_frames[4] = {2,9,11,13}; // In lte-enb.c extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]); -extern void init_eNB(eNB_func_t *, eNB_timing_t *); -extern void stop_eNB(void); +extern void init_eNB(eNB_func_t *, eNB_timing_t *,int); +extern void stop_eNB(int); extern void kill_eNB_proc(void); // In lte-ue.c @@ -1843,7 +1843,7 @@ int main( int argc, char **argv ) // start the main thread if (UE_flag == 1) init_UE(1); - else init_eNB(node_function,node_timing); + else init_eNB(node_function,node_timing,1); // Sleep to allow all threads to setup sleep(3); @@ -1902,7 +1902,7 @@ int main( int argc, char **argv ) // cleanup if (UE_flag == 1) { } else { - stop_eNB(); + stop_eNB(1); } diff --git a/targets/SIMU/USER/channel_sim.c b/targets/SIMU/USER/channel_sim.c index 5970adfa5f80f51a7b4796b79572c33bf35b5922..8ff6c8896246021ddd78b22309dfabb6eb1423d0 100644 --- a/targets/SIMU/USER/channel_sim.c +++ b/targets/SIMU/USER/channel_sim.c @@ -76,16 +76,21 @@ int first_rbUL ; extern Signal_buffers_t *signal_buffers_g; - -void do_DL_sig(double **r_re0,double **r_im0, - double **r_re,double **r_im, - double **s_re,double **s_im, - channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs], - node_desc_t *enb_data[NUMBER_OF_eNB_MAX], - node_desc_t *ue_data[NUMBER_OF_UE_MAX], - uint16_t next_slot,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms, - uint8_t UE_id, - int CC_id) +double r_re_DL[NUMBER_OF_UE_MAX][2][30720]; +double r_im_DL[NUMBER_OF_UE_MAX][2][30720]; +double r_re_UL[NUMBER_OF_eNB_MAX][2][30720]; +double r_im_UL[NUMBER_OF_eNB_MAX][2][30720]; +int eNB_output_mask[NUMBER_OF_UE_MAX]; +int UE_output_mask[NUMBER_OF_eNB_MAX]; +pthread_mutex_t eNB_output_mutex[NUMBER_OF_UE_MAX]; +pthread_mutex_t UE_output_mutex[NUMBER_OF_eNB_MAX]; + +void do_DL_sig(channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs], + node_desc_t *enb_data[NUMBER_OF_eNB_MAX], + node_desc_t *ue_data[NUMBER_OF_UE_MAX], + uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms, + uint8_t UE_id, + int CC_id) { int32_t att_eNB_id=-1; @@ -96,19 +101,20 @@ void do_DL_sig(double **r_re0,double **r_im0, double rx_pwr; int32_t rx_pwr2; uint32_t i,aa; - uint32_t slot_offset,slot_offset_meas = 0; + uint32_t sf_offset; double min_path_loss=-200; uint8_t hold_channel=0; - // uint8_t aatx,aarx; uint8_t nb_antennas_rx = eNB2UE[0][0][CC_id]->nb_rx; // number of rx antennas at UE uint8_t nb_antennas_tx = eNB2UE[0][0][CC_id]->nb_tx; // number of tx antennas at eNB - //LTE_DL_FRAME_PARMS *fp; - // int subframe_sched = ((next_slot>>1) == 0) ? 9 : ((next_slot>>1)-1); - + double s_re[2][PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti]; + double s_im[2][PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti]; + double r_re0[2][PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti]; + double r_im0[2][PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti]; + - if (next_slot==0) + if (subframe==0) hold_channel = 0; else hold_channel = 1; @@ -186,19 +192,6 @@ void do_DL_sig(double **r_re0,double **r_im0, } } - /* - if(PHY_vars_UE_g[UE_id]->transmission_mode[att_eNB_id]>=5) - { - lte_ue_measurements(PHY_vars_UE_g[UE_id], - ((next_slot-1)>>1)*frame_parms->samples_per_tti, - 1, - abstraction_flag); - - PHY_vars_eNB_g[att_eNB_id]->dlsch_eNB[0][0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE_g[UE_id]->PHY_measurements,0); - // printf("pmi_alloc in channel sim: %d",PHY_vars_eNB_g[att_eNB_id]->dlsch_eNB[0][0]->pmi_alloc); - } - */ - // calculate the SNR for the attached eNB (this assumes eNB always uses PMI stored in eNB_UE_stats; to be improved) init_snr(eNB2UE[att_eNB_id][UE_id][CC_id], enb_data[att_eNB_id], ue_data[UE_id], PHY_vars_UE_g[UE_id][CC_id]->sinr_dB, &PHY_vars_UE_g[UE_id][CC_id]->N0, PHY_vars_UE_g[UE_id][CC_id]->transmission_mode[att_eNB_id], PHY_vars_eNB_g[att_eNB_id][CC_id]->UE_stats[UE_id].DL_pmi_single, @@ -214,52 +207,44 @@ void do_DL_sig(double **r_re0,double **r_im0, } else { //abstraction_flag - /* - Call do_OFDM_mod from phy_procedures_eNB_TX function - */ - - // printf("r_re[0] %p\n",r_re[0]); - for (aa=0; aa<nb_antennas_rx; aa++) { - memset((void*)r_re[aa],0,(frame_parms->samples_per_tti>>1)*sizeof(double)); - memset((void*)r_im[aa],0,(frame_parms->samples_per_tti>>1)*sizeof(double)); + + + pthread_mutex_lock(&eNB_output_mutex[UE_id]); + if (eNB_output_mask[UE_id] == 0) { // This is the first eNodeB for this UE, clear the buffer + + for (aa=0; aa<nb_antennas_rx; aa++) { + memset((void*)r_re_DL[UE_id][aa],0,(frame_parms->samples_per_tti)*sizeof(double)); + memset((void*)r_im_DL[UE_id][aa],0,(frame_parms->samples_per_tti)*sizeof(double)); + } } + pthread_mutex_unlock(&eNB_output_mutex[UE_id]); - /* - for (i=0;i<16;i++) - printf("%f, %X\n",r_re[aa][i],(unsigned long long)r_re[aa][i]); - */ for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) { - // if (((double)PHY_vars_UE_g[UE_id]->tx_power_dBm + - // eNB2UE[eNB_id][UE_id]->path_loss_dB) <= -107.0) - // break; - txdata = PHY_vars_eNB_g[eNB_id][CC_id]->common_vars.txdata[0]; - slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1); - slot_offset_meas = ((next_slot&1)==0) ? slot_offset : (slot_offset-(frame_parms->samples_per_tti>>1)); - tx_pwr = dac_fixed_gain(s_re, - s_im, + sf_offset = subframe*frame_parms->samples_per_tti; + tx_pwr = dac_fixed_gain((double**)s_re, + (double**)s_im, txdata, - slot_offset, + sf_offset, nb_antennas_tx, - frame_parms->samples_per_tti>>1, - slot_offset_meas, + frame_parms->samples_per_tti, + sf_offset, frame_parms->ofdm_symbol_size, 14, - // enb_data[eNB_id]->tx_power_dBm); frame_parms->pdsch_config_common.referenceSignalPower, // dBm/RE frame_parms->N_RB_DL*12); #ifdef DEBUG_SIM - LOG_D(OCM,"[SIM][DL] eNB %d (CCid %d): tx_pwr %.1f dBm/RE (target %d dBm/RE), for slot %d (subframe %d)\n", + LOG_D(OCM,"[SIM][DL] eNB %d (CCid %d): tx_pwr %.1f dBm/RE (target %d dBm/RE), for subframe %d\n", eNB_id,CC_id, 10*log10(tx_pwr), frame_parms->pdsch_config_common.referenceSignalPower, - next_slot, - next_slot>>1); + subframe); + #endif //eNB2UE[eNB_id][UE_id]->path_loss_dB = 0; - multipath_channel(eNB2UE[eNB_id][UE_id][CC_id],s_re,s_im,r_re0,r_im0, - frame_parms->samples_per_tti>>1,hold_channel); + multipath_channel(eNB2UE[eNB_id][UE_id][CC_id],(double**)s_re,(double**)s_im,(double**)r_re0,(double**)r_im0, + frame_parms->samples_per_tti,hold_channel); #ifdef DEBUG_SIM rx_pwr = signal_energy_fp2(eNB2UE[eNB_id][UE_id][CC_id]->ch[0], eNB2UE[eNB_id][UE_id][CC_id]->channel_length)*eNB2UE[eNB_id][UE_id][CC_id]->channel_length; @@ -281,17 +266,17 @@ void do_DL_sig(double **r_re0,double **r_im0, eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB); #ifdef DEBUG_SIM - rx_pwr = signal_energy_fp(r_re0,r_im0,nb_antennas_rx, + rx_pwr = signal_energy_fp((double**)r_re0,(double**)r_im0,nb_antennas_rx, frame_parms->ofdm_symbol_size, - slot_offset_meas)/(12.0*frame_parms->N_RB_DL); - LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr %f dBm/RE (%f dBm RSSI)for slot %d (subframe %d)\n",UE_id, + sf_offset)/(12.0*frame_parms->N_RB_DL); + LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr %f dBm/RE (%f dBm RSSI)for subframe %d\n",UE_id, 10*log10(rx_pwr), - 10*log10(rx_pwr*(double)frame_parms->N_RB_DL*12),next_slot,next_slot>>1); + 10*log10(rx_pwr*(double)frame_parms->N_RB_DL*12),subframe); LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr (noise) -132 dBm/RE (N0fs = %.1f dBm, N0B = %.1f dBm) for slot %d (subframe %d)\n", UE_id, 10*log10(eNB2UE[eNB_id][UE_id][CC_id]->sampling_rate*1e6)-174, 10*log10(eNB2UE[eNB_id][UE_id][CC_id]->sampling_rate*1e6*12*frame_parms->N_RB_DL/(double)frame_parms->ofdm_symbol_size)-174, - next_slot,next_slot>>1); + subframe); #endif if (eNB2UE[eNB_id][UE_id][CC_id]->first_run == 1) @@ -300,96 +285,85 @@ void do_DL_sig(double **r_re0,double **r_im0, // RF model #ifdef DEBUG_SIM - LOG_D(OCM,"[SIM][DL] UE %d (CCid %d): rx_gain %d dB (-ADC %f) for slot %d (subframe %d)\n",UE_id,CC_id,PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB, - PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB-66.227,next_slot,next_slot>>1); + LOG_D(OCM,"[SIM][DL] UE %d (CCid %d): rx_gain %d dB (-ADC %f) for subframe %d\n",UE_id,CC_id,PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB, + PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB-66.227,subframe); #endif - /* - rf_rx(r_re0, - r_im0, - NULL, - NULL, - 0, - nb_antennas_rx, - frame_parms->samples_per_tti>>1, - 1e3/eNB2UE[eNB_id][UE_id]->BW, // sampling time (ns) - 0.0, // freq offset (Hz) (-20kHz..20kHz) - 0.0, // drift (Hz) NOT YET IMPLEMENTED - ue_data[UE_id]->rx_noise_level, // noise_figure NOT YET IMPLEMENTED - (double)PHY_vars_UE_g[UE_id]->rx_total_gain_dB - 66.227, // rx_gain (dB) (66.227 = 20*log10(pow2(11)) = gain from the adc that will be applied later) - 200.0, // IP3_dBm (dBm) - &eNB2UE[eNB_id][UE_id]->ip, // initial phase - 30.0e3, // pn_cutoff (kHz) - -500.0, // pn_amp (dBc) default: 50 - 0.0, // IQ imbalance (dB), - 0.0); // IQ phase imbalance (rad) - */ - - rf_rx_simple(r_re0, - r_im0, + + rf_rx_simple((double**)r_re0, + (double**)r_im0, nb_antennas_rx, - frame_parms->samples_per_tti>>1, + frame_parms->samples_per_tti, 1e3/eNB2UE[eNB_id][UE_id][CC_id]->sampling_rate, // sampling time (ns) (double)PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB - 66.227); // rx_gain (dB) (66.227 = 20*log10(pow2(11)) = gain from the adc that will be applied later) #ifdef DEBUG_SIM - rx_pwr = signal_energy_fp(r_re0,r_im0, + rx_pwr = signal_energy_fp((double**)r_re0,(double**)r_im0, nb_antennas_rx, frame_parms->ofdm_symbol_size, - slot_offset_meas)/(12.0*frame_parms->N_RB_DL); - LOG_D(OCM,"[SIM][DL] UE %d : ADC in (eNB %d) %f dBm/RE for slot %d (subframe %d)\n", + sf_offset)/(12.0*frame_parms->N_RB_DL); + LOG_D(OCM,"[SIM][DL] UE %d : ADC in (eNB %d) %f dBm/RE for subframe %d\n", UE_id,eNB_id, - 10*log10(rx_pwr),next_slot,next_slot>>1); + 10*log10(rx_pwr),subframe); #endif - - for (i=0; i<(frame_parms->samples_per_tti>>1); i++) { + + pthread_mutex_lock(&eNB_output_mutex[UE_id]); + for (i=0; i<frame_parms->samples_per_tti; i++) { for (aa=0; aa<nb_antennas_rx; aa++) { - r_re[aa][i]+=r_re0[aa][i]; - r_im[aa][i]+=r_im0[aa][i]; + r_re_DL[UE_id][aa][i]+=r_re0[aa][i]; + r_im_DL[UE_id][aa][i]+=r_im0[aa][i]; } } - - } - + eNB_output_mask[UE_id] |= (1<<eNB_id); + if (eNB_output_mask[UE_id] == (1<<NB_eNB_INST)-1) { + eNB_output_mask[UE_id]=0; + + #ifdef DEBUG_SIM - rx_pwr = signal_energy_fp(r_re,r_im,nb_antennas_rx,frame_parms->ofdm_symbol_size,slot_offset_meas)/(12.0*frame_parms->N_RB_DL); - LOG_D(OCM,"[SIM][DL] UE %d : ADC in %f dBm for slot %d (subframe %d)\n",UE_id,10*log10(rx_pwr),next_slot,next_slot>>1); + rx_pwr = signal_energy_fp((double**)r_re_DL[UE_id],(double**)r_im_DL[UE_id],nb_antennas_rx,frame_parms->ofdm_symbol_size,sf_offset)/(12.0*frame_parms->N_RB_DL); + LOG_D(OCM,"[SIM][DL] UE %d : ADC in %f dBm for subframe %d\n",UE_id,10*log10(rx_pwr),subframe); #endif - - rxdata = PHY_vars_UE_g[UE_id][CC_id]->common_vars.rxdata; - slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1); - - adc(r_re, - r_im, - 0, - slot_offset, - rxdata, - nb_antennas_rx, - frame_parms->samples_per_tti>>1, - 12); - + + rxdata = PHY_vars_UE_g[UE_id][CC_id]->common_vars.rxdata; + sf_offset = subframe*frame_parms->samples_per_tti; + + adc((double**)r_re_DL[UE_id], + (double**)r_im_DL[UE_id], + 0, + sf_offset, + rxdata, + nb_antennas_rx, + frame_parms->samples_per_tti, + 12); + #ifdef DEBUG_SIM - rx_pwr2 = signal_energy(rxdata[0]+slot_offset,frame_parms->ofdm_symbol_size)/(12.0*frame_parms->N_RB_DL); - LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr (ADC out) %f dB/RE (%d) for slot %d (subframe %d), writing to %p\n",UE_id, 10*log10((double)rx_pwr2),rx_pwr2,next_slot,next_slot>>1,rxdata); + rx_pwr2 = signal_energy(rxdata[0]+sf_offset,frame_parms->ofdm_symbol_size)/(12.0*frame_parms->N_RB_DL); + LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr (ADC out) %f dB/RE (%d) for subframe %d, writing to %p\n",UE_id, 10*log10((double)rx_pwr2),rx_pwr2,subframe,rxdata); #else - UNUSED_VARIABLE(rx_pwr2); - UNUSED_VARIABLE(tx_pwr); - UNUSED_VARIABLE(rx_pwr); + UNUSED_VARIABLE(rx_pwr2); + UNUSED_VARIABLE(tx_pwr); + UNUSED_VARIABLE(rx_pwr); #endif - //}// UE_index loop + + } // eNB_output_mask + pthread_mutex_unlock(&eNB_output_mutex[UE_id]); + } // eNB_id + } } -void do_UL_sig(double **r_re0,double **r_im0,double **r_re,double **r_im,double **s_re,double **s_im,channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_NUM_CCs], - node_desc_t *enb_data[NUMBER_OF_eNB_MAX],node_desc_t *ue_data[NUMBER_OF_UE_MAX],uint16_t next_slot,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms, uint32_t frame,uint8_t CC_id) +void do_UL_sig(channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_NUM_CCs], + node_desc_t *enb_data[NUMBER_OF_eNB_MAX],node_desc_t *ue_data[NUMBER_OF_UE_MAX], + uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms, + uint32_t frame,int eNB_id,uint8_t CC_id) { int32_t **txdata,**rxdata; #ifdef PHY_ABSTRACTION_UL int32_t att_eNB_id=-1; #endif - uint8_t eNB_id=0,UE_id=0; + uint8_t UE_id=0; uint8_t nb_antennas_rx = UE2eNB[0][0][CC_id]->nb_rx; // number of rx antennas at eNB uint8_t nb_antennas_tx = UE2eNB[0][0][CC_id]->nb_tx; // number of tx antennas at UE @@ -397,7 +371,7 @@ void do_UL_sig(double **r_re0,double **r_im0,double **r_re,double **r_im,double double tx_pwr, rx_pwr; int32_t rx_pwr2; uint32_t i,aa; - uint32_t slot_offset,slot_offset_meas; + uint32_t sf_offset; uint8_t hold_channel=0; @@ -408,192 +382,149 @@ void do_UL_sig(double **r_re0,double **r_im0,double **r_re,double **r_im,double int ulnbrb2 ; int ulfrrb2 ; uint8_t harq_pid; - int subframe = (next_slot>>1); #endif - - /* - if (next_slot==4) - hold_channel = 0; - else - hold_channel = 1; - */ + double s_re[2][PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti]; + double s_im[2][PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti]; + double r_re0[2][PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti]; + double r_im0[2][PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti]; if (abstraction_flag!=0) { #ifdef PHY_ABSTRACTION_UL - for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) { - for (UE_id=0; UE_id<NB_UE_INST; UE_id++) { - if (!hold_channel) { - random_channel(UE2eNB[UE_id][eNB_id][CC_id],abstraction_flag); - freq_channel(UE2eNB[UE_id][eNB_id][CC_id], frame_parms->N_RB_UL,frame_parms->N_RB_UL*12+1); - - // REceived power at the eNB - rx_pwr = signal_energy_fp2(UE2eNB[UE_id][eNB_id][CC_id]->ch[0], - UE2eNB[UE_id][eNB_id][CC_id]->channel_length)*UE2eNB[UE_id][att_eNB_id][CC_id]->channel_length; // calculate the rx power at the eNB - } - - // write_output("SINRch.m","SINRch",PHY_vars_eNB_g[att_eNB_id]->sinr_dB_eNB,frame_parms->N_RB_UL*12+1,1,1); - if(subframe>1 && subframe <5) { - harq_pid = subframe2harq_pid(frame_parms,frame,subframe); - ul_nb_rb = PHY_vars_eNB_g[att_eNB_id][CC_id]->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->nb_rb; - ul_fr_rb = PHY_vars_eNB_g[att_eNB_id][CC_id]->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->first_rb; - } - - if(ul_nb_rb>1 && (ul_fr_rb < 25 && ul_fr_rb > -1)) { - number_rb_ul = ul_nb_rb; - first_rbUL = ul_fr_rb; - init_snr_up(UE2eNB[UE_id][att_eNB_id][CC_id],enb_data[att_eNB_id], ue_data[UE_id],PHY_vars_eNB_g[att_eNB_id][CC_id]->sinr_dB,&PHY_vars_UE_g[att_eNB_id][CC_id]->N0,ul_nb_rb,ul_fr_rb); - - } - } //UE_id - } //eNB_id + for (UE_id=0; UE_id<NB_UE_INST; UE_id++) { + if (!hold_channel) { + random_channel(UE2eNB[UE_id][eNB_id][CC_id],abstraction_flag); + freq_channel(UE2eNB[UE_id][eNB_id][CC_id], frame_parms->N_RB_UL,frame_parms->N_RB_UL*12+1); + + // REceived power at the eNB + rx_pwr = signal_energy_fp2(UE2eNB[UE_id][eNB_id][CC_id]->ch[0], + UE2eNB[UE_id][eNB_id][CC_id]->channel_length)*UE2eNB[UE_id][att_eNB_id][CC_id]->channel_length; // calculate the rx power at the eNB + } + + // write_output("SINRch.m","SINRch",PHY_vars_eNB_g[att_eNB_id]->sinr_dB_eNB,frame_parms->N_RB_UL*12+1,1,1); + if(subframe>1 && subframe <5) { + harq_pid = subframe2harq_pid(frame_parms,frame,subframe); + ul_nb_rb = PHY_vars_eNB_g[att_eNB_id][CC_id]->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->nb_rb; + ul_fr_rb = PHY_vars_eNB_g[att_eNB_id][CC_id]->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->first_rb; + } + + if(ul_nb_rb>1 && (ul_fr_rb < 25 && ul_fr_rb > -1)) { + number_rb_ul = ul_nb_rb; + first_rbUL = ul_fr_rb; + init_snr_up(UE2eNB[UE_id][att_eNB_id][CC_id],enb_data[att_eNB_id], ue_data[UE_id],PHY_vars_eNB_g[att_eNB_id][CC_id]->sinr_dB,&PHY_vars_UE_g[att_eNB_id][CC_id]->N0,ul_nb_rb,ul_fr_rb); + + } + } //UE_id #else - /* the following functions are not needed */ - /* - if (abstraction_flag!=0) { - for (eNB_id=0;eNB_id<NB_eNB_INST;eNB_id++) { - for (UE_id=0;UE_id<NB_UE_INST;UE_id++) { - random_channel(UE2eNB[UE_id][eNB_id]); - freq_channel(UE2eNB[UE_id][eNB_id], frame_parms->N_RB_UL,2); - } - } - } - */ + #endif } else { //without abstraction - for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) { - // Clear RX signal for eNB = eNB_id - for (i=0; i<(frame_parms->samples_per_tti>>1); i++) { - for (aa=0; aa<nb_antennas_rx; aa++) { - r_re[aa][i]=0.0; - r_im[aa][i]=0.0; - } + pthread_mutex_lock(&UE_output_mutex[eNB_id]); + // Clear RX signal for eNB = eNB_id + for (i=0; i<frame_parms->samples_per_tti; i++) { + for (aa=0; aa<nb_antennas_rx; aa++) { + r_re_UL[eNB_id][aa][i]=0.0; + r_im_UL[eNB_id][aa][i]=0.0; } - - // Compute RX signal for eNB = eNB_id - for (UE_id=0; UE_id<NB_UE_INST; UE_id++) { - - txdata = PHY_vars_UE_g[UE_id][CC_id]->common_vars.txdata; - slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1); - slot_offset_meas = ((next_slot&1)==0) ? slot_offset : (slot_offset-(frame_parms->samples_per_tti>>1)); - - if (((double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm + - UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB) <= -125.0) { - - // don't simulate a UE that is too weak - } else { - - tx_pwr = dac_fixed_gain(s_re, - s_im, - txdata, - slot_offset, - nb_antennas_tx, - frame_parms->samples_per_tti>>1, - slot_offset_meas, - frame_parms->ofdm_symbol_size, - 14, - (double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm-10*log10((double)PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE), - PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE); // This make the previous argument the total power - //ue_data[UE_id]->tx_power_dBm); - //#ifdef DEBUG_SIM - LOG_D(OCM,"[SIM][UL] UE %d tx_pwr %f dBm (target %d dBm, num_RE %d) for slot %d (subframe %d, slot_offset %d, slot_offset_meas %d)\n", - UE_id, - 10*log10(tx_pwr), - PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm, - PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE, - next_slot,next_slot>>1,slot_offset,slot_offset_meas); - //#endif - - multipath_channel(UE2eNB[UE_id][eNB_id][CC_id],s_re,s_im,r_re0,r_im0, - frame_parms->samples_per_tti>>1,hold_channel); - - //#ifdef DEBUG_SIM - rx_pwr = signal_energy_fp2(UE2eNB[UE_id][eNB_id][CC_id]->ch[0], - UE2eNB[UE_id][eNB_id][CC_id]->channel_length)*UE2eNB[UE_id][eNB_id][CC_id]->channel_length; - LOG_D(OCM,"[SIM][UL] slot %d Channel UE %d => eNB %d : %f dB (hold %d,length %d, PL %f)\n",next_slot,UE_id,eNB_id,10*log10(rx_pwr), - hold_channel,UE2eNB[UE_id][eNB_id][CC_id]->channel_length, - UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB); - //#endif - - //#ifdef DEBUG_SIM - rx_pwr = signal_energy_fp(r_re0,r_im0,nb_antennas_rx,frame_parms->samples_per_tti>>1,0); - LOG_D(OCM,"[SIM][UL] eNB %d : rx_pwr %f dBm (%f) for slot %d (subframe %d), sptti %d\n", - eNB_id,10*log10(rx_pwr),rx_pwr,next_slot,next_slot>>1,frame_parms->samples_per_tti); - //#endif - - - if (UE2eNB[UE_id][eNB_id][CC_id]->first_run == 1) - UE2eNB[UE_id][eNB_id][CC_id]->first_run = 0; - - - - for (aa=0; aa<nb_antennas_rx; aa++) { - for (i=0; i<(frame_parms->samples_per_tti>>1); i++) { - r_re[aa][i]+=r_re0[aa][i]; - r_im[aa][i]+=r_im0[aa][i]; - } - } - } - } //UE_id - - // RF model - /* - rf_rx(r_re0, - r_im0, - NULL, - NULL, - 0, - frame_parms->nb_antennas_rx, - frame_parms->samples_per_tti>>1, - 1e3/UE2eNB[UE_id][eNB_id]->BW, // sampling time (ns) - 0.0, // freq offset (Hz) (-20kHz..20kHz) - 0.0, // drift (Hz) NOT YET IMPLEMENTED - enb_data[eNB_id]->rx_noise_level, // noise_figure NOT YET IMPLEMENTED - (double)PHY_vars_eNB_g[eNB_id]->rx_total_gain_eNB_dB - 66.227, // rx_gain (dB) (66.227 = 20*log10(pow2(11)) = gain from the adc that will be applied later) - 200.0, // IP3_dBm (dBm) - &UE2eNB[UE_id][eNB_id]->ip, // initial phase - 30.0e3, // pn_cutoff (kHz) - -500.0, // pn_amp (dBc) default: 50 - 0.0, // IQ imbalance (dB), - 0.0); // IQ phase imbalance (rad) - */ - - rf_rx_simple(r_re, - r_im, - nb_antennas_rx, - frame_parms->samples_per_tti>>1, - 1e3/UE2eNB[0][eNB_id][CC_id]->sampling_rate, // sampling time (ns) - (double)PHY_vars_eNB_g[eNB_id][CC_id]->rx_total_gain_dB - 66.227); // rx_gain (dB) (66.227 = 20*log10(pow2(11)) = gain from the adc that will be applied later) - + } + pthread_mutex_unlock(&UE_output_mutex[eNB_id]); + + // Compute RX signal for eNB = eNB_id + for (UE_id=0; UE_id<NB_UE_INST; UE_id++) { + + txdata = PHY_vars_UE_g[UE_id][CC_id]->common_vars.txdata; + sf_offset = subframe*frame_parms->samples_per_tti; + + if (((double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm + + UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB) <= -125.0) { + // don't simulate a UE that is too weak + } else { + + tx_pwr = dac_fixed_gain((double**)s_re, + (double**)s_im, + txdata, + sf_offset, + nb_antennas_tx, + frame_parms->samples_per_tti, + sf_offset, + frame_parms->ofdm_symbol_size, + 14, + (double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm-10*log10((double)PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE), + PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE); // This make the previous argument the total power + LOG_D(OCM,"[SIM][UL] UE %d tx_pwr %f dBm (target %d dBm, num_RE %d) for subframe %d (sf_offset %d)\n", + UE_id, + 10*log10(tx_pwr), + PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm, + PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE, + subframe,sf_offset); + + + multipath_channel(UE2eNB[UE_id][eNB_id][CC_id],(double**)s_re,(double**)s_im,(double**)r_re0,(double**)r_im0, + frame_parms->samples_per_tti,hold_channel); + + + rx_pwr = signal_energy_fp2(UE2eNB[UE_id][eNB_id][CC_id]->ch[0], + UE2eNB[UE_id][eNB_id][CC_id]->channel_length)*UE2eNB[UE_id][eNB_id][CC_id]->channel_length; + + LOG_D(OCM,"[SIM][UL] subframe %d Channel UE %d => eNB %d : %f dB (hold %d,length %d, PL %f)\n",subframe,UE_id,eNB_id,10*log10(rx_pwr), + hold_channel,UE2eNB[UE_id][eNB_id][CC_id]->channel_length, + UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB); + + rx_pwr = signal_energy_fp((double**)r_re0,(double**)r_im0,nb_antennas_rx,frame_parms->samples_per_tti,0); + LOG_D(OCM,"[SIM][UL] eNB %d : rx_pwr %f dBm (%f) for subframe %d, sptti %d\n", + eNB_id,10*log10(rx_pwr),rx_pwr,subframe,frame_parms->samples_per_tti); + + + if (UE2eNB[UE_id][eNB_id][CC_id]->first_run == 1) + UE2eNB[UE_id][eNB_id][CC_id]->first_run = 0; + + + pthread_mutex_lock(&UE_output_mutex[eNB_id]); + for (aa=0; aa<nb_antennas_rx; aa++) { + for (i=0; i<frame_parms->samples_per_tti; i++) { + r_re_UL[eNB_id][aa][i]+=r_re0[aa][i]; + r_im_UL[eNB_id][aa][i]+=r_im0[aa][i]; + } + } + pthread_mutex_unlock(&UE_output_mutex[eNB_id]); + } + } //UE_id + + rf_rx_simple((double**)r_re_UL[eNB_id], + (double**)r_im_UL[eNB_id], + nb_antennas_rx, + frame_parms->samples_per_tti, + 1e3/UE2eNB[0][eNB_id][CC_id]->sampling_rate, // sampling time (ns) + (double)PHY_vars_eNB_g[eNB_id][CC_id]->rx_total_gain_dB - 66.227); // rx_gain (dB) (66.227 = 20*log10(pow2(11)) = gain from the adc that will be applied later) + #ifdef DEBUG_SIM - rx_pwr = signal_energy_fp(r_re,r_im,nb_antennas_rx,frame_parms->samples_per_tti>>1,0)*(double)frame_parms->ofdm_symbol_size/(12.0*frame_parms->N_RB_DL); - LOG_D(OCM,"[SIM][UL] rx_pwr (ADC in) %f dB for slot %d (subframe %d)\n",10*log10(rx_pwr),next_slot,next_slot>>1); + rx_pwr = signal_energy_fp((double**)r_re_UL[eNB_id],(double**)r_im_UL[eNB_id],nb_antennas_rx,frame_parms->samples_per_tti,0)*(double)frame_parms->ofdm_symbol_size/(12.0*frame_parms->N_RB_DL); + LOG_D(OCM,"[SIM][UL] rx_pwr (ADC in) %f dB for subframe %d\n",10*log10(rx_pwr),subframe); #endif - - rxdata = PHY_vars_eNB_g[eNB_id][CC_id]->common_vars.rxdata[0]; - slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1); - - adc(r_re, - r_im, - 0, - slot_offset, - rxdata, - nb_antennas_rx, - frame_parms->samples_per_tti>>1, - 12); - + + rxdata = PHY_vars_eNB_g[eNB_id][CC_id]->common_vars.rxdata[0]; + sf_offset = subframe*frame_parms->samples_per_tti; + + adc((double**)r_re_UL[eNB_id], + (double**)r_im_UL[eNB_id], + 0, + sf_offset, + rxdata, + nb_antennas_rx, + frame_parms->samples_per_tti, + 12); + #ifdef DEBUG_SIM - rx_pwr2 = signal_energy(rxdata[0]+slot_offset,frame_parms->samples_per_tti>>1)*(double)frame_parms->ofdm_symbol_size/(12.0*frame_parms->N_RB_DL); - LOG_D(OCM,"[SIM][UL] eNB %d rx_pwr (ADC out) %f dB (%d) for slot %d (subframe %d)\n",eNB_id,10*log10((double)rx_pwr2),rx_pwr2,next_slot,next_slot>>1); + rx_pwr2 = signal_energy(rxdata[0]+sf_offset,frame_parms->samples_per_tti)*(double)frame_parms->ofdm_symbol_size/(12.0*frame_parms->N_RB_DL); + LOG_D(OCM,"[SIM][UL] eNB %d rx_pwr (ADC out) %f dB (%d) for subframe %d\n",eNB_id,10*log10((double)rx_pwr2),rx_pwr2,subframe); #else - UNUSED_VARIABLE(tx_pwr); - UNUSED_VARIABLE(rx_pwr); - UNUSED_VARIABLE(rx_pwr2); + UNUSED_VARIABLE(tx_pwr); + UNUSED_VARIABLE(rx_pwr); + UNUSED_VARIABLE(rx_pwr2); #endif - - } // eNB_id + } // abstraction_flag==0 } @@ -604,29 +535,13 @@ void init_channel_vars(LTE_DL_FRAME_PARMS *frame_parms, double ***s_re,double ** int i; - *s_re = malloc(2*sizeof(double*)); - *s_im = malloc(2*sizeof(double*)); - *r_re = malloc(2*sizeof(double*)); - *r_im = malloc(2*sizeof(double*)); - *r_re0 = malloc(2*sizeof(double*)); - *r_im0 = malloc(2*sizeof(double*)); - - - 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)); - (*r_re0)[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); - bzero((*r_re0)[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); - (*r_im0)[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); - bzero((*r_im0)[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); - } -} + memset(eNB_output_mask,0,sizeof(int)*NUMBER_OF_UE_MAX); + for (i=0;i<NB_UE_INST;i++) + pthread_mutex_init(&eNB_output_mutex[i],NULL); + memset(UE_output_mask,0,sizeof(int)*NUMBER_OF_eNB_MAX); + for (i=0;i<NB_eNB_INST;i++) + pthread_mutex_init(&UE_output_mutex[i],NULL); + +} diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index f59c7d7f544feee8594e51e990f49a456e307743..2447eca0e6264d3059c3fb3aeddc81e29d577e15 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -179,7 +179,6 @@ extern uint16_t Nid_cell; extern LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; -extern Enb_properties_array_t enb_properties; //#ifdef XFORMS @@ -759,8 +758,9 @@ l2l1_task (void *args_p) proc->frame_rx = frame; proc->subframe_rx = sf; proc->timestamp_rx += PHY_vars_eNB_g[eNB_inst][CC_id]->frame_parms.samples_per_tti; + pthread_mutex_unlock( &proc->mutex_FH ); - if (proc->instance_cnt_FH == 0) { + if (cnt_FH == 0) { if (pthread_cond_signal(&proc->cond_FH) != 0) { LOG_E(PHY,"ERROR pthread_cond_signal for eNB FH CCid %d\n",proc->CC_id); exit_fun("ERROR pthread_cond_signal"); diff --git a/targets/SIMU/USER/oaisim.h b/targets/SIMU/USER/oaisim.h index 6fb16b82db56ddc83fa395a4fff85cbd86df0baa..47eefe472cdcfea8674a116b8f6354b213ca5aff 100644 --- a/targets/SIMU/USER/oaisim.h +++ b/targets/SIMU/USER/oaisim.h @@ -50,11 +50,13 @@ eNB_MAC_INST* get_eNB_mac_inst(module_id_t module_idP); OAI_Emulation* get_OAI_emulation(void); void init_channel_vars(LTE_DL_FRAME_PARMS *frame_parms, double ***s_re,double ***s_im,double ***r_re,double ***r_im,double ***r_re0,double ***r_im0); -void do_UL_sig(double **r_re0,double **r_im0,double **r_re,double **r_im,double **s_re,double **s_im,channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_NUM_CCs], - node_desc_t *enb_data[NUMBER_OF_eNB_MAX],node_desc_t *ue_data[NUMBER_OF_UE_MAX],uint16_t next_slot,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms, uint32_t,uint8_t); +void do_UL_sig(channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_NUM_CCs], + node_desc_t *enb_data[NUMBER_OF_eNB_MAX],node_desc_t *ue_data[NUMBER_OF_UE_MAX], + uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms, + uint32_t frame,int eNB_id,uint8_t CC_id); -void do_DL_sig(double **r_re0,double **r_im0,double **r_re,double **r_im,double **s_re,double **s_im,channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs], - node_desc_t *enb_data[NUMBER_OF_eNB_MAX],node_desc_t *ue_data[NUMBER_OF_UE_MAX],uint16_t next_slot,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms,uint8_t UE_id,int CC_id); +void do_DL_sig(channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs], + node_desc_t *enb_data[NUMBER_OF_eNB_MAX],node_desc_t *ue_data[NUMBER_OF_UE_MAX],uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms,uint8_t UE_id,int CC_id); void init_ue(node_desc_t *ue_data, UE_Antenna ue_ant);//Abstraction changes void init_enb(node_desc_t *enb_data, eNB_Antenna enb_ant);//Abstraction changes diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index 8148730a2456d18d5928fd19edb633bb3d02b3fb..c4a70f8716438e0118444f6d8c365d9335faed47 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -173,6 +173,12 @@ extern time_stats_t ul_chan_stats; extern int xforms; +extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; +extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + +void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst); +void stop_eNB(int nb_inst); + void get_simulation_options(int argc, char *argv[]) { int option; @@ -774,11 +780,15 @@ void get_simulation_options(int argc, char *argv[]) conf_config_file_name, oai_emulation.info.nb_enb_local, enb_properties->number); /* Update some simulation parameters */ - oai_emulation.info.frame_type[0] = enb_properties->properties[0]->frame_type[0]; - oai_emulation.info.tdd_config[0] = enb_properties->properties[0]->tdd_config[0]; - oai_emulation.info.tdd_config_S[0] = enb_properties->properties[0]->tdd_config_s[0]; + oai_emulation.info.frame_type[0] = enb_properties->properties[0]->frame_type[0]; + oai_emulation.info.tdd_config[0] = enb_properties->properties[0]->tdd_config[0]; + oai_emulation.info.tdd_config_S[0] = enb_properties->properties[0]->tdd_config_s[0]; oai_emulation.info.extended_prefix_flag[0] = enb_properties->properties[0]->prefix_type[0]; + oai_emulation.info.node_function[0] = enb_properties->properties[0]->cc_node_function[0]; + oai_emulation.info.node_timing[0] = enb_properties->properties[0]->cc_node_timing[0]; + downlink_frequency[0][0] = enb_properties->properties[0]->downlink_frequency[0]; + uplink_frequency_offset[0][0] = enb_properties->properties[0]->uplink_frequency_offset[0]; } free(conf_config_file_name); @@ -939,6 +949,119 @@ void init_seed(uint8_t set_seed) } } +int eNB_trx_start(openair0_device *device) { + return(0); +} + +void eNB_trx_end(openair0_device *device) { + return; +} + +int eNB_trx_stop(openair0_device *device) { + return(0); +} +int UE_trx_start(openair0_device *device) { + return(0); +} +int UE_trx_end(openair0_device *device) { + return(0); +} +int UE_trx_stop(openair0_device *device) { + return(0); +} +int eNB_trx_set_freq(openair0_device *device, openair0_config_t *openair0_cfg, int dummy) { + return(0); +} +int eNB_trx_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { + return(0); +} +int UE_trx_set_freq(openair0_device *device, openair0_config_t *openair0_cfg, int dummy) { + return(0); +} +int UE_trx_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { + return(0); +} + +int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { + return(0); +} + +int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { + return(0); +} + +int eNB_trx_write(openair0_device *device,openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { + + int eNB_id = device->Mod_id; + int CC_id = device->CC_id; + int UE_id; + int subframe = (timestamp/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10; + + for (UE_id=0;UE_id<=NB_UE_INST;UE_id++) { + do_DL_sig(eNB2UE, + enb_data, + ue_data, + subframe, + 0, //abstraction_flag, + &PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms, + UE_id, + CC_id); + } + return(0); +} + +int UE_trx_write(openair0_device *device,openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { + + int UE_id = device->Mod_id; + int CC_id = device->CC_id; + int eNB_id; + int subframe = (timestamp/PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)%10; + + for (eNB_id=0;eNB_id<=NB_eNB_INST;eNB_id++) { + do_UL_sig(UE2eNB, + enb_data, + ue_data, + subframe, + 0, // abstraction_flag + &PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms, + 0, // frame is only used for abstraction + eNB_id, + CC_id); + } + return(0); +} + +void init_devices(void){ + + module_id_t UE_id, eNB_id; + uint8_t CC_id; + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + for (eNB_id=0;eNB_id<NB_eNB_INST;eNB_id++) { + PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.Mod_id = eNB_id; + PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.CC_id = CC_id; + PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_start_func = eNB_trx_start; + PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_read_func = eNB_trx_read; + PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_write_func = eNB_trx_write; + PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_end_func = eNB_trx_end; + PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_stop_func = eNB_trx_stop; + PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_set_freq_func = eNB_trx_set_freq; + PHY_vars_eNB_g[eNB_id][CC_id]->rfdevice.trx_set_gains_func = eNB_trx_set_gains; + } + for (UE_id=0;UE_id<NB_eNB_INST;UE_id++) { + PHY_vars_UE_g[UE_id][CC_id]->rfdevice.Mod_id = UE_id; + PHY_vars_UE_g[UE_id][CC_id]->rfdevice.CC_id = CC_id; + PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_start_func = UE_trx_start; + PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_read_func = UE_trx_read; + PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_write_func = UE_trx_write; + PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_end_func = UE_trx_end; + PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_stop_func = UE_trx_stop; + PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_set_freq_func = UE_trx_set_freq; + PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_set_gains_func = UE_trx_set_gains; + } + } +} + void init_openair1(void) { module_id_t UE_id, eNB_id; @@ -1029,7 +1152,9 @@ void init_openair1(void) } } - init_eNB(eNodeB_3GPP,NB_eNB_INST); + init_devices (); + + init_eNB(oai_emulation.info.node_function,oai_emulation.info.node_timing,NB_eNB_INST); // init_ue_status(); for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {