Merge remote-tracking branch 'origin/simpler-parallel-exclusion-ue-tx' into integration_2024_w21b
This commit is contained in:
@@ -19,7 +19,7 @@ gNBs =
|
|||||||
|
|
||||||
////////// Physical parameters:
|
////////// Physical parameters:
|
||||||
|
|
||||||
min_rxtxtime = 2;
|
min_rxtxtime = 5;
|
||||||
do_SRS = 0;
|
do_SRS = 0;
|
||||||
force_256qam_off = 1;
|
force_256qam_off = 1;
|
||||||
pdsch_AntennaPorts_N1 = 1;
|
pdsch_AntennaPorts_N1 = 1;
|
||||||
|
|||||||
+21
-23
@@ -526,6 +526,14 @@ void processSlotTX(void *arg)
|
|||||||
PHY_VARS_NR_UE *UE = rxtxD->UE;
|
PHY_VARS_NR_UE *UE = rxtxD->UE;
|
||||||
nr_phy_data_tx_t phy_data = {0};
|
nr_phy_data_tx_t phy_data = {0};
|
||||||
|
|
||||||
|
// Force sequential execution, even if we launch in // for all slots
|
||||||
|
// at least ULstatus variable is a pure race condition that is quickly detected by assert() in the code because one thread sets it
|
||||||
|
// to active, so the other thread try to steal&run the ul work
|
||||||
|
if (rxtxD->stream_status == STREAM_STATUS_SYNCED) {
|
||||||
|
notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo + proc->nr_slot_tx);
|
||||||
|
delNotifiedFIFO_elt(res);
|
||||||
|
}
|
||||||
|
|
||||||
if (UE->if_inst)
|
if (UE->if_inst)
|
||||||
UE->if_inst->slot_indication(UE->Mod_id);
|
UE->if_inst->slot_indication(UE->Mod_id);
|
||||||
|
|
||||||
@@ -560,11 +568,6 @@ void processSlotTX(void *arg)
|
|||||||
instead,
|
instead,
|
||||||
we may run in place the processSlotTX() when the conditions are met (when a decreasing tx_wait_for_dlsch[slot] will become 0)
|
we may run in place the processSlotTX() when the conditions are met (when a decreasing tx_wait_for_dlsch[slot] will become 0)
|
||||||
It will remove the condition signals (for a thread safe semaphore or counter) and make the system simpler
|
It will remove the condition signals (for a thread safe semaphore or counter) and make the system simpler
|
||||||
This require also other modifications to
|
|
||||||
remove txFifo that is also a big issue
|
|
||||||
add out of order RF board sending, because,
|
|
||||||
if we encode and send tx slot as soon as we can,
|
|
||||||
it will be thrown out of order, especially in TDD mode
|
|
||||||
*/
|
*/
|
||||||
notifiedFIFO_elt_t *res = pollNotifiedFIFO(UE->tx_resume_ind_fifo + proc->nr_slot_tx);
|
notifiedFIFO_elt_t *res = pollNotifiedFIFO(UE->tx_resume_ind_fifo + proc->nr_slot_tx);
|
||||||
if (res)
|
if (res)
|
||||||
@@ -590,6 +593,11 @@ void processSlotTX(void *arg)
|
|||||||
phy_procedures_nrUE_TX(UE, proc, &phy_data);
|
phy_procedures_nrUE_TX(UE, proc, &phy_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(int), 0, NULL, NULL);
|
||||||
|
int *msgData = (int *)NotifiedFifoData(newElt);
|
||||||
|
int newslot = (proc->nr_slot_tx + 1) % UE->frame_parms.slots_per_frame;
|
||||||
|
*msgData = newslot;
|
||||||
|
pushNotifiedFIFO(UE->tx_resume_ind_fifo + newslot, newElt);
|
||||||
RU_write(rxtxD);
|
RU_write(rxtxD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -743,7 +751,7 @@ void *UE_thread(void *arg)
|
|||||||
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
|
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
|
||||||
// int tx_enabled = 0;
|
// int tx_enabled = 0;
|
||||||
void *rxp[NB_ANTENNAS_RX];
|
void *rxp[NB_ANTENNAS_RX];
|
||||||
int start_rx_stream = 0;
|
enum stream_status_e stream_status = STREAM_STATUS_UNSYNC;
|
||||||
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
|
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
|
||||||
int tmp = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]);
|
int tmp = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]);
|
||||||
AssertFatal(tmp == 0, "Could not load the device\n");
|
AssertFatal(tmp == 0, "Could not load the device\n");
|
||||||
@@ -755,9 +763,6 @@ void *UE_thread(void *arg)
|
|||||||
notifiedFIFO_t nf;
|
notifiedFIFO_t nf;
|
||||||
initNotifiedFIFO(&nf);
|
initNotifiedFIFO(&nf);
|
||||||
|
|
||||||
notifiedFIFO_t txFifo;
|
|
||||||
initNotifiedFIFO(&txFifo);
|
|
||||||
|
|
||||||
notifiedFIFO_t freeBlocks;
|
notifiedFIFO_t freeBlocks;
|
||||||
initNotifiedFIFO_nothreadSafe(&freeBlocks);
|
initNotifiedFIFO_nothreadSafe(&freeBlocks);
|
||||||
|
|
||||||
@@ -796,7 +801,7 @@ void *UE_thread(void *arg)
|
|||||||
intialSyncOffset = syncMsg->rx_offset;
|
intialSyncOffset = syncMsg->rx_offset;
|
||||||
}
|
}
|
||||||
delNotifiedFIFO_elt(res);
|
delNotifiedFIFO_elt(res);
|
||||||
start_rx_stream = 0;
|
stream_status = STREAM_STATUS_UNSYNC;
|
||||||
} else {
|
} else {
|
||||||
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
|
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
|
||||||
// For IQ recorder-player we force synchronization to happen in 280 ms
|
// For IQ recorder-player we force synchronization to happen in 280 ms
|
||||||
@@ -826,8 +831,8 @@ void *UE_thread(void *arg)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start_rx_stream == 0) {
|
if (stream_status == STREAM_STATUS_UNSYNC) {
|
||||||
start_rx_stream=1;
|
stream_status = STREAM_STATUS_SYNCING;
|
||||||
syncInFrame(UE, &sync_timestamp, intialSyncOffset);
|
syncInFrame(UE, &sync_timestamp, intialSyncOffset);
|
||||||
openair0_write_reorder_clear_context(&UE->rfdevice);
|
openair0_write_reorder_clear_context(&UE->rfdevice);
|
||||||
shiftForNextFrame = 0; // will be used to track clock drift
|
shiftForNextFrame = 0; // will be used to track clock drift
|
||||||
@@ -938,25 +943,18 @@ void *UE_thread(void *arg)
|
|||||||
|
|
||||||
// Start TX slot processing here. It runs in parallel with RX slot processing
|
// Start TX slot processing here. It runs in parallel with RX slot processing
|
||||||
// in current code, DURATION_RX_TO_TX constant is the limit to get UL data to encode from a RX slot
|
// in current code, DURATION_RX_TO_TX constant is the limit to get UL data to encode from a RX slot
|
||||||
notifiedFIFO_elt_t *newTx = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, &txFifo, processSlotTX);
|
notifiedFIFO_elt_t *newTx = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, NULL, processSlotTX);
|
||||||
nr_rxtx_thread_data_t *curMsgTx = (nr_rxtx_thread_data_t *)NotifiedFifoData(newTx);
|
nr_rxtx_thread_data_t *curMsgTx = (nr_rxtx_thread_data_t *)NotifiedFifoData(newTx);
|
||||||
curMsgTx->proc = curMsg.proc;
|
curMsgTx->proc = curMsg.proc;
|
||||||
curMsgTx->writeBlockSize = writeBlockSize;
|
curMsgTx->writeBlockSize = writeBlockSize;
|
||||||
curMsgTx->proc.timestamp_tx = writeTimestamp;
|
curMsgTx->proc.timestamp_tx = writeTimestamp;
|
||||||
curMsgTx->UE = UE;
|
curMsgTx->UE = UE;
|
||||||
curMsgTx->tx_wait_for_dlsch = tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx];
|
curMsgTx->tx_wait_for_dlsch = tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx];
|
||||||
|
curMsgTx->stream_status = stream_status;
|
||||||
|
stream_status = STREAM_STATUS_SYNCED;
|
||||||
tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx] = 0;
|
tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx] = 0;
|
||||||
pushTpool(&(get_nrUE_params()->Tpool), newTx);
|
pushTpool(&(get_nrUE_params()->Tpool), newTx);
|
||||||
|
}
|
||||||
// Wait for TX slot processing to finish
|
|
||||||
// Should be removed when bugs, race conditions, will be fixed
|
|
||||||
notifiedFIFO_elt_t *res;
|
|
||||||
res = pullTpool(&txFifo, &(get_nrUE_params()->Tpool));
|
|
||||||
if (res == NULL)
|
|
||||||
LOG_E(PHY, "Tpool has been aborted\n");
|
|
||||||
else
|
|
||||||
delNotifiedFIFO_elt(res);
|
|
||||||
} // while !oai_exit
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -645,7 +645,7 @@ void clean_UE_harq(PHY_VARS_NR_UE *UE)
|
|||||||
for (int harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) {
|
for (int harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) {
|
||||||
NR_UL_UE_HARQ_t *ul_harq_process = &UE->ul_harq_processes[harq_pid];
|
NR_UL_UE_HARQ_t *ul_harq_process = &UE->ul_harq_processes[harq_pid];
|
||||||
ul_harq_process->tx_status = NEW_TRANSMISSION_HARQ;
|
ul_harq_process->tx_status = NEW_TRANSMISSION_HARQ;
|
||||||
ul_harq_process->status = SCH_IDLE;
|
ul_harq_process->ULstatus = SCH_IDLE;
|
||||||
ul_harq_process->round = 0;
|
ul_harq_process->round = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ typedef struct {
|
|||||||
/// HARQ tx status
|
/// HARQ tx status
|
||||||
harq_result_t tx_status;
|
harq_result_t tx_status;
|
||||||
/// Status Flag indicating for this ULSCH (idle,active,disabled)
|
/// Status Flag indicating for this ULSCH (idle,active,disabled)
|
||||||
SCH_status_t status;
|
SCH_status_t ULstatus;
|
||||||
/// Last TPC command
|
/// Last TPC command
|
||||||
uint8_t TPC;
|
uint8_t TPC;
|
||||||
/// Length of ACK information (bits)
|
/// Length of ACK information (bits)
|
||||||
|
|||||||
@@ -557,7 +557,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
|||||||
|
|
||||||
NR_UL_UE_HARQ_t *harq_process_ulsch = NULL;
|
NR_UL_UE_HARQ_t *harq_process_ulsch = NULL;
|
||||||
harq_process_ulsch = &UE->ul_harq_processes[harq_pid];
|
harq_process_ulsch = &UE->ul_harq_processes[harq_pid];
|
||||||
harq_process_ulsch->status = SCH_IDLE;
|
harq_process_ulsch->ULstatus = SCH_IDLE;
|
||||||
///////////
|
///////////
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -632,6 +632,8 @@ typedef struct nr_phy_data_s {
|
|||||||
sl_nr_rx_config_type_enum_t sl_rx_action;
|
sl_nr_rx_config_type_enum_t sl_rx_action;
|
||||||
|
|
||||||
} nr_phy_data_t;
|
} nr_phy_data_t;
|
||||||
|
|
||||||
|
enum stream_status_e { STREAM_STATUS_UNSYNC, STREAM_STATUS_SYNCING, STREAM_STATUS_SYNCED};
|
||||||
/* this structure is used to pass both UE phy vars and
|
/* this structure is used to pass both UE phy vars and
|
||||||
* proc to the function UE_thread_rxn_txnp4
|
* proc to the function UE_thread_rxn_txnp4
|
||||||
*/
|
*/
|
||||||
@@ -642,6 +644,7 @@ typedef struct nr_rxtx_thread_data_s {
|
|||||||
nr_phy_data_t phy_data;
|
nr_phy_data_t phy_data;
|
||||||
int tx_wait_for_dlsch;
|
int tx_wait_for_dlsch;
|
||||||
int rx_offset;
|
int rx_offset;
|
||||||
|
enum stream_status_e stream_status;
|
||||||
} nr_rxtx_thread_data_t;
|
} nr_rxtx_thread_data_t;
|
||||||
|
|
||||||
typedef struct LDPCDecode_ue_s {
|
typedef struct LDPCDecode_ue_s {
|
||||||
|
|||||||
@@ -272,7 +272,7 @@
|
|||||||
/* - between reception of pdsch and tarnsmission of its acknowlegment */
|
/* - between reception of pdsch and tarnsmission of its acknowlegment */
|
||||||
/* - between reception of un uplink grant and its related transmission */
|
/* - between reception of un uplink grant and its related transmission */
|
||||||
// should be 2 as per NR standard, but current UE is not able to perform this value
|
// should be 2 as per NR standard, but current UE is not able to perform this value
|
||||||
#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (2)
|
#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (3)
|
||||||
|
|
||||||
#define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX)
|
#define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX)
|
||||||
|
|
||||||
|
|||||||
@@ -473,7 +473,7 @@ static void nr_ue_scheduled_response_ul(PHY_VARS_NR_UE *phy, fapi_nr_ul_config_r
|
|||||||
pdu->pusch_config_pdu.tx_request_body.pdu_length);
|
pdu->pusch_config_pdu.tx_request_body.pdu_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
harq_process_ul_ue->status = ACTIVE;
|
harq_process_ul_ue->ULstatus = ACTIVE;
|
||||||
pdu->pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more
|
pdu->pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
|
|||||||
start_meas(&ue->phy_proc_tx);
|
start_meas(&ue->phy_proc_tx);
|
||||||
|
|
||||||
for (uint8_t harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) {
|
for (uint8_t harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) {
|
||||||
if (ue->ul_harq_processes[harq_pid].status == ACTIVE) {
|
if (ue->ul_harq_processes[harq_pid].ULstatus == ACTIVE) {
|
||||||
nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, gNB_id, phy_data, (c16_t **)&txdataF);
|
nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, gNB_id, phy_data, (c16_t **)&txdataF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -788,6 +788,10 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dci_ind->rnti != mac->ra.ra_rnti && dci_ind->rnti != SI_RNTI)
|
if (dci_ind->rnti != mac->ra.ra_rnti && dci_ind->rnti != SI_RNTI)
|
||||||
|
AssertFatal(1 + dci->pdsch_to_harq_feedback_timing_indicator.val > DURATION_RX_TO_TX,
|
||||||
|
"PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%d).\n",
|
||||||
|
1 + dci->pdsch_to_harq_feedback_timing_indicator.val,
|
||||||
|
DURATION_RX_TO_TX);
|
||||||
|
|
||||||
// set the harq status at MAC for feedback
|
// set the harq status at MAC for feedback
|
||||||
set_harq_status(mac,
|
set_harq_status(mac,
|
||||||
@@ -1115,6 +1119,12 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
|
|||||||
// according to TS 38.213 Table 9.2.3-1
|
// according to TS 38.213 Table 9.2.3-1
|
||||||
uint8_t feedback_ti = pucch_Config->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0];
|
uint8_t feedback_ti = pucch_Config->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0];
|
||||||
|
|
||||||
|
AssertFatal(feedback_ti > DURATION_RX_TO_TX,
|
||||||
|
"PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%d). Min feedback time set in config "
|
||||||
|
"file (min_rxtxtime).\n",
|
||||||
|
feedback_ti,
|
||||||
|
DURATION_RX_TO_TX);
|
||||||
|
|
||||||
// set the harq status at MAC for feedback
|
// set the harq status at MAC for feedback
|
||||||
set_harq_status(mac,
|
set_harq_status(mac,
|
||||||
dci->pucch_resource_indicator,
|
dci->pucch_resource_indicator,
|
||||||
|
|||||||
@@ -1009,6 +1009,9 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssertFatal(slot_offset > DURATION_RX_TO_TX,
|
||||||
|
"Slot offset between DCI and aperiodic SRS (%d) needs to be higher than DURATION_RX_TO_TX (%d)\n",
|
||||||
|
slot_offset, DURATION_RX_TO_TX);
|
||||||
int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
|
int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
|
||||||
int sched_slot = (slot + slot_offset) % n_slots_frame;
|
int sched_slot = (slot + slot_offset) % n_slots_frame;
|
||||||
NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon;
|
NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon;
|
||||||
@@ -1467,6 +1470,13 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
|
|||||||
AssertFatal(1 == 0, "Invalid numerology %i\n", mu);
|
AssertFatal(1 == 0, "Invalid numerology %i\n", mu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssertFatal((k2 + delta) > DURATION_RX_TO_TX,
|
||||||
|
"Slot offset (%ld) for Msg3 needs to be higher than DURATION_RX_TO_TX (%d). Please set min_rxtxtime at least to %d in gNB config file or gNBs.[0].min_rxtxtime=%d via command line.\n",
|
||||||
|
k2,
|
||||||
|
DURATION_RX_TO_TX,
|
||||||
|
DURATION_RX_TO_TX,
|
||||||
|
DURATION_RX_TO_TX);
|
||||||
|
|
||||||
*slot_tx = (current_slot + k2 + delta) % nr_slots_per_frame[mu];
|
*slot_tx = (current_slot + k2 + delta) % nr_slots_per_frame[mu];
|
||||||
if (current_slot + k2 + delta >= nr_slots_per_frame[mu]){
|
if (current_slot + k2 + delta >= nr_slots_per_frame[mu]){
|
||||||
*frame_tx = (current_frame + 1) % 1024;
|
*frame_tx = (current_frame + 1) % 1024;
|
||||||
@@ -1475,6 +1485,14 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
AssertFatal(k2 > DURATION_RX_TO_TX,
|
||||||
|
"Slot offset K2 (%ld) needs to be higher than DURATION_RX_TO_TX (%d). Please set min_rxtxtime at least to %d in gNB config file or gNBs.[0].min_rxtxtime=%d via command line.\n",
|
||||||
|
k2,
|
||||||
|
DURATION_RX_TO_TX,
|
||||||
|
DURATION_RX_TO_TX,
|
||||||
|
DURATION_RX_TO_TX);
|
||||||
|
|
||||||
if (k2 < 0) { // This can happen when a false DCI is received
|
if (k2 < 0) { // This can happen when a false DCI is received
|
||||||
LOG_W(PHY, "%d.%d. Received k2 %ld\n", current_frame, current_slot, k2);
|
LOG_W(PHY, "%d.%d. Received k2 %ld\n", current_frame, current_slot, k2);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user