diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index cf3959e220..5df5075295 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -255,10 +255,34 @@ const char* eurecomFunctionsNames[] = { "phy_procedures_eNb_tx1", "phy_procedures_ru_feprx0", "phy_procedures_ru_feprx1", + "phy_procedures_ru_feprx2", + "phy_procedures_ru_feprx3", + "phy_procedures_ru_feprx4", + "phy_procedures_ru_feprx5", + "phy_procedures_ru_feprx6", + "phy_procedures_ru_feprx7", + "phy_procedures_ru_feprx8", + "phy_procedures_ru_feprx9", "phy_procedures_ru_feptx_ofdm0", "phy_procedures_ru_feptx_ofdm1", + "phy_procedures_ru_feptx_ofdm2", + "phy_procedures_ru_feptx_ofdm3", + "phy_procedures_ru_feptx_ofdm4", + "phy_procedures_ru_feptx_ofdm5", + "phy_procedures_ru_feptx_ofdm6", + "phy_procedures_ru_feptx_ofdm7", + "phy_procedures_ru_feptx_ofdm8", + "phy_procedures_ru_feptx_ofdm9", "phy_procedures_ru_feptx_prec0", "phy_procedures_ru_feptx_prec1", + "phy_procedures_ru_feptx_prec2", + "phy_procedures_ru_feptx_prec3", + "phy_procedures_ru_feptx_prec4", + "phy_procedures_ru_feptx_prec5", + "phy_procedures_ru_feptx_prec6", + "phy_procedures_ru_feptx_prec7", + "phy_procedures_ru_feptx_prec8", + "phy_procedures_ru_feptx_prec9", "phy_procedures_eNb_rx_uespec0", "phy_procedures_eNb_rx_uespec1", "phy_procedures_ue_tx", diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index 590717c726..1d4dea01e8 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -232,10 +232,34 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX1, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX2, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX3, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX4, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX5, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX6, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX7, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX8, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX9, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM1, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM2, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM3, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM4, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM5, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM6, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM7, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM8, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM9, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC1, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC2, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC3, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC4, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC5, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC6, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC7, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC8, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC9, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC1, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index b0b9940c30..14dc4c553f 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -39,10 +39,10 @@ typedef struct { #define T_SHM_FILENAME "/T_shm_segment" /* number of VCD functions (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_FUNCTIONS 190 +#define VCD_NUM_FUNCTIONS (190+24) /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_VARIABLES 128 +#define VCD_NUM_VARIABLES (128+24) /* first VCD function (to be kept up to date! see in T_messages.txt) */ #define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index fd4425063b..51b6f9b0c5 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1656,6 +1656,49 @@ ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPRX1 DESC = VCD function PHY_PROCEDURES_RU_FEPRX1 GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value +<<<<<<< HEAD +======= + VCD_NAME = phy_procedures_ru_feprx1 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPRX2 + DESC = VCD function PHY_PROCEDURES_RU_FEPRX2 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feprx2 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPRX3 + DESC = VCD function PHY_PROCEDURES_RU_FEPRX3 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feprx3 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPRX4 + DESC = VCD function PHY_PROCEDURES_RU_FEPRX4 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feprx4 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPRX5 + DESC = VCD function PHY_PROCEDURES_RU_FEPRX5 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feprx5 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPRX6 + DESC = VCD function PHY_PROCEDURES_RU_FEPRX6 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feprx6 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPRX7 + DESC = VCD function PHY_PROCEDURES_RU_FEPRX7 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feprx7 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPRX8 + DESC = VCD function PHY_PROCEDURES_RU_FEPRX8 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feprx8 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPRX9 + DESC = VCD function PHY_PROCEDURES_RU_FEPRX9 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feprx9 ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM GROUP = ALL:VCD:ENB:VCD_FUNCTION @@ -1664,6 +1707,47 @@ ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM1 DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM1 GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm1 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM2 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM2 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm2 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM3 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM3 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm3 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM4 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM4 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm4 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM5 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM5 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm5 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM6 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM6 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm6 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM7 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM7 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm7 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM8 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM8 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm8 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM9 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM9 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm9 ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC GROUP = ALL:VCD:ENB:VCD_FUNCTION @@ -1672,6 +1756,47 @@ ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC1 DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC1 GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_prec1 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC2 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC2 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_prec2 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC3 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC3 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_prec3 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC4 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC4 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_prec4 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC5 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC5 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_prec5 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC6 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC6 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_prec6 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC7 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC7 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_prec7 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC8 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC8 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_prec8 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC9 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC9 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_prec9 ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_RX_UESPEC DESC = VCD function PHY_PROCEDURES_ENB_RX_UESPEC GROUP = ALL:VCD:ENB:VCD_FUNCTION diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index 9b1563e4f5..8dff913fdc 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -29,6 +29,19 @@ * \note * \warning */ + + /*! \function beam_precoding_one_eNB + * \brief Create and Implementation of beamforming in one eNB + * \author TY Hsu, SY Yeh(fdragon), TH Wang(Judy) + * \date 2018 + * \version 0.1 + * \company ISIP@NCTU and Eurecom + * \email: tyhsu@cs.nctu.edu.tw,fdragon.cs96g@g2.nctu.edu.tw,Tsu-Han.Wang@eurecom.fr + * \note + * \warning + */ + + #include "PHY/defs_common.h" #include "PHY/defs_eNB.h" #include "PHY/phy_extern.h" @@ -43,49 +56,107 @@ int beam_precoding(int32_t **txdataF, int32_t **txdataF_BF, LTE_DL_FRAME_PARMS *frame_parms, int32_t ***beam_weights, - int slot, int symbol, - int aa) + int aa, + int p) { - uint8_t p; - //uint16_t re=0; - int slot_offset_F; + //LOG_I(PHY,"Starting precoding for symbol %d, physical antenna %d, logical port %d\n",symbol,aa,p); + int rb_offset_neg = frame_parms->ofdm_symbol_size - (6*frame_parms->N_RB_DL); +/* if(rb<(frame_parms->N_RB_DL/2)) { + rb_offset = rb*12; + }else if(rb>=(frame_parms->N_RB_DL/2)) { + rb_offset = 12*(rb-(frame_parms->N_RB_DL/2)); + //rb_offset = 1+(12*(rb-(frame_parms->N_RB_DL>>1))); + }*/ + //printf("aa = %d, p = %d, symbol = %d, rb = %d, rb_offset = %d, orisma = %d\n",aa,p,symbol,rb,rb_offset,rb_offset+symbol*12); + //printf("aa = %d, p = %d, symbol = %d\n",aa,p,symbol); + - slot_offset_F = slot*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==1) ? 6 : 7); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTADD,1); - // clear txdata_BF[aa][re] for each call of ue_spec_beamforming - memset(txdataF_BF[aa],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size)); + multadd_cpx_vector((int16_t*)&txdataF[p][rb_offset_neg+(symbol*frame_parms->ofdm_symbol_size)], + (int16_t*)&beam_weights[p][aa][rb_offset_neg], + (int16_t*)&txdataF_BF[aa][rb_offset_neg+(symbol*frame_parms->ofdm_symbol_size)], + 0, + 6*frame_parms->N_RB_DL, + 15); + multadd_cpx_vector((int16_t*)&txdataF[p][(symbol*frame_parms->ofdm_symbol_size)], + (int16_t*)&beam_weights[p][aa][0], + (int16_t*)&txdataF_BF[aa][(symbol*frame_parms->ofdm_symbol_size)], + 0, + 7*frame_parms->N_RB_DL, // to allow for extra RE at the end, 12 useless multipy-adds (first one at DC and 11 at end) + 15); +/* + if (last_prb == 1 && rb>=(frame_parms->N_RB_DL/2)) { + // do extra complex multiplication for remaining RE + uint16_t re = frame_parms->ofdm_symbol_size-1; + ((int16_t*)&txdataF_BF[aa][(rb_offset+1)+re])[0] += (int16_t)((((int16_t*)&txdataF[p][(rb_offset+1)+(symbol*frame_parms->ofdm_symbol_size)+re])[0]*((int16_t*)&beam_weights[p][aa][(rb_offset+1)+re])[0])>>15); + ((int16_t*)&txdataF_BF[aa][(rb_offset+1)+re])[0] -= (int16_t)((((int16_t*)&txdataF[p][(rb_offset+1)+(symbol*frame_parms->ofdm_symbol_size)+re])[1]*((int16_t*)&beam_weights[p][aa][(rb_offset+1)+re])[1])>>15); + ((int16_t*)&txdataF_BF[aa][(rb_offset+1)+re])[1] += (int16_t)((((int16_t*)&txdataF[p][(rb_offset+1)+(symbol*frame_parms->ofdm_symbol_size)+re])[0]*((int16_t*)&beam_weights[p][aa][(rb_offset+1)+re])[1])>>15); + ((int16_t*)&txdataF_BF[aa][(rb_offset+1)+re])[1] += (int16_t)((((int16_t*)&txdataF[p][(rb_offset+1)+(symbol*frame_parms->ofdm_symbol_size)+re])[1]*((int16_t*)&beam_weights[p][aa][(rb_offset+1)+re])[0])>>15); + } +*/ + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MULTADD,0); - for (p=0; pnb_antenna_ports_eNB || p==5) { - multadd_cpx_vector((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size], - (int16_t*)beam_weights[p][aa], - (int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], - 0, - frame_parms->ofdm_symbol_size, - 15); - //mult_cpx_conj_vector((int16_t*)beam_weights[p][aa], (int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size], (int16_t*)txdataF_BF[aa], frame_parms->ofdm_symbol_size, 15, 1); + return 0; +} - // if check version - /*for (re=0;reofdm_symbol_size;re++) { - if (txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re]!=0) { - ((int16_t*)&txdataF_BF[aa][re])[0] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0]*((int16_t*)&beam_weights[p][aa][re])[0])>>15); - ((int16_t*)&txdataF_BF[aa][re])[0] -= (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); - ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); - ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1]*((int16_t*)&beam_weights[p][aa][re])[0])>>15); - printf("beamforming.c:txdataF[%d][%d]=%d+j%d, beam_weights[%d][%d][%d]=%d+j%d,txdata_BF[%d][%d]=%d+j%d\n", - p,slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re, - ((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0], - ((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1], - p,aa,re, - ((int16_t*)&beam_weights[p][aa][re])[0],((int16_t*)&beam_weights[p][aa][re])[1], - aa,re, - ((int16_t*)&txdataF_BF[aa][re])[0], - ((int16_t*)&txdataF_BF[aa][re])[1]); - } - }*/ - } +int beam_precoding_one_eNB(int32_t **txdataF, + int32_t **txdataF_BF, + int32_t ***beam_weights, + int subframe, + int nb_antenna_ports, + int nb_tx, // total physical antenna + LTE_DL_FRAME_PARMS *frame_parms + ) +{ + int p, re, symbol, aa; // loop index + int re_offset; + int ofdm_symbol_size = frame_parms->ofdm_symbol_size; + int symbols_per_tti = frame_parms->symbols_per_tti; + int nb_antenna_ports_eNB = frame_parms->nb_antenna_ports_eNB; // logic antenna ports + + + re_offset = ofdm_symbol_size*symbols_per_tti*subframe; + + + // txdataF_BF[aa][re] = sum(beam_weghts[p][aa][re]*txdataF[p][re]), p=0~nb_antenna_ports-1 + // real part and image part need to compute separately + + for (aa=0; aa>15); + ((int16_t*)&txdataF_BF[aa][re])[0] -= (int16_t)((((int16_t*)&txdataF[p][re+symbol*ofdm_symbol_size+re_offset])[1]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); + ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][re+symbol*ofdm_symbol_size+re_offset])[0]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); + ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][re+symbol*ofdm_symbol_size+re_offset])[1]*((int16_t*)&beam_weights[p][aa][re])[0])>>15); + } + */ + } + } + } } + + + + + + + return 0; } diff --git a/openair1/PHY/MODULATION/modulation_eNB.h b/openair1/PHY/MODULATION/modulation_eNB.h index 3608610887..1e80b90f4b 100644 --- a/openair1/PHY/MODULATION/modulation_eNB.h +++ b/openair1/PHY/MODULATION/modulation_eNB.h @@ -50,9 +50,29 @@ int beam_precoding(int32_t **txdataF, int32_t **txdataF_BF, LTE_DL_FRAME_PARMS *frame_parms, int32_t ***beam_weights, - int slot, int symbol, - int aa); + int aa, + int p); + +/** \brief This function performs beamforming precoding for common + * data for only one eNB, fdragon + @param txdataF Table of pointers for frequency-domain TX signals + @param txdataF_BF Table of pointers for frequency-domain TX signals + @param frame_parms Frame descriptor structure +after beamforming + @param beam_weights Beamforming weights applied on each +antenna element and each carrier + @param slot Slot number + @param symbol Symbol index on which to act + @param aa physical antenna index*/ +int beam_precoding_one_eNB(int32_t **txdataF, + int32_t **txdataF_BF, + int32_t ***beam_weights, + int subframe, + int nb_antenna_ports, + int nb_tx, // total physical antenna + LTE_DL_FRAME_PARMS *frame_parms + ); int f_read(char *calibF_fname, int nb_ant, int nb_freq, int32_t **tdd_calib_coeffs); diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index 9135ef651f..c8300c463a 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -29,6 +29,18 @@ * \note * \warning */ + +/*! \function feptx_prec + * \brief Implementation of precoding for beamforming in one eNB + * \author TY Hsu, SY Yeh(fdragon), TH Wang(Judy) + * \date 2018 + * \version 0.1 + * \company ISIP@NCTU and Eurecom + * \email: tyhsu@cs.nctu.edu.tw,fdragon.cs96g@g2.nctu.edu.tw,Tsu-Han.Wang@eurecom.fr + * \note + * \warning + */ + #include "PHY/defs_eNB.h" #include "PHY/phy_extern.h" @@ -71,7 +83,7 @@ void feptx0(RU_t *ru,int slot) { int subframe = ru->proc.subframe_tx; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+slot , 1 ); + //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)); @@ -148,7 +160,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 , 0); } static void *feptx_thread(void *param) { @@ -200,12 +212,12 @@ void feptx_ofdm_2thread(RU_t *ru) { 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 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+ru->idx , 1 ); start_meas(&ru->ofdm_mod_stats); if (subframe_select(fp,subframe) == SF_UL) return; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); if (subframe_select(fp,subframe)==SF_DL) { // If this is not an S-subframe @@ -245,10 +257,10 @@ 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 ); + //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 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+ru->idx , 0 ); } @@ -267,7 +279,7 @@ void feptx_ofdm(RU_t *ru) { // int CC_id = ru->proc.CC_id; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+ru->idx , 1 ); slot_offset_F = 0; slot_offset = subframe*fp->samples_per_tti; @@ -389,32 +401,143 @@ void feptx_ofdm(RU_t *ru) { dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF))); } } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+ru->idx , 0 ); } void feptx_prec(RU_t *ru) { + + // Theoni's + int l,i,aa,rb,p; + int subframe = ru->proc.subframe_tx; + PHY_VARS_eNB **eNB_list = ru->eNB_list,*eNB; + LTE_DL_FRAME_PARMS *fp; + int32_t ***bw; + RU_proc_t *proc = &ru->proc; + /* fdragon 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.subframe_tx; + */ if (ru->idx != 0) return; if (ru->num_eNB == 1) { - eNB = eNB_list[0]; + // Theoni's part //////////////////////////////////// + eNB = eNB_list[0]; fp = &eNB->frame_parms; + LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[subframe&1]; + //int bf_mask_pdcch = 1; + + //int bf_mask[15][fp->N_RB_DL]; + /*for (p=0;p<15;p++) { + for (int j=0;jN_RB_DL;j++){ + // set p=5 to bfmask=2 (beamforming) except in subframes 0 and 5 + // p=0,1 bf_mask=0 for subframes different than 0,5 and to + if (subframe != 0 && subframe != 5) + if (pnb_antenna_ports_eNB || p!=5) bf_mask[p][j]=0; else bf_mask[p][j]=2; + else + if (pnb_antenna_ports_eNB) bf_mask[p][j]=1; else bf_mask[p][j]=0; + } + + //printf("subframe %d : bf_mask[%d][0] %d\n",subframe,p,bf_mask[p][0]); + }*/ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+ru->idx , 1); - // simple antenna port mapping rule that works both for single antenna eNB and dual antenna eNB. It maps antenna ports evenly to RUs - for (aa=0;aanb_tx;aa++) - memcpy((void*)ru->common.txdataF_BF[aa], - (void*)&eNB->common_vars.txdataF[(aa+ru->idx)%eNB->frame_parms.nb_antenna_ports_eNB][subframe*fp->symbols_per_tti*fp->ofdm_symbol_size], - fp->symbols_per_tti*fp->ofdm_symbol_size*sizeof(int32_t)); + for (aa=0;aanb_tx;aa++) { + memset(ru->common.txdataF_BF[aa],0,sizeof(int32_t)*(fp->ofdm_symbol_size)); + for (p=0;pnb_antenna_ports_eNB) { +// pdcch region, copy entire signal from txdataF->txdataF_BF (bf_mask = 1) +// else do beamforming for pdcch according to beam_weights +// to be updated for eMBMS (p=4) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 0); + /* AssertFatal(bf_mask[p][0]>=0 && bf_mask[p][0] < 3, + "Illegal bf_mask[%d][0] %d\n",p,bf_mask[p][0]); + */ + /*if (bf_mask_pdcch == 1) + memcpy((void*)ru->common.txdataF_BF[aa], + (void*)&eNB->common_vars.txdataF[p][0], + pdcch_vars->num_pdcch_symbols*fp->ofdm_symbol_size*sizeof(int32_t)); + else if (bf_mask_pdcch == 2) {*/ + for (l=0;lnum_pdcch_symbols;l++) + // for (rb=0;rbN_RB_DL;rb++) + beam_precoding(eNB->common_vars.txdataF, + ru->common.txdataF_BF, + fp, + ru->beam_weights, + l, + aa, + p); + //} // else if (bf_mask_pdcch == 2) + } //if (pnb_antenna_ports_eNB) + +// PDSCH region + if (pnb_antenna_ports_eNB || p==5 || p==7 || p==8) { + for (l=pdcch_vars->num_pdcch_symbols;lsymbols_per_tti;l++) { + beam_precoding(eNB->common_vars.txdataF, + ru->common.txdataF_BF, + fp, + ru->beam_weights, + l, + aa, + p); + /*for (rb=0;rbN_RB_DL;rb++) { + AssertFatal(bf_mask[p][rb]>=0 && bf_mask[p][rb] < 3, + "Illegal bf_mask[%d][%d] %d\n",p,rb,bf_mask[p][rb]); + if (bf_mask[p][rb]==1) { + memcpy((void*)&ru->common.txdataF_BF[aa][l*fp->ofdm_symbol_size], + (void*)&eNB->common_vars.txdataF[p][l*fp->ofdm_symbol_size], + fp->ofdm_symbol_size*sizeof(int32_t)); + } else if (bf_mask[p][rb]==2) { + beam_precoding(eNB->common_vars.txdataF, + ru->common.txdataF_BF, + fp, + ru->beam_weights, + l, + aa, + p, + rb, + 0); + } // else if (bf_mask[p][rb]==1) + }// for (rb=0;rb<...)*/ + } // for (l=pdcch_vars ....) + } // if (pnb_antenna_ports_eNB) ... + } // for (p=0...) + } // for (aa=0 ...) + + if(ru->idx<2) + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+ru->idx , 0); + // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RU_FEPTX_PREC+ru->idx,0); + + /////////////////////////////////////////////////// + + + /* fdragon + eNB = eNB_list[0]; + bw = ru->beam_weights[0]; + fp = &eNB->frame_parms; + int nb_antenna_ports=15; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+ru->idx , 1); + + + beam_precoding_one_eNB(eNB->common_vars.txdataF, + ru->common.txdataF_BF, + bw, + subframe, + nb_antenna_ports, + ru->nb_tx, + fp); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+ru->idx , 0); + + + */ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+ru->idx , 0); } else { for (i=0;inum_eNB;i++) { @@ -445,7 +568,7 @@ void fep0(RU_t *ru,int slot) { // printf("fep0: slot %d\n",slot); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+slot, 1); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+slot, 1); remove_7_5_kHz(ru,(slot&1)+(proc->subframe_rx<<1)); for (l=0; lsymbols_per_tti/2; l++) { @@ -455,7 +578,7 @@ void fep0(RU_t *ru,int slot) { 0 ); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+slot, 0); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+slot, 0); } @@ -480,9 +603,9 @@ static void *fep_thread(void *param) { if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread")<0) break; if (oai_exit) break; //stop_meas(&ru->ofdm_demod_wakeup_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 1 ); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 1 ); fep0(ru,0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 0 ); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 0 ); if (release_thread(&proc->mutex_fep,&proc->instance_cnt_fep,"fep thread")<0) break; if (pthread_cond_signal(&proc->cond_fep) != 0) { @@ -566,12 +689,12 @@ void ru_fep_full_2thread(RU_t *ru) { if ((fp->frame_type == TDD) && (subframe_select(fp,proc->subframe_rx) != SF_UL)) return; - if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); + //if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); wait.tv_sec=0; wait.tv_nsec=5000000L; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 1 ); start_meas(&ru->ofdm_demod_stats); if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) { @@ -611,7 +734,7 @@ void ru_fep_full_2thread(RU_t *ru) { } stop_meas(&ru->ofdm_demod_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 0 ); } @@ -626,7 +749,7 @@ void fep_full(RU_t *ru) { (subframe_select(fp,proc->subframe_rx) != 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 ); + if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 1 ); remove_7_5_kHz(ru,proc->subframe_rx<<1); remove_7_5_kHz(ru,1+(proc->subframe_rx<<1)); @@ -643,7 +766,7 @@ void fep_full(RU_t *ru) { 0 ); } - if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 ); + if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 0 ); stop_meas(&ru->ofdm_demod_stats); diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 1ca0024d88..2120250630 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -29,6 +29,18 @@ * \note * \warning */ + +/*! \function wakeup_txfh + * \brief Implementation of creating multiple RU threads for beamforming emulation + * \author TH Wang(Judy), TY Hsu, SY Yeh(fdragon) + * \date 2018 + * \version 0.1 + * \company Eurecom and ISIP@NCTU + * \email: Tsu-Han.Wang@eurecom.fr,tyhsu@cs.nctu.edu.tw,fdragon.cs96g@g2.nctu.edu.tw + * \note + * \warning + */ + #define _GNU_SOURCE #include @@ -148,7 +160,7 @@ void init_eNB(int,int); void stop_eNB(int nb_inst); int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc); -int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc); +int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB); void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); @@ -308,9 +320,10 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam static void* tx_thread(void* param) { - eNB_proc_t *eNB_proc = (eNB_proc_t*)param; + PHY_VARS_eNB *eNB = (PHY_VARS_eNB *)param; + eNB_proc_t *eNB_proc = &eNB->proc; eNB_rxtx_proc_t *proc = &eNB_proc->proc_rxtx[1]; - PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; + //PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; char thread_name[100]; sprintf(thread_name,"TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); @@ -344,7 +357,7 @@ static void* tx_thread(void* param) { exit_fun( "ERROR pthread_cond_signal" ); } pthread_mutex_unlock( &proc->mutex_rxtx ); - wakeup_txfh(proc,eNB_proc->ru_proc); + wakeup_txfh(proc,eNB); } return 0; @@ -367,7 +380,8 @@ static void* eNB_thread_rxtx( void* param ) { proc = (eNB_rxtx_proc_t*)param; } else{ - eNB_proc_t *eNB_proc = (eNB_proc_t*)param; + PHY_VARS_eNB *eNB = (PHY_VARS_eNB *)param; + eNB_proc_t *eNB_proc = &eNB->proc; proc = &eNB_proc->proc_rxtx[0]; } @@ -431,7 +445,7 @@ static void* eNB_thread_rxtx( void* param ) { else { phy_procedures_eNB_TX(eNB, proc, 1); - wakeup_txfh(proc,eNB->proc.ru_proc); + wakeup_txfh(proc,eNB); } } @@ -473,45 +487,47 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t } } -int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc) { +int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { - if(ru_proc == NULL) - return(0); + RU_proc_t *ru_proc; struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; - - if(wait_on_condition(&ru_proc->mutex_eNBs,&ru_proc->cond_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) { - LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", ru_proc->frame_tx, ru_proc->subframe_tx); - return(-1); - } - if (release_thread(&ru_proc->mutex_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) return(-1); - - if (ru_proc->instance_cnt_eNBs == 0) { - LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx); - return(-1); - } - if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs ); - exit_fun( "error locking mutex_eNB" ); - return(-1); - } + for(int ru_id=0; ru_idnum_RU; ru_id++){ + ru_proc = &eNB->RU_list[ru_id]->proc; + if(ru_proc == NULL) + return(0); + if(wait_on_condition(&ru_proc->mutex_eNBs,&ru_proc->cond_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) { + LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", ru_proc->frame_tx, ru_proc->subframe_tx); + return(-1); + } + if (release_thread(&ru_proc->mutex_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) return(-1); + + if (ru_proc->instance_cnt_eNBs == 0) { + LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx); + return(-1); + } + if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs ); + exit_fun( "error locking mutex_eNB" ); + return(-1); + } - ++ru_proc->instance_cnt_eNBs; - ru_proc->timestamp_tx = proc->timestamp_tx; - ru_proc->subframe_tx = proc->subframe_tx; - ru_proc->frame_tx = proc->frame_tx; - - // the thread can now be woken up - if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return(-1); + ++ru_proc->instance_cnt_eNBs; + ru_proc->timestamp_tx = proc->timestamp_tx; + ru_proc->subframe_tx = proc->subframe_tx; + ru_proc->frame_tx = proc->frame_tx; + + // the thread can now be woken up + if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return(-1); + } + + pthread_mutex_unlock( &ru_proc->mutex_eNBs ); } - - pthread_mutex_unlock( &ru_proc->mutex_eNBs ); - return(0); } @@ -978,8 +994,8 @@ void init_eNB_proc(int inst) { LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); if (eNB->single_thread_flag==0 && nfapi_mode!=2) { - pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc ); - pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc); + pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, eNB ); + pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, eNB); } pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))