Commit d52b8179 authored by Raymond Knopp's avatar Raymond Knopp Committed by Robert Schmidt

Introduce separate thread to handle gNB TX processing

This commit introduces a separate thread (l1_tx_thread) that processes
gNB DL/TX slots. It receives a message from the ru_thread when a new
slot started, and starts processing.

The DL part of the scheduler is run in the l1_tx_thread.  Therefore,
only call UL indication (for scheduler) in UL slots.  The UL indication
previously triggered the DL scheduler -- hence, it had to be called in
every slot. Now, since the DL scheduler is moved into the DL thread, we
don't have to call the scheduler in every slot anymore.

The reorder thread is removed, as reordering with this scheme is not
necessary anymore.

The main advantage of this version is that the TX can be scheduled
earlier (sl_ahead). Further, there can no longer be race conditions in
the TX path, since the scheduler/L2, TX L1 processing and the RU tx
function are all execute in the same thread (L1_tX_thread).

Also, the scheduler prepares PRACH/PUSCH/PUCCH FAPI PDUs. As of this
commit, the scheduler runs in the TX processing chain, whereas these
PDUs are destined for RX processing.  Thus, too avoid data races,
instead of triggering the RX processing at the same time as TX
processing in the RU thread, this commit changes the code to trigger RX
processing after the scheduler has been run in TX processing to avoid
data races.

Finally, we synchronize RU and L1 threads. This is important for
rfsimulator, since unlike most radios, rfsimulator can run slower or
faster, depending on I/O and CPU (it does not have a stable "tick").
Co-authored-by: default avatarkiran <saikiran@iitj.ac.in>
parent fb69d9c6
...@@ -111,42 +111,63 @@ time_stats_t softmodem_stats_rx_sf; // total rx time ...@@ -111,42 +111,63 @@ time_stats_t softmodem_stats_rx_sf; // total rx time
#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials) #define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
#define L1STATSSTRLEN 16384 #define L1STATSSTRLEN 16384
static void tx_func(void *param)
void tx_func(void *param)
{ {
processingData_L1tx_t *info = (processingData_L1tx_t *) param; processingData_L1tx_t *info = (processingData_L1tx_t *) param;
PHY_VARS_gNB *gNB = info->gNB;
int frame_tx = info->frame; int frame_tx = info->frame;
int slot_tx = info->slot; int slot_tx = info->slot;
int cumul_samples = gNB->frame_parms.get_samples_per_slot(0, &gNB->frame_parms); int frame_rx = info->frame_rx;
int i = 1; int slot_rx = info->slot_rx;
for (; i < gNB->frame_parms.slots_per_subframe / 2; i++) int absslot_tx = info->timestamp_tx / info->gNB->frame_parms.get_samples_per_slot(slot_tx, &info->gNB->frame_parms);
cumul_samples += gNB->frame_parms.get_samples_per_slot(i, &gNB->frame_parms); int absslot_rx = absslot_tx - info->gNB->RU_list[0]->sl_ahead;
int samples = cumul_samples / i;
int absslot_tx = info->timestamp_tx / samples; LOG_D(NR_PHY, "%d.%d running tx_func\n", frame_tx, slot_tx);
int absslot_rx = absslot_tx - gNB->RU_list[0]->sl_ahead; PHY_VARS_gNB *gNB = info->gNB;
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH; module_id_t module_id = gNB->Mod_id;
start_meas(&gNB->phy_proc_tx); uint8_t CC_id = gNB->CC_id;
NR_IF_Module_t *ifi = gNB->if_inst;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
clock_gettime(CLOCK_MONOTONIC, &gNB->rt_L1_profiling.start_L1_TX[rt_prof_idx]); T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
phy_procedures_gNB_TX(info,
frame_tx,
slot_tx,
1);
clock_gettime(CLOCK_MONOTONIC, &gNB->rt_L1_profiling.return_L1_TX[rt_prof_idx]);
if (get_softmodem_params()->reorder_thread_disable) { ifi->NR_slot_indication(module_id, CC_id, frame_tx, slot_tx);
gNB->msgDataTx->timestamp_tx = info->timestamp_tx;
info = gNB->msgDataTx;
info->gNB = gNB;
// At this point, MAC scheduler just ran, including scheduling
// PRACH/PUCCH/PUSCH, so trigger RX chain processing
LOG_D(NR_PHY, "%s() trigger RX for %d.%d\n", __func__, frame_rx, slot_rx);
notifiedFIFO_elt_t *res = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->resp_L1, NULL);
processingData_L1_t *syncMsg = NotifiedFifoData(res);
syncMsg->gNB = gNB;
syncMsg->frame_rx = frame_rx;
syncMsg->slot_rx = slot_rx;
syncMsg->timestamp_tx = info->timestamp_tx;
res->key = slot_rx;
pushNotifiedFIFO(&gNB->resp_L1, res);
int tx_slot_type = nr_slot_select(cfg, frame_tx, slot_tx);
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx) {
start_meas(&info->gNB->phy_proc_tx);
phy_procedures_gNB_TX(info, frame_tx, slot_tx, 1);
const int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
clock_gettime(CLOCK_MONOTONIC, &info->gNB->rt_L1_profiling.return_L1_TX[rt_prof_idx]);
PHY_VARS_gNB *gNB = info->gNB;
processingData_RU_t syncMsgRU; processingData_RU_t syncMsgRU;
syncMsgRU.frame_tx = frame_tx; syncMsgRU.frame_tx = frame_tx;
syncMsgRU.slot_tx = slot_tx; syncMsgRU.slot_tx = slot_tx;
syncMsgRU.ru = gNB->RU_list[0]; syncMsgRU.ru = gNB->RU_list[0];
syncMsgRU.timestamp_tx = info->timestamp_tx; syncMsgRU.timestamp_tx = info->timestamp_tx;
LOG_D(PHY,"gNB: %d.%d : calling RU TX function\n",syncMsgRU.frame_tx,syncMsgRU.slot_tx); LOG_D(PHY, "gNB: %d.%d : calling RU TX function\n", syncMsgRU.frame_tx, syncMsgRU.slot_tx);
ru_tx_func((void*)&syncMsgRU); ru_tx_func((void *)&syncMsgRU);
stop_meas(&info->gNB->phy_proc_tx);
} }
/* this thread is done with the sched_info, decrease the reference counter */ /* this thread is done with the sched_info, decrease the reference counter */
LOG_D(NR_PHY, "Calling deref_sched_response for id %d (tx_func) in %d.%d\n", info->sched_response_id, frame_tx, slot_tx);
deref_sched_response(info->sched_response_id); deref_sched_response(info->sched_response_id);
stop_meas(&gNB->phy_proc_tx);
} }
...@@ -164,27 +185,27 @@ void *L1_rx_thread(void *arg) ...@@ -164,27 +185,27 @@ void *L1_rx_thread(void *arg)
} }
return NULL; return NULL;
} }
/* to be added for URLLC, requires MAC scheduling to be split from UL indication // Added for URLLC, requires MAC scheduling to be split from UL indication
void *L1_tx_thread(void *arg) { void *L1_tx_thread(void *arg) {
PHY_VARS_gNB *gNB = (PHY_VARS_gNB*)arg; PHY_VARS_gNB *gNB = (PHY_VARS_gNB*)arg;
while (oai_exit == 0) { while (oai_exit == 0) {
notifiedFIFO_elt_t *res = pullNotifiedFIFO(&gNB->L1_tx_out); notifiedFIFO_elt_t *res = pullNotifiedFIFO(&gNB->L1_tx_out);
if (res == NULL) // stopping condition, happens only when queue is freed
break;
processingData_L1tx_t *info = (processingData_L1tx_t *)NotifiedFifoData(res); processingData_L1tx_t *info = (processingData_L1tx_t *)NotifiedFifoData(res);
tx_func(info); tx_func(info);
delNotifiedFIFO_elt(res); delNotifiedFIFO_elt(res);
} }
return NULL; return NULL;
} }
*/
void rx_func(void *param) void rx_func(void *param)
{ {
processingData_L1_t *info = (processingData_L1_t *) param; processingData_L1_t *info = (processingData_L1_t *) param;
PHY_VARS_gNB *gNB = info->gNB; PHY_VARS_gNB *gNB = info->gNB;
int frame_rx = info->frame_rx; int frame_rx = info->frame_rx;
int slot_rx = info->slot_rx; int slot_rx = info->slot_rx;
int frame_tx = info->frame_tx;
int slot_tx = info->slot_tx;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
int cumul_samples = gNB->frame_parms.get_samples_per_slot(0, &gNB->frame_parms); int cumul_samples = gNB->frame_parms.get_samples_per_slot(0, &gNB->frame_parms);
int i = 1; int i = 1;
...@@ -209,14 +230,11 @@ void rx_func(void *param) ...@@ -209,14 +230,11 @@ void rx_func(void *param)
} }
// **************************************** // ****************************************
T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
reset_active_stats(gNB, frame_tx);
reset_active_ulsch(gNB, frame_tx);
// RX processing // RX processing
int rx_slot_type = nr_slot_select(cfg, frame_rx, slot_rx); int rx_slot_type = nr_slot_select(cfg, frame_rx, slot_rx);
if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) { if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) {
LOG_D(NR_PHY, "%d.%d Starting RX processing\n", frame_rx, slot_rx);
// UE-specific RX processing for subframe n // UE-specific RX processing for subframe n
// TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT // TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT
...@@ -239,57 +257,30 @@ void rx_func(void *param) ...@@ -239,57 +257,30 @@ void rx_func(void *param)
} }
} }
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
}
stop_meas( &softmodem_stats_rxtx_sf ); // Call the scheduler
LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx); start_meas(&gNB->ul_indication_stats);
clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.return_L1_RX[rt_prof_idx]); gNB->UL_INFO.frame = frame_rx;
gNB->UL_INFO.slot = slot_rx;
// Call the scheduler gNB->UL_INFO.module_id = gNB->Mod_id;
start_meas(&gNB->ul_indication_stats); gNB->UL_INFO.CC_id = gNB->CC_id;
gNB->UL_INFO.frame = frame_rx; gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
gNB->UL_INFO.slot = slot_rx; stop_meas(&gNB->ul_indication_stats);
gNB->UL_INFO.module_id = gNB->Mod_id;
gNB->UL_INFO.CC_id = gNB->CC_id; notifiedFIFO_elt_t *res = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->L1_rx_out, NULL);
gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); processingData_L1_t *syncMsg = NotifiedFifoData(res);
stop_meas(&gNB->ul_indication_stats);
int tx_slot_type = nr_slot_select(cfg,frame_tx,slot_tx);
if ((tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) && NFAPI_MODE != NFAPI_MODE_PNF) {
notifiedFIFO_elt_t *res;
processingData_L1tx_t *syncMsg;
// Its a FIFO so it maitains the order in which the MAC fills the messages
// so no need for checking for right slot
if (get_softmodem_params()->reorder_thread_disable) {
// call the TX function directly from this thread
syncMsg = gNB->msgDataTx;
syncMsg->gNB = gNB;
syncMsg->timestamp_tx = info->timestamp_tx;
tx_func(syncMsg);
} else {
res = pullTpool(&gNB->L1_tx_filled, &gNB->threadPool);
if (res == NULL)
return; // Tpool has been stopped
syncMsg = (processingData_L1tx_t *)NotifiedFifoData(res);
syncMsg->gNB = gNB;
syncMsg->timestamp_tx = info->timestamp_tx;
res->key = slot_tx;
pushTpool(&gNB->threadPool, res);
}
} else if (get_softmodem_params()->continuous_tx) {
notifiedFIFO_elt_t *res = pullNotifiedFIFO(&gNB->L1_tx_free);
if (res == NULL)
return; // Tpool has been stopped
processingData_L1tx_t *syncMsg = (processingData_L1tx_t *)NotifiedFifoData(res);
syncMsg->gNB = gNB; syncMsg->gNB = gNB;
syncMsg->timestamp_tx = info->timestamp_tx; syncMsg->frame_rx = frame_rx;
syncMsg->frame = frame_tx; syncMsg->slot_rx = slot_rx;
syncMsg->slot = slot_tx; res->key = slot_rx;
res->key = slot_tx; LOG_D(NR_PHY, "Signaling completion for %d.%d (mod_slot %d) on L1_rx_out\n", frame_rx, slot_rx, slot_rx % RU_RX_SLOT_DEPTH);
pushNotifiedFIFO(&gNB->L1_tx_out, res); pushNotifiedFIFO(&gNB->L1_rx_out, res);
} }
stop_meas(&softmodem_stats_rxtx_sf);
clock_gettime(CLOCK_MONOTONIC, &info->gNB->rt_L1_profiling.return_L1_RX[rt_prof_idx]);
} }
static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size_t outputlen) { static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size_t outputlen) {
const char *begin = output; const char *begin = output;
const char *end = output + outputlen; const char *end = output + outputlen;
...@@ -367,60 +358,6 @@ void *nrL1_stats_thread(void *param) { ...@@ -367,60 +358,6 @@ void *nrL1_stats_thread(void *param) {
return(NULL); return(NULL);
} }
// This thread reads the finished L1 tx jobs from threaPool
// and pushes RU tx thread in the right order. It works only
// two parallel L1 tx threads.
void *tx_reorder_thread(void* param) {
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
notifiedFIFO_elt_t *resL1Reserve = pullNotifiedFIFO(&gNB->L1_tx_out);
AssertFatal(resL1Reserve != NULL, "pullTpool() did not return start message in %s\n", __func__);
int next_tx_slot=((processingData_L1tx_t *)NotifiedFifoData(resL1Reserve))->slot;
LOG_I(PHY,"tx_reorder_thread started\n");
while (!oai_exit) {
notifiedFIFO_elt_t *resL1;
if (resL1Reserve) {
resL1=resL1Reserve;
if (((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot) {
LOG_E(PHY,"order mistake\n");
resL1Reserve = NULL;
resL1 = pullNotifiedFIFO(&gNB->L1_tx_out);
}
} else {
resL1 = pullNotifiedFIFO(&gNB->L1_tx_out);
if (resL1 != NULL && ((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot) {
if (resL1Reserve)
LOG_E(PHY,"error, have a stored packet, then a second one\n");
resL1Reserve = resL1;
resL1 = pullNotifiedFIFO(&gNB->L1_tx_out);
if (((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot)
LOG_E(PHY,"error, pull two msg, none is good\n");
}
}
if (resL1 == NULL)
break; // Tpool has been stopped
processingData_L1tx_t *syncMsgL1= (processingData_L1tx_t *)NotifiedFifoData(resL1);
processingData_RU_t syncMsgRU;
syncMsgRU.frame_tx = syncMsgL1->frame;
syncMsgRU.slot_tx = syncMsgL1->slot;
syncMsgRU.timestamp_tx = syncMsgL1->timestamp_tx;
syncMsgRU.ru = gNB->RU_list[0];
if (get_softmodem_params()->continuous_tx) {
int slots_per_frame = gNB->frame_parms.slots_per_frame;
next_tx_slot = (syncMsgRU.slot_tx + 1) % slots_per_frame;
} else
next_tx_slot = get_next_downlink_slot(gNB, &gNB->gNB_config, syncMsgRU.frame_tx, syncMsgRU.slot_tx);
pushNotifiedFIFO(&gNB->L1_tx_free, resL1);
if (resL1==resL1Reserve)
resL1Reserve=NULL;
LOG_D(PHY,"gNB: %d.%d : calling RU TX function\n",syncMsgL1->frame,syncMsgL1->slot);
ru_tx_func((void*)&syncMsgRU);
}
return(NULL);
}
void init_gNB_Tpool(int inst) { void init_gNB_Tpool(int inst) {
PHY_VARS_gNB *gNB; PHY_VARS_gNB *gNB;
gNB = RC.gNB[inst]; gNB = RC.gNB[inst];
...@@ -433,47 +370,26 @@ void init_gNB_Tpool(int inst) { ...@@ -433,47 +370,26 @@ void init_gNB_Tpool(int inst) {
initNotifiedFIFO(&gNB->respPuschSymb); initNotifiedFIFO(&gNB->respPuschSymb);
initNotifiedFIFO(&gNB->respDecode); initNotifiedFIFO(&gNB->respDecode);
// L1 RX result FIFO // L1 RX result FIFO
initNotifiedFIFO(&gNB->resp_L1); initNotifiedFIFO(&gNB->resp_L1);
if (!get_softmodem_params()->reorder_thread_disable) {
notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->resp_L1, rx_func);
pushNotifiedFIFO(&gNB->resp_L1, msg); // to unblock the process in the beginning
}
// L1 TX result FIFO // L1 TX result FIFO
initNotifiedFIFO(&gNB->L1_tx_free); initNotifiedFIFO(&gNB->L1_tx_free);
initNotifiedFIFO(&gNB->L1_tx_filled); initNotifiedFIFO(&gNB->L1_tx_filled);
initNotifiedFIFO(&gNB->L1_tx_out); initNotifiedFIFO(&gNB->L1_tx_out);
initNotifiedFIFO(&gNB->L1_rx_out);
if (get_softmodem_params()->reorder_thread_disable) {
// create the RX thread responsible for triggering RX processing and then TX processing if a single thread is used // create the RX thread responsible for RX processing start event (resp_L1 msg queue), then launch rx_func()
threadCreate(&gNB->L1_rx_thread, L1_rx_thread, (void *)gNB, "L1_rx_thread", threadCreate(&gNB->L1_rx_thread, L1_rx_thread, (void *)gNB, "L1_rx_thread", gNB->L1_rx_thread_core, OAI_PRIORITY_RT_MAX);
gNB->L1_rx_thread_core, OAI_PRIORITY_RT_MAX); // create the TX thread responsible for TX processing start event (L1_tx_out msg queue), then launch tx_func()
// if separate threads are used for RX and TX, create the TX thread threadCreate(&gNB->L1_tx_thread, L1_tx_thread, (void *)gNB, "L1_tx_thread", gNB->L1_tx_thread_core, OAI_PRIORITY_RT_MAX);
// threadCreate(&gNB->L1_tx_thread, L1_tx_thread, (void *)gNB, "L1_tx_thread",
// gNB->L1_tx_thread_core, OAI_PRIORITY_RT_MAX); notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, tx_func);
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, tx_func); memset(msgDataTx, 0, sizeof(processingData_L1tx_t));
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx); init_DLSCH_struct(gNB, msgDataTx);
memset(msgDataTx, 0, sizeof(processingData_L1tx_t)); memset(msgDataTx->ssb, 0, 64 * sizeof(NR_gNB_SSB_t));
init_DLSCH_struct(gNB, msgDataTx); // this will be removed when the msgDataTx is not necessary anymore
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t)); gNB->msgDataTx = msgDataTx;
// this will be removed when the msgDataTx is not necessary anymore
gNB->msgDataTx = msgDataTx;
} else {
// we create 2 threads for L1 tx processing
for (int i=0; i < 2; i++) {
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, tx_func);
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
memset(msgDataTx, 0, sizeof(processingData_L1tx_t));
init_DLSCH_struct(gNB, msgDataTx);
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
pushNotifiedFIFO(&gNB->L1_tx_free, msgL1Tx); // to unblock the process in the beginning
}
LOG_I(PHY,"Creating thread for TX reordering and dispatching to RU\n");
threadCreate(&proc->pthread_tx_reorder, tx_reorder_thread, (void *)gNB, "thread_tx_reorder",
gNB->RU_list[0] ? gNB->RU_list[0]->tpcores[1] : -1, OAI_PRIORITY_RT_MAX);
}
if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT) && (NFAPI_MODE!=NFAPI_MODE_VNF)) if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT) && (NFAPI_MODE!=NFAPI_MODE_VNF))
threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW); threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW);
...@@ -489,12 +405,11 @@ void term_gNB_Tpool(int inst) { ...@@ -489,12 +405,11 @@ void term_gNB_Tpool(int inst) {
abortNotifiedFIFO(&gNB->L1_tx_free); abortNotifiedFIFO(&gNB->L1_tx_free);
abortNotifiedFIFO(&gNB->L1_tx_filled); abortNotifiedFIFO(&gNB->L1_tx_filled);
abortNotifiedFIFO(&gNB->L1_tx_out); abortNotifiedFIFO(&gNB->L1_tx_out);
abortNotifiedFIFO(&gNB->L1_rx_out);
gNB_L1_proc_t *proc = &gNB->proc; gNB_L1_proc_t *proc = &gNB->proc;
if (!get_softmodem_params()->emulate_l1) if (!get_softmodem_params()->emulate_l1)
pthread_join(proc->L1_stats_thread, NULL); pthread_join(proc->L1_stats_thread, NULL);
if (!get_softmodem_params()->reorder_thread_disable)
pthread_join(proc->pthread_tx_reorder, NULL);
} }
void reset_opp_meas(void) { void reset_opp_meas(void) {
...@@ -534,7 +449,6 @@ void init_eNB_afterRU(void) { ...@@ -534,7 +449,6 @@ void init_eNB_afterRU(void) {
gNB = RC.gNB[inst]; gNB = RC.gNB[inst];
gNB->ldpc_offload_flag = get_softmodem_params()->ldpc_offload_flag; gNB->ldpc_offload_flag = get_softmodem_params()->ldpc_offload_flag;
gNB->reorder_thread_disable = get_softmodem_params()->reorder_thread_disable;
phy_init_nr_gNB(gNB); phy_init_nr_gNB(gNB);
......
...@@ -624,7 +624,8 @@ void *emulatedRF_thread(void *param) { ...@@ -624,7 +624,8 @@ void *emulatedRF_thread(void *param) {
return 0; return 0;
} }
void rx_rf(RU_t *ru,int *frame,int *slot) { static void rx_rf(RU_t *ru, int *frame, int *slot)
{
RU_proc_t *proc = &ru->proc; RU_proc_t *proc = &ru->proc;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
openair0_config_t *cfg = &ru->openair0_cfg; openair0_config_t *cfg = &ru->openair0_cfg;
...@@ -662,13 +663,17 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { ...@@ -662,13 +663,17 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
//AssertFatal(rxs == fp->samples_per_subframe, //AssertFatal(rxs == fp->samples_per_subframe,
//"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_subframe,rxs); //"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_subframe,rxs);
if (rxs != samples_per_slot) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",samples_per_slot,rxs); if (rxs != samples_per_slot)
LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n", samples_per_slot, rxs);
if (proc->first_rx != 1) { if (proc->first_rx != 1) {
samples_per_slot_prev = fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp); samples_per_slot_prev = fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp);
if (proc->timestamp_rx - old_ts != samples_per_slot_prev) { if (proc->timestamp_rx - old_ts != samples_per_slot_prev) {
LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - samples_per_slot_prev,ru->ts_offset); LOG_D(PHY,
"rx_rf: rfdevice timing drift of %" PRId64 " samples (ts_off %" PRId64 ")\n",
proc->timestamp_rx - old_ts - samples_per_slot_prev,
ru->ts_offset);
ru->ts_offset += (proc->timestamp_rx - old_ts - samples_per_slot_prev); ru->ts_offset += (proc->timestamp_rx - old_ts - samples_per_slot_prev);
proc->timestamp_rx = ts-ru->ts_offset; proc->timestamp_rx = ts-ru->ts_offset;
} }
...@@ -705,8 +710,14 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { ...@@ -705,8 +710,14 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
} }
if (proc->frame_rx != *frame) { if (proc->frame_rx != *frame) {
LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, proc->tti_rx %d, slot %d)\n",(long long unsigned int)proc->timestamp_rx,proc->frame_rx, LOG_E(PHY,
*frame,proc->tti_rx,*slot); "Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, proc->tti_rx %d, "
"slot %d)\n",
(long long unsigned int)proc->timestamp_rx,
proc->frame_rx,
*frame,
proc->tti_rx,
*slot);
exit_fun("Exiting"); exit_fun("Exiting");
} }
} else { } else {
...@@ -1169,6 +1180,7 @@ void *ru_thread( void *param ) { ...@@ -1169,6 +1180,7 @@ void *ru_thread( void *param ) {
int initial_wait=0; int initial_wait=0;
int opp_enabled0 = opp_enabled; int opp_enabled0 = opp_enabled;
bool rx_tti_busy[RU_RX_SLOT_DEPTH] = {false};
nfapi_nr_config_request_scf_t *cfg = &ru->config; nfapi_nr_config_request_scf_t *cfg = &ru->config;
// set default return value // set default return value
ru_thread_status = 0; ru_thread_status = 0;
...@@ -1233,9 +1245,6 @@ void *ru_thread( void *param ) { ...@@ -1233,9 +1245,6 @@ void *ru_thread( void *param ) {
pthread_mutex_unlock(&RC.ru_mutex); pthread_mutex_unlock(&RC.ru_mutex);
wait_sync("ru_thread"); wait_sync("ru_thread");
processingData_L1_t *syncMsg;
notifiedFIFO_elt_t *res;
if(!emulate_rf) { if(!emulate_rf) {
// Start RF device if any // Start RF device if any
if (ru->start_rf) { if (ru->start_rf) {
...@@ -1299,14 +1308,13 @@ void *ru_thread( void *param ) { ...@@ -1299,14 +1308,13 @@ void *ru_thread( void *param ) {
if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot); if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot);
else AssertFatal(1==0, "No fronthaul interface at south port"); else AssertFatal(1==0, "No fronthaul interface at south port");
if (initial_wait == 1 && proc->frame_rx < 300) {
if (initial_wait == 1 && proc->frame_rx < 300 && ru->fh_south_in == rx_rf) { if (proc->frame_rx > 0 && ((proc->frame_rx % 100) == 0) && proc->tti_rx == 0) {
if (proc->frame_rx>0 && ((proc->frame_rx % 100) == 0) && proc->tti_rx==0) { LOG_D(PHY, "delay processing to let RX stream settle, frame %d (trials %d)\n", proc->frame_rx, ru->rx_fhaul.trials);
LOG_I(PHY,"delay processing to let RX stream settle, frame %d (trials %d)\n",proc->frame_rx,ru->rx_fhaul.trials); print_meas(&ru->rx_fhaul, "rx_fhaul", NULL, NULL);
print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL); reset_meas(&ru->rx_fhaul);
reset_meas(&ru->rx_fhaul); }
} continue;
continue;
} }
if (proc->frame_rx>=300) { if (proc->frame_rx>=300) {
initial_wait=0; initial_wait=0;
...@@ -1314,15 +1322,14 @@ void *ru_thread( void *param ) { ...@@ -1314,15 +1322,14 @@ void *ru_thread( void *param ) {
} }
if (initial_wait == 0 && ru->rx_fhaul.trials > 1000) { if (initial_wait == 0 && ru->rx_fhaul.trials > 1000) {
reset_meas(&ru->rx_fhaul); reset_meas(&ru->rx_fhaul);
/*if (ru->if_south == REMOTE_IF5) reset_meas(&ru->ifdevice.tx_fhaul); reset_meas(&ru->tx_fhaul);
else*/ reset_meas(&ru->tx_fhaul);
} }
proc->timestamp_tx = proc->timestamp_rx; proc->timestamp_tx = proc->timestamp_rx;
int sl=proc->tti_tx; int sl=proc->tti_tx;
for (int slidx=0;slidx<ru->sl_ahead;slidx++) for (int slidx=0;slidx<ru->sl_ahead;slidx++)
proc->timestamp_tx += fp->get_samples_per_slot((sl+slidx)%fp->slots_per_frame,fp); proc->timestamp_tx += fp->get_samples_per_slot((sl+slidx)%fp->slots_per_frame,fp);
proc->frame_tx = (proc->tti_rx > (fp->slots_per_frame-1-(ru->sl_ahead))) ? (proc->frame_rx+1)&1023 : proc->frame_rx; proc->frame_tx = (proc->tti_rx > (fp->slots_per_frame - 1 - (ru->sl_ahead))) ? (proc->frame_rx + 1) & 1023 : proc->frame_rx;
proc->tti_tx = (proc->tti_rx + ru->sl_ahead)%fp->slots_per_frame; proc->tti_tx = (proc->tti_rx + ru->sl_ahead) % fp->slots_per_frame;
int absslot_rx = proc->timestamp_rx/fp->get_samples_per_slot(proc->tti_rx,fp); int absslot_rx = proc->timestamp_rx/fp->get_samples_per_slot(proc->tti_rx,fp);
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH; int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_south_in[rt_prof_idx]); clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_south_in[rt_prof_idx]);
...@@ -1333,14 +1340,62 @@ void *ru_thread( void *param ) { ...@@ -1333,14 +1340,62 @@ void *ru_thread( void *param ) {
RC.gNB[0]->proc.frame_rx,RC.gNB[0]->proc.slot_rx, RC.gNB[0]->proc.frame_rx,RC.gNB[0]->proc.slot_rx,
RC.gNB[0]->proc.frame_tx); RC.gNB[0]->proc.frame_tx);
if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; if (ru->idx != 0)
proc->frame_tx = (proc->frame_tx + proc->frame_offset) & 1023;
LOG_D(NR_PHY, "In %d.%d: Checking L1 status\n", proc->frame_rx, proc->tti_rx);
for (int n = 0; n < RU_RX_SLOT_DEPTH; n++)
LOG_D(NR_PHY, "slot n %d => %d\n", n, rx_tti_busy[n]);
// handle potential race by blocking if rxdataF is being used by L1
// collect all pending msg in L1 return fifo to not down the memory is available (rx_tti_busy[slot] boolean array)
notifiedFIFO_elt_t *res = pollNotifiedFIFO(&gNB->L1_rx_out);
LOG_D(NR_PHY, "%d.%d Polling L1_rx_out %p\n", proc->frame_rx, proc->tti_rx, res);
while (res) {
processingData_L1_t *info = (processingData_L1_t *)NotifiedFifoData(res);
LOG_D(NR_PHY,
"%d.%d res %d.%d completed, clearing %d\n",
proc->frame_rx,
proc->tti_rx,
info->frame_rx,
info->slot_rx,
info->slot_rx % RU_RX_SLOT_DEPTH);
rx_tti_busy[info->slot_rx % RU_RX_SLOT_DEPTH] = false;
res = pollNotifiedFIFO(&gNB->L1_rx_out);
}
LOG_D(NR_PHY, "%d.%d Done polling\n", proc->frame_rx, proc->tti_rx);
// do RX front-end processing (frequency-shift, dft) if needed // do RX front-end processing (frequency-shift, dft) if needed
int slot_type = nr_slot_select(cfg,proc->frame_rx,proc->tti_rx); int slot_type = nr_slot_select(cfg, proc->frame_rx, proc->tti_rx);
if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
if (ru->feprx) { if (ru->feprx) {
if (rx_tti_busy[proc->tti_rx % RU_RX_SLOT_DEPTH]) {
bool not_done = true;
LOG_D(NR_PHY, "%d.%d Waiting to access RX slot %d\n", proc->frame_rx, proc->tti_rx, proc->tti_rx % RU_RX_SLOT_DEPTH);
// now we block and wait our slot memory zone is freed from previous slot processing
// as we can get other slots ending, we loop on the queue
while (not_done) {
res = pullNotifiedFIFO(&gNB->L1_rx_out);
if (!res)
break;
processingData_L1_t *info = (processingData_L1_t *)NotifiedFifoData(res);
LOG_D(NR_PHY,
"%d.%d Got access to RX slot %d.%d (%d)\n",
proc->frame_rx,
proc->tti_rx,
info->frame_rx,
info->slot_rx,
proc->tti_rx % RU_RX_SLOT_DEPTH);
rx_tti_busy[info->slot_rx % RU_RX_SLOT_DEPTH] = false;
if ((info->slot_rx % RU_RX_SLOT_DEPTH) == (proc->tti_rx % RU_RX_SLOT_DEPTH))
not_done = false;
}
if (!res)
break;
}
ru->feprx(ru,proc->tti_rx); ru->feprx(ru,proc->tti_rx);
// set the tti that was generated to busy
LOG_D(NR_PHY, "Setting %d.%d (%d) to busy\n", proc->frame_rx, proc->tti_rx, proc->tti_rx % RU_RX_SLOT_DEPTH);
rx_tti_busy[proc->tti_rx % RU_RX_SLOT_DEPTH] = true;
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_feprx[rt_prof_idx]); clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_feprx[rt_prof_idx]);
//LOG_M("rxdata.m","rxs",ru->common.rxdata[0],1228800,1,1); //LOG_M("rxdata.m","rxs",ru->common.rxdata[0],1228800,1,1);
LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx); LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx);
...@@ -1383,26 +1438,16 @@ void *ru_thread( void *param ) { ...@@ -1383,26 +1438,16 @@ void *ru_thread( void *param ) {
} }
} // end if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { } // end if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
// At this point, all information for subframe has been received on FH interface notifiedFIFO_elt_t *resTx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, NULL);
if (!get_softmodem_params()->reorder_thread_disable) { processingData_L1tx_t *syncMsgTx = NotifiedFifoData(resTx);
res = pullTpool(&gNB->resp_L1, &gNB->threadPool); syncMsgTx->gNB = gNB;
if (res == NULL) syncMsgTx->frame = proc->frame_tx;
break; // Tpool has been stopped syncMsgTx->slot = proc->tti_tx;
} else { syncMsgTx->frame_rx = proc->frame_rx;
res=newNotifiedFIFO_elt(sizeof(processingData_L1_t),0, &gNB->resp_L1,NULL); syncMsgTx->slot_rx = proc->tti_rx;
} syncMsgTx->timestamp_tx = proc->timestamp_tx;
syncMsg = (processingData_L1_t *)NotifiedFifoData(res); resTx->key = proc->tti_tx;
syncMsg->gNB = gNB; pushNotifiedFIFO(&gNB->L1_tx_out, resTx);
syncMsg->frame_rx = proc->frame_rx;
syncMsg->slot_rx = proc->tti_rx;
syncMsg->frame_tx = proc->frame_tx;
syncMsg->slot_tx = proc->tti_tx;
syncMsg->timestamp_tx = proc->timestamp_tx;
res->key = proc->tti_rx;
if (!get_softmodem_params()->reorder_thread_disable)
pushTpool(&gNB->threadPool, res);
else
pushNotifiedFIFO(&gNB->resp_L1, res);
} }
printf( "Exiting ru_thread \n"); printf( "Exiting ru_thread \n");
......
...@@ -44,7 +44,6 @@ extern "C" ...@@ -44,7 +44,6 @@ extern "C"
example: -1,3 launches two working threads one floating, the second set on core 3\n\ example: -1,3 launches two working threads one floating, the second set on core 3\n\
default 8 floating threads\n\ default 8 floating threads\n\
use N for no pool (runs in calling thread) recommended with rfsim.\n" use N for no pool (runs in calling thread) recommended with rfsim.\n"
#define CONFIG_HLP_REORDER "Disable reorder thread\n"
#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n" #define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n"
#define CONFIG_HLP_CALUER "set UE RX calibration\n" #define CONFIG_HLP_CALUER "set UE RX calibration\n"
#define CONFIG_HLP_CALUERM "" #define CONFIG_HLP_CALUERM ""
...@@ -147,7 +146,6 @@ extern "C" ...@@ -147,7 +146,6 @@ extern "C"
#define NID2 softmodem_params.nid2 #define NID2 softmodem_params.nid2
#define LDPC_OFFLOAD_FLAG softmodem_params.ldpc_offload_flag #define LDPC_OFFLOAD_FLAG softmodem_params.ldpc_offload_flag
#define REORDER_THREAD_DISABLE softmodem_params.reorder_thread_disable
#define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat"; #define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat";
extern int usrp_tx_thread; extern int usrp_tx_thread;
...@@ -155,7 +153,6 @@ extern int usrp_tx_thread; ...@@ -155,7 +153,6 @@ extern int usrp_tx_thread;
#define CMDLINE_PARAMS_DESC { \ #define CMDLINE_PARAMS_DESC { \
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, .strptr=&RF_CONFIG_FILE, .defstrval=NULL, TYPE_STRING, 0}, \ {"rf-config-file", CONFIG_HLP_RFCFGF, 0, .strptr=&RF_CONFIG_FILE, .defstrval=NULL, TYPE_STRING, 0}, \
{"thread-pool", CONFIG_HLP_TPOOL, 0, .strptr=&TP_CONFIG, .defstrval="-1,-1,-1,-1,-1,-1,-1,-1", TYPE_STRING, 0}, \ {"thread-pool", CONFIG_HLP_TPOOL, 0, .strptr=&TP_CONFIG, .defstrval="-1,-1,-1,-1,-1,-1,-1,-1", TYPE_STRING, 0}, \
{"reorder-thread-disable",CONFIG_HLP_REORDER, PARAMFLAG_BOOL, .iptr=&REORDER_THREAD_DISABLE, .defintval=0, TYPE_INT, 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}, \
{"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, .iptr=&DO_RA, .defintval=0, TYPE_INT, 0}, \ {"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, .iptr=&DO_RA, .defintval=0, TYPE_INT, 0}, \
{"sa", CONFIG_HLP_SA, PARAMFLAG_BOOL, .iptr=&SA, .defintval=0, TYPE_INT, 0}, \ {"sa", CONFIG_HLP_SA, PARAMFLAG_BOOL, .iptr=&SA, .defintval=0, TYPE_INT, 0}, \
...@@ -232,7 +229,6 @@ extern int usrp_tx_thread; ...@@ -232,7 +229,6 @@ extern int usrp_tx_thread;
{ .s5 = { NULL } }, \ { .s5 = { NULL } }, \
{ .s5 = { NULL } }, \ { .s5 = { NULL } }, \
{ .s5 = { NULL } }, \ { .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s3a = { config_checkstr_assign_integer, \ { .s3a = { config_checkstr_assign_integer, \
{"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \ {"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \
{NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \ {NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \
...@@ -326,8 +322,7 @@ typedef struct { ...@@ -326,8 +322,7 @@ typedef struct {
uint64_t optmask; uint64_t optmask;
//THREAD_STRUCT thread_struct; //THREAD_STRUCT thread_struct;
char *rf_config_file; char *rf_config_file;
char *threadPoolConfig; char *threadPoolConfig;
int reorder_thread_disable;
int phy_test; int phy_test;
int do_ra; int do_ra;
int sa; int sa;
...@@ -375,7 +370,6 @@ extern uint16_t sl_ahead; ...@@ -375,7 +370,6 @@ extern uint16_t sl_ahead;
extern uint16_t sf_ahead; extern uint16_t sf_ahead;
extern int oai_exit; extern int oai_exit;
void tx_func(void *param);
void rx_func(void *param); void rx_func(void *param);
void ru_tx_func(void *param); void ru_tx_func(void *param);
extern uint8_t nfapi_mode; extern uint8_t nfapi_mode;
......
...@@ -76,8 +76,7 @@ void nr_fill_prach(PHY_VARS_gNB *gNB, ...@@ -76,8 +76,7 @@ void nr_fill_prach(PHY_VARS_gNB *gNB,
nfapi_nr_prach_pdu_t *prach_pdu) { nfapi_nr_prach_pdu_t *prach_pdu) {
int prach_id = find_nr_prach(gNB,SFN,Slot,SEARCH_EXIST_OR_FREE); int prach_id = find_nr_prach(gNB,SFN,Slot,SEARCH_EXIST_OR_FREE);
AssertFatal( ((prach_id>=0) && (prach_id<NUMBER_OF_NR_PRACH_MAX)) || (prach_id < 0), AssertFatal(((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)), "illegal or no prach_id found!!! prach_id %d\n", prach_id);
"illegal or no prach_id found!!! prach_id %d\n",prach_id);
gNB->prach_vars.list[prach_id].frame=SFN; gNB->prach_vars.list[prach_id].frame=SFN;
gNB->prach_vars.list[prach_id].slot=Slot; gNB->prach_vars.list[prach_id].slot=Slot;
......
...@@ -74,8 +74,8 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t ...@@ -74,8 +74,8 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t
NR_UL_gNB_HARQ_t *harq = ulsch->harq_process; NR_UL_gNB_HARQ_t *harq = ulsch->harq_process;
if (ulsch_pdu->pusch_data.new_data_indicator) if (ulsch_pdu->pusch_data.new_data_indicator)
harq->harq_to_be_cleared = true; harq->harq_to_be_cleared = true;
LOG_D(PHY, LOG_D(NR_PHY,
"%d.%d RNTI %x HARQ PID %d new data indicator %d\n", "NEW ULSCH %d.%d RNTI %x HARQ PID %d new data indicator %d\n",
frame, frame,
slot, slot,
ulsch_pdu->rnti, ulsch_pdu->rnti,
...@@ -98,8 +98,17 @@ void reset_active_ulsch(PHY_VARS_gNB *gNB, int frame) ...@@ -98,8 +98,17 @@ void reset_active_ulsch(PHY_VARS_gNB *gNB, int frame)
// assuming UE disconnected or some other error occurred // assuming UE disconnected or some other error occurred
for (int i = 0; i < gNB->max_nb_pusch; i++) { for (int i = 0; i < gNB->max_nb_pusch; i++) {
NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[i]; NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[i];
if (ulsch->active && (((frame - ulsch->frame + 1024) % 1024) > NUMBER_FRAMES_PHY_UE_INACTIVE)) int diff = (frame - ulsch->frame + 1024) & 1023;
if (ulsch->active && diff > NUMBER_FRAMES_PHY_UE_INACTIVE && diff < 100) {
ulsch->active = false; ulsch->active = false;
LOG_D(NR_PHY,
"Frame %d: resetting ulsch %d harq %d (programmed in %d.%d)\n",
frame,
i,
ulsch->harq_pid,
ulsch->frame,
ulsch->slot);
}
} }
} }
......
...@@ -1409,7 +1409,7 @@ static void nr_pusch_symbol_processing(void *arg) ...@@ -1409,7 +1409,7 @@ static void nr_pusch_symbol_processing(void *arg)
if (gNB->pusch_vars[ulsch_id].ul_valid_re_per_slot[symbol] == 0) if (gNB->pusch_vars[ulsch_id].ul_valid_re_per_slot[symbol] == 0)
continue; continue;
int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size; int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
inner_rx(gNB, inner_rx(gNB,
ulsch_id, ulsch_id,
slot, slot,
...@@ -1591,7 +1591,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, ...@@ -1591,7 +1591,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
// extract the first dmrs for the channel level computation // extract the first dmrs for the channel level computation
// extract the data in the OFDM frame, to the start of the array // extract the data in the OFDM frame, to the start of the array
int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size; int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
nb_re_pusch = (nb_re_pusch + 15) & ~15; nb_re_pusch = (nb_re_pusch + 15) & ~15;
......
...@@ -501,7 +501,7 @@ void nr_decode_pucch1(c16_t **rxdataF, ...@@ -501,7 +501,7 @@ void nr_decode_pucch1(c16_t **rxdataF,
* Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation * Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation
* *
*/ */
const int soffset = (nr_tti_tx & 3) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; const int soffset = (nr_tti_tx % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
// lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213]
const int lprime = startingSymbolIndex; const int lprime = startingSymbolIndex;
// mcs = 0 except for PUCCH format 0 // mcs = 0 except for PUCCH format 0
...@@ -1021,14 +1021,10 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, ...@@ -1021,14 +1021,10 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
//extract pucch and dmrs first //extract pucch and dmrs first
int l2 = pucch_pdu->start_symbol_index; int l2 = pucch_pdu->start_symbol_index;
int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
int soffset = (slot & 3) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
int re_offset[2]; int re_offset[2];
re_offset[0] = re_offset[0] =
(12 * (pucch_pdu->prb_start + pucch_pdu->bwp_start) + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; (12 * (pucch_pdu->prb_start + pucch_pdu->bwp_start) + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
if (re_offset[0]>= frame_parms->ofdm_symbol_size)
re_offset[0]-=frame_parms->ofdm_symbol_size;
if (pucch_pdu->freq_hop_flag == 0) if (pucch_pdu->freq_hop_flag == 0)
re_offset[1] = re_offset[0]; re_offset[1] = re_offset[0];
else { else {
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "PHY/impl_defs_nr.h" #include "PHY/impl_defs_nr.h"
#include "PHY/defs_nr_common.h" #include "PHY/defs_nr_common.h"
#include "PHY/defs_gNB.h" #include "PHY/defs_gNB.h"
#include "PHY/defs_RU.h"
#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h" #include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h"
#include "PHY/NR_UE_TRANSPORT/srs_modulation_nr.h" #include "PHY/NR_UE_TRANSPORT/srs_modulation_nr.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
...@@ -75,7 +76,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, ...@@ -75,7 +76,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
c16_t **rxdataF = gNB->common_vars.rxdataF; c16_t **rxdataF = gNB->common_vars.rxdataF;
const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
const uint16_t n_symbols = (slot&3)*frame_parms->symbols_per_slot; // number of symbols until this slot const uint16_t n_symbols = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot; // number of symbols until this slot
const uint8_t l0 = frame_parms->symbols_per_slot - 1 - srs_pdu->time_start_position; // starting symbol in this slot const uint8_t l0 = frame_parms->symbols_per_slot - 1 - srs_pdu->time_start_position; // starting symbol in this slot
const uint64_t symbol_offset = (n_symbols+l0)*frame_parms->ofdm_symbol_size; const uint64_t symbol_offset = (n_symbols+l0)*frame_parms->ofdm_symbol_size;
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB; const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB;
......
...@@ -197,7 +197,7 @@ typedef struct { ...@@ -197,7 +197,7 @@ typedef struct {
#define NUMBER_OF_NR_RU_PRACH_MAX 8 #define NUMBER_OF_NR_RU_PRACH_MAX 8
#define NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX 12 #define NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX 12
#define RU_RX_SLOT_DEPTH 4
typedef struct RU_proc_t_s { typedef struct RU_proc_t_s {
/// Pointer to associated RU descriptor /// Pointer to associated RU descriptor
struct RU_t_s *ru; struct RU_t_s *ru;
......
...@@ -639,8 +639,6 @@ typedef struct PHY_VARS_gNB_s { ...@@ -639,8 +639,6 @@ typedef struct PHY_VARS_gNB_s {
int ldpc_offload_flag; int ldpc_offload_flag;
int reorder_thread_disable;
int max_ldpc_iterations; int max_ldpc_iterations;
/// indicate the channel estimation technique in time domain /// indicate the channel estimation technique in time domain
int chest_time; int chest_time;
...@@ -718,6 +716,7 @@ typedef struct PHY_VARS_gNB_s { ...@@ -718,6 +716,7 @@ typedef struct PHY_VARS_gNB_s {
notifiedFIFO_t L1_tx_free; notifiedFIFO_t L1_tx_free;
notifiedFIFO_t L1_tx_filled; notifiedFIFO_t L1_tx_filled;
notifiedFIFO_t L1_tx_out; notifiedFIFO_t L1_tx_out;
notifiedFIFO_t L1_rx_out;
notifiedFIFO_t resp_RU_tx; notifiedFIFO_t resp_RU_tx;
tpool_t threadPool; tpool_t threadPool;
int nbSymb; int nbSymb;
...@@ -795,9 +794,7 @@ union ldpcReqUnion { ...@@ -795,9 +794,7 @@ union ldpcReqUnion {
typedef struct processingData_L1 { typedef struct processingData_L1 {
int frame_rx; int frame_rx;
int frame_tx;
int slot_rx; int slot_rx;
int slot_tx;
openair0_timestamp timestamp_tx; openair0_timestamp timestamp_tx;
PHY_VARS_gNB *gNB; PHY_VARS_gNB *gNB;
} processingData_L1_t; } processingData_L1_t;
...@@ -811,6 +808,8 @@ typedef enum { ...@@ -811,6 +808,8 @@ typedef enum {
typedef struct processingData_L1tx { typedef struct processingData_L1tx {
int frame; int frame;
int slot; int slot;
int frame_rx;
int slot_rx;
openair0_timestamp timestamp_tx; openair0_timestamp timestamp_tx;
PHY_VARS_gNB *gNB; PHY_VARS_gNB *gNB;
nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu[NFAPI_NR_MAX_NB_CORESETS]; nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu[NFAPI_NR_MAX_NB_CORESETS];
...@@ -825,4 +824,9 @@ typedef struct processingData_L1tx { ...@@ -825,4 +824,9 @@ typedef struct processingData_L1tx {
int sched_response_id; int sched_response_id;
} processingData_L1tx_t; } processingData_L1tx_t;
typedef struct processingData_L1rx {
int frame_rx;
int slot_rx;
PHY_VARS_gNB *gNB;
} processingData_L1rx_t;
#endif #endif
...@@ -156,21 +156,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) ...@@ -156,21 +156,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
uint8_t number_tx_data_pdu = (TX_req == NULL) ? 0 : TX_req->Number_of_PDUs; uint8_t number_tx_data_pdu = (TX_req == NULL) ? 0 : TX_req->Number_of_PDUs;
if (NFAPI_MODE == NFAPI_MONOLITHIC){ if (NFAPI_MODE == NFAPI_MONOLITHIC){
if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT) { if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT) {
notifiedFIFO_elt_t *res=NULL;
processingData_L1tx_t *msgTx=NULL; processingData_L1tx_t *msgTx=NULL;
if (!gNB->reorder_thread_disable) { msgTx = gNB->msgDataTx;
res = pullNotifiedFIFO(&gNB->L1_tx_free);
if (res == NULL)
return; // Tpool has been stopped, nothing to process
msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
} else {
msgTx = gNB->msgDataTx; //newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0, &gNB->L1_tx_out,NULL);
}
/*const time_stats_t ts = exec_time_stats_NotifiedFIFO(res);
merge_meas(&gNB->phy_proc_tx, &ts);
*/
msgTx->num_pdsch_slot = 0; msgTx->num_pdsch_slot = 0;
msgTx->num_dl_pdcch = 0; msgTx->num_dl_pdcch = 0;
msgTx->num_ul_pdcch = number_ul_dci_pdu; msgTx->num_ul_pdcch = number_ul_dci_pdu;
...@@ -222,8 +210,6 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) ...@@ -222,8 +210,6 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
* released only when both threads are done with it. * released only when both threads are done with it.
*/ */
inc_ref_sched_response(Sched_INFO->sched_response_id); inc_ref_sched_response(Sched_INFO->sched_response_id);
if (!gNB->reorder_thread_disable)
pushNotifiedFIFO(&gNB->L1_tx_filled,res);
} }
for (int i = 0; i < number_ul_tti_pdu; i++) { for (int i = 0; i < number_ul_tti_pdu; i++) {
...@@ -267,7 +253,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) ...@@ -267,7 +253,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
} }
/* this thread is done with the sched_info, decrease the reference counter */ /* this thread is done with the sched_info, decrease the reference counter */
deref_sched_response(Sched_INFO->sched_response_id); if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT) {
LOG_D(NR_PHY, "Calling dref_sched_response for id %d in %d.%d (sched_response)\n", Sched_INFO->sched_response_id, frame, slot);
deref_sched_response(Sched_INFO->sched_response_id);
}
stop_meas(&gNB->schedule_response_stats); stop_meas(&gNB->schedule_response_stats);
} }
...@@ -242,7 +242,7 @@ void nr_fep_full(RU_t *ru, int slot) { ...@@ -242,7 +242,7 @@ void nr_fep_full(RU_t *ru, int slot) {
// remove_7_5_kHz(ru,proc->tti_rx<<1); // remove_7_5_kHz(ru,proc->tti_rx<<1);
// remove_7_5_kHz(ru,1+(proc->tti_rx<<1)); // remove_7_5_kHz(ru,1+(proc->tti_rx<<1));
int offset = (proc->tti_rx&3)*(fp->symbols_per_slot * fp->ofdm_symbol_size); int offset = (proc->tti_rx % RU_RX_SLOT_DEPTH) * (fp->symbols_per_slot * fp->ofdm_symbol_size);
for (l = 0; l < fp->symbols_per_slot; l++) { for (l = 0; l < fp->symbols_per_slot; l++) {
for (aa = 0; aa < fp->nb_antennas_rx; aa++) { for (aa = 0; aa < fp->nb_antennas_rx; aa++) {
nr_slot_fep_ul(fp, nr_slot_fep_ul(fp,
...@@ -378,7 +378,7 @@ void nr_fep(void* arg) { ...@@ -378,7 +378,7 @@ void nr_fep(void* arg) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 1);
int offset = (tti_rx&3) * fp->symbols_per_slot * fp->ofdm_symbol_size; int offset = (tti_rx % RU_RX_SLOT_DEPTH) * fp->symbols_per_slot * fp->ofdm_symbol_size;
for (int l = startSymbol; l <= endSymbol; l++) for (int l = startSymbol; l <= endSymbol; l++)
nr_slot_fep_ul(fp, nr_slot_fep_ul(fp,
ru->common.rxdata[aid], ru->common.rxdata[aid],
......
...@@ -272,10 +272,11 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) ...@@ -272,10 +272,11 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
} }
if (crc_valid && !check_abort(&ulsch_harq->abort_decode) && !gNB->pusch_vars[rdata->ulsch_id].DTX) { if (crc_valid && !check_abort(&ulsch_harq->abort_decode) && !gNB->pusch_vars[rdata->ulsch_id].DTX) {
LOG_D(PHY, LOG_D(NR_PHY,
"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (rnti %x, pid %d, ndi %d, status %d, round %d, TBS %d, Max interation " "[gNB %d] ULSCH %d: Setting ACK for SFN/SF %d.%d (rnti %x, pid %d, ndi %d, status %d, round %d, TBS %d, Max interation "
"(all seg) %d)\n", "(all seg) %d)\n",
gNB->Mod_id, gNB->Mod_id,
rdata->ulsch_id,
ulsch->frame, ulsch->frame,
ulsch->slot, ulsch->slot,
ulsch->rnti, ulsch->rnti,
...@@ -316,7 +317,7 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) ...@@ -316,7 +317,7 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
if (ulsch_harq->ulsch_pdu.mcs_index == 0 && dumpsig==1) { if (ulsch_harq->ulsch_pdu.mcs_index == 0 && dumpsig==1) {
int off = ((ulsch_harq->ulsch_pdu.rb_size&1) == 1)? 4:0; int off = ((ulsch_harq->ulsch_pdu.rb_size&1) == 1)? 4:0;
LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][(ulsch_harq->slot&3)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1); LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][(ulsch_harq->slot%RU_RX_SLOT_DEPTH)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1);
LOG_M("rxsigF0_ext.m","rxsF0_ext", LOG_M("rxsigF0_ext.m","rxsF0_ext",
&gNB->pusch_vars[0].rxdataF_ext[0][ulsch_harq->ulsch_pdu.start_symbol_index*NR_NB_SC_PER_RB * &gNB->pusch_vars[0].rxdataF_ext[0][ulsch_harq->ulsch_pdu.start_symbol_index*NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB *
...@@ -410,9 +411,6 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ...@@ -410,9 +411,6 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int
void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, uint8_t harq_pid, uint8_t crc_flag, int dtx_flag) void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, uint8_t harq_pid, uint8_t crc_flag, int dtx_flag)
{ {
if (!get_softmodem_params()->reorder_thread_disable)
pthread_mutex_lock(&gNB->UL_INFO_mutex);
NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id]; NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
NR_gNB_PHY_STATS_t *stats = get_phy_stats(gNB, ulsch->rnti); NR_gNB_PHY_STATS_t *stats = get_phy_stats(gNB, ulsch->rnti);
...@@ -467,7 +465,13 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, ...@@ -467,7 +465,13 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
__attribute__((unused)) __attribute__((unused))
int off = ((pusch_pdu->rb_size&1) == 1)? 4:0; int off = ((pusch_pdu->rb_size&1) == 1)? 4:0;
LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][(slot_rx&3)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1); LOG_M("rxsigF0.m",
"rxsF0",
&gNB->common_vars
.rxdataF[0][(slot_rx % RU_RX_SLOT_DEPTH) * gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot],
gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot,
1,
1);
LOG_M("chestF0.m", LOG_M("chestF0.m",
"chF0", "chF0",
&gNB->pusch_vars[0].ul_ch_estimates[0][pusch_pdu->start_symbol_index * gNB->frame_parms.ofdm_symbol_size], &gNB->pusch_vars[0].ul_ch_estimates[0][pusch_pdu->start_symbol_index * gNB->frame_parms.ofdm_symbol_size],
...@@ -494,7 +498,14 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, ...@@ -494,7 +498,14 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
1, 1,
0); 0);
if (gNB->frame_parms.nb_antennas_rx > 1) { if (gNB->frame_parms.nb_antennas_rx > 1) {
LOG_M("rxsigF1.m","rxsF1",&gNB->common_vars.rxdataF[1][(slot_rx&3)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1); LOG_M(
"rxsigF1.m",
"rxsF1",
&gNB->common_vars
.rxdataF[1][(slot_rx % RU_RX_SLOT_DEPTH) * gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot],
gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot,
1,
1);
LOG_M("chestF1.m", LOG_M("chestF1.m",
"chF1", "chF1",
&gNB->pusch_vars[0].ul_ch_estimates[1][pusch_pdu->start_symbol_index * gNB->frame_parms.ofdm_symbol_size], &gNB->pusch_vars[0].ul_ch_estimates[1][pusch_pdu->start_symbol_index * gNB->frame_parms.ofdm_symbol_size],
...@@ -557,9 +568,6 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, ...@@ -557,9 +568,6 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
} }
gNB->UL_INFO.rx_ind.number_of_pdus++; gNB->UL_INFO.rx_ind.number_of_pdus++;
if (!get_softmodem_params()->reorder_thread_disable)
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
} }
// Function to fill UL RB mask to be used for N0 measurements // Function to fill UL RB mask to be used for N0 measurements
...@@ -834,9 +842,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) ...@@ -834,9 +842,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id]; NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id];
NR_UL_gNB_HARQ_t *ulsch_harq = ulsch->harq_process; NR_UL_gNB_HARQ_t *ulsch_harq = ulsch->harq_process;
AssertFatal(ulsch_harq != NULL, "harq_pid %d is not allocated\n", ulsch->harq_pid); AssertFatal(ulsch_harq != NULL, "harq_pid %d is not allocated\n", ulsch->harq_pid);
if ((ulsch->active == true) && (ulsch->frame == frame_rx) && (ulsch->slot == slot_rx) && (ulsch->handled == 0)) { if ((ulsch->active == true) && (ulsch->frame == frame_rx) && (ulsch->slot == slot_rx) && (ulsch->handled == 0)) {
LOG_D(PHY, "PUSCH ID %d with RNTI %x detection started in frame %d slot %d\n", ULSCH_id, ulsch->rnti, frame_rx, slot_rx); LOG_D(PHY, "PUSCH ID %d with RNTI %x detection started in frame %d slot %d\n", ULSCH_id, ulsch->rnti, frame_rx, slot_rx);
int num_dmrs = 0; int num_dmrs = 0;
for (int s = 0; s < NR_NUMBER_OF_SYMBOLS_PER_SLOT; s++) for (int s = 0; s < NR_NUMBER_OF_SYMBOLS_PER_SLOT; s++)
num_dmrs += (ulsch_harq->ulsch_pdu.ul_dmrs_symb_pos >> s) & 1; num_dmrs += (ulsch_harq->ulsch_pdu.ul_dmrs_symb_pos >> s) & 1;
......
...@@ -895,6 +895,7 @@ int main(int argc, char **argv) ...@@ -895,6 +895,7 @@ int main(int argc, char **argv)
msgDataTx->slot = slot; msgDataTx->slot = slot;
msgDataTx->frame = frame; msgDataTx->frame = frame;
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t)); memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
gNB->msgDataTx = msgDataTx;
// Buffers to store internal memory of slot process // Buffers to store internal memory of slot process
int rx_size = (((14 * frame_parms->N_RB_DL * 12 * sizeof(int32_t)) + 15) >> 4) << 4; int rx_size = (((14 * frame_parms->N_RB_DL * 12 * sizeof(int32_t)) + 15) >> 4) << 4;
......
...@@ -563,6 +563,7 @@ int main(int argc, char *argv[]) ...@@ -563,6 +563,7 @@ int main(int argc, char *argv[])
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_free, NULL); notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_free, NULL);
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx); processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
msgDataTx->slot = -1; msgDataTx->slot = -1;
gNB->msgDataTx = msgDataTx;
//gNB_config = &gNB->gNB_config; //gNB_config = &gNB->gNB_config;
//memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO)); //memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
......
...@@ -486,21 +486,6 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { ...@@ -486,21 +486,6 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
if (get_softmodem_params()->emulate_l1) { if (get_softmodem_params()->emulate_l1) {
free_unqueued_nfapi_indications(rach_ind, uci_ind, rx_ind, crc_ind); free_unqueued_nfapi_indications(rach_ind, uci_ind, rx_ind, crc_ind);
} }
if (NFAPI_MODE != NFAPI_MODE_PNF) {
gNB_MAC_INST *mac = RC.nrmac[module_id];
NR_IF_Module_t *ifi = nr_if_inst[module_id];
ifi->current_frame = UL_info->frame;
ifi->current_slot = UL_info->slot;
nfapi_nr_config_request_scf_t *cfg = &mac->config[CC_id];
int spf = get_spf(cfg);
int CC_id = 0;
int frame_tx = UL_info->frame + ((UL_info->slot > (spf - 1 - ifi->sl_ahead)) ? 1 : 0);
int slot_tx = (UL_info->slot + ifi->sl_ahead) % spf;
ifi->NR_slot_indication(module_id, CC_id, frame_tx, slot_tx);
}
} }
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {
......
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