Commit bf678f7f authored by Cedric Roux's avatar Cedric Roux

Merge remote-tracking branch...

Merge remote-tracking branch 'origin/RU-RAU-split-parallel-EMUFH-phy-test-merge' into develop_integration_2018_w15
parents 1272cabb 68fdd19c
...@@ -1365,6 +1365,7 @@ set (MAC_SRC ...@@ -1365,6 +1365,7 @@ set (MAC_SRC
${MAC_DIR}/eNB_scheduler_bch.c ${MAC_DIR}/eNB_scheduler_bch.c
${MAC_DIR}/eNB_scheduler_primitives.c ${MAC_DIR}/eNB_scheduler_primitives.c
${MAC_DIR}/eNB_scheduler_RA.c ${MAC_DIR}/eNB_scheduler_RA.c
${MAC_DIR}/eNB_scheduler_phytest.c
${MAC_DIR}/pre_processor.c ${MAC_DIR}/pre_processor.c
${MAC_DIR}/config.c ${MAC_DIR}/config.c
${MAC_DIR}/config_ue.c ${MAC_DIR}/config_ue.c
......
...@@ -130,6 +130,7 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) ...@@ -130,6 +130,7 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
{ {
case TYPE_STRING: case TYPE_STRING:
printf("call config_lookup_string for '%s' %p\n", cfgpath, &(libconfig_privdata.cfg)); fflush(stdout);
if ( config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) { if ( config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) {
if ( cfgoptions[i].numelt > 0 && str != NULL && strlen(str) >= cfgoptions[i].numelt ) { if ( cfgoptions[i].numelt > 0 && str != NULL && strlen(str) >= cfgoptions[i].numelt ) {
fprintf(stderr,"[LIBCONFIG] %s: %s exceeds maximum length of %i bytes, value truncated\n", fprintf(stderr,"[LIBCONFIG] %s: %s exceeds maximum length of %i bytes, value truncated\n",
......
...@@ -72,6 +72,9 @@ const int itti_debug = (ITTI_DEBUG_ISSUES | ITTI_DEBUG_MP_STATISTICS); ...@@ -72,6 +72,9 @@ const int itti_debug = (ITTI_DEBUG_ISSUES | ITTI_DEBUG_MP_STATISTICS);
/* Global message size */ /* Global message size */
#define MESSAGE_SIZE(mESSAGEiD) (sizeof(MessageHeader) + itti_desc.messages_info[mESSAGEiD].size) #define MESSAGE_SIZE(mESSAGEiD) (sizeof(MessageHeader) + itti_desc.messages_info[mESSAGEiD].size)
extern int emulate_rf;
typedef enum task_state_s { typedef enum task_state_s {
TASK_STATE_NOT_CONFIGURED, TASK_STATE_STARTING, TASK_STATE_READY, TASK_STATE_ENDED, TASK_STATE_MAX, TASK_STATE_NOT_CONFIGURED, TASK_STATE_STARTING, TASK_STATE_READY, TASK_STATE_ENDED, TASK_STATE_MAX,
} task_state_t; } task_state_t;
...@@ -342,14 +345,16 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me ...@@ -342,14 +345,16 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me
destination_task_id, destination_task_id,
itti_get_task_name(destination_task_id)); itti_get_task_name(destination_task_id));
} else { } else {
/* We cannot send a message if the task is not running */ if(!emulate_rf){
AssertFatal (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_READY, /* We cannot send a message if the task is not running */
"Task %s Cannot send message %s (%d) to thread %d, it is not in ready state (%d)!\n", AssertFatal (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_READY,
itti_get_task_name(origin_task_id), "Task %s Cannot send message %s (%d) to thread %d, it is not in ready state (%d)!\n",
itti_desc.messages_info[message_id].name, itti_get_task_name(origin_task_id),
message_id, itti_desc.messages_info[message_id].name,
destination_thread_id, message_id,
itti_desc.threads[destination_thread_id].task_state); destination_thread_id,
itti_desc.threads[destination_thread_id].task_state);
}
/* Allocate new list element */ /* Allocate new list element */
new = (message_list_t *) itti_malloc (origin_task_id, destination_task_id, sizeof(struct message_list_s)); new = (message_list_t *) itti_malloc (origin_task_id, destination_task_id, sizeof(struct message_list_s));
......
...@@ -201,8 +201,8 @@ void oai_create_enb(void) { ...@@ -201,8 +201,8 @@ void oai_create_enb(void) {
eNB->CC_id = bodge_counter; eNB->CC_id = bodge_counter;
eNB->abstraction_flag = 0; eNB->abstraction_flag = 0;
eNB->single_thread_flag = 0;//single_thread_flag; eNB->single_thread_flag = 0;//single_thread_flag;
eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; eNB->td = ulsch_decoding_data_all;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data;
eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; eNB->te = dlsch_encoding_all;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding;
RC.nb_CC[bodge_counter] = 1; RC.nb_CC[bodge_counter] = 1;
......
...@@ -738,6 +738,7 @@ void phy_config_cba_rnti (module_id_t Mod_id,int CC_id,eNB_flag_t eNB_flag, uin ...@@ -738,6 +738,7 @@ void phy_config_cba_rnti (module_id_t Mod_id,int CC_id,eNB_flag_t eNB_flag, uin
} }
} }
int phy_init_lte_eNB(PHY_VARS_eNB *eNB, int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
unsigned char is_secondary_eNB, unsigned char is_secondary_eNB,
unsigned char abstraction_flag) unsigned char abstraction_flag)
......
...@@ -2276,7 +2276,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, ...@@ -2276,7 +2276,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
/* clear all bits, the above code may generate too much false detections /* clear all bits, the above code may generate too much false detections
* (not sure about this, to be checked somehow) * (not sure about this, to be checked somehow)
*/ */
// memset(e, 0, DCI_BITS_MAX); //memset(e, 0, DCI_BITS_MAX);
e_ptr = e; e_ptr = e;
...@@ -2298,6 +2298,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, ...@@ -2298,6 +2298,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
#endif #endif
if (dci_alloc[i].firstCCE>=0) { if (dci_alloc[i].firstCCE>=0) {
//printf("generate DCI .%d rnti %d length %d\n", subframe, dci_alloc[i].rnti, dci_alloc[i].dci_length);
e_ptr = generate_dci0(dci_alloc[i].dci_pdu, e_ptr = generate_dci0(dci_alloc[i].dci_pdu,
e+(72*dci_alloc[i].firstCCE), e+(72*dci_alloc[i].firstCCE),
dci_alloc[i].dci_length, dci_alloc[i].dci_length,
......
...@@ -2183,6 +2183,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t ...@@ -2183,6 +2183,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
#endif #endif
//printf("DCI %d.%d rnti %d harq %d TBS %d\n", frame, subframe, rel8->rnti, rel8->harq_process, dlsch0_harq->TBS);
#if T_TRACER #if T_TRACER
if (dlsch0->active) if (dlsch0->active)
T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame), T_INT(subframe), T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame), T_INT(subframe),
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/LOG/log.h" #include "UTIL/LOG/log.h"
#include <syscall.h> #include <syscall.h>
#include "targets/RT/USER/rt_wrapper.h"
//#define DEBUG_DLSCH_CODING //#define DEBUG_DLSCH_CODING
//#define DEBUG_DLSCH_FREE 1 //#define DEBUG_DLSCH_FREE 1
...@@ -52,7 +53,13 @@ ...@@ -52,7 +53,13 @@
((pilots==1)&&(first_pilot==0)&&(((re<3))||((re>5)&&(re<9)))) \ ((pilots==1)&&(first_pilot==0)&&(((re<3))||((re>5)&&(re<9)))) \
*/ */
#define is_not_pilot(pilots,first_pilot,re) (1) #define is_not_pilot(pilots,first_pilot,re) (1)
/*extern void thread_top_init(char *thread_name,
int affinity,
uint64_t runtime,
uint64_t deadline,
uint64_t period);*/
extern int codingw;
void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch)
{ {
...@@ -244,11 +251,15 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) ...@@ -244,11 +251,15 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch)
} }
int dlsch_encoding_2threads0(te_params *tep) { int dlsch_encoding_2threads0(te_params *tep) {
LTE_eNB_DLSCH_t *dlsch = tep->dlsch; LTE_eNB_DLSCH_t *dlsch = tep->dlsch;
unsigned int G = tep->G; unsigned int G = tep->G;
unsigned char harq_pid = tep->harq_pid; unsigned char harq_pid = tep->harq_pid;
unsigned int total_worker = tep->total_worker;
unsigned int current_worker = tep->current_worker;
unsigned short iind; unsigned short iind;
...@@ -261,7 +272,7 @@ int dlsch_encoding_2threads0(te_params *tep) { ...@@ -261,7 +272,7 @@ int dlsch_encoding_2threads0(te_params *tep) {
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
for (r=0; r<dlsch->harq_processes[harq_pid]->C>>1; r++) { for (r=(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*current_worker; r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker+1); r++) {
if (r<dlsch->harq_processes[harq_pid]->Cminus) if (r<dlsch->harq_processes[harq_pid]->Cminus)
Kr = dlsch->harq_processes[harq_pid]->Kminus; Kr = dlsch->harq_processes[harq_pid]->Kminus;
...@@ -304,21 +315,34 @@ int dlsch_encoding_2threads0(te_params *tep) { ...@@ -304,21 +315,34 @@ int dlsch_encoding_2threads0(te_params *tep) {
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20 // outputs for each code segment, see Section 5.1.5 p.20
for (r=0; r<dlsch->harq_processes[harq_pid]->C>>1; r++) { for (r=0,r_offset=0; r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker+1); r++) {
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], if(r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker)){
G, //G int Nl=dlsch->harq_processes[harq_pid]->Nl;
dlsch->harq_processes[harq_pid]->w[r], int Qm=dlsch->harq_processes[harq_pid]->Qm;
dlsch->harq_processes[harq_pid]->e+r_offset, int C = dlsch->harq_processes[harq_pid]->C;
dlsch->harq_processes[harq_pid]->C, // C int Gp = G/Nl/Qm;
dlsch->Nsoft, // Nsoft, int GpmodC = Gp%C;
dlsch->Mdlharq, if (r < (C-(GpmodC)))
dlsch->Kmimo, r_offset += Nl*Qm * (Gp/C);
dlsch->harq_processes[harq_pid]->rvidx, else
dlsch->harq_processes[harq_pid]->Qm, r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
dlsch->harq_processes[harq_pid]->Nl, }
r, else{
nb_rb); r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
// m); // r G, //G
dlsch->harq_processes[harq_pid]->w[r],
dlsch->harq_processes[harq_pid]->e+r_offset,
dlsch->harq_processes[harq_pid]->C, // C
dlsch->Nsoft, // Nsoft,
dlsch->Mdlharq,
dlsch->Kmimo,
dlsch->harq_processes[harq_pid]->rvidx,
dlsch->harq_processes[harq_pid]->Qm,
dlsch->harq_processes[harq_pid]->Nl,
r,
nb_rb);
// m); // r
}
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_OUT);
...@@ -326,32 +350,46 @@ int dlsch_encoding_2threads0(te_params *tep) { ...@@ -326,32 +350,46 @@ int dlsch_encoding_2threads0(te_params *tep) {
return(0); return(0);
} }
extern int oai_exit; extern int oai_exit;
void *te_thread(void *param) { void *te_thread(void *param) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
thread_top_init("te_thread",1,200000,250000,500000);
pthread_setname_np( pthread_self(),"te processing"); pthread_setname_np( pthread_self(),"te processing");
LOG_I(PHY,"thread te created id=%ld", syscall(__NR_gettid)); LOG_I(PHY,"thread te created id=%ld\n", syscall(__NR_gettid));
eNB_proc_t *proc = &((te_params *)param)->eNB->proc; te_params *tep = (te_params *)param;
//wait_sync("te_thread");
while (!oai_exit) { while (!oai_exit) {
if (wait_on_condition(&tep->mutex_te,&tep->cond_te,&tep->instance_cnt_te,"te thread")<0) break;
if(oai_exit) break;
if (wait_on_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread")<0) break; dlsch_encoding_2threads0(tep);
dlsch_encoding_2threads0((te_params*)param); if (release_thread(&tep->mutex_te,&tep->instance_cnt_te,"te thread")<0) break;
if (pthread_cond_signal(&tep->cond_te) != 0) {
if (release_thread(&proc->mutex_te,&proc->instance_cnt_te,"te thread")<0) break;
if (pthread_cond_signal(&proc->cond_te) != 0) {
printf("[eNB] ERROR pthread_cond_signal for te thread exit\n"); printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return(NULL); return(NULL);
} }
/*if(opp_enabled == 1 && te_wakeup_stats0->diff_now>50*3000){
print_meas_now(te_wakeup_stats0,"coding_wakeup",stderr);
printf("te_thread0 delay for waking up in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
}*/
} }
return(NULL); return(NULL);
} }
int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
unsigned char *a, unsigned char *a,
uint8_t num_pdcch_symbols, uint8_t num_pdcch_symbols,
...@@ -360,9 +398,16 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, ...@@ -360,9 +398,16 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
uint8_t subframe, uint8_t subframe,
time_stats_t *rm_stats, time_stats_t *rm_stats,
time_stats_t *te_stats, time_stats_t *te_stats,
time_stats_t *i_stats) time_stats_t *te_wait_stats,
time_stats_t *te_main_stats,
time_stats_t *te_wakeup_stats0,
time_stats_t *te_wakeup_stats1,
time_stats_t *i_stats,
int worker_num)
{ {
//start_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
unsigned int G; unsigned int G;
...@@ -382,19 +427,22 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, ...@@ -382,19 +427,22 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
mod_order = dlsch->harq_processes[harq_pid]->Qm; mod_order = dlsch->harq_processes[harq_pid]->Qm;
G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0); G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0);
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
start_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
// Add 24-bit crc (polynomial A) to payload // Add 24-bit crc (polynomial A) to payload
crc = crc24a(a, crc = crc24a(a,
A)>>8; A)>>8;
stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
a[A>>3] = ((uint8_t*)&crc)[2]; a[A>>3] = ((uint8_t*)&crc)[2];
a[1+(A>>3)] = ((uint8_t*)&crc)[1]; a[1+(A>>3)] = ((uint8_t*)&crc)[1];
a[2+(A>>3)] = ((uint8_t*)&crc)[0]; a[2+(A>>3)] = ((uint8_t*)&crc)[0];
dlsch->harq_processes[harq_pid]->B = A+24; dlsch->harq_processes[harq_pid]->B = A+24;
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
//stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
start_meas(&eNB->dlsch_turbo_encoding_segmentation_stats);
if (lte_segmentation(dlsch->harq_processes[harq_pid]->b, if (lte_segmentation(dlsch->harq_processes[harq_pid]->b,
dlsch->harq_processes[harq_pid]->c, dlsch->harq_processes[harq_pid]->c,
dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->B,
...@@ -406,34 +454,41 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, ...@@ -406,34 +454,41 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
&dlsch->harq_processes[harq_pid]->F)<0) &dlsch->harq_processes[harq_pid]->F)<0)
return(-1); return(-1);
stop_meas(&eNB->dlsch_turbo_encoding_segmentation_stats);
if (proc->instance_cnt_te==0) { start_meas(&eNB->dlsch_turbo_encoding_signal_stats);
printf("[eNB] TE thread busy\n"); for(int i=0;i<worker_num;i++)
exit_fun("TE thread busy"); {
pthread_mutex_unlock( &proc->mutex_te ); proc->tep[i].eNB = eNB;
return(-1); proc->tep[i].dlsch = dlsch;
} proc->tep[i].G = G;
proc->tep[i].harq_pid = harq_pid;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); proc->tep[i].total_worker = worker_num;
++proc->instance_cnt_te; proc->tep[i].current_worker = i;
proc->tep.eNB = eNB; pthread_mutex_lock( &proc->tep[i].mutex_te );
proc->tep.dlsch = dlsch; if (proc->tep[i].instance_cnt_te==0) {
proc->tep.G = G; printf("[eNB] TE thread busy\n");
proc->tep.harq_pid = harq_pid; exit_fun("TE thread busy");
pthread_mutex_unlock( &proc->tep[i].mutex_te );
// wakeup worker to do second half segments return(-1);
if (pthread_cond_signal(&proc->cond_te) != 0) { }
printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
exit_fun( "ERROR pthread_cond_signal" ); ++proc->tep[i].instance_cnt_te;
return (-1);
// wakeup worker to do segments
if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) {
printf("[eNB] ERROR pthread_cond_signal for te thread %d exit\n",i);
exit_fun( "ERROR pthread_cond_signal" );
return (-1);
}
pthread_mutex_unlock( &proc->tep[i].mutex_te );
} }
pthread_mutex_unlock( &proc->mutex_te ); stop_meas(&eNB->dlsch_turbo_encoding_signal_stats);
start_meas(te_main_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); for (r=(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num; r<dlsch->harq_processes[harq_pid]->C; r++) {
for (r=dlsch->harq_processes[harq_pid]->C>>1; r<dlsch->harq_processes[harq_pid]->C; r++) {
if (r<dlsch->harq_processes[harq_pid]->Cminus) if (r<dlsch->harq_processes[harq_pid]->Cminus)
Kr = dlsch->harq_processes[harq_pid]->Kminus; Kr = dlsch->harq_processes[harq_pid]->Kminus;
...@@ -478,15 +533,18 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, ...@@ -478,15 +533,18 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
} }
else { else {
proc->tep.eNB = eNB; for(int i=0;i<worker_num;i++)
proc->tep.dlsch = dlsch; {
proc->tep.G = G; proc->tep[i].eNB = eNB;
proc->tep[i].dlsch = dlsch;
// wakeup worker to do second half segments proc->tep[i].G = G;
if (pthread_cond_signal(&proc->cond_te) != 0) { proc->tep[i].total_worker = worker_num;
proc->tep[i].current_worker = i;
if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) {
printf("[eNB] ERROR pthread_cond_signal for te thread exit\n"); printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return (-1); return (-1);
}
} }
} }
...@@ -496,7 +554,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, ...@@ -496,7 +554,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
for (r=0,r_offset=0; r<dlsch->harq_processes[harq_pid]->C; r++) { for (r=0,r_offset=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
// get information for E for the segments that are handled by the worker thread // get information for E for the segments that are handled by the worker thread
if (r<(dlsch->harq_processes[harq_pid]->C>>1)) { if (r<(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num) {
int Nl=dlsch->harq_processes[harq_pid]->Nl; int Nl=dlsch->harq_processes[harq_pid]->Nl;
int Qm=dlsch->harq_processes[harq_pid]->Qm; int Qm=dlsch->harq_processes[harq_pid]->Qm;
int C = dlsch->harq_processes[harq_pid]->C; int C = dlsch->harq_processes[harq_pid]->C;
...@@ -526,16 +584,138 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, ...@@ -526,16 +584,138 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
stop_meas(rm_stats); stop_meas(rm_stats);
} }
} }
stop_meas(te_main_stats);
// wait for worker to finish start_meas(te_wait_stats);
if(worker_num == 1)
wait_on_busy_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread"); {
wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
}
else if(worker_num == 2)
{
wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1");
}
else
{
wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1");
wait_on_busy_condition(&proc->tep[2].mutex_te,&proc->tep[2].cond_te,&proc->tep[2].instance_cnt_te,"te thread 2");
}
stop_meas(te_wait_stats);
/*if(opp_enabled == 1 && te_wait_stats->diff_now>100*3000){
print_meas_now(te_wait_stats,"coding_wait",stderr);
printf("coding delay in wait on codition in frame_rx: %d \n",proc->frame_rx);
}*/
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return(0); return(0);
} }
int dlsch_encoding_all(PHY_VARS_eNB *eNB,
unsigned char *a,
uint8_t num_pdcch_symbols,
LTE_eNB_DLSCH_t *dlsch,
int frame,
uint8_t subframe,
time_stats_t *rm_stats,
time_stats_t *te_stats,
time_stats_t *te_wait_stats,
time_stats_t *te_main_stats,
time_stats_t *te_wakeup_stats0,
time_stats_t *te_wakeup_stats1,
time_stats_t *i_stats)
{
int encoding_return = 0;
unsigned int L,C,B;
B = dlsch->harq_processes[dlsch->harq_ids[subframe]]->B;
if(B<=6144)
{
L=0;
C=1;
}
else
{
L=24;
C = B/(6144-L);
if((6144-L)*C < B)
{
C = C+1;
}
}
if(C >= 8 && get_nprocs()>=16 && codingw)//one main three worker
{
encoding_return =
dlsch_encoding_2threads(eNB,
a,
num_pdcch_symbols,
dlsch,
frame,
subframe,
rm_stats,
te_stats,
te_wait_stats,
te_main_stats,
te_wakeup_stats0,
te_wakeup_stats1,
i_stats,
3);
}
else if(C >= 6 && get_nprocs()>=8 && codingw)//one main two worker
{
encoding_return =
dlsch_encoding_2threads(eNB,
a,
num_pdcch_symbols,
dlsch,
frame,
subframe,
rm_stats,
te_stats,
te_wait_stats,
te_main_stats,
te_wakeup_stats0,
te_wakeup_stats1,
i_stats,
2);
}
else if(C >= 4 && get_nprocs()>=4 && codingw)//one main one worker
{
encoding_return =
dlsch_encoding_2threads(eNB,
a,
num_pdcch_symbols,
dlsch,
frame,
subframe,
rm_stats,
te_stats,
te_wait_stats,
te_main_stats,
te_wakeup_stats0,
te_wakeup_stats1,
i_stats,
1);
}
else
{
encoding_return =
dlsch_encoding(eNB,
a,
num_pdcch_symbols,
dlsch,
frame,
subframe,
rm_stats,
te_stats,
i_stats);
}
return encoding_return;
}
int dlsch_encoding(PHY_VARS_eNB *eNB, int dlsch_encoding(PHY_VARS_eNB *eNB,
unsigned char *a, unsigned char *a,
......
...@@ -38,7 +38,8 @@ ...@@ -38,7 +38,8 @@
#include "defs.h" #include "defs.h"
#include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/LOG/vcd_signal_dumper.h"
//#define DEBUG_DLSCH_MODULATION 1 //#define DEBUG_DLSCH_MODULATION
#define NEW_ALLOC_RE
//#define is_not_pilot(pilots,re,nushift,use2ndpilots) ((pilots==0) || ((re!=nushift) && (re!=nushift+6)&&((re!=nushift+3)||(use2ndpilots==1))&&((re!=nushift+9)||(use2ndpilots==1)))?1:0) //#define is_not_pilot(pilots,re,nushift,use2ndpilots) ((pilots==0) || ((re!=nushift) && (re!=nushift+6)&&((re!=nushift+3)||(use2ndpilots==1))&&((re!=nushift+9)||(use2ndpilots==1)))?1:0)
...@@ -120,6 +121,17 @@ void generate_16qam_table(void) ...@@ -120,6 +121,17 @@ void generate_16qam_table(void)
} }
} }
void generate_qpsk_table(void)
{
int a,index;
for (a=-1; a<=1; a+=2) {
index = (1+a)/2;
qpsk_table[index] = -a*QPSK;
}
}
...@@ -157,6 +169,158 @@ void layer1prec2A(int32_t *antenna0_sample, int32_t *antenna1_sample, uint8_t pr ...@@ -157,6 +169,158 @@ void layer1prec2A(int32_t *antenna0_sample, int32_t *antenna1_sample, uint8_t pr
uint32_t FOUR[2]={0,4}; uint32_t FOUR[2]={0,4};
uint32_t TWO[2]={0,2}; uint32_t TWO[2]={0,2};
int allocate_REs_in_RB_no_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB,
int **txdataF,
uint32_t *jj,
uint32_t *jj2,
uint16_t re_offset,
uint32_t symbol_offset,
LTE_DL_eNB_HARQ_t *dlsch0_harq,
LTE_DL_eNB_HARQ_t *dlsch1_harq,
uint8_t pilots,
int16_t amp,
uint8_t precoder_index,
int16_t *qam_table_s0,
int16_t *qam_table_s1,
uint32_t *re_allocated,
uint8_t skip_dc,
uint8_t skip_half,
uint8_t lprime,
uint8_t mprime,
uint8_t Ns,
int *P1_SHIFT,
int *P2_SHIFT)
{
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
uint8_t *x0 = dlsch0_harq->e;
uint32_t qpsk_table_offset_re = 0;
uint32_t qpsk_table_offset_im = 0;
uint32_t tti_offset;
uint8_t re;
uint8_t *x0p;
if (skip_dc == 0) {
for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
re<12;
re++,x0p+=2,tti_offset++) {
qpsk_table_offset_re=x0p[0];
qpsk_table_offset_im=x0p[1];
((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im];
}
}
else {
// 1st half of PRB
for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
re<6;
re++,x0p+=2,tti_offset++) {
qpsk_table_offset_re=x0p[0];
qpsk_table_offset_im=x0p[1];
((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im];
}
// 2nd half of PRB
for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+7;
re<12;
re++,x0p+=2,tti_offset++) {
qpsk_table_offset_re=x0p[0];
qpsk_table_offset_im=x0p[1];
((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im];
}
}
*re_allocated = *re_allocated + 12;
*jj=*jj + 24;
return(0);
}
int allocate_REs_in_RB_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB,
int **txdataF,
uint32_t *jj,
uint32_t *jj2,
uint16_t re_offset,
uint32_t symbol_offset,
LTE_DL_eNB_HARQ_t *dlsch0_harq,
LTE_DL_eNB_HARQ_t *dlsch1_harq,
uint8_t pilots,
int16_t amp,
uint8_t precoder_index,
int16_t *qam_table_s0,
int16_t *qam_table_s1,
uint32_t *re_allocated,
uint8_t skip_dc,
uint8_t skip_half,
uint8_t lprime,
uint8_t mprime,
uint8_t Ns,
int *P1_SHIFT,
int *P2_SHIFT)
{
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
uint8_t *x0 = dlsch0_harq->e;
uint32_t qpsk_table_offset_re = 0;
uint32_t qpsk_table_offset_im = 0;
uint32_t tti_offset;
uint8_t re;
uint8_t *x0p;
if (skip_dc == 0) {
// printf("pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]);
for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0];
re<12;
x0p+=2) {
qpsk_table_offset_re=x0p[0];
qpsk_table_offset_im=x0p[1];
((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im];
// printf("pilots: re %d, tti_offset %d, P1_SHIFT %d\n",re,tti_offset,P1_SHIFT[re+1]);
tti_offset+=P1_SHIFT[re+1];
re+=P1_SHIFT[re+1];
}
}
else {
for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0];
re<6;
x0p+=2) {
qpsk_table_offset_re+=x0p[0];
qpsk_table_offset_im+=x0p[1];
((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im];
tti_offset+=P1_SHIFT[re+1];
re+=P1_SHIFT[re+1];
}
for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+6+P1_SHIFT[6];
re<12;
x0p+=2) {
qpsk_table_offset_re+=x0p[0];
qpsk_table_offset_im+=x0p[1];
((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im];
tti_offset+=P1_SHIFT[re+1];
re+=P1_SHIFT[re+1];
}
}
*re_allocated = *re_allocated + 10;
*jj=*jj + 20;
return(0);
}
int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB, int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
int **txdataF, int **txdataF,
uint32_t *jj, uint32_t *jj,
...@@ -2011,11 +2175,11 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, ...@@ -2011,11 +2175,11 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
uint8_t mod_order0 = 0; uint8_t mod_order0 = 0;
uint8_t mod_order1 = 0; uint8_t mod_order1 = 0;
int16_t amp_rho_a, amp_rho_b; int16_t amp_rho_a, amp_rho_b;
int16_t qam16_table_a0[4],qam64_table_a0[8],qam16_table_b0[4],qam64_table_b0[8]; int16_t qam16_table_a0[4],qam64_table_a0[8],qam16_table_b0[4],qam64_table_b0[8];//qpsk_table_a0[2],qpsk_table_b0[2]
int16_t qam16_table_a1[4],qam64_table_a1[8],qam16_table_b1[4],qam64_table_b1[8]; int16_t qam16_table_a1[4],qam64_table_a1[8],qam16_table_b1[4],qam64_table_b1[8];//qpsk_table_a1[2],qpsk_table_b1[2]
int16_t *qam_table_s0=NULL,*qam_table_s1=NULL; int16_t *qam_table_s0=NULL,*qam_table_s1=NULL;
#if 0 #ifdef NEW_ALLOC_RE
/* TODO: variable to be removed? */ /* TODO: variable to be removed? */
int (*allocate_REs)(PHY_VARS_eNB*, int (*allocate_REs)(PHY_VARS_eNB*,
int **, int **,
...@@ -2125,8 +2289,15 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, ...@@ -2125,8 +2289,15 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
amp_rho_b = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_b)>>13); amp_rho_b = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_b)>>13);
} }
/*if(mod_order0 == 2)
if (mod_order0 == 4) {
for(i=0;i<2;i++)
{
qpsk_table_a0[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_a)>>15);
qpsk_table_b0[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_b)>>15);
}
}
else*/ if (mod_order0 == 4)
for (i=0;i<4; i++) { for (i=0;i<4; i++) {
qam16_table_a0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15); qam16_table_a0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15);
qam16_table_b0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_b)>>15); qam16_table_b0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_b)>>15);
...@@ -2137,7 +2308,14 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, ...@@ -2137,7 +2308,14 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
qam64_table_b0[i] = (int16_t)(((int32_t)qam64_table[i]*amp_rho_b)>>15); qam64_table_b0[i] = (int16_t)(((int32_t)qam64_table[i]*amp_rho_b)>>15);
} }
if (mod_order1 == 4) /*if (mod_order1 == 2)
{
for (i=0; i<2; i++) {
qpsk_table_a1[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_a)>>15);
qpsk_table_b1[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_b)>>15);
}
}
else*/ if (mod_order1 == 4)
for (i=0; i<4; i++) { for (i=0; i<4; i++) {
qam16_table_a1[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15); qam16_table_a1[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15);
qam16_table_b1[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_b)>>15); qam16_table_b1[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_b)>>15);
...@@ -2259,7 +2437,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, ...@@ -2259,7 +2437,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
re_offset = frame_parms->first_carrier_offset; re_offset = frame_parms->first_carrier_offset;
symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb)); symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb));
#if 0 #ifdef NEW_ALLOC_RE
/* TODO: remove this code? */ /* TODO: remove this code? */
allocate_REs = allocate_REs_in_RB; allocate_REs = allocate_REs_in_RB;
#endif #endif
...@@ -2267,11 +2445,30 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, ...@@ -2267,11 +2445,30 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
switch (mod_order0) { switch (mod_order0) {
case 2: case 2:
qam_table_s0 = NULL; qam_table_s0 = NULL;
/*if (pilots) {
qam_table_s0 = qpsk_table_b0;
#ifdef NEW_ALLOC_RE
// TODO: remove this code? //
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_pilots_QPSK_siso :
allocate_REs_in_RB;
#endif
}
else {
qam_table_s0 = qpsk_table_a0;
#ifdef NEW_ALLOC_RE
// TODO: remove this code? //
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_no_pilots_QPSK_siso :
allocate_REs_in_RB;
#endif
}*/
break; break;
case 4: case 4:
if (pilots) { if (pilots) {
qam_table_s0 = qam16_table_b0; qam_table_s0 = qam16_table_b0;
#if 0 #ifdef NEW_ALLOC_RE
/* TODO: remove this code? */ /* TODO: remove this code? */
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_pilots_16QAM_siso : allocate_REs_in_RB_pilots_16QAM_siso :
...@@ -2280,7 +2477,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, ...@@ -2280,7 +2477,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
} }
else { else {
qam_table_s0 = qam16_table_a0; qam_table_s0 = qam16_table_a0;
#if 0 #ifdef NEW_ALLOC_RE
/* TODO: remove this code? */ /* TODO: remove this code? */
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_no_pilots_16QAM_siso : allocate_REs_in_RB_no_pilots_16QAM_siso :
...@@ -2293,7 +2490,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, ...@@ -2293,7 +2490,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
case 6: case 6:
if (pilots) { if (pilots) {
qam_table_s0 = qam64_table_b0; qam_table_s0 = qam64_table_b0;
#if 0 #ifdef NEW_ALLOC_RE
/* TODO: remove this code? */ /* TODO: remove this code? */
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_pilots_64QAM_siso : allocate_REs_in_RB_pilots_64QAM_siso :
...@@ -2302,7 +2499,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, ...@@ -2302,7 +2499,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
} }
else { else {
qam_table_s0 = qam64_table_a0; qam_table_s0 = qam64_table_a0;
#if 0 #ifdef NEW_ALLOC_RE
/* TODO: remove this code? */ /* TODO: remove this code? */
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_no_pilots_64QAM_siso : allocate_REs_in_RB_no_pilots_64QAM_siso :
...@@ -2316,10 +2513,16 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, ...@@ -2316,10 +2513,16 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
switch (mod_order1) { switch (mod_order1) {
case 2: case 2:
qam_table_s1 = NULL; qam_table_s1 = NULL;
#if 0 #ifdef NEW_ALLOC_RE
/* TODO: remove this code? */ /* TODO: remove this code? */
allocate_REs = allocate_REs_in_RB; allocate_REs = allocate_REs_in_RB;
#endif #endif
/*if (pilots) {
qam_table_s1 = qpsk_table_b1;
}
else {
qam_table_s1 = qpsk_table_a1;
}*/
break; break;
case 4: case 4:
if (pilots) { if (pilots) {
......
...@@ -30,7 +30,7 @@ extern short *ul_ref_sigs_rx[30][2][33]; ...@@ -30,7 +30,7 @@ extern short *ul_ref_sigs_rx[30][2][33];
extern unsigned short dftsizes[33]; extern unsigned short dftsizes[33];
extern unsigned short ref_primes[33]; extern unsigned short ref_primes[33];
extern int qam64_table[8],qam16_table[4]; extern int qam64_table[8],qam16_table[4],qpsk_table[2];
extern unsigned char cs_ri_normal[4]; extern unsigned char cs_ri_normal[4];
extern unsigned char cs_ri_extended[4]; extern unsigned char cs_ri_extended[4];
......
...@@ -127,6 +127,20 @@ int32_t dlsch_encoding(PHY_VARS_eNB *eNB, ...@@ -127,6 +127,20 @@ int32_t dlsch_encoding(PHY_VARS_eNB *eNB,
time_stats_t *rm_stats, time_stats_t *rm_stats,
time_stats_t *te_stats, time_stats_t *te_stats,
time_stats_t *i_stats); time_stats_t *i_stats);
int32_t dlsch_encoding_all(PHY_VARS_eNB *eNB,
uint8_t *a,
uint8_t num_pdcch_symbols,
LTE_eNB_DLSCH_t *dlsch,
int frame,
uint8_t subframe,
time_stats_t *rm_stats,
time_stats_t *te_stats,
time_stats_t *te_wait_stats,
time_stats_t *te_main_stats,
time_stats_t *te_wakeup_stats0,
time_stats_t *te_wakeup_stats1,
time_stats_t *i_stats);
int32_t dlsch_encoding_SIC(PHY_VARS_UE *ue, int32_t dlsch_encoding_SIC(PHY_VARS_UE *ue,
uint8_t *a, uint8_t *a,
...@@ -171,7 +185,12 @@ int32_t dlsch_encoding_2threads(PHY_VARS_eNB *eNB, ...@@ -171,7 +185,12 @@ int32_t dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
uint8_t subframe, uint8_t subframe,
time_stats_t *rm_stats, time_stats_t *rm_stats,
time_stats_t *te_stats, time_stats_t *te_stats,
time_stats_t *i_stats); time_stats_t *te_wait_stats,
time_stats_t *te_main_stats,
time_stats_t *te_wakeup_stats0,
time_stats_t *te_wakeup_stats1,
time_stats_t *i_stats,
int worker_num);
void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB, void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB,
uint8_t *DLSCH_pdu, uint8_t *DLSCH_pdu,
...@@ -1488,6 +1507,7 @@ uint8_t generate_dci_top_emul(PHY_VARS_eNB *phy_vars_eNB, ...@@ -1488,6 +1507,7 @@ uint8_t generate_dci_top_emul(PHY_VARS_eNB *phy_vars_eNB,
void generate_64qam_table(void); void generate_64qam_table(void);
void generate_16qam_table(void); void generate_16qam_table(void);
void generate_qpsk_table(void);
uint16_t extract_crc(uint8_t *dci,uint8_t DCI_LENGTH); uint16_t extract_crc(uint8_t *dci,uint8_t DCI_LENGTH);
...@@ -1897,6 +1917,11 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB, ...@@ -1897,6 +1917,11 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB,
uint8_t Nbundled, uint8_t Nbundled,
uint8_t llr8_flag); uint8_t llr8_flag);
int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,
int UE_id,
int harq_pid,
int llr8_flag);
/*! /*!
\brief Decoding of ULSCH data component from 36-212. This one spawns 1 worker thread in parallel,half of the segments in each thread. \brief Decoding of ULSCH data component from 36-212. This one spawns 1 worker thread in parallel,half of the segments in each thread.
@param phy_vars_eNB Pointer to eNB top-level descriptor @param phy_vars_eNB Pointer to eNB top-level descriptor
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
*/ */
//#include "defs.h" //#include "defs.h"
#include <syscall.h>
#include "PHY/defs.h" #include "PHY/defs.h"
#include "PHY/extern.h" #include "PHY/extern.h"
#include "PHY/CODING/extern.h" #include "PHY/CODING/extern.h"
...@@ -46,6 +46,9 @@ ...@@ -46,6 +46,9 @@
#include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/LOG/vcd_signal_dumper.h"
//#define DEBUG_ULSCH_DECODING //#define DEBUG_ULSCH_DECODING
#include "targets/RT/USER/rt_wrapper.h"
extern int codingw;
void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch) void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch)
{ {
...@@ -221,8 +224,6 @@ uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH) ...@@ -221,8 +224,6 @@ uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH)
int ulsch_decoding_data_2thread0(td_params* tdp) { int ulsch_decoding_data_2thread0(td_params* tdp) {
PHY_VARS_eNB *eNB = tdp->eNB; PHY_VARS_eNB *eNB = tdp->eNB;
...@@ -414,13 +415,20 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { ...@@ -414,13 +415,20 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
extern int oai_exit; extern int oai_exit;
void *td_thread(void *param) { void *td_thread(void *param) {
pthread_setname_np( pthread_self(), "td processing");
PHY_VARS_eNB *eNB = ((td_params*)param)->eNB; PHY_VARS_eNB *eNB = ((td_params*)param)->eNB;
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
thread_top_init("td_thread",1,200000,250000,500000);
pthread_setname_np( pthread_self(),"td processing");
LOG_I(PHY,"thread td created id=%ld\n", syscall(__NR_gettid));
//wait_sync("td_thread");
while (!oai_exit) { while (!oai_exit) {
if (wait_on_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread")<0) break; if (wait_on_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread")<0) break;
if(oai_exit) break;
((td_params*)param)->ret = ulsch_decoding_data_2thread0((td_params*)param); ((td_params*)param)->ret = ulsch_decoding_data_2thread0((td_params*)param);
...@@ -623,6 +631,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr ...@@ -623,6 +631,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
break; break;
} }
stop_meas(&eNB->ulsch_turbo_decoding_stats); stop_meas(&eNB->ulsch_turbo_decoding_stats);
//printf("/////////////////////////////////////////**************************loop for %d time in ulsch_decoding main\n",r);
} }
// wait for worker to finish // wait for worker to finish
...@@ -782,6 +791,20 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) ...@@ -782,6 +791,20 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
return(ret); return(ret);
} }
int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
{
int ret = 0;
/*if(codingw)
{
ret = ulsch_decoding_data_2thread(eNB,UE_id,harq_pid,llr8_flag);
}
else*/
{
ret = ulsch_decoding_data(eNB,UE_id,harq_pid,llr8_flag);
}
return ret;
}
static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline)); static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline));
static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset)
{ {
......
...@@ -62,7 +62,7 @@ unsigned char ue_power_offsets[25] = {14,11,9,8,7,6,6,5,4,4,4,3,3,3,2,2,2,1,1,1, ...@@ -62,7 +62,7 @@ unsigned char ue_power_offsets[25] = {14,11,9,8,7,6,6,5,4,4,4,3,3,3,2,2,2,1,1,1,
short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1}; short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1}; short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
int qam64_table[8],qam16_table[4]; int qam64_table[8],qam16_table[4],qpsk_table[2];
unsigned char cs_ri_normal[4] = {1,4,7,10}; unsigned char cs_ri_normal[4] = {1,4,7,10};
unsigned char cs_ri_extended[4] = {0,3,5,8}; unsigned char cs_ri_extended[4] = {0,3,5,8};
......
...@@ -53,7 +53,7 @@ void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name){ ...@@ -53,7 +53,7 @@ void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name){
if (ts->trials>0) { if (ts->trials>0) {
//fprintf(file_name,"Name %25s: Processing %15.3f ms for SF %d, diff_now %15.3f \n", name,(ts->diff_now/(cpu_freq_GHz*1000000.0)),subframe,ts->diff_now); //fprintf(file_name,"Name %25s: Processing %15.3f ms for SF %d, diff_now %15.3f \n", name,(ts->diff_now/(cpu_freq_GHz*1000000.0)),subframe,ts->diff_now);
fprintf(file_name,"%15.3f ms, diff_now %15.3f \n",(ts->diff_now/(cpu_freq_GHz*1000000.0)),(double)ts->diff_now); fprintf(file_name,"%15.3f us, diff_now %15.3f \n",(ts->diff_now/(cpu_freq_GHz*1000.0)),(double)ts->diff_now);
} }
} }
......
...@@ -270,6 +270,8 @@ typedef struct { ...@@ -270,6 +270,8 @@ typedef struct {
pthread_mutex_t mutex_rxtx; pthread_mutex_t mutex_rxtx;
/// scheduling parameters for RXn-TXnp4 thread /// scheduling parameters for RXn-TXnp4 thread
struct sched_param sched_param_rxtx; struct sched_param sched_param_rxtx;
/// pipeline ready state
int pipe_ready;
} eNB_rxtx_proc_t; } eNB_rxtx_proc_t;
typedef struct { typedef struct {
...@@ -285,6 +287,20 @@ typedef struct { ...@@ -285,6 +287,20 @@ typedef struct {
LTE_eNB_DLSCH_t *dlsch; LTE_eNB_DLSCH_t *dlsch;
int G; int G;
int harq_pid; int harq_pid;
int total_worker;
int current_worker;
/// \internal This variable is protected by \ref mutex_te.
int instance_cnt_te;
/// pthread attributes for parallel turbo-encoder thread
pthread_attr_t attr_te;
/// scheduling parameters for parallel turbo-encoder thread
struct sched_param sched_param_te;
/// pthread structure for parallel turbo-encoder thread
pthread_t pthread_te;
/// condition variable for parallel turbo-encoder thread
pthread_cond_t cond_te;
/// mutex for parallel turbo-encoder thread
pthread_mutex_t mutex_te;
} te_params; } te_params;
typedef struct RU_proc_t_s { typedef struct RU_proc_t_s {
...@@ -321,6 +337,7 @@ typedef struct RU_proc_t_s { ...@@ -321,6 +337,7 @@ typedef struct RU_proc_t_s {
/// \brief Instance count for FH processing thread. /// \brief Instance count for FH processing thread.
/// \internal This variable is protected by \ref mutex_FH. /// \internal This variable is protected by \ref mutex_FH.
int instance_cnt_FH; int instance_cnt_FH;
int instance_cnt_FH1;
/// \internal This variable is protected by \ref mutex_prach. /// \internal This variable is protected by \ref mutex_prach.
int instance_cnt_prach; int instance_cnt_prach;
#ifdef Rel14 #ifdef Rel14
...@@ -336,10 +353,13 @@ typedef struct RU_proc_t_s { ...@@ -336,10 +353,13 @@ typedef struct RU_proc_t_s {
int instance_cnt_asynch_rxtx; int instance_cnt_asynch_rxtx;
/// \internal This variable is protected by \ref mutex_fep /// \internal This variable is protected by \ref mutex_fep
int instance_cnt_fep; int instance_cnt_fep;
/// \internal This variable is protected by \ref mutex_fep /// \internal This variable is protected by \ref mutex_feptx
int instance_cnt_feptx; int instance_cnt_feptx;
/// This varible is protected by \ref mutex_emulatedRF
int instance_cnt_emulateRF;
/// pthread structure for RU FH processing thread /// pthread structure for RU FH processing thread
pthread_t pthread_FH; pthread_t pthread_FH;
pthread_t pthread_FH1;
/// pthread structure for RU prach processing thread /// pthread structure for RU prach processing thread
pthread_t pthread_prach; pthread_t pthread_prach;
#ifdef Rel14 #ifdef Rel14
...@@ -350,8 +370,10 @@ typedef struct RU_proc_t_s { ...@@ -350,8 +370,10 @@ typedef struct RU_proc_t_s {
pthread_t pthread_synch; pthread_t pthread_synch;
/// pthread struct for RU RX FEP worker thread /// pthread struct for RU RX FEP worker thread
pthread_t pthread_fep; pthread_t pthread_fep;
/// pthread struct for RU RX FEPTX worker thread /// pthread struct for RU TX FEP worker thread
pthread_t pthread_feptx; pthread_t pthread_feptx;
/// pthread struct for emulated RF
pthread_t pthread_emulateRF;
/// pthread structure for asychronous RX/TX processing thread /// pthread structure for asychronous RX/TX processing thread
pthread_t pthread_asynch_rxtx; pthread_t pthread_asynch_rxtx;
/// flag to indicate first RX acquisition /// flag to indicate first RX acquisition
...@@ -360,6 +382,7 @@ typedef struct RU_proc_t_s { ...@@ -360,6 +382,7 @@ typedef struct RU_proc_t_s {
int first_tx; int first_tx;
/// pthread attributes for RU FH processing thread /// pthread attributes for RU FH processing thread
pthread_attr_t attr_FH; pthread_attr_t attr_FH;
pthread_attr_t attr_FH1;
/// pthread attributes for RU prach /// pthread attributes for RU prach
pthread_attr_t attr_prach; pthread_attr_t attr_prach;
#ifdef Rel14 #ifdef Rel14
...@@ -374,8 +397,11 @@ typedef struct RU_proc_t_s { ...@@ -374,8 +397,11 @@ typedef struct RU_proc_t_s {
pthread_attr_t attr_fep; pthread_attr_t attr_fep;
/// pthread attributes for worker feptx thread /// pthread attributes for worker feptx thread
pthread_attr_t attr_feptx; pthread_attr_t attr_feptx;
/// pthread attributes for emulated RF
pthread_attr_t attr_emulateRF;
/// scheduling parameters for RU FH thread /// scheduling parameters for RU FH thread
struct sched_param sched_param_FH; struct sched_param sched_param_FH;
struct sched_param sched_param_FH1;
/// scheduling parameters for RU prach thread /// scheduling parameters for RU prach thread
struct sched_param sched_param_prach; struct sched_param sched_param_prach;
#ifdef Rel14 #ifdef Rel14
...@@ -388,6 +414,7 @@ typedef struct RU_proc_t_s { ...@@ -388,6 +414,7 @@ typedef struct RU_proc_t_s {
struct sched_param sched_param_asynch_rxtx; struct sched_param sched_param_asynch_rxtx;
/// condition variable for RU FH thread /// condition variable for RU FH thread
pthread_cond_t cond_FH; pthread_cond_t cond_FH;
pthread_cond_t cond_FH1;
/// condition variable for RU prach thread /// condition variable for RU prach thread
pthread_cond_t cond_prach; pthread_cond_t cond_prach;
#ifdef Rel14 #ifdef Rel14
...@@ -398,14 +425,17 @@ typedef struct RU_proc_t_s { ...@@ -398,14 +425,17 @@ typedef struct RU_proc_t_s {
pthread_cond_t cond_synch; pthread_cond_t cond_synch;
/// condition variable for asynch RX/TX thread /// condition variable for asynch RX/TX thread
pthread_cond_t cond_asynch_rxtx; pthread_cond_t cond_asynch_rxtx;
/// condition varaible for RU RX FEP thread /// condition varible for RU RX FEP thread
pthread_cond_t cond_fep; pthread_cond_t cond_fep;
/// condition varaible for RU RX FEPTX thread /// condition varible for RU TX FEP thread
pthread_cond_t cond_feptx; pthread_cond_t cond_feptx;
/// condition varible for emulated RF
pthread_cond_t cond_emulateRF;
/// condition variable for eNB signal /// condition variable for eNB signal
pthread_cond_t cond_eNBs; pthread_cond_t cond_eNBs;
/// mutex for RU FH /// mutex for RU FH
pthread_mutex_t mutex_FH; pthread_mutex_t mutex_FH;
pthread_mutex_t mutex_FH1;
/// mutex for RU prach /// mutex for RU prach
pthread_mutex_t mutex_prach; pthread_mutex_t mutex_prach;
#ifdef Rel14 #ifdef Rel14
...@@ -422,12 +452,17 @@ typedef struct RU_proc_t_s { ...@@ -422,12 +452,17 @@ typedef struct RU_proc_t_s {
pthread_mutex_t mutex_fep; pthread_mutex_t mutex_fep;
/// mutex for fep TX worker thread /// mutex for fep TX worker thread
pthread_mutex_t mutex_feptx; pthread_mutex_t mutex_feptx;
/// mutex for emulated RF thread
pthread_mutex_t mutex_emulateRF;
/// symbol mask for IF4p5 reception per subframe /// symbol mask for IF4p5 reception per subframe
uint32_t symbol_mask[10]; uint32_t symbol_mask[10];
/// number of slave threads /// number of slave threads
int num_slaves; int num_slaves;
/// array of pointers to slaves /// array of pointers to slaves
struct RU_proc_t_s **slave_proc; struct RU_proc_t_s **slave_proc;
/// pipeline ready state
int ru_rx_ready;
int ru_tx_ready;
} RU_proc_t; } RU_proc_t;
/// Context data structure for eNB subframe processing /// Context data structure for eNB subframe processing
...@@ -461,7 +496,7 @@ typedef struct eNB_proc_t_s { ...@@ -461,7 +496,7 @@ typedef struct eNB_proc_t_s {
/// \internal This variable is protected by \ref mutex_td. /// \internal This variable is protected by \ref mutex_td.
int instance_cnt_td; int instance_cnt_td;
/// \internal This variable is protected by \ref mutex_te. /// \internal This variable is protected by \ref mutex_te.
int instance_cnt_te; //int instance_cnt_te[3];
/// \internal This variable is protected by \ref mutex_prach. /// \internal This variable is protected by \ref mutex_prach.
int instance_cnt_prach; int instance_cnt_prach;
#ifdef Rel14 #ifdef Rel14
...@@ -483,7 +518,7 @@ typedef struct eNB_proc_t_s { ...@@ -483,7 +518,7 @@ typedef struct eNB_proc_t_s {
/// pthread attributes for parallel turbo-decoder thread /// pthread attributes for parallel turbo-decoder thread
pthread_attr_t attr_td; pthread_attr_t attr_td;
/// pthread attributes for parallel turbo-encoder thread /// pthread attributes for parallel turbo-encoder thread
pthread_attr_t attr_te; //pthread_attr_t attr_te[3];
/// pthread attributes for single eNB processing thread /// pthread attributes for single eNB processing thread
pthread_attr_t attr_single; pthread_attr_t attr_single;
/// pthread attributes for prach processing thread /// pthread attributes for prach processing thread
...@@ -497,7 +532,7 @@ typedef struct eNB_proc_t_s { ...@@ -497,7 +532,7 @@ typedef struct eNB_proc_t_s {
/// scheduling parameters for parallel turbo-decoder thread /// scheduling parameters for parallel turbo-decoder thread
struct sched_param sched_param_td; struct sched_param sched_param_td;
/// scheduling parameters for parallel turbo-encoder thread /// scheduling parameters for parallel turbo-encoder thread
struct sched_param sched_param_te; //struct sched_param sched_param_te[3];
/// scheduling parameters for single eNB thread /// scheduling parameters for single eNB thread
struct sched_param sched_param_single; struct sched_param sched_param_single;
/// scheduling parameters for prach thread /// scheduling parameters for prach thread
...@@ -511,7 +546,7 @@ typedef struct eNB_proc_t_s { ...@@ -511,7 +546,7 @@ typedef struct eNB_proc_t_s {
/// pthread structure for parallel turbo-decoder thread /// pthread structure for parallel turbo-decoder thread
pthread_t pthread_td; pthread_t pthread_td;
/// pthread structure for parallel turbo-encoder thread /// pthread structure for parallel turbo-encoder thread
pthread_t pthread_te; //pthread_t pthread_te[3];
/// pthread structure for PRACH thread /// pthread structure for PRACH thread
pthread_t pthread_prach; pthread_t pthread_prach;
#ifdef Rel14 #ifdef Rel14
...@@ -521,7 +556,7 @@ typedef struct eNB_proc_t_s { ...@@ -521,7 +556,7 @@ typedef struct eNB_proc_t_s {
/// condition variable for parallel turbo-decoder thread /// condition variable for parallel turbo-decoder thread
pthread_cond_t cond_td; pthread_cond_t cond_td;
/// condition variable for parallel turbo-encoder thread /// condition variable for parallel turbo-encoder thread
pthread_cond_t cond_te; //pthread_cond_t cond_te[3];
/// condition variable for PRACH processing thread; /// condition variable for PRACH processing thread;
pthread_cond_t cond_prach; pthread_cond_t cond_prach;
#ifdef Rel14 #ifdef Rel14
...@@ -533,7 +568,7 @@ typedef struct eNB_proc_t_s { ...@@ -533,7 +568,7 @@ typedef struct eNB_proc_t_s {
/// mutex for parallel turbo-decoder thread /// mutex for parallel turbo-decoder thread
pthread_mutex_t mutex_td; pthread_mutex_t mutex_td;
/// mutex for parallel turbo-encoder thread /// mutex for parallel turbo-encoder thread
pthread_mutex_t mutex_te; //pthread_mutex_t mutex_te[3];
/// mutex for PRACH thread /// mutex for PRACH thread
pthread_mutex_t mutex_prach; pthread_mutex_t mutex_prach;
#ifdef Rel14 #ifdef Rel14
...@@ -559,9 +594,13 @@ typedef struct eNB_proc_t_s { ...@@ -559,9 +594,13 @@ typedef struct eNB_proc_t_s {
/// parameters for turbo-decoding worker thread /// parameters for turbo-decoding worker thread
td_params tdp; td_params tdp;
/// parameters for turbo-encoding worker thread /// parameters for turbo-encoding worker thread
te_params tep; te_params tep[3];
/// set of scheduling variables RXn-TXnp4 threads /// set of scheduling variables RXn-TXnp4 threads
eNB_rxtx_proc_t proc_rxtx[2]; eNB_rxtx_proc_t proc_rxtx[2];
/// stats thread pthread descriptor
pthread_t process_stats_thread;
/// for waking up tx procedure
RU_proc_t *ru_proc;
} eNB_proc_t; } eNB_proc_t;
...@@ -663,6 +702,7 @@ typedef enum { ...@@ -663,6 +702,7 @@ typedef enum {
REMOTE_IF4p5 =3, REMOTE_IF4p5 =3,
REMOTE_IF1pp =4, REMOTE_IF1pp =4,
MAX_RU_IF_TYPES =5 MAX_RU_IF_TYPES =5
//EMULATE_RF =6
} RU_if_south_t; } RU_if_south_t;
typedef struct RU_t_s{ typedef struct RU_t_s{
...@@ -757,11 +797,19 @@ typedef struct RU_t_s{ ...@@ -757,11 +797,19 @@ typedef struct RU_t_s{
void (*wakeup_prach_eNB_br)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe); void (*wakeup_prach_eNB_br)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe);
#endif #endif
/// function pointer to eNB entry routine /// function pointer to eNB entry routine
void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string); void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string,struct RU_t_s *ru);
/// Timing statistics /// Timing statistics
time_stats_t ofdm_demod_stats; time_stats_t ofdm_demod_stats;
/// Timing statistics (TX) /// Timing statistics (TX)
time_stats_t ofdm_mod_stats; time_stats_t ofdm_mod_stats;
/// Timing wait statistics
time_stats_t ofdm_demod_wait_stats;
/// Timing wakeup statistics
time_stats_t ofdm_demod_wakeup_stats;
/// Timing wait statistics (TX)
time_stats_t ofdm_mod_wait_stats;
/// Timing wakeup statistics (TX)
time_stats_t ofdm_mod_wakeup_stats;
/// Timing statistics (RX Fronthaul + Compression) /// Timing statistics (RX Fronthaul + Compression)
time_stats_t rx_fhaul; time_stats_t rx_fhaul;
/// Timing statistics (TX Fronthaul + Compression) /// Timing statistics (TX Fronthaul + Compression)
...@@ -955,7 +1003,7 @@ typedef struct PHY_VARS_eNB_s { ...@@ -955,7 +1003,7 @@ typedef struct PHY_VARS_eNB_s {
eth_params_t eth_params; eth_params_t eth_params;
int rx_total_gain_dB; int rx_total_gain_dB;
int (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag); int (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag);
int (*te)(struct PHY_VARS_eNB_s *,uint8_t *,uint8_t,LTE_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *); int (*te)(struct PHY_VARS_eNB_s *,uint8_t *,uint8_t,LTE_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *);
int (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB); int (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB);
uint8_t local_flag; uint8_t local_flag;
LTE_DL_FRAME_PARMS frame_parms; LTE_DL_FRAME_PARMS frame_parms;
...@@ -1134,7 +1182,14 @@ typedef struct PHY_VARS_eNB_s { ...@@ -1134,7 +1182,14 @@ typedef struct PHY_VARS_eNB_s {
time_stats_t dlsch_modulation_stats; time_stats_t dlsch_modulation_stats;
time_stats_t dlsch_scrambling_stats; time_stats_t dlsch_scrambling_stats;
time_stats_t dlsch_rate_matching_stats; time_stats_t dlsch_rate_matching_stats;
time_stats_t dlsch_turbo_encoding_preperation_stats;
time_stats_t dlsch_turbo_encoding_segmentation_stats;
time_stats_t dlsch_turbo_encoding_stats; time_stats_t dlsch_turbo_encoding_stats;
time_stats_t dlsch_turbo_encoding_waiting_stats;
time_stats_t dlsch_turbo_encoding_signal_stats;
time_stats_t dlsch_turbo_encoding_main_stats;
time_stats_t dlsch_turbo_encoding_wakeup_stats0;
time_stats_t dlsch_turbo_encoding_wakeup_stats1;
time_stats_t dlsch_interleaving_stats; time_stats_t dlsch_interleaving_stats;
time_stats_t rx_dft_stats; time_stats_t rx_dft_stats;
......
...@@ -203,6 +203,9 @@ ...@@ -203,6 +203,9 @@
// QAM amplitude definitions // QAM amplitude definitions
/// Amplitude for QPSK (\f$ 2^15 \times 1/\sqrt{2}\f$)
#define QPSK 23170
/// First Amplitude for QAM16 (\f$ 2^{15} \times 2/\sqrt{10}\f$) /// First Amplitude for QAM16 (\f$ 2^{15} \times 2/\sqrt{10}\f$)
#define QAM16_n1 20724 #define QAM16_n1 20724
/// Second Amplitude for QAM16 (\f$ 2^{15} \times 1/\sqrt{10}\f$) /// Second Amplitude for QAM16 (\f$ 2^{15} \times 1/\sqrt{10}\f$)
......
...@@ -201,8 +201,8 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr ...@@ -201,8 +201,8 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr
dlsch0_harq->pdsch_start = eNB->pdcch_vars[subframe & 1].num_pdcch_symbols; dlsch0_harq->pdsch_start = eNB->pdcch_vars[subframe & 1].num_pdcch_symbols;
if (dlsch0_harq->round==0) { //get pointer to SDU if this a new SDU if (dlsch0_harq->round==0) { //get pointer to SDU if this a new SDU
AssertFatal(sdu!=NULL,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n", AssertFatal(sdu!=NULL,"sdu==%d, NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n",
frame,subframe, *sdu,frame,subframe,
proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid, proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start);
if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d, subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d\n", if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d, subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d\n",
......
...@@ -346,14 +346,24 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, ...@@ -346,14 +346,24 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
start_meas(&eNB->dlsch_encoding_stats); start_meas(&eNB->dlsch_encoding_stats);
eNB->te(eNB, eNB->te(eNB,
dlsch_harq->pdu, dlsch_harq->pdu,
dlsch_harq->pdsch_start, dlsch_harq->pdsch_start,
dlsch, dlsch,
frame,subframe, frame,
&eNB->dlsch_rate_matching_stats, subframe,
&eNB->dlsch_turbo_encoding_stats, &eNB->dlsch_rate_matching_stats,
&eNB->dlsch_interleaving_stats); &eNB->dlsch_turbo_encoding_stats,
&eNB->dlsch_turbo_encoding_waiting_stats,
&eNB->dlsch_turbo_encoding_main_stats,
&eNB->dlsch_turbo_encoding_wakeup_stats0,
&eNB->dlsch_turbo_encoding_wakeup_stats1,
&eNB->dlsch_interleaving_stats);
stop_meas(&eNB->dlsch_encoding_stats); stop_meas(&eNB->dlsch_encoding_stats);
//////////////////////////////////////////////////*******************************************
if(eNB->dlsch_encoding_stats.diff_now>500*3000 && opp_enabled == 1)
{
print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr);
}
// 36-211 // 36-211
start_meas(&eNB->dlsch_scrambling_stats); start_meas(&eNB->dlsch_scrambling_stats);
dlsch_scrambling(fp, dlsch_scrambling(fp,
...@@ -546,6 +556,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, ...@@ -546,6 +556,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
else else
{ {
// generate pdsch // generate pdsch
pdsch_procedures(eNB, pdsch_procedures(eNB,
proc, proc,
harq_pid, harq_pid,
...@@ -1359,37 +1370,63 @@ extern int oai_exit; ...@@ -1359,37 +1370,63 @@ extern int oai_exit;
extern void *td_thread(void*); extern void *td_thread(void*);
void init_td_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_td) { void init_td_thread(PHY_VARS_eNB *eNB) {
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
proc->tdp.eNB = eNB; proc->tdp.eNB = eNB;
proc->instance_cnt_td = -1; proc->instance_cnt_td = -1;
pthread_attr_init( &proc->attr_td);
pthread_mutex_init( &proc->mutex_td, NULL); pthread_mutex_init( &proc->mutex_td, NULL);
pthread_cond_init( &proc->cond_td, NULL); pthread_cond_init( &proc->cond_td, NULL);
pthread_create(&proc->pthread_td, &proc->attr_td, td_thread, (void*)&proc->tdp);
pthread_create(&proc->pthread_td, attr_td, td_thread, (void*)&proc->tdp); }
void kill_td_thread(PHY_VARS_eNB *eNB) {
eNB_proc_t *proc = &eNB->proc;
proc->instance_cnt_td = 0;
pthread_cond_signal(&proc->cond_td);
pthread_join(proc->pthread_td, NULL);
pthread_mutex_destroy( &proc->mutex_td );
pthread_cond_destroy( &proc->cond_td );
} }
extern void *te_thread(void*); extern void *te_thread(void*);
void init_te_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_te) { void init_te_thread(PHY_VARS_eNB *eNB) {
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
proc->tep.eNB = eNB; for(int i=0; i<3 ;i++){
proc->instance_cnt_te = -1; proc->tep[i].eNB = eNB;
proc->tep[i].instance_cnt_te = -1;
pthread_mutex_init( &proc->tep[i].mutex_te, NULL);
pthread_cond_init( &proc->tep[i].cond_te, NULL);
pthread_attr_init( &proc->tep[i].attr_te);
pthread_mutex_init( &proc->mutex_te, NULL); printf("Creating te_thread 0\n");
pthread_cond_init( &proc->cond_te, NULL); pthread_create(&proc->tep[i].pthread_te, &proc->tep[i].attr_te, te_thread, (void*)&proc->tep[i]);
}
}
void kill_te_thread(PHY_VARS_eNB *eNB) {
printf("Creating te_thread\n"); eNB_proc_t *proc = &eNB->proc;
pthread_create(&proc->pthread_te, attr_te, te_thread, (void*)&proc->tep);
for(int i=0; i<3 ;i++){
proc->tep[i].instance_cnt_te = 0;
pthread_cond_signal(&proc->tep[i].cond_te);
pthread_join(proc->tep[i].pthread_te, NULL);
pthread_mutex_destroy( &proc->tep[i].mutex_te);
pthread_cond_destroy( &proc->tep[i].cond_te);
}
} }
void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe)
{ {
nfapi_rx_indication_pdu_t *pdu; nfapi_rx_indication_pdu_t *pdu;
...@@ -1624,6 +1661,7 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq, ...@@ -1624,6 +1661,7 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,
// release DLSCH if needed // release DLSCH if needed
release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1); release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
#if T_TRACER #if T_TRACER
/* TODO: get correct harq pid */ /* TODO: get correct harq pid */
if (ulsch_harq->o_ACK[i] != 1) if (ulsch_harq->o_ACK[i] != 1)
...@@ -1722,6 +1760,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, ...@@ -1722,6 +1760,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
// release DLSCH if needed // release DLSCH if needed
release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
#if T_TRACER #if T_TRACER
if (harq_ack[0] != 1) if (harq_ack[0] != 1)
T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe),
......
...@@ -138,12 +138,22 @@ static void *feptx_thread(void *param) { ...@@ -138,12 +138,22 @@ static void *feptx_thread(void *param) {
RU_t *ru = (RU_t *)param; RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc; RU_proc_t *proc = &ru->proc;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
thread_top_init("feptx_thread",1,85000,120000,500000);
pthread_setname_np( pthread_self(),"feptx processing");
LOG_I(PHY,"thread feptx created id=%ld\n", syscall(__NR_gettid));
//CPU_SET(6, &cpuset);
//pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
//wait_sync("feptx_thread");
thread_top_init("feptx_thread",0,870000,1000000,1000000);
while (!oai_exit) { while (!oai_exit) {
if (wait_on_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break; if (wait_on_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break;
//stop_meas(&ru->ofdm_mod_wakeup_stats);
feptx0(ru,1); feptx0(ru,1);
if (release_thread(&proc->mutex_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break; if (release_thread(&proc->mutex_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break;
...@@ -152,6 +162,10 @@ static void *feptx_thread(void *param) { ...@@ -152,6 +162,10 @@ static void *feptx_thread(void *param) {
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return NULL; return NULL;
} }
/*if(opp_enabled == 1 && ru->ofdm_mod_wakeup_stats.diff_now>30*3000){
print_meas_now(&ru->ofdm_mod_wakeup_stats,"fep wakeup",stderr);
printf("delay in fep wakeup in frame_tx: %d subframe_rx: %d \n",proc->frame_tx,proc->subframe_tx);
}*/
} }
...@@ -168,7 +182,7 @@ void feptx_ofdm_2thread(RU_t *ru) { ...@@ -168,7 +182,7 @@ void feptx_ofdm_2thread(RU_t *ru) {
wait.tv_sec=0; wait.tv_sec=0;
wait.tv_nsec=5000000L; 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); start_meas(&ru->ofdm_mod_stats);
if (subframe_select(fp,subframe) == SF_UL) return; if (subframe_select(fp,subframe) == SF_UL) return;
...@@ -198,17 +212,25 @@ void feptx_ofdm_2thread(RU_t *ru) { ...@@ -198,17 +212,25 @@ void feptx_ofdm_2thread(RU_t *ru) {
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return; return;
} }
//start_meas(&ru->ofdm_mod_wakeup_stats);
pthread_mutex_unlock( &proc->mutex_feptx ); pthread_mutex_unlock( &proc->mutex_feptx );
} }
// call first slot in this thread // call first slot in this thread
feptx0(ru,0); feptx0(ru,0);
start_meas(&ru->ofdm_mod_wait_stats);
wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread"); wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread");
stop_meas(&ru->ofdm_mod_wait_stats);
/*if(opp_enabled == 1 && ru->ofdm_mod_wait_stats.diff_now>30*3000){
print_meas_now(&ru->ofdm_mod_wait_stats,"fep wakeup",stderr);
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); stop_meas(&ru->ofdm_mod_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 );
} }
...@@ -426,12 +448,23 @@ static void *fep_thread(void *param) { ...@@ -426,12 +448,23 @@ static void *fep_thread(void *param) {
RU_t *ru = (RU_t *)param; RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc; RU_proc_t *proc = &ru->proc;
thread_top_init("fep_thread",0,870000,1000000,1000000); thread_top_init("fep_thread",1,100000,120000,5000000);
pthread_setname_np( pthread_self(),"fep processing");
LOG_I(PHY,"thread fep created id=%ld\n", syscall(__NR_gettid));
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
//CPU_SET(2, &cpuset);
//pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
//wait_sync("fep_thread");
while (!oai_exit) { while (!oai_exit) {
if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread")<0) break; if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread")<0) break;
//stop_meas(&ru->ofdm_demod_wakeup_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 1 );
fep0(ru,0); fep0(ru,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 (release_thread(&proc->mutex_fep,&proc->instance_cnt_fep,"fep thread")<0) break;
if (pthread_cond_signal(&proc->cond_fep) != 0) { if (pthread_cond_signal(&proc->cond_fep) != 0) {
...@@ -439,6 +472,10 @@ static void *fep_thread(void *param) { ...@@ -439,6 +472,10 @@ static void *fep_thread(void *param) {
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return NULL; return NULL;
} }
/*if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.diff_now>30*3000){
print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr);
printf("delay in fep wakeup in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
}*/
} }
...@@ -489,6 +526,7 @@ void ru_fep_full_2thread(RU_t *ru) { ...@@ -489,6 +526,7 @@ void ru_fep_full_2thread(RU_t *ru) {
wait.tv_sec=0; wait.tv_sec=0;
wait.tv_nsec=5000000L; wait.tv_nsec=5000000L;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
start_meas(&ru->ofdm_demod_stats); start_meas(&ru->ofdm_demod_stats);
if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) { if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) {
...@@ -512,15 +550,23 @@ void ru_fep_full_2thread(RU_t *ru) { ...@@ -512,15 +550,23 @@ void ru_fep_full_2thread(RU_t *ru) {
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return; return;
} }
//start_meas(&ru->ofdm_demod_wakeup_stats);
pthread_mutex_unlock( &proc->mutex_fep ); pthread_mutex_unlock( &proc->mutex_fep );
// call second slot in this symbol // call second slot in this symbol
fep0(ru,1); fep0(ru,1);
start_meas(&ru->ofdm_demod_wait_stats);
wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread"); wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread");
stop_meas(&ru->ofdm_demod_wait_stats);
if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.diff_now>30*3000){
print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr);
printf("delay in fep wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
}
stop_meas(&ru->ofdm_demod_stats); stop_meas(&ru->ofdm_demod_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 );
} }
......
...@@ -297,6 +297,9 @@ void RCconfig_macrlc() { ...@@ -297,6 +297,9 @@ void RCconfig_macrlc() {
mac_top_init_eNB(); mac_top_init_eNB();
for (j=0;j<RC.nb_macrlc_inst;j++) { for (j=0;j<RC.nb_macrlc_inst;j++) {
//RC.mac[j]->phy_test = *(MacRLC_ParamList.paramarray[j][MACRLC_PHY_TEST_IDX].iptr);
//printf("PHY_TEST = %d,%d\n", RC.mac[j]->phy_test, j);
if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) { if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) {
// check number of instances is same as RRC/PDCP // check number of instances is same as RRC/PDCP
......
...@@ -687,4 +687,43 @@ typedef enum { ...@@ -687,4 +687,43 @@ typedef enum {
#define CONFIG_STRING_MACRLC_CONFIG "macrlc_config" #define CONFIG_STRING_MACRLC_CONFIG "macrlc_config"
/* MACRLC configuration parameters names */
#define CONFIG_STRING_MACRLC_CC "num_cc"
#define CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE "tr_n_preference"
#define CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME "local_n_if_name"
#define CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS "local_n_address"
#define CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS "remote_n_address"
#define CONFIG_STRING_MACRLC_LOCAL_N_PORTC "local_n_portc"
#define CONFIG_STRING_MACRLC_REMOTE_N_PORTC "remote_n_portc"
#define CONFIG_STRING_MACRLC_LOCAL_N_PORTD "local_n_portd"
#define CONFIG_STRING_MACRLC_REMOTE_N_PORTD "remote_n_portd"
#define CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE "tr_s_preference"
#define CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME "local_s_if_name"
#define CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS "local_s_address"
#define CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS "remote_s_address"
#define CONFIG_STRING_MACRLC_LOCAL_S_PORTC "local_s_portc"
#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc"
#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd"
#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd"
#define CONFIG_STRING_MACRLC_PHY_TEST_MODE "phy_test_mode"
#define MACRLC_CC_IDX 0
#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1
#define MACRLC_LOCAL_N_IF_NAME_IDX 2
#define MACRLC_LOCAL_N_ADDRESS_IDX 3
#define MACRLC_REMOTE_N_ADDRESS_IDX 4
#define MACRLC_LOCAL_N_PORTC_IDX 5
#define MACRLC_REMOTE_N_PORTC_IDX 6
#define MACRLC_LOCAL_N_PORTD_IDX 7
#define MACRLC_REMOTE_N_PORTD_IDX 8
#define MACRLC_TRANSPORT_S_PREFERENCE_IDX 9
#define MACRLC_LOCAL_S_IF_NAME_IDX 10
#define MACRLC_LOCAL_S_ADDRESS_IDX 11
#define MACRLC_REMOTE_S_ADDRESS_IDX 12
#define MACRLC_LOCAL_S_PORTC_IDX 13
#define MACRLC_REMOTE_S_PORTC_IDX 14
#define MACRLC_LOCAL_S_PORTD_IDX 15
#define MACRLC_REMOTE_S_PORTD_IDX 16
#define MACRLC_PHY_TEST_IDX 17
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
...@@ -1071,6 +1071,8 @@ typedef struct eNB_MAC_INST_s { ...@@ -1071,6 +1071,8 @@ typedef struct eNB_MAC_INST_s {
COMMON_channels_t common_channels[MAX_NUM_CCs]; COMMON_channels_t common_channels[MAX_NUM_CCs];
/// current PDU index (BCH,MCH,DLSCH) /// current PDU index (BCH,MCH,DLSCH)
uint16_t pdu_index[MAX_NUM_CCs]; uint16_t pdu_index[MAX_NUM_CCs];
/// flag to enable phy-test (disables the scheduler)
uint16_t phy_test;
/// NFAPI Config Request Structure /// NFAPI Config Request Structure
nfapi_config_request_t config[MAX_NUM_CCs]; nfapi_config_request_t config[MAX_NUM_CCs];
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#define DEBUG_eNB_SCHEDULER 1 #define DEBUG_eNB_SCHEDULER 1
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
extern int phy_test;
uint16_t pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; uint16_t pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
...@@ -640,26 +641,33 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, ...@@ -640,26 +641,33 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
#endif #endif
// This schedules MIB // This schedules MIB
if ((subframeP == 0) && (frameP & 3) == 0) if ((subframeP == 0) && (frameP & 3) == 0)
schedule_mib(module_idP, frameP, subframeP); schedule_mib(module_idP, frameP, subframeP);
// This schedules SI for legacy LTE and eMTC starting in subframeP if (phy_test == 0){
schedule_SI(module_idP, frameP, subframeP); // This schedules SI for legacy LTE and eMTC starting in subframeP
// This schedules Paging in subframeP schedule_SI(module_idP, frameP, subframeP);
schedule_PCH(module_idP,frameP,subframeP); // This schedules Paging in subframeP
// This schedules Random-Access for legacy LTE and eMTC starting in subframeP schedule_PCH(module_idP,frameP,subframeP);
schedule_RA(module_idP, frameP, subframeP); // This schedules Random-Access for legacy LTE and eMTC starting in subframeP
// copy previously scheduled UL resources (ULSCH + HARQ) schedule_RA(module_idP, frameP, subframeP);
copy_ulreq(module_idP, frameP, subframeP); // copy previously scheduled UL resources (ULSCH + HARQ)
// This schedules SRS in subframeP copy_ulreq(module_idP, frameP, subframeP);
schedule_SRS(module_idP, frameP, subframeP); // This schedules SRS in subframeP
// This schedules ULSCH in subframeP (dci0) schedule_SRS(module_idP, frameP, subframeP);
schedule_ulsch(module_idP, frameP, subframeP); // This schedules ULSCH in subframeP (dci0)
// This schedules UCI_SR in subframeP schedule_ulsch(module_idP, frameP, subframeP);
schedule_SR(module_idP, frameP, subframeP); // This schedules UCI_SR in subframeP
// This schedules UCI_CSI in subframeP schedule_SR(module_idP, frameP, subframeP);
schedule_CSI(module_idP, frameP, subframeP); // This schedules UCI_CSI in subframeP
// This schedules DLSCH in subframeP schedule_CSI(module_idP, frameP, subframeP);
schedule_dlsch(module_idP, frameP, subframeP, mbsfn_status); // This schedules DLSCH in subframeP
schedule_dlsch(module_idP, frameP, subframeP, mbsfn_status);
}
else{
schedule_ulsch_phy_test(module_idP,frameP,subframeP);
schedule_ue_spec_phy_test(module_idP,frameP,subframeP,mbsfn_status);
}
if (RC.flexran[module_idP]->enabled) if (RC.flexran[module_idP]->enabled)
flexran_agent_send_update_stats(module_idP); flexran_agent_send_update_stats(module_idP);
......
...@@ -787,6 +787,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) ...@@ -787,6 +787,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
eNB->eNB_stats[CC_id].bcch_buffer = bcch_sdu_length; eNB->eNB_stats[CC_id].bcch_buffer = bcch_sdu_length;
eNB->eNB_stats[CC_id].total_bcch_buffer += bcch_sdu_length; eNB->eNB_stats[CC_id].total_bcch_buffer += bcch_sdu_length;
eNB->eNB_stats[CC_id].bcch_mcs = mcs; eNB->eNB_stats[CC_id].bcch_mcs = mcs;
//printf("SI %d.%d\n", frameP, subframeP);/////////////////////////////////////////******************************
} else { } else {
//LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame);
......
/*
* 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.0 (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
*/
/*! \file eNB_scheduler_dlsch.c
* \brief procedures related to eNB for the DLSCH transport channel
* \author Navid Nikaein and Raymond Knopp
* \date 2010 - 2014
* \email: navid.nikaein@eurecom.fr
* \version 1.0
* @ingroup _mac
*/
#include "assertions.h"
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "SCHED/extern.h"
#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/proto.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "SIMULATION/TOOLS/defs.h" // for taus
#include "T.h"
extern RAN_CONTEXT_t RC;
//------------------------------------------------------------------------------
void
schedule_ue_spec_phy_test(
module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP,
int* mbsfn_flag
)
//------------------------------------------------------------------------------
{
uint8_t CC_id;
int UE_id=0;
uint16_t N_RB_DL;
uint16_t TBS;
uint16_t nb_rb;
unsigned char harq_pid = subframeP%5;
uint16_t rnti = 0x1235;
uint32_t rb_alloc = 0x1FFFFFFF;
int32_t tpc = 1;
int32_t mcs = 28;
int32_t cqi = 15;
int32_t ndi = subframeP/5;
int32_t dai = 0;
eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc = eNB->common_channels;
nfapi_dl_config_request_body_t *dl_req;
nfapi_dl_config_request_pdu_t *dl_config_pdu;
N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth);
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n",CC_id);
dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
if (mbsfn_flag[CC_id]>0)
continue;
nb_rb = conv_nprb(0,rb_alloc,N_RB_DL);
//printf("////////////////////////////////////*************************nb_rb = %d\n",nb_rb);
TBS = get_TBS_DL(mcs,nb_rb);
LOG_D(PHY,"schedule_ue_spec_phy_test: subframe %d/%d: nb_rb=%d, TBS=%d, mcs=%d (rb_alloc=%x, N_RB_DL=%d)\n",frameP,subframeP,nb_rb,TBS,mcs,rb_alloc,N_RB_DL);
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP,CC_id),cqi,format1);
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = rb_alloc;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0;
//deactivate second codeword
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1;
if (cc[CC_id].tdd_Config != NULL) { //TDD
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = dai;
LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n",
module_idP,CC_id,harq_pid,dai,mcs);
} else {
LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n",
module_idP,CC_id,harq_pid,mcs);
}
LOG_D(MAC,"Checking feasibility pdu %d (new sdu)\n",dl_req->number_pdu);
if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,rnti)) {
//ue_sched_ctl->round[CC_id][harq_pid] = 0;
dl_req->number_dci++;
dl_req->number_pdu++;
// Toggle NDI for next time
/*
LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",
CC_id, frameP,subframeP,UE_id,
rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]);
UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs;
UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0;
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n");
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
*/
fill_nfapi_dlsch_config(eNB,
dl_req,
TBS,
eNB->pdu_index[CC_id],
rnti,
0, // type 0 allocation from 7.1.6 in 36.213
0, // virtual_resource_block_assignment_flag
rb_alloc, // resource_block_coding
getQm(mcs),
0, // redundancy version
1, // transport blocks
0, // transport block to codeword swap flag
cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme
1, // number of layers
1, // number of subbands
// uint8_t codebook_index,
4, // UE category capacity
PDSCH_ConfigDedicated__p_a_dB0,
0, // delta_power_offset for TM5
0, // ngap
0, // nprb
cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode
0, //number of PRBs treated as one subband, not used here
0 // number of beamforming vectors, not used here
);
eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body,
(frameP*10)+subframeP,
TBS,
eNB->pdu_index[CC_id],
eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]);
}
else {
LOG_W(MAC,"[eNB_scheduler_phytest] DCI allocation infeasible!\n");
}
}
}
void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
{
uint16_t first_rb[MAX_NUM_CCs];
int UE_id = 0;
uint8_t aggregation = 2;
rnti_t rnti = 0x1235;
uint8_t mcs = 0;
uint8_t harq_pid = 0;
uint32_t cqi_req = 0,cshift,ndi,tpc = 1;
int32_t normalized_rx_power;
int32_t target_rx_power= 178;
int CC_id = 0;
int nb_rb = 96;
eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc = eNB->common_channels;
UE_list_t *UE_list=&eNB->UE_list;
UE_TEMPLATE *UE_template;
UE_sched_ctrl *UE_sched_ctrl;
int sched_frame=frameP;
int sched_subframe = (subframeP+4)%10;
if (sched_subframe<subframeP) sched_frame++;
nfapi_hi_dci0_request_body_t *hi_dci0_req = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body;
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu;
//nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[0];;
nfapi_ul_config_request_body_t *ul_req = &eNB->UL_req[CC_id].ul_config_request_body;
eNB->UL_req[CC_id].sfn_sf = (sched_frame<<4) + sched_subframe;
eNB->HI_DCI0_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
//rnti = UE_RNTI(module_idP,UE_id);
//leave out first RB for PUCCH
first_rb[CC_id] = 1;
// loop over all active UEs
// if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
UE_template = &UE_list->UE_template[CC_id][UE_id];
UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
harq_pid = subframe2harqpid(&cc[CC_id],sched_frame,sched_subframe);
LOG_D(MAC,"Scheduling for frame %d, subframe %d => harq_pid %d\n",sched_frame,sched_subframe,harq_pid);
RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->TBS_UL[harq_pid];
//power control
//compute the expected ULSCH RX power (for the stats)
// this is the normalized RX power and this should be constant (regardless of mcs
normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id];
// new transmission
ndi = 1-UE_template->oldNDI_UL[harq_pid];
UE_template->oldNDI_UL[harq_pid]=ndi;
UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power;
UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power;
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = mcs;
UE_template->mcs_UL[harq_pid] = mcs;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = mcs;
// buffer_occupancy = UE_template->ul_total_buffer;
UE_template->TBS_UL[harq_pid] = get_TBS_UL(mcs,nb_rb);
UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += nb_rb;
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = get_TBS_UL(mcs,nb_rb);
// buffer_occupancy -= TBS;
// bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
//store for possible retransmission
UE_template->nb_rb_ul[harq_pid] = nb_rb;
UE_template->first_rb_ul[harq_pid] = first_rb[CC_id];
UE_sched_ctrl->ul_scheduled |= (1<<harq_pid);
// adjust total UL buffer status by TBS, wait for UL sdus to do final update
//UE_template->ul_total_buffer = UE_template->TBS_UL[harq_pid];
// Cyclic shift for DM RS
cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
// save it for a potential retransmission
UE_template->cshift[harq_pid] = cshift;
hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci+eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_hi];
memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE;
hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_dci_pdu);
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb[CC_id];
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = nb_rb;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = mcs;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframe];
eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci++;
// Add UL_config PDUs
fill_nfapi_ulsch_config_request_rel8(&ul_req->ul_config_pdu_list[ul_req->number_of_pdus],
cqi_req,
cc,
0,//UE_template->physicalConfigDedicated,
get_tmode(module_idP,CC_id,UE_id),
eNB->ul_handle,
rnti,
first_rb[CC_id], // resource_block_start
nb_rb, // number_of_resource_blocks
mcs,
cshift, // cyclic_shift_2_for_drms
0, // frequency_hopping_enabled_flag
0, // frequency_hopping_bits
ndi, // new_data_indication
0, // redundancy_version
harq_pid, // harq_process_number
0, // ul_tx_mode
0, // current_tx_nb
0, // n_srs
get_TBS_UL(mcs,nb_rb)
);
#ifdef Rel14
if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation
fill_nfapi_ulsch_config_request_emtc(&ul_req->ul_config_pdu_list[ul_req->number_of_pdus],
UE_template->rach_resource_type>2 ? 2 : 1,
1, //total_number_of_repetitions
1, //repetition_number
(frameP*10)+subframeP);
}
#endif
ul_req->number_of_pdus = 1;
eNB->ul_handle++;
add_ue_ulsch_info(module_idP,
CC_id,
UE_id,
subframeP,
S_UL_SCHEDULED);
// increment first rb for next UE allocation
first_rb[CC_id]+= nb_rb;
} // loop of CC_id
}
...@@ -150,6 +150,9 @@ void schedule_dlsch(module_id_t module_idP, frame_t frameP, ...@@ -150,6 +150,9 @@ void schedule_dlsch(module_id_t module_idP, frame_t frameP,
void schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, void schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP,
frame_t frameP,sub_frame_t subframe, int *mbsfn_flag); frame_t frameP,sub_frame_t subframe, int *mbsfn_flag);
void schedule_ue_spec_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,int *mbsfn_flag);
void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP);
/** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure. /** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure.
@param Mod_id Module id of UE @param Mod_id Module id of UE
......
...@@ -191,6 +191,9 @@ const char* eurecomVariablesNames[] = { ...@@ -191,6 +191,9 @@ const char* eurecomVariablesNames[] = {
"ue0_trx_write_ns", "ue0_trx_write_ns",
"ue0_trx_read_ns_missing", "ue0_trx_read_ns_missing",
"ue0_trx_write_ns_missing", "ue0_trx_write_ns_missing",
"enb_thread_rxtx_CPUID",
"ru_thread_CPUID",
"ru_thread_tx_CPUID"
}; };
const char* eurecomFunctionsNames[] = { const char* eurecomFunctionsNames[] = {
......
...@@ -167,6 +167,9 @@ typedef enum { ...@@ -167,6 +167,9 @@ typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS, VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS,
VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS_MISSING, VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS_MISSING,
VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS_MISSING, VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS_MISSING,
VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX,
VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD,
VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD_TX,
VCD_SIGNAL_DUMPER_VARIABLES_END VCD_SIGNAL_DUMPER_VARIABLES_END
} vcd_signal_dump_variables; } vcd_signal_dump_variables;
......
...@@ -117,7 +117,7 @@ int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cf ...@@ -117,7 +117,7 @@ int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cf
rc=load_lib(device, openair0_cfg, NULL,RAU_LOCAL_RADIO_HEAD ); rc=load_lib(device, openair0_cfg, NULL,RAU_LOCAL_RADIO_HEAD );
if ( rc >= 0) { if ( rc >= 0) {
if ( set_device(device) < 0) { if ( set_device(device) < 0) {
fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__); fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__);
return -1; return -1;
} }
......
...@@ -982,15 +982,20 @@ extern "C" { ...@@ -982,15 +982,20 @@ extern "C" {
// workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate // workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate
args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock);
// args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096";
// args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096";
uhd::device_addrs_t device_adds = uhd::device::find(args); uhd::device_addrs_t device_adds = uhd::device::find(args);
if(device_adds.size() == 0) { if(device_adds.size() == 0) {
std::cerr<<"No USRP Device Found. " << std::endl; args += ",addr=192.168.30.2";
free(s);
return -1; uhd::device_addrs_t device_adds = uhd::device::find(args);
if(device_adds.size() == 0) {
std::cerr<<"No USRP Device Found. " << std::endl;
free(s);
return -1;
}
} }
LOG_I(PHY,"Found USRP X300\n"); LOG_I(PHY,"Found USRP X300\n");
s->usrp = uhd::usrp::multi_usrp::make(args); s->usrp = uhd::usrp::multi_usrp::make(args);
...@@ -1016,6 +1021,20 @@ extern "C" { ...@@ -1016,6 +1021,20 @@ extern "C" {
LOG_I(PHY,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate); LOG_I(PHY,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate);
switch ((int)openair0_cfg[0].sample_rate) { switch ((int)openair0_cfg[0].sample_rate) {
case 122880000:
// from usrp_time_offset
//openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg[0].tx_sample_advance = 15; //to be checked
openair0_cfg[0].tx_bw = 80e6;
openair0_cfg[0].rx_bw = 80e6;
break;
case 61440000:
// from usrp_time_offset
//openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg[0].tx_sample_advance = 15;
openair0_cfg[0].tx_bw = 40e6;
openair0_cfg[0].rx_bw = 40e6;
break;
case 30720000: case 30720000:
// from usrp_time_offset // from usrp_time_offset
//openair0_cfg[0].samples_per_packet = 2048; //openair0_cfg[0].samples_per_packet = 2048;
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
# endif # endif
# include "enb_app.h" # include "enb_app.h"
extern int emulate_rf;
int create_tasks(uint32_t enb_nb) int create_tasks(uint32_t enb_nb)
{ {
LOG_D(ENB_APP, "%s(enb_nb:%d\n", __FUNCTION__, enb_nb); LOG_D(ENB_APP, "%s(enb_nb:%d\n", __FUNCTION__, enb_nb);
...@@ -69,10 +71,11 @@ int create_tasks(uint32_t enb_nb) ...@@ -69,10 +71,11 @@ int create_tasks(uint32_t enb_nb)
LOG_E(S1AP, "Create task for S1AP failed\n"); LOG_E(S1AP, "Create task for S1AP failed\n");
return -1; return -1;
} }
if(!emulate_rf){
if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
LOG_E(UDP_, "Create task for UDP failed\n"); LOG_E(UDP_, "Create task for UDP failed\n");
return -1; return -1;
}
} }
if (itti_create_task (TASK_GTPV1_U, &gtpv1u_eNB_task, NULL) < 0) { if (itti_create_task (TASK_GTPV1_U, &gtpv1u_eNB_task, NULL) < 0) {
......
Active_eNBs = ( "eNB_Eurecom_LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1";
mobile_country_code = "208";
mobile_network_code = "93";
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "eNodeB_3GPP";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2685000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 100;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
pbch_repetition = "FALSE";
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -27;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -96;
pusch_alpha = "AL1";
pucch_p0_Nominal = -104;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.26";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth6";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth6";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 116;
eNB_instances = [0];
}
);
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="medium";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
...@@ -151,9 +151,9 @@ eNBs = ...@@ -151,9 +151,9 @@ eNBs =
{ {
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.19/24"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_INTERFACE_NAME_FOR_S1U = "eth0";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.19/24"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152 ENB_PORT_FOR_S1U = 2152; # Spec 2152
}; };
} }
...@@ -164,6 +164,7 @@ MACRLCs = ( ...@@ -164,6 +164,7 @@ MACRLCs = (
num_cc = 1; num_cc = 1;
tr_s_preference = "local_L1"; tr_s_preference = "local_L1";
tr_n_preference = "local_RRC"; tr_n_preference = "local_RRC";
phy_test_mode = 1;
} }
); );
......
[*] [*]
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI [*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
[*] Tue Jul 25 20:26:12 2017 [*] Thu Feb 22 14:46:40 2018
[*] [*]
[dumpfile] "/tmp/openair_dump_eNB.vcd" [dumpfile] "/tmp/openair_dump_eNB.vcd"
[dumpfile_mtime] "Tue Jul 25 20:11:55 2017" [dumpfile_mtime] "Thu Feb 22 14:44:26 2018"
[dumpfile_size] 19201475 [dumpfile_size] 3482761
[savefile] "/home/papillon/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw" [savefile] "/homes/wangts/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw"
[timestart] 29023604000 [timestart] 4525000000
[size] 1236 578 [size] 1920 1018
[pos] 309 0 [pos] 0 22
*-20.793451 29026062100 -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 *-21.506693 4530514310 -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 [sst_width] 386
[signals_width] 262 [signals_width] 344
[sst_expanded] 1 [sst_expanded] 1
[sst_vpaned_height] 146 [sst_vpaned_height] 303
@28 @28
functions.trx_read functions.trx_read
functions.trx_write functions.trx_write
...@@ -25,12 +25,42 @@ functions.eNB_thread_rxtx0 ...@@ -25,12 +25,42 @@ functions.eNB_thread_rxtx0
@24 @24
variables.frame_number_RX0_RU[63:0] variables.frame_number_RX0_RU[63:0]
variables.subframe_number_RX0_RU[63:0] variables.subframe_number_RX0_RU[63:0]
@25
variables.frame_number_TX0_RU[63:0] variables.frame_number_TX0_RU[63:0]
@24
variables.subframe_number_TX0_RU[63:0] variables.subframe_number_TX0_RU[63:0]
@28 @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_eNB[63:0]
@25
variables.subframe_number_RX0_eNB[63:0]
@24
variables.frame_number_TX0_eNB[63:0]
variables.subframe_number_TX0_eNB[63:0]
variables.frame_number_RX1_eNB[63:0]
variables.subframe_number_RX1_eNB[63:0]
variables.frame_number_TX1_eNB[63:0]
variables.subframe_number_TX1_eNB[63:0]
@28
functions.phy_eNB_dlsch_modulation
functions.phy_eNB_dlsch_encoding
functions.phy_eNB_dlsch_scrambling
functions.phy_eNB_beam_precoding
functions.phy_enb_pdcch_tx
functions.phy_enb_prach_rx
functions.phy_procedures_ru_feprx0
functions.phy_procedures_eNb_rx_uespec0
functions.phy_procedures_eNb_rx_uespec1
functions.phy_enb_sfgen
functions.phy_procedures_eNb_tx0 functions.phy_procedures_eNb_tx0
functions.phy_procedures_eNb_tx1
functions.phy_procedures_ru_feprx1
functions.phy_procedures_ru_feptx_ofdm0
functions.phy_procedures_ru_feptx_ofdm1
functions.phy_procedures_ru_feptx_prec0
functions.phy_procedures_ru_feptx_prec1
functions.eNB_thread_rxtx1 functions.eNB_thread_rxtx1
functions.phy_enb_sfgen functions.phy_enb_sfgen
functions.phy_enb_prach_rx functions.phy_enb_prach_rx
......
...@@ -148,11 +148,13 @@ void exit_fun(const char* s); ...@@ -148,11 +148,13 @@ void exit_fun(const char* s);
void init_eNB(int,int); void init_eNB(int,int);
void stop_eNB(int nb_inst); 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);
void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
#ifdef Rel14 #ifdef Rel14
void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
#endif #endif
extern int codingw;
extern uint8_t nfapi_mode; extern uint8_t nfapi_mode;
extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
...@@ -220,6 +222,15 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam ...@@ -220,6 +222,15 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
if (nfapi_mode == 0 || nfapi_mode == 1) { if (nfapi_mode == 0 || nfapi_mode == 1) {
phy_procedures_eNB_uespec_RX(eNB, proc, no_relay ); phy_procedures_eNB_uespec_RX(eNB, proc, no_relay );
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 1 );
if(get_nprocs() >= 8){
if(wait_on_condition(&proc[1].mutex_rxtx,&proc[1].cond_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) {
LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc[1].frame_rx,proc[1].subframe_rx);
return(-1);
}
if (release_thread(&proc[1].mutex_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) return(-1);
}
pthread_mutex_lock(&eNB->UL_INFO_mutex); pthread_mutex_lock(&eNB->UL_INFO_mutex);
...@@ -231,17 +242,13 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam ...@@ -231,17 +242,13 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
eNB->if_inst->UL_indication(&eNB->UL_INFO); eNB->if_inst->UL_indication(&eNB->UL_INFO);
pthread_mutex_unlock(&eNB->UL_INFO_mutex); pthread_mutex_unlock(&eNB->UL_INFO_mutex);
// *****************************************
// TX processing for subframe n+sf_ahead
// run PHY TX procedures the one after the other for all CCs to avoid race conditions
// (may be relaxed in the future for performance reasons)
// *****************************************
//if (wait_CCs(proc)<0) return(-1);
if (oai_exit) return(-1);
phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 );
if(oai_exit) return(-1);
if(get_nprocs() <= 4){
phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
}
stop_meas( &softmodem_stats_rxtx_sf ); stop_meas( &softmodem_stats_rxtx_sf );
...@@ -293,6 +300,50 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam ...@@ -293,6 +300,50 @@ 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;
eNB_rxtx_proc_t *proc = &eNB_proc->proc_rxtx[1];
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);
thread_top_init(thread_name,1,470000,500000,500000);
//wait_sync("tx_thread");
while (!oai_exit) {
if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
if (oai_exit) break;
// *****************************************
// TX processing for subframe n+4
// run PHY TX procedures the one after the other for all CCs to avoid race conditions
// (may be relaxed in the future for performance reasons)
// *****************************************
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX1_ENB,proc->subframe_tx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX1_ENB,proc->subframe_rx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_ENB,proc->frame_tx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_ENB,proc->frame_rx);
phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
pthread_mutex_lock( &proc->mutex_rxtx );
proc->pipe_ready++;
// the thread can now be woken up
if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" );
}
pthread_mutex_unlock( &proc->mutex_rxtx );
wakeup_txfh(proc,eNB_proc->ru_proc);
}
return 0;
}
/*! /*!
* \brief The RX UE-specific and TX thread of eNB. * \brief The RX UE-specific and TX thread of eNB.
* \param param is a \ref eNB_proc_t structure which contains the info what to process. * \param param is a \ref eNB_proc_t structure which contains the info what to process.
...@@ -302,36 +353,66 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam ...@@ -302,36 +353,66 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
static void* eNB_thread_rxtx( void* param ) { static void* eNB_thread_rxtx( void* param ) {
static int eNB_thread_rxtx_status; static int eNB_thread_rxtx_status;
eNB_proc_t *eNB_proc = (eNB_proc_t*)param;
eNB_rxtx_proc_t *proc = (eNB_rxtx_proc_t*)param; eNB_rxtx_proc_t *proc = &eNB_proc->proc_rxtx[0];
PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
//RU_proc_t *ru_proc = NULL;
char thread_name[100]; char thread_name[100];
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
// set default return value // set default return value
eNB_thread_rxtx_status = 0; eNB_thread_rxtx_status = 0;
sprintf(thread_name,"RXn_TXnp4_%d",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
thread_top_init(thread_name,1,850000L,1000000L,2000000L); thread_top_init(thread_name,1,470000,500000,500000);
pthread_setname_np( pthread_self(),"rxtx processing");
LOG_I(PHY,"thread rxtx created id=%ld\n", syscall(__NR_gettid));
while (!oai_exit) { while (!oai_exit) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX,sched_getcpu());
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB,proc->subframe_tx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_ENB,proc->subframe_rx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB,proc->frame_tx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_ENB,proc->frame_rx);
if (oai_exit) break; if (oai_exit) break;
if (eNB->CC_id==0) if (eNB->CC_id==0)
{ {
if (rxtx(eNB,proc,thread_name) < 0) break; if (rxtx(eNB,proc,thread_name) < 0) break;
} }
if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
pthread_mutex_lock( &proc->mutex_rxtx );
proc->pipe_ready++;
// the thread can now be woken up
if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" );
}
pthread_mutex_unlock( &proc->mutex_rxtx );
if(get_nprocs() >= 8) wakeup_tx(eNB,eNB->proc.ru_proc);
else
{
phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
wakeup_txfh(proc,eNB->proc.ru_proc);
}
} // while !oai_exit } // while !oai_exit
...@@ -367,10 +448,12 @@ static void wait_system_ready (char *message, volatile int *start_flag) { ...@@ -367,10 +448,12 @@ static void wait_system_ready (char *message, volatile int *start_flag) {
void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string) void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru)
{ {
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0]; eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0];
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
RU_proc_t *ru_proc=&ru->proc;
proc->frame_rx = frame_rx; proc->frame_rx = frame_rx;
proc->subframe_rx = subframe_rx; proc->subframe_rx = subframe_rx;
...@@ -378,23 +461,113 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string) ...@@ -378,23 +461,113 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string)
if (!oai_exit) { if (!oai_exit) {
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx)); T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
proc_rxtx->subframe_rx = proc->subframe_rx; proc_rxtx->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
proc_rxtx->frame_rx = proc->frame_rx; proc_rxtx->frame_rx = ru_proc->frame_rx;
proc_rxtx->subframe_tx = (proc->subframe_rx+sf_ahead)%10; proc_rxtx->subframe_rx = ru_proc->subframe_rx;
proc_rxtx->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (1+proc->frame_rx)&1023 : proc->frame_rx; proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > (9-sf_ahead)) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
proc->frame_tx = proc_rxtx->frame_tx; proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + sf_ahead)%10;
proc_rxtx->timestamp_tx = proc->timestamp_tx;
if (rxtx(eNB,proc_rxtx,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id); if (rxtx(eNB,proc_rxtx,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
ru_proc->timestamp_tx = proc_rxtx->timestamp_tx;
ru_proc->subframe_tx = proc_rxtx->subframe_tx;
ru_proc->frame_tx = proc_rxtx->frame_tx;
} }
} }
int wakeup_txfh(eNB_rxtx_proc_t *proc,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);
}
++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 );
return(0);
}
int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) {
eNB_proc_t *proc=&eNB->proc;
eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];//*proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1];
eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
if (proc_rxtx1->instance_cnt_rxtx == 0) {
LOG_E(PHY,"Frame %d, subframe %d: TX1 thread busy, dropping\n",proc_rxtx1->frame_rx,proc_rxtx1->subframe_rx);
return(-1);
}
if (pthread_mutex_timedlock(&proc_rxtx1->mutex_rxtx,&wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", proc_rxtx1->subframe_rx&1,proc_rxtx1->instance_cnt_rxtx );
exit_fun( "error locking mutex_tx" );
return(-1);
}
++proc_rxtx1->instance_cnt_rxtx;
proc_rxtx1->subframe_rx = proc_rxtx0->subframe_rx;
proc_rxtx1->frame_rx = proc_rxtx0->frame_rx;
proc_rxtx1->subframe_tx = proc_rxtx0->subframe_tx;
proc_rxtx1->frame_tx = proc_rxtx0->frame_tx;
proc_rxtx1->timestamp_tx = proc_rxtx0->timestamp_tx;
// the thread can now be woken up
if (pthread_cond_signal(&proc_rxtx1->cond_rxtx) != 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( &proc_rxtx1->mutex_rxtx );
return(0);
}
int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
eNB_proc_t *proc=&eNB->proc; eNB_proc_t *proc=&eNB->proc;
RU_proc_t *ru_proc=&ru->proc;
eNB_rxtx_proc_t *proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1]; eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];//*proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1];
//eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
...@@ -426,25 +599,28 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { ...@@ -426,25 +599,28 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
wait.tv_sec=0; wait.tv_sec=0;
wait.tv_nsec=5000000L; wait.tv_nsec=5000000L;
/* accept some delay in processing - up to 5ms */
for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) { if(wait_on_condition(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->cond_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) {
LOG_W( PHY,"[eNB] Frame %d Subframe %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx); LOG_E(PHY,"Frame %d, subframe %d: RXTX0 not ready\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx);
usleep(500); return(-1);
} }
if (proc_rxtx->instance_cnt_rxtx == 0) { if (release_thread(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) return(-1);
exit_fun( "TX thread busy" );
if (proc_rxtx0->instance_cnt_rxtx == 0) {
LOG_E(PHY,"Frame %d, subframe %d: RXTX0 thread busy, dropping\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx);
return(-1); return(-1);
} }
// wake up TX for subframe n+sf_ahead // wake up TX for subframe n+sf_ahead
// lock the TX mutex and make sure the thread is ready // lock the TX mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) { if (pthread_mutex_timedlock(&proc_rxtx0->mutex_rxtx,&wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx ); LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx0->subframe_rx&1,proc_rxtx0->instance_cnt_rxtx );
exit_fun( "error locking mutex_rxtx" ); exit_fun( "error locking mutex_rxtx" );
return(-1); return(-1);
} }
++proc_rxtx->instance_cnt_rxtx;
++proc_rxtx0->instance_cnt_rxtx;
// We have just received and processed the common part of a subframe, say n. // 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 // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
...@@ -452,20 +628,20 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { ...@@ -452,20 +628,20 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
// 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+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti, // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti,
// and proc->subframe_tx = proc->subframe_rx+sf_ahead // and proc->subframe_tx = proc->subframe_rx+sf_ahead
proc_rxtx->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_tti); proc_rxtx0->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
proc_rxtx->frame_rx = proc->frame_rx; proc_rxtx0->frame_rx = ru_proc->frame_rx;
proc_rxtx->subframe_rx = proc->subframe_rx; proc_rxtx0->subframe_rx = ru_proc->subframe_rx;
proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > (9-sf_ahead)) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx; proc_rxtx0->frame_tx = (proc_rxtx0->subframe_rx > (9-sf_ahead)) ? (proc_rxtx0->frame_rx+1)&1023 : proc_rxtx0->frame_rx;
proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + sf_ahead)%10; proc_rxtx0->subframe_tx = (proc_rxtx0->subframe_rx + sf_ahead)%10;
// the thread can now be woken up // the thread can now be woken up
if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) { if (pthread_cond_signal(&proc_rxtx0->cond_rxtx) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n"); LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return(-1); return(-1);
} }
pthread_mutex_unlock( &proc_rxtx->mutex_rxtx ); pthread_mutex_unlock( &proc_rxtx0->mutex_rxtx );
return(0); return(0);
} }
...@@ -605,8 +781,9 @@ static void* eNB_thread_prach( void* param ) { ...@@ -605,8 +781,9 @@ static void* eNB_thread_prach( void* param ) {
// set default return value // set default return value
eNB_thread_prach_status = 0; eNB_thread_prach_status = 0;
thread_top_init("eNB_thread_prach",1,500000L,1000000L,20000000L); thread_top_init("eNB_thread_prach",1,500000,1000000,20000000);
//wait_sync("eNB_thread_prach");
while (!oai_exit) { while (!oai_exit) {
...@@ -647,7 +824,7 @@ static void* eNB_thread_prach_br( void* param ) { ...@@ -647,7 +824,7 @@ static void* eNB_thread_prach_br( void* param ) {
// set default return value // set default return value
eNB_thread_prach_status = 0; eNB_thread_prach_status = 0;
thread_top_init("eNB_thread_prach_br",1,500000L,1000000L,20000000L); thread_top_init("eNB_thread_prach_br",1,500000,1000000,20000000);
while (!oai_exit) { while (!oai_exit) {
...@@ -671,8 +848,40 @@ static void* eNB_thread_prach_br( void* param ) { ...@@ -671,8 +848,40 @@ static void* eNB_thread_prach_br( void* param ) {
#endif #endif
extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *);
extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *); extern void init_td_thread(PHY_VARS_eNB *);
extern void init_te_thread(PHY_VARS_eNB *);
extern void kill_td_thread(PHY_VARS_eNB *);
extern void kill_te_thread(PHY_VARS_eNB *);
//////////////////////////////////////need to modified////////////////*****
static void* process_stats_thread(void* param) {
PHY_VARS_eNB *eNB = (PHY_VARS_eNB*)param;
wait_sync("process_stats_thread");
while (!oai_exit) {
sleep(1);
if (opp_enabled == 1) {
if (eNB->td) print_meas(&eNB->ulsch_decoding_stats,"ulsch_decoding",NULL,NULL);
if (eNB->te)
{
print_meas(&eNB->dlsch_turbo_encoding_preperation_stats,"dlsch_coding_crc",NULL,NULL);
print_meas(&eNB->dlsch_turbo_encoding_segmentation_stats,"dlsch_segmentation",NULL,NULL);
print_meas(&eNB->dlsch_encoding_stats,"dlsch_encoding",NULL,NULL);
print_meas(&eNB->dlsch_turbo_encoding_signal_stats,"coding_signal",NULL,NULL);
print_meas(&eNB->dlsch_turbo_encoding_main_stats,"coding_main",NULL,NULL);
print_meas(&eNB->dlsch_turbo_encoding_waiting_stats,"coding_wait",NULL,NULL);
print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats0,"coding_worker_0",NULL,NULL);
print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats1,"coding_worker_1",NULL,NULL);
}
print_meas(&eNB->dlsch_modulation_stats,"dlsch_modulation",NULL,NULL);
}
}
return(NULL);
}
void init_eNB_proc(int inst) { void init_eNB_proc(int inst) {
...@@ -682,7 +891,6 @@ void init_eNB_proc(int inst) { ...@@ -682,7 +891,6 @@ void init_eNB_proc(int inst) {
eNB_proc_t *proc; eNB_proc_t *proc;
eNB_rxtx_proc_t *proc_rxtx; eNB_rxtx_proc_t *proc_rxtx;
pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL; pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL;
//*attr_td=NULL,*attr_te=NULL;
#ifdef Rel14 #ifdef Rel14
pthread_attr_t *attr_prach_br=NULL; pthread_attr_t *attr_prach_br=NULL;
#endif #endif
...@@ -699,8 +907,11 @@ void init_eNB_proc(int inst) { ...@@ -699,8 +907,11 @@ void init_eNB_proc(int inst) {
proc_rxtx = proc->proc_rxtx; proc_rxtx = proc->proc_rxtx;
proc_rxtx[0].instance_cnt_rxtx = -1; proc_rxtx[0].instance_cnt_rxtx = -1;
proc_rxtx[1].instance_cnt_rxtx = -1; proc_rxtx[1].instance_cnt_rxtx = -1;
proc_rxtx[0].pipe_ready = 0;
proc_rxtx[1].pipe_ready = 0;
proc->instance_cnt_prach = -1; proc->instance_cnt_prach = -1;
proc->instance_cnt_asynch_rxtx = -1; proc->instance_cnt_asynch_rxtx = -1;
proc->instance_cnt_synch = -1;
proc->CC_id = CC_id; proc->CC_id = CC_id;
proc->first_rx=1; proc->first_rx=1;
...@@ -724,8 +935,6 @@ void init_eNB_proc(int inst) { ...@@ -724,8 +935,6 @@ void init_eNB_proc(int inst) {
pthread_attr_init( &proc->attr_prach); pthread_attr_init( &proc->attr_prach);
pthread_attr_init( &proc->attr_asynch_rxtx); pthread_attr_init( &proc->attr_asynch_rxtx);
// pthread_attr_init( &proc->attr_td);
// pthread_attr_init( &proc->attr_te);
pthread_attr_init( &proc_rxtx[0].attr_rxtx); pthread_attr_init( &proc_rxtx[0].attr_rxtx);
pthread_attr_init( &proc_rxtx[1].attr_rxtx); pthread_attr_init( &proc_rxtx[1].attr_rxtx);
#ifdef Rel14 #ifdef Rel14
...@@ -747,6 +956,15 @@ void init_eNB_proc(int inst) { ...@@ -747,6 +956,15 @@ void init_eNB_proc(int inst) {
// attr_td = &proc->attr_td; // attr_td = &proc->attr_td;
// attr_te = &proc->attr_te; // attr_te = &proc->attr_te;
#endif #endif
//////////////////////////////////////need to modified////////////////*****
if(get_nprocs() > 2 && codingw)
{
init_te_thread(eNB);
init_td_thread(eNB);
}
//////////////////////////////////////need to modified////////////////*****
pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc );
pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc);
LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag);
...@@ -767,6 +985,9 @@ void init_eNB_proc(int inst) { ...@@ -767,6 +985,9 @@ void init_eNB_proc(int inst) {
} }
AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);
if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void*)eNB);
} }
...@@ -792,6 +1013,8 @@ void init_eNB_proc(int inst) { ...@@ -792,6 +1013,8 @@ void init_eNB_proc(int inst) {
pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
sync_phy_proc.phy_proc_CC_id = 0; sync_phy_proc.phy_proc_CC_id = 0;
} }
...@@ -805,21 +1028,22 @@ void kill_eNB_proc(int inst) { ...@@ -805,21 +1028,22 @@ void kill_eNB_proc(int inst) {
PHY_VARS_eNB *eNB; PHY_VARS_eNB *eNB;
eNB_proc_t *proc; eNB_proc_t *proc;
eNB_rxtx_proc_t *proc_rxtx; eNB_rxtx_proc_t *proc_rxtx;
int i;
for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
eNB=RC.eNB[inst][CC_id]; eNB=RC.eNB[inst][CC_id];
proc = &eNB->proc; proc = &eNB->proc;
proc_rxtx = &proc->proc_rxtx[0]; proc_rxtx = &proc->proc_rxtx[0];
kill_td_thread(eNB);
kill_te_thread(eNB);
LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst ); LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst );
for (i=0; i<2; i++) {
if (eNB->single_thread_flag==0) { pthread_mutex_lock(&proc_rxtx[i].mutex_rxtx);
pthread_mutex_lock(&proc_rxtx[0].mutex_rxtx); proc_rxtx[i].instance_cnt_rxtx = 0;
proc_rxtx[0].instance_cnt_rxtx = 0; proc_rxtx[i].pipe_ready = 0;
pthread_mutex_unlock(&proc_rxtx[0].mutex_rxtx); pthread_cond_signal(&proc_rxtx[i].cond_rxtx);
pthread_mutex_lock(&proc_rxtx[1].mutex_rxtx); pthread_mutex_unlock(&proc_rxtx[i].mutex_rxtx);
proc_rxtx[1].instance_cnt_rxtx = 0;
pthread_mutex_unlock(&proc_rxtx[1].mutex_rxtx);
} }
proc->instance_cnt_prach = 0; proc->instance_cnt_prach = 0;
pthread_cond_signal( &proc->cond_prach ); pthread_cond_signal( &proc->cond_prach );
...@@ -842,15 +1066,12 @@ void kill_eNB_proc(int inst) { ...@@ -842,15 +1066,12 @@ void kill_eNB_proc(int inst) {
#endif #endif
LOG_I(PHY, "Destroying UL_INFO mutex\n"); LOG_I(PHY, "Destroying UL_INFO mutex\n");
pthread_mutex_destroy(&eNB->UL_INFO_mutex); pthread_mutex_destroy(&eNB->UL_INFO_mutex);
int i; for (i=0;i<2;i++) {
if (eNB->single_thread_flag==0) { LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n",i);
for (i=0;i<2;i++) { pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status );
LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n",i); LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n",i);
pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status ); pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx );
LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n",i); pthread_cond_destroy( &proc_rxtx[i].cond_rxtx );
pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx );
pthread_cond_destroy( &proc_rxtx[i].cond_rxtx );
}
} }
} }
} }
...@@ -1094,8 +1315,8 @@ void init_eNB(int single_thread_flag,int wait_for_sync) { ...@@ -1094,8 +1315,8 @@ void init_eNB(int single_thread_flag,int wait_for_sync) {
#endif #endif
eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; eNB->td = ulsch_decoding_data_all;//(get_nprocs()<=4) ? ulsch_decoding_data : ulsch_decoding_data_2thread;
eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; eNB->te = dlsch_encoding_all;//(get_nprocs()<=4) ? dlsch_encoding : dlsch_encoding_2threads;
LOG_I(PHY,"Registering with MAC interface module\n"); LOG_I(PHY,"Registering with MAC interface module\n");
......
...@@ -117,7 +117,11 @@ static int DEFENBS[] = {0}; ...@@ -117,7 +117,11 @@ static int DEFENBS[] = {0};
#include "T.h" #include "T.h"
extern volatile int oai_exit; extern volatile int oai_exit;
extern int emulate_rf;
extern int numerology;
extern int fepw;
extern void phy_init_RU(RU_t*); extern void phy_init_RU(RU_t*);
...@@ -679,6 +683,34 @@ void fh_if4p5_north_out(RU_t *ru) { ...@@ -679,6 +683,34 @@ void fh_if4p5_north_out(RU_t *ru) {
} }
static void* emulatedRF_thread(void* param) {
RU_proc_t *proc = (RU_proc_t *) param;
int microsec = 500; // length of time to sleep, in miliseconds
struct timespec req = {0};
req.tv_sec = 0;
req.tv_nsec = (numerology>0)? ((microsec * 1000L)/numerology):(microsec * 1000L)*2;
cpu_set_t cpuset;
CPU_SET(1,&cpuset);
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
int policy;
struct sched_param sparam;
memset(&sparam, 0, sizeof(sparam));
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
policy = SCHED_FIFO ;
pthread_setschedparam(pthread_self(), policy, &sparam);
wait_sync("emulatedRF_thread");
while(!oai_exit){
nanosleep(&req, (struct timespec *)NULL);
pthread_mutex_lock(&proc->mutex_emulateRF);
++proc->instance_cnt_emulateRF;
pthread_mutex_unlock(&proc->mutex_emulateRF);
pthread_cond_signal(&proc->cond_emulateRF);
}
return 0;
}
void rx_rf(RU_t *ru,int *frame,int *subframe) { void rx_rf(RU_t *ru,int *frame,int *subframe) {
RU_proc_t *proc = &ru->proc; RU_proc_t *proc = &ru->proc;
...@@ -686,7 +718,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { ...@@ -686,7 +718,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
void *rxp[ru->nb_rx]; void *rxp[ru->nb_rx];
unsigned int rxs; unsigned int rxs;
int i; int i;
openair0_timestamp ts,old_ts; openair0_timestamp ts=0,old_ts=0;
for (i=0; i<ru->nb_rx; i++) for (i=0; i<ru->nb_rx; i++)
rxp[i] = (void*)&ru->common.rxdata[i][*subframe*fp->samples_per_tti]; rxp[i] = (void*)&ru->common.rxdata[i][*subframe*fp->samples_per_tti];
...@@ -694,12 +726,18 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { ...@@ -694,12 +726,18 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
old_ts = proc->timestamp_rx; old_ts = proc->timestamp_rx;
if(emulate_rf){
rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
release_thread(&proc->mutex_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
rxs = fp->samples_per_tti;
}
else{
rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
&ts, &ts,
rxp, rxp,
fp->samples_per_tti, fp->samples_per_tti,
ru->nb_rx); ru->nb_rx);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
...@@ -715,7 +753,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { ...@@ -715,7 +753,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
} }
else { else {
if (proc->timestamp_rx - old_ts != fp->samples_per_tti) { if (proc->timestamp_rx - old_ts != fp->samples_per_tti) {
LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset); //LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset);
ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti);
proc->timestamp_rx = ts-ru->ts_offset; proc->timestamp_rx = ts-ru->ts_offset;
} }
...@@ -725,9 +763,9 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { ...@@ -725,9 +763,9 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
// synchronize first reception to frame 0 subframe 0 // synchronize first reception to frame 0 subframe 0
proc->timestamp_tx = proc->timestamp_rx+(sf_ahead*fp->samples_per_tti); //proc->timestamp_tx = proc->timestamp_rx+(sf_ahead*fp->samples_per_tti);
proc->subframe_tx = (proc->subframe_rx+sf_ahead)%10; //proc->subframe_tx = (proc->subframe_rx+sf_ahead)%10;
proc->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx; //proc->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, subframe %d\n", LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, subframe %d\n",
ru->idx, ru->idx,
...@@ -739,8 +777,6 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { ...@@ -739,8 +777,6 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
if (ru == RC.ru[0]) { if (ru == RC.ru[0]) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, proc->frame_rx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, proc->frame_rx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_RU, proc->subframe_rx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_RU, proc->subframe_rx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx );
} }
if (proc->first_rx == 0) { if (proc->first_rx == 0) {
...@@ -815,6 +851,8 @@ void tx_rf(RU_t *ru) { ...@@ -815,6 +851,8 @@ void tx_rf(RU_t *ru) {
for (i=0; i<ru->nb_tx; i++) for (i=0; i<ru->nb_tx; i++)
txp[i] = (void*)&ru->common.txdata[i][(proc->subframe_tx*fp->samples_per_tti)-sf_extension]; txp[i] = (void*)&ru->common.txdata[i][(proc->subframe_tx*fp->samples_per_tti)-sf_extension];
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx );
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, (proc->timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
...@@ -855,7 +893,7 @@ static void* ru_thread_asynch_rxtx( void* param ) { ...@@ -855,7 +893,7 @@ static void* ru_thread_asynch_rxtx( void* param ) {
int subframe=0, frame=0; int subframe=0, frame=0;
thread_top_init("ru_thread_asynch_rxtx",1,870000L,1000000L,1000000L); thread_top_init("ru_thread_asynch_rxtx",1,870000,1000000,1000000);
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
...@@ -881,7 +919,7 @@ static void* ru_thread_asynch_rxtx( void* param ) { ...@@ -881,7 +919,7 @@ static void* ru_thread_asynch_rxtx( void* param ) {
subframe++; subframe++;
} }
LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n"); LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n");
// asynchronous receive from south (Mobipass) // asynchronous receive from south (Mobipass)
if (ru->fh_south_asynch_in) ru->fh_south_asynch_in(ru,&frame,&subframe); if (ru->fh_south_asynch_in) ru->fh_south_asynch_in(ru,&frame,&subframe);
// asynchronous receive from north (RRU IF4/IF5) // asynchronous receive from north (RRU IF4/IF5)
else if (ru->fh_north_asynch_in) { else if (ru->fh_north_asynch_in) {
...@@ -907,6 +945,7 @@ void wakeup_slaves(RU_proc_t *proc) { ...@@ -907,6 +945,7 @@ void wakeup_slaves(RU_proc_t *proc) {
wait.tv_nsec=5000000L; wait.tv_nsec=5000000L;
for (i=0;i<proc->num_slaves;i++) { for (i=0;i<proc->num_slaves;i++) {
//printf("////////////////////calling for slave thrads\n");////////////////////////********
RU_proc_t *slave_proc = proc->slave_proc[i]; RU_proc_t *slave_proc = proc->slave_proc[i];
// wake up slave FH thread // wake up slave FH thread
// lock the FH mutex and make sure the thread is ready // lock the FH mutex and make sure the thread is ready
...@@ -954,7 +993,8 @@ static void* ru_thread_prach( void* param ) { ...@@ -954,7 +993,8 @@ static void* ru_thread_prach( void* param ) {
// set default return value // set default return value
ru_thread_prach_status = 0; ru_thread_prach_status = 0;
thread_top_init("ru_thread_prach",1,500000L,1000000L,20000000L); thread_top_init("ru_thread_prach",1,500000,1000000,20000000);
//wait_sync("ru_thread_prach");
while (RC.ru_mask>0) { while (RC.ru_mask>0) {
usleep(1e6); usleep(1e6);
...@@ -1009,7 +1049,8 @@ static void* ru_thread_prach_br( void* param ) { ...@@ -1009,7 +1049,8 @@ static void* ru_thread_prach_br( void* param ) {
// set default return value // set default return value
ru_thread_prach_status = 0; ru_thread_prach_status = 0;
thread_top_init("ru_thread_prach_br",1,500000L,1000000L,20000000L); thread_top_init("ru_thread_prach_br",1,500000,1000000,20000000);
//wait_sync("ru_thread_prach_br");
while (!oai_exit) { while (!oai_exit) {
...@@ -1139,13 +1180,14 @@ void wakeup_eNBs(RU_t *ru) { ...@@ -1139,13 +1180,14 @@ void wakeup_eNBs(RU_t *ru) {
LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top); LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top);
if (ru->num_eNB==1 && ru->eNB_top!=0) {
// call eNB function directly
if (ru->num_eNB==1 && ru->eNB_top!=0 && get_nprocs() <= 4) {
// call eNB function directly
char string[20]; char string[20];
sprintf(string,"Incoming RU %d",ru->idx); sprintf(string,"Incoming RU %d",ru->idx);
LOG_D(PHY,"RU %d Call eNB_top\n",ru->idx); LOG_D(PHY,"RU %d Call eNB_top\n",ru->idx);
ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string); ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string,ru);
} }
else { else {
...@@ -1154,7 +1196,7 @@ void wakeup_eNBs(RU_t *ru) { ...@@ -1154,7 +1196,7 @@ void wakeup_eNBs(RU_t *ru) {
for (i=0;i<ru->num_eNB;i++) for (i=0;i<ru->num_eNB;i++)
{ {
LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->wakeup_rxtx); LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->wakeup_rxtx);
eNB_list[i]->proc.ru_proc = &ru->proc;
if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0) if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0)
{ {
LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx); LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx);
...@@ -1231,20 +1273,39 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { ...@@ -1231,20 +1273,39 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
openair0_config_t *cfg = &ru->openair0_cfg; openair0_config_t *cfg = &ru->openair0_cfg;
//printf("////////////////numerology in config = %d\n",numerology);
if(fp->N_RB_DL == 100) { if(fp->N_RB_DL == 100) {
if (fp->threequarter_fs) { if(numerology == 0){
cfg->sample_rate=23.04e6; if (fp->threequarter_fs) {
cfg->samples_per_frame = 230400; cfg->sample_rate=23.04e6;
cfg->tx_bw = 10e6; cfg->samples_per_frame = 230400;
cfg->rx_bw = 10e6; cfg->tx_bw = 10e6;
} cfg->rx_bw = 10e6;
else { }
cfg->sample_rate=30.72e6; else {
cfg->sample_rate=30.72e6;
cfg->samples_per_frame = 307200;
cfg->tx_bw = 10e6;
cfg->rx_bw = 10e6;
}
}else if(numerology == 1){
cfg->sample_rate=61.44e6;
cfg->samples_per_frame = 307200;
cfg->tx_bw = 20e6;
cfg->rx_bw = 20e6;
}else if(numerology == 2){
cfg->sample_rate=122.88e6;
cfg->samples_per_frame = 307200;
cfg->tx_bw = 40e6;
cfg->rx_bw = 40e6;
}else{
printf("Wrong input for numerology %d\n setting to 20MHz normal CP configuration",numerology);
cfg->sample_rate=30.72e6;
cfg->samples_per_frame = 307200; cfg->samples_per_frame = 307200;
cfg->tx_bw = 10e6; cfg->tx_bw = 10e6;
cfg->rx_bw = 10e6; cfg->rx_bw = 10e6;
} }
} else if(fp->N_RB_DL == 50) { } else if(fp->N_RB_DL == 50) {
cfg->sample_rate=15.36e6; cfg->sample_rate=15.36e6;
cfg->samples_per_frame = 153600; cfg->samples_per_frame = 153600;
...@@ -1363,7 +1424,7 @@ static void* ru_stats_thread(void* param) { ...@@ -1363,7 +1424,7 @@ static void* ru_stats_thread(void* param) {
while (!oai_exit) { while (!oai_exit) {
sleep(1); sleep(1);
if (opp_enabled == 1) { if (opp_enabled == 1 && fepw) {
if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL); if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL);
if (ru->feptx_ofdm) print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); if (ru->feptx_ofdm) print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL);
if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL); if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL);
...@@ -1377,6 +1438,59 @@ static void* ru_stats_thread(void* param) { ...@@ -1377,6 +1438,59 @@ static void* ru_stats_thread(void* param) {
return(NULL); return(NULL);
} }
static void* ru_thread_tx( void* param ) {
RU_t *ru = (RU_t*)param;
RU_proc_t *proc = &ru->proc;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
thread_top_init("ru_thread_tx",1,400000,500000,500000);
//CPU_SET(5, &cpuset);
//pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
//wait_sync("ru_thread_tx");
wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
printf( "ru_thread_tx ready\n");
while (!oai_exit) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD_TX,sched_getcpu());
if (oai_exit) break;
LOG_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_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
if (oai_exit) break;
// do TX front-end processing if needed (precoding and/or IDFTs)
if (ru->feptx_prec) ru->feptx_prec(ru);
// do OFDM if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
if(!emulate_rf){
// do outgoing fronthaul (south) if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
if (ru->fh_north_out) ru->fh_north_out(ru);
}
release_thread(&proc->mutex_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
pthread_mutex_lock( &proc->mutex_eNBs );
proc->ru_tx_ready++;
// the thread can now be woken up
if (pthread_cond_signal(&proc->cond_eNBs) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" );
}
pthread_mutex_unlock( &proc->mutex_eNBs );
}
release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
return 0;
}
static void* ru_thread( void* param ) { static void* ru_thread( void* param ) {
static int ru_thread_status; static int ru_thread_status;
...@@ -1387,35 +1501,54 @@ static void* ru_thread( void* param ) { ...@@ -1387,35 +1501,54 @@ static void* ru_thread( void* param ) {
int ret; int ret;
int subframe =9; int subframe =9;
int frame =1023; int frame =1023;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
// set default return value // set default return value
ru_thread_status = 0; ru_thread_status = 0;
// set default return value // set default return value
thread_top_init("ru_thread",0,870000,1000000,1000000); thread_top_init("ru_thread",1,400000,500000,500000);
LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]); //CPU_SET(1, &cpuset);
//pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
pthread_setname_np( pthread_self(),"ru thread");
LOG_I(PHY,"thread ru created id=%ld\n", syscall(__NR_gettid));
LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]);
// Start IF device if any if(emulate_rf){
if (ru->start_if) { fill_rf_config(ru,ru->rf_config_file);
LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx); init_frame_parms(&ru->frame_parms,1);
AssertFatal(ru->start_if(ru,NULL) == 0, "Could not start the IF device\n"); phy_init_RU(ru);
if (ru->if_south == LOCAL_RF) ret = connect_rau(ru); if (setup_RU_buffers(ru)!=0) {
else ret = attach_rru(ru); printf("Exiting, cannot initialize RU Buffers\n");
AssertFatal(ret==0,"Cannot connect to radio\n"); exit(-1);
} }
if (ru->if_south == LOCAL_RF) { // configure RF parameters only
fill_rf_config(ru,ru->rf_config_file);
init_frame_parms(&ru->frame_parms,1);
phy_init_RU(ru);
ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
} }
if (setup_RU_buffers(ru)!=0) { else{
printf("Exiting, cannot initialize RU Buffers\n"); // Start IF device if any
exit(-1); if (ru->start_if) {
LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx);
AssertFatal(ru->start_if(ru,NULL) == 0, "Could not start the IF device\n");
if (ru->if_south == LOCAL_RF) ret = connect_rau(ru);
else ret = attach_rru(ru);
AssertFatal(ret==0,"Cannot connect to radio\n");
}
if (ru->if_south == LOCAL_RF) { // configure RF parameters only
fill_rf_config(ru,ru->rf_config_file);
init_frame_parms(&ru->frame_parms,1);
phy_init_RU(ru);
ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
}
if (setup_RU_buffers(ru)!=0) {
printf("Exiting, cannot initialize RU Buffers\n");
exit(-1);
}
} }
LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx); LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx);
...@@ -1424,38 +1557,46 @@ static void* ru_thread( void* param ) { ...@@ -1424,38 +1557,46 @@ static void* ru_thread( void* param ) {
pthread_cond_signal(&RC.ru_cond); pthread_cond_signal(&RC.ru_cond);
pthread_mutex_unlock(&RC.ru_mutex); pthread_mutex_unlock(&RC.ru_mutex);
wait_sync("ru_thread");
pthread_mutex_lock(&proc->mutex_FH1);
proc->instance_cnt_FH1 = 0;
pthread_mutex_unlock(&proc->mutex_FH1);
pthread_cond_signal(&proc->cond_FH1);
wait_sync("ru_thread");
if(!emulate_rf){
// Start RF device if any // Start RF device if any
if (ru->start_rf) { if (ru->start_rf) {
if (ru->start_rf(ru) != 0) if (ru->start_rf(ru) != 0)
LOG_E(HW,"Could not start the RF device\n"); LOG_E(HW,"Could not start the RF device\n");
else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
}
else LOG_I(PHY,"RU %d no rf device\n",ru->idx);
// if an asnych_rxtx thread exists
// wakeup the thread because the devices are ready at this point
if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) {
pthread_mutex_lock(&proc->mutex_asynch_rxtx);
proc->instance_cnt_asynch_rxtx=0;
pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
pthread_cond_signal(&proc->cond_asynch_rxtx);
}
else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx);
// if this is a slave RRU, try to synchronize on the DL frequency
if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
} }
else LOG_I(PHY,"RU %d no rf device\n",ru->idx);
// if an asnych_rxtx thread exists
// wakeup the thread because the devices are ready at this point
if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) {
pthread_mutex_lock(&proc->mutex_asynch_rxtx);
proc->instance_cnt_asynch_rxtx=0;
pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
pthread_cond_signal(&proc->cond_asynch_rxtx);
}
else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx);
// if this is a slave RRU, try to synchronize on the DL frequency
if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
while (!oai_exit) { while (!oai_exit) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD,sched_getcpu());
// these are local subframe/frame counters to check that we are in synch with the fronthaul timing. // these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
// They are set on the first rx/tx in the underly FH routines. // They are set on the first rx/tx in the underly FH routines.
if (subframe==9) { if (subframe==9) {
...@@ -1505,20 +1646,21 @@ static void* ru_thread( void* param ) { ...@@ -1505,20 +1646,21 @@ static void* ru_thread( void* param ) {
// wakeup all eNB processes waiting for this RU // wakeup all eNB processes waiting for this RU
if (ru->num_eNB>0) wakeup_eNBs(ru); if (ru->num_eNB>0) wakeup_eNBs(ru);
if(get_nprocs() <= 4){
// do TX front-end processing if needed (precoding and/or IDFTs)
if (ru->feptx_prec) ru->feptx_prec(ru);
// do OFDM if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
if(!emulate_rf){
// do outgoing fronthaul (south) if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
if (ru->fh_north_out) ru->fh_north_out(ru);
}
}
// wait until eNBs are finished subframe RX n and TX n+sf_ahead
wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread");
// do TX front-end processing if needed (precoding and/or IDFTs)
if (ru->feptx_prec) ru->feptx_prec(ru);
// do OFDM if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
// do outgoing fronthaul (south) if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
if (ru->fh_north_out) ru->fh_north_out(ru);
} }
...@@ -1641,7 +1783,7 @@ void init_RU_proc(RU_t *ru) { ...@@ -1641,7 +1783,7 @@ void init_RU_proc(RU_t *ru) {
int i=0; int i=0;
RU_proc_t *proc; RU_proc_t *proc;
pthread_attr_t *attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_synch=NULL; pthread_attr_t *attr_FH=NULL,*attr_FH1=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_synch=NULL,*attr_emulateRF=NULL;
//pthread_attr_t *attr_fep=NULL; //pthread_attr_t *attr_fep=NULL;
#ifdef Rel14 #ifdef Rel14
pthread_attr_t *attr_prach_br=NULL; pthread_attr_t *attr_prach_br=NULL;
...@@ -1656,14 +1798,19 @@ void init_RU_proc(RU_t *ru) { ...@@ -1656,14 +1798,19 @@ void init_RU_proc(RU_t *ru) {
proc->ru = ru; proc->ru = ru;
proc->instance_cnt_prach = -1; proc->instance_cnt_prach = -1;
proc->instance_cnt_synch = -1; ; proc->instance_cnt_synch = -1;
proc->instance_cnt_FH = -1; proc->instance_cnt_FH = -1;
proc->instance_cnt_FH1 = -1;
proc->instance_cnt_emulateRF = -1;
proc->instance_cnt_asynch_rxtx = -1; proc->instance_cnt_asynch_rxtx = -1;
proc->instance_cnt_eNBs = -1;
proc->first_rx = 1; proc->first_rx = 1;
proc->first_tx = 1; proc->first_tx = 1;
proc->frame_offset = 0; proc->frame_offset = 0;
proc->num_slaves = 0; proc->num_slaves = 0;
proc->frame_tx_unwrap = 0; proc->frame_tx_unwrap = 0;
proc->ru_rx_ready = 0;
proc->ru_tx_ready = 0;
for (i=0;i<10;i++) proc->symbol_mask[i]=0; for (i=0;i<10;i++) proc->symbol_mask[i]=0;
...@@ -1671,15 +1818,21 @@ void init_RU_proc(RU_t *ru) { ...@@ -1671,15 +1818,21 @@ void init_RU_proc(RU_t *ru) {
pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
pthread_mutex_init( &proc->mutex_synch,NULL); pthread_mutex_init( &proc->mutex_synch,NULL);
pthread_mutex_init( &proc->mutex_FH,NULL); pthread_mutex_init( &proc->mutex_FH,NULL);
pthread_mutex_init( &proc->mutex_FH1,NULL);
pthread_mutex_init( &proc->mutex_emulateRF,NULL);
pthread_mutex_init( &proc->mutex_eNBs, NULL); pthread_mutex_init( &proc->mutex_eNBs, NULL);
pthread_cond_init( &proc->cond_prach, NULL); pthread_cond_init( &proc->cond_prach, NULL);
pthread_cond_init( &proc->cond_FH, NULL); pthread_cond_init( &proc->cond_FH, NULL);
pthread_cond_init( &proc->cond_FH1, NULL);
pthread_cond_init( &proc->cond_emulateRF, NULL);
pthread_cond_init( &proc->cond_asynch_rxtx, NULL); pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
pthread_cond_init( &proc->cond_synch,NULL); pthread_cond_init( &proc->cond_synch,NULL);
pthread_cond_init( &proc->cond_eNBs, NULL); pthread_cond_init( &proc->cond_eNBs, NULL);
pthread_attr_init( &proc->attr_FH); pthread_attr_init( &proc->attr_FH);
pthread_attr_init( &proc->attr_FH1);
pthread_attr_init( &proc->attr_emulateRF);
pthread_attr_init( &proc->attr_prach); pthread_attr_init( &proc->attr_prach);
pthread_attr_init( &proc->attr_synch); pthread_attr_init( &proc->attr_synch);
pthread_attr_init( &proc->attr_asynch_rxtx); pthread_attr_init( &proc->attr_asynch_rxtx);
...@@ -1694,15 +1847,22 @@ void init_RU_proc(RU_t *ru) { ...@@ -1694,15 +1847,22 @@ void init_RU_proc(RU_t *ru) {
#ifndef DEADLINE_SCHEDULER #ifndef DEADLINE_SCHEDULER
attr_FH = &proc->attr_FH; attr_FH = &proc->attr_FH;
attr_FH1 = &proc->attr_FH1;
attr_prach = &proc->attr_prach; attr_prach = &proc->attr_prach;
attr_synch = &proc->attr_synch; attr_synch = &proc->attr_synch;
attr_asynch = &proc->attr_asynch_rxtx; attr_asynch = &proc->attr_asynch_rxtx;
attr_emulateRF = &proc->attr_emulateRF;
#ifdef Rel14 #ifdef Rel14
attr_prach_br = &proc->attr_prach_br; attr_prach_br = &proc->attr_prach_br;
#endif #endif
#endif #endif
pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru ); pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru );
if(emulate_rf)
pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void*)proc );
if (get_nprocs() > 4)
pthread_create( &proc->pthread_FH1, attr_FH1, ru_thread_tx, (void*)ru );
if (ru->function == NGFI_RRU_IF4p5) { if (ru->function == NGFI_RRU_IF4p5) {
pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru );
...@@ -1714,7 +1874,10 @@ void init_RU_proc(RU_t *ru) { ...@@ -1714,7 +1874,10 @@ void init_RU_proc(RU_t *ru) {
if ((ru->if_timing == synch_to_other) || if ((ru->if_timing == synch_to_other) ||
(ru->function == NGFI_RRU_IF5) || (ru->function == NGFI_RRU_IF5) ||
(ru->function == NGFI_RRU_IF4p5)) pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, ru_thread_asynch_rxtx, (void*)ru ); (ru->function == NGFI_RRU_IF4p5))
{
pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, ru_thread_asynch_rxtx, (void*)ru );
}
snprintf( name, sizeof(name), "ru_thread_FH %d", ru->idx ); snprintf( name, sizeof(name), "ru_thread_FH %d", ru->idx );
pthread_setname_np( proc->pthread_FH, name ); pthread_setname_np( proc->pthread_FH, name );
...@@ -1725,7 +1888,7 @@ void init_RU_proc(RU_t *ru) { ...@@ -1725,7 +1888,7 @@ void init_RU_proc(RU_t *ru) {
pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru );
} }
if (get_nprocs()>=2) { if (get_nprocs()> 2 && fepw) {
if (ru->feprx) init_fep_thread(ru,NULL); if (ru->feprx) init_fep_thread(ru,NULL);
if (ru->feptx_ofdm) init_feptx_thread(ru,NULL); if (ru->feptx_ofdm) init_feptx_thread(ru,NULL);
} }
...@@ -1740,38 +1903,46 @@ void kill_RU_proc(int inst) ...@@ -1740,38 +1903,46 @@ void kill_RU_proc(int inst)
pthread_mutex_lock(&proc->mutex_FH); pthread_mutex_lock(&proc->mutex_FH);
proc->instance_cnt_FH = 0; proc->instance_cnt_FH = 0;
pthread_mutex_unlock(&proc->mutex_FH);
pthread_cond_signal(&proc->cond_FH); pthread_cond_signal(&proc->cond_FH);
pthread_mutex_unlock(&proc->mutex_FH);
pthread_mutex_lock(&proc->mutex_FH1);
proc->instance_cnt_FH1 = 0;
pthread_cond_signal(&proc->cond_FH1);
pthread_mutex_unlock(&proc->mutex_FH1);
pthread_mutex_lock(&proc->mutex_prach); pthread_mutex_lock(&proc->mutex_prach);
proc->instance_cnt_prach = 0; proc->instance_cnt_prach = 0;
pthread_mutex_unlock(&proc->mutex_prach);
pthread_cond_signal(&proc->cond_prach); pthread_cond_signal(&proc->cond_prach);
pthread_mutex_unlock(&proc->mutex_prach);
#ifdef Rel14 #ifdef Rel14
pthread_mutex_lock(&proc->mutex_prach_br); pthread_mutex_lock(&proc->mutex_prach_br);
proc->instance_cnt_prach_br = 0; proc->instance_cnt_prach_br = 0;
pthread_mutex_unlock(&proc->mutex_prach_br);
pthread_cond_signal(&proc->cond_prach_br); pthread_cond_signal(&proc->cond_prach_br);
pthread_mutex_unlock(&proc->mutex_prach_br);
#endif #endif
pthread_mutex_lock(&proc->mutex_synch); pthread_mutex_lock(&proc->mutex_synch);
proc->instance_cnt_synch = 0; proc->instance_cnt_synch = 0;
pthread_mutex_unlock(&proc->mutex_synch);
pthread_cond_signal(&proc->cond_synch); pthread_cond_signal(&proc->cond_synch);
pthread_mutex_unlock(&proc->mutex_synch);
pthread_mutex_lock(&proc->mutex_eNBs); pthread_mutex_lock(&proc->mutex_eNBs);
proc->ru_tx_ready = 0;
proc->instance_cnt_eNBs = 0; proc->instance_cnt_eNBs = 0;
pthread_mutex_unlock(&proc->mutex_eNBs);
pthread_cond_signal(&proc->cond_eNBs); pthread_cond_signal(&proc->cond_eNBs);
pthread_mutex_unlock(&proc->mutex_eNBs);
pthread_mutex_lock(&proc->mutex_asynch_rxtx); pthread_mutex_lock(&proc->mutex_asynch_rxtx);
proc->instance_cnt_asynch_rxtx = 0; proc->instance_cnt_asynch_rxtx = 0;
pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
pthread_cond_signal(&proc->cond_asynch_rxtx); pthread_cond_signal(&proc->cond_asynch_rxtx);
pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
LOG_D(PHY, "Joining pthread_FH\n"); LOG_D(PHY, "Joining pthread_FH\n");
pthread_join(proc->pthread_FH, NULL); pthread_join(proc->pthread_FH, NULL);
LOG_D(PHY, "Joining pthread_FHTX\n");
pthread_join(proc->pthread_FH1, NULL);
if (ru->function == NGFI_RRU_IF4p5) { if (ru->function == NGFI_RRU_IF4p5) {
LOG_D(PHY, "Joining pthread_prach\n"); LOG_D(PHY, "Joining pthread_prach\n");
pthread_join(proc->pthread_prach, NULL); pthread_join(proc->pthread_prach, NULL);
...@@ -1791,7 +1962,7 @@ void kill_RU_proc(int inst) ...@@ -1791,7 +1962,7 @@ void kill_RU_proc(int inst)
pthread_join(proc->pthread_asynch_rxtx, NULL); pthread_join(proc->pthread_asynch_rxtx, NULL);
} }
} }
if (get_nprocs() >= 2) { if (get_nprocs() > 2 && fepw) {
if (ru->feprx) { if (ru->feprx) {
pthread_mutex_lock(&proc->mutex_fep); pthread_mutex_lock(&proc->mutex_fep);
proc->instance_cnt_fep = 0; proc->instance_cnt_fep = 0;
...@@ -1822,15 +1993,18 @@ void kill_RU_proc(int inst) ...@@ -1822,15 +1993,18 @@ void kill_RU_proc(int inst)
pthread_mutex_destroy(&proc->mutex_asynch_rxtx); pthread_mutex_destroy(&proc->mutex_asynch_rxtx);
pthread_mutex_destroy(&proc->mutex_synch); pthread_mutex_destroy(&proc->mutex_synch);
pthread_mutex_destroy(&proc->mutex_FH); pthread_mutex_destroy(&proc->mutex_FH);
pthread_mutex_destroy(&proc->mutex_FH1);
pthread_mutex_destroy(&proc->mutex_eNBs); pthread_mutex_destroy(&proc->mutex_eNBs);
pthread_cond_destroy(&proc->cond_prach); pthread_cond_destroy(&proc->cond_prach);
pthread_cond_destroy(&proc->cond_FH); pthread_cond_destroy(&proc->cond_FH);
pthread_cond_destroy(&proc->cond_FH1);
pthread_cond_destroy(&proc->cond_asynch_rxtx); pthread_cond_destroy(&proc->cond_asynch_rxtx);
pthread_cond_destroy(&proc->cond_synch); pthread_cond_destroy(&proc->cond_synch);
pthread_cond_destroy(&proc->cond_eNBs); pthread_cond_destroy(&proc->cond_eNBs);
pthread_attr_destroy(&proc->attr_FH); pthread_attr_destroy(&proc->attr_FH);
pthread_attr_destroy(&proc->attr_FH1);
pthread_attr_destroy(&proc->attr_prach); pthread_attr_destroy(&proc->attr_prach);
pthread_attr_destroy(&proc->attr_synch); pthread_attr_destroy(&proc->attr_synch);
pthread_attr_destroy(&proc->attr_asynch_rxtx); pthread_attr_destroy(&proc->attr_asynch_rxtx);
...@@ -2083,8 +2257,8 @@ void set_function_spec_param(RU_t *ru) ...@@ -2083,8 +2257,8 @@ void set_function_spec_param(RU_t *ru)
} }
else if (ru->function == eNodeB_3GPP) { else if (ru->function == eNodeB_3GPP) {
ru->do_prach = 0; // no prach processing in RU ru->do_prach = 0; // no prach processing in RU
ru->feprx = (get_nprocs()<=2) ? fep_full : ru_fep_full_2thread; // RX DFTs ru->feprx = (get_nprocs()<=2 || !fepw) ? fep_full : ru_fep_full_2thread; // RX DFTs
ru->feptx_ofdm = (get_nprocs()<=2) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding ru->feptx_ofdm = (get_nprocs()<=2 || !fepw) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding
ru->feptx_prec = feptx_prec; // this is fep with idft and precoding ru->feptx_prec = feptx_prec; // this is fep with idft and precoding
ru->fh_north_in = NULL; // no incoming fronthaul from north ru->fh_north_in = NULL; // no incoming fronthaul from north
ru->fh_north_out = NULL; // no outgoing fronthaul to north ru->fh_north_out = NULL; // no outgoing fronthaul to north
...@@ -2245,7 +2419,7 @@ void init_RU(char *rf_config_file) { ...@@ -2245,7 +2419,7 @@ void init_RU(char *rf_config_file) {
} }
} }
} }
// LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function); LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function);
set_function_spec_param(ru); set_function_spec_param(ru);
LOG_I(PHY,"Starting ru_thread %d\n",ru_id); LOG_I(PHY,"Starting ru_thread %d\n",ru_id);
......
...@@ -217,6 +217,10 @@ extern PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, ...@@ -217,6 +217,10 @@ extern PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
extern void init_eNB_afterRU(void); extern void init_eNB_afterRU(void);
int transmission_mode=1; int transmission_mode=1;
int emulate_rf = 0;
int numerology = 0;
int codingw = 0;
int fepw = 0;
...@@ -632,6 +636,7 @@ void init_openair0(void) { ...@@ -632,6 +636,7 @@ void init_openair0(void) {
int card; int card;
int i; int i;
for (card=0; card<MAX_CARDS; card++) { for (card=0; card<MAX_CARDS; card++) {
...@@ -639,6 +644,8 @@ void init_openair0(void) { ...@@ -639,6 +644,8 @@ void init_openair0(void) {
openair0_cfg[card].configFilename = NULL; openair0_cfg[card].configFilename = NULL;
if(frame_parms[0]->N_RB_DL == 100) { if(frame_parms[0]->N_RB_DL == 100) {
if(numerology == 0)
{
if (frame_parms[0]->threequarter_fs) { if (frame_parms[0]->threequarter_fs) {
openair0_cfg[card].sample_rate=23.04e6; openair0_cfg[card].sample_rate=23.04e6;
openair0_cfg[card].samples_per_frame = 230400; openair0_cfg[card].samples_per_frame = 230400;
...@@ -650,6 +657,22 @@ void init_openair0(void) { ...@@ -650,6 +657,22 @@ void init_openair0(void) {
openair0_cfg[card].tx_bw = 10e6; openair0_cfg[card].tx_bw = 10e6;
openair0_cfg[card].rx_bw = 10e6; openair0_cfg[card].rx_bw = 10e6;
} }
}else if(numerology == 1)
{
openair0_cfg[card].sample_rate=61.44e6;
openair0_cfg[card].samples_per_frame = 307200;
openair0_cfg[card].tx_bw = 20e6;
openair0_cfg[card].rx_bw = 20e6;
}else if(numerology == 2)
{
openair0_cfg[card].sample_rate=122.88e6;
openair0_cfg[card].samples_per_frame = 307200;
openair0_cfg[card].tx_bw = 20e6;
openair0_cfg[card].rx_bw = 20e6;
}else
{
printf("Un supported numerology\n");
}
} else if(frame_parms[0]->N_RB_DL == 50) { } else if(frame_parms[0]->N_RB_DL == 50) {
openair0_cfg[card].sample_rate=15.36e6; openair0_cfg[card].sample_rate=15.36e6;
openair0_cfg[card].samples_per_frame = 153600; openair0_cfg[card].samples_per_frame = 153600;
......
...@@ -85,6 +85,12 @@ ...@@ -85,6 +85,12 @@
#define CONFIG_HLP_TPORT "tracer port\n" #define CONFIG_HLP_TPORT "tracer port\n"
#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n" #define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n"
#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" #define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n"
#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n"
#define CONFIG_HLP_CODINGW "coding worker thread enable(disable by defult)\n"
#define CONFIG_HLP_FEPW "FEP worker thread enabled(disable by defult)\n"
#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
/***************************************************************************************************************************************/ /***************************************************************************************************************************************/
...@@ -139,35 +145,39 @@ extern int16_t dlsch_demod_shift; ...@@ -139,35 +145,39 @@ extern int16_t dlsch_demod_shift;
/* optname helpstr paramflags XXXptr defXXXval type numelt */ /* optname helpstr paramflags XXXptr defXXXval type numelt */
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_PARAMS_DESC { \ #define CMDLINE_PARAMS_DESC { \
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \ {"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}, \ {"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}, \ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \
{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
{"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ {"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \ {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"threadIQ", NULL, 0, iptr:&(threads.iq), defintval:1, TYPE_INT, 0}, \ {"threadIQ", NULL, 0, iptr:&(threads.iq), defintval:1, TYPE_INT, 0}, \
{"threadOneSubframe", NULL, 0, iptr:&(threads.one), defintval:1, TYPE_INT, 0}, \ {"threadOneSubframe", NULL, 0, iptr:&(threads.one), defintval:1, TYPE_INT, 0}, \
{"threadTwoSubframe", NULL, 0, iptr:&(threads.two), defintval:1, TYPE_INT, 0}, \ {"threadTwoSubframe", NULL, 0, iptr:&(threads.two), defintval:1, TYPE_INT, 0}, \
{"threadThreeSubframe", NULL, 0, iptr:&(threads.three), defintval:1, TYPE_INT, 0}, \ {"threadThreeSubframe", NULL, 0, iptr:&(threads.three), defintval:1, TYPE_INT, 0}, \
{"threadSlot1ProcOne", NULL, 0, iptr:&(threads.slot1_proc_one), defintval:1, TYPE_INT, 0}, \ {"threadSlot1ProcOne", NULL, 0, iptr:&(threads.slot1_proc_one), defintval:1, TYPE_INT, 0}, \
{"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \ {"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT, 0}, \ {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ {"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \
{"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \ {"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \
{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
{"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \ {"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \
{"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \ {"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&ouput_vcd, defintval:0, TYPE_INT, 0}, \ {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&ouput_vcd, defintval:0, TYPE_INT, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
{"codingw" , CONFIG_HLP_CODINGW, PARAMFLAG_BOOL, iptr:&codingw, defintval:0, TYPE_INT, 0}, \
{"fepw" , CONFIG_HLP_FEPW, PARAMFLAG_BOOL, iptr:&fepw, defintval:0, TYPE_INT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT,PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT,PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \
} }
...@@ -262,8 +272,10 @@ extern void reset_opp_meas(void); ...@@ -262,8 +272,10 @@ extern void reset_opp_meas(void);
extern void print_opp_meas(void); extern void print_opp_meas(void);
extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *); extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *);
extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *); extern void init_td_thread(PHY_VARS_eNB *);
extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *); extern void init_te_thread(PHY_VARS_eNB *);
extern void kill_td_thread(PHY_VARS_eNB *);
extern void kill_te_thread(PHY_VARS_eNB *);
PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t UE_id, uint8_t UE_id,
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <getopt.h> #include <getopt.h>
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include "rt_wrapper.h" #include "rt_wrapper.h"
#include <errno.h>
#include "openair1/PHY/defs.h" #include "openair1/PHY/defs.h"
...@@ -283,6 +284,7 @@ void thread_top_init(char *thread_name, ...@@ -283,6 +284,7 @@ void thread_top_init(char *thread_name,
if (sched_setattr(0, &attr, flags) < 0 ) { if (sched_setattr(0, &attr, flags) < 0 ) {
perror("[SCHED] eNB tx thread: sched_setattr failed\n"); perror("[SCHED] eNB tx thread: sched_setattr failed\n");
fprintf(stderr,"sched_setattr Error = %s",strerror(errno));
exit(1); exit(1);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment