Commit cd9a8f96 authored by francescomani's avatar francescomani

moving pucch functions for harq at MAC (version still to be tested)

parent f691d880
......@@ -1487,7 +1487,6 @@ set(SCHED_SRC_NR_UE
${OPENAIR1_DIR}/SCHED_NR_UE/phy_frame_config_nr_ue.c
${OPENAIR1_DIR}/SCHED_NR_UE/harq_nr.c
${OPENAIR1_DIR}/SCHED_NR_UE/pucch_uci_ue_nr.c
${OPENAIR1_DIR}/SCHED_NR_UE/pucch_power_control_ue_nr.c
)
add_library(SCHED_NR_UE_LIB ${SCHED_SRC_NR_UE})
......
......@@ -373,8 +373,7 @@ void processSlotRX(void *arg) {
if (get_softmodem_params()->usim_test==0) {
pucch_procedures_ue_nr(UE,
gNB_id,
proc,
FALSE);
proc);
}
LOG_D(PHY, "Sending Uplink data \n");
......
......@@ -101,6 +101,8 @@ typedef struct {
typedef struct {
uint8_t harq_pid;
uint8_t ack_nack;
uint32_t pdu_length;
uint8_t* pdu;
} fapi_nr_pdsch_pdu_t;
......@@ -188,87 +190,33 @@ typedef struct {
} fapi_nr_ul_config_prach_pdu;
typedef struct {
pucch_format_nr_t format; /* format 0 1 2 3 4 */
uint8_t initialCyclicShift; /* x x */
uint8_t nrofSymbols; /* x x x x x */
uint8_t startingSymbolIndex; /* x x x x x */
uint8_t timeDomainOCC; /* x */
uint8_t nrofPRBs; /* x x */
uint16_t startingPRB; /* maxNrofPhysicalResourceBlocks = 275 */
uint8_t occ_length; /* x */
uint8_t occ_Index; /* x */
feature_status_t intraSlotFrequencyHopping;
uint16_t secondHopPRB;
/*
-- Enabling inter-slot frequency hopping when PUCCH Format 1, 3 or 4 is repeated over multiple slots.
-- The field is not applicable for format 2.
*/
feature_status_t interslotFrequencyHopping;
/*
-- Enabling 2 DMRS symbols per hop of a PUCCH Format 3 or 4 if both hops are more than X symbols when FH is enabled (X=4).
-- Enabling 4 DMRS sybmols for a PUCCH Format 3 or 4 with more than 2X+1 symbols when FH is disabled (X=4).
-- Corresponds to L1 parameter 'PUCCH-F3-F4-additional-DMRS' (see 38.213, section 9.2.1)
-- The field is not applicable for format 1 and 2.
*/
enable_feature_t additionalDMRS;
/*
-- Max coding rate to determine how to feedback UCI on PUCCH for format 2, 3 or 4
-- Corresponds to L1 parameter 'PUCCH-F2-maximum-coderate', 'PUCCH-F3-maximum-coderate' and 'PUCCH-F4-maximum-coderate'
-- (see 38.213, section 9.2.5)
-- The field is not applicable for format 1.
*/
PUCCH_MaxCodeRate_t maxCodeRate;
/*
-- Number of slots with the same PUCCH F1, F3 or F4. When the field is absent the UE applies the value n1.
-- Corresponds to L1 parameter 'PUCCH-F1-number-of-slots', 'PUCCH-F3-number-of-slots' and 'PUCCH-F4-number-of-slots'
-- (see 38.213, section 9.2.6)
-- The field is not applicable for format 2.
*/
uint8_t nrofSlots;
/*
-- Enabling pi/2 BPSK for UCI symbols instead of QPSK for PUCCH.
-- Corresponds to L1 parameter 'PUCCH-PF3-PF4-pi/2PBSK' (see 38.213, section 9.2.5)
-- The field is not applicable for format 1 and 2.
*/
feature_status_t pi2PBSK;
/*
-- Enabling simultaneous transmission of CSI and HARQ-ACK feedback with or without SR with PUCCH Format 2, 3 or 4
-- Corresponds to L1 parameter 'PUCCH-F2-Simultaneous-HARQ-ACK-CSI', 'PUCCH-F3-Simultaneous-HARQ-ACK-CSI' and
-- 'PUCCH-F4-Simultaneous-HARQ-ACK-CSI' (see 38.213, section 9.2.5)
-- When the field is absent the UE applies the value OFF
-- The field is not applicable for format 1.
*/
enable_feature_t simultaneousHARQ_ACK_CSI;
/*
-- Configuration of group- and sequence hopping for all the PUCCH formats 0, 1, 3 and 4. "neither" implies neither group
-- or sequence hopping is enabled. "enable" enables group hopping and disables sequence hopping. "disable"” disables group
-- hopping and enables sequence hopping. Corresponds to L1 parameter 'PUCCH-GroupHopping' (see 38.211, section 6.4.1.3)
pucch-GroupHopping ENUMERATED { neither, enable, disable },
*/
pucch_GroupHopping_t pucch_GroupHopping;
/*
-- Cell-Specific scrambling ID for group hoppping and sequence hopping if enabled.
-- Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2)
hoppingId BIT STRING (SIZE (10)) OPTIONAL, -- Need R
*/
uint16_t hoppingId;
/*
-- Power control parameter P0 for PUCCH transmissions. Value in dBm. Only even values (step size 2) allowed.
-- Corresponds to L1 parameter 'p0-nominal-pucch' (see 38.213, section 7.2)
p0-nominal INTEGER (-202..24) OPTIONAL, -- Need R
*/
int8_t p0_nominal;
int8_t deltaF_PUCCH_f[NUMBER_PUCCH_FORMAT_NR];
uint8_t p0_PUCCH_Id; /* INTEGER (1..8) */
int8_t p0_PUCCH_Value;
// pathlossReferenceRSs SEQUENCE (SIZE (1..maxNrofPUCCH-PathlossReferenceRSs)) OF PUCCH-PathlossReferenceRS OPTIONAL, -- Need M
int8_t twoPUCCH_PC_AdjustmentStates;
} fapi_nr_ul_config_pucch_pdu;
uint16_t rnti;
uint16_t bwp_size;
uint16_t bwp_start;
uint8_t format_type;
uint8_t start_symbol_index;
uint8_t nr_of_symbols;
uint16_t prb_start;
uint16_t prb_size;
uint32_t hopping_id;
uint8_t freq_hop_flag;
uint8_t group_hop_flag;
uint8_t sequence_hop_flag;
uint16_t second_hop_prb;
uint16_t initial_cyclic_shift;
uint8_t time_domain_occ_idx;
uint8_t add_dmrs_flag;
uint16_t dmrs_scrambling_id;
uint16_t data_scrambling_id;
uint8_t dmrs_cyclic_shift;
uint8_t pi_2bpsk;
uint8_t mcs;
uint8_t pre_dft_occ_idx;
uint8_t pre_dft_occ_len;
int16_t pucch_tx_power;
uint32_t n_bit;
uint64_t payload;
} fapi_nr_ul_config_pucch_pdu;
typedef struct
{
......@@ -460,11 +408,8 @@ typedef struct {
uint8_t tb2_rv;
uint8_t harq_process_nbr;
vrb_to_prb_mapping_t vrb_to_prb_mapping;
uint8_t dai;
double scaling_factor_S;
int8_t accumulated_delta_PUCCH;
uint8_t pucch_resource_id;
uint8_t pdsch_to_harq_feedback_time_ind;
uint8_t n_dmrs_cdm_groups;
uint8_t dmrs_ports[10];
uint8_t n_front_load_symb;
......
......@@ -182,6 +182,16 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
}
}
/////////////////////////PUCCH init/////////////////////////
///////////
for (th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
ue->pucch_vars[th_id][gNB_id] = (NR_UE_PUCCH *)malloc16(sizeof(NR_UE_PUCCH));
for (i=0; i<2; i++)
ue->pucch_vars[th_id][gNB_id]->active[i] = false;
}
}
///////////
////////////////////////////////////////////////////////////////////////////////////////////
......
......@@ -955,7 +955,8 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
currentPtrDCI);
n_rnti = rel15->rnti;
LOG_D(PHY, "(%i.%i) dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d)\n", proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length);
LOG_D(PHY, "(%i.%i) dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d)\n",
proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length);
if (crc == n_rnti) {
LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d,payload %llx)\n",
proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length,*(unsigned long long*)dci_estimation);
......@@ -970,6 +971,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
dci_ind->slot = proc->nr_slot_rx;
dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind;
dci_ind->dci_list[dci_ind->number_of_dcis].N_CCE = L;
dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format_options[k];
dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
......
......@@ -625,9 +625,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
harq_process->harq_ack.ack = 0;
harq_process->harq_ack.harq_id = harq_pid;
harq_process->harq_ack.send_harq_status = 1;
harq_process->ack = 0;
harq_process->errors[harq_process->round]++;
if (harq_process->round >= dlsch->Mlimit) {
......@@ -650,9 +648,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
harq_process->status = SCH_IDLE;
harq_process->round = 0;
harq_process->harq_ack.ack = 1;
harq_process->harq_ack.harq_id = harq_pid;
harq_process->harq_ack.send_harq_status = 1;
harq_process->ack = 1;
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
// phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);
......@@ -1171,9 +1167,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
harq_process->harq_ack.ack = 0;
harq_process->harq_ack.harq_id = harq_pid;
harq_process->harq_ack.send_harq_status = 1;
harq_process->ack = 0;
harq_process->errors[harq_process->round]++;
harq_process->round++;
......@@ -1195,9 +1189,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
harq_process->status = SCH_IDLE;
harq_process->round = 0;
harq_process->harq_ack.ack = 1;
harq_process->harq_ack.harq_id = harq_pid;
harq_process->harq_ack.send_harq_status = 1;
harq_process->ack = 1;
//LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
// phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);
......
......@@ -613,7 +613,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
uint16_t number_pdus = 1;
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, number_pdus);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, NULL, number_pdus);
if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&dl_indication, NULL);
......
......@@ -56,34 +56,6 @@ typedef enum {
RETRANSMISSION_HARQ
} harq_result_t;
//#if defined(UPGRADE_RAT_NR)
#if 1
typedef struct {
/// HARQ process id
uint8_t harq_id;
/// HARQ rx status
harq_result_t rx_status;
/// ACK bits (after decoding) 0:NACK / 1:ACK / 2:DTX
uint8_t ack;
/// send status (for PUCCH)
uint8_t send_harq_status;
/// nCCE (for PUCCH)
uint8_t nCCE;
/// DAI value detected from DCI1/1a/1b/1d/2/2a/2b/2c. 0xff indicates not touched
uint8_t vDAI_DL;
/// DAI value detected from DCI0/4. 0xff indicates not touched
uint8_t vDAI_UL;
/// allow to define pucch parameters TS 38.213 9.2.3 UE procedure for reporting HARQ-ACK
uint8_t pucch_resource_indicator;
/// slot on which feedback ack should be send to network
uint16_t slot_for_feedback_ack;
/// index of a first CCE for the PDCCH reception
uint8_t n_CCE;
/// number of CCEs in a control resource set of a PDCCH reception conveying DCI format 1_0
uint8_t N_CCE;
} NR_UE_HARQ_STATUS_t;
#endif
typedef struct {
/// NDAPI struct for UE
nfapi_nr_ue_pusch_pdu_t pusch_pdu;
......@@ -319,7 +291,7 @@ typedef struct {
/// codeword this transport block is mapped to
uint8_t codeword;
/// HARQ-ACKs
NR_UE_HARQ_STATUS_t harq_ack;
uint8_t ack;
/// PTRS Frequency Density
uint8_t PTRSFreqDensity;
/// PTRS Time Density
......
This diff is collapsed.
......@@ -49,62 +49,30 @@
void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
long pucch_GroupHopping,
long hoppingId,
int16_t amp,
int nr_slot_tx,
uint8_t m0,
uint8_t mcs,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint16_t startingPRB,
uint16_t secondHopPRB);
fapi_nr_ul_config_pucch_pdu *pucch_pdu);
void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint64_t payload,
int16_t amp,
int nr_slot_tx,
uint8_t m0,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint16_t startingPRB,
uint16_t startingPRB_intraSlotHopping,
uint8_t timeDomainOCC,
uint8_t nr_bit);
fapi_nr_ul_config_pucch_pdu *pucch_pdu);
void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
uint16_t crnti,
uint32_t dmrs_scrambling_id,
uint32_t data_scrambling_id,
int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint64_t payload,
int16_t amp,
int nr_slot_tx,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint8_t nrofPRB,
uint16_t startingPRB,
uint8_t nr_bit);
fapi_nr_ul_config_pucch_pdu *pucch_pdu);
void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
uint16_t crnti,
int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
pucch_format_nr_t fmt,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint64_t payload,
int16_t amp,
int nr_slot_tx,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint8_t nrofPRB,
uint16_t startingPRB,
uint16_t startingPRB_intraSlotHopping,
uint8_t nr_bit,
uint8_t occ_length_format4,
uint8_t occ_index_format4);
fapi_nr_ul_config_pucch_pdu *pucch_pdu);
// tables for mcs values for different payloads
static const uint8_t table1_mcs[]={0,6,3,9};
......
......@@ -235,6 +235,11 @@ typedef struct {
int32_t *txdataF_layers[NR_MAX_NB_LAYERS];
} NR_UE_PUSCH;
typedef struct {
bool active[2];
fapi_nr_ul_config_pucch_pdu pucch_pdu[2];
} NR_UE_PUCCH;
typedef struct {
/// \brief Holds the transmit data in time domain.
/// For IFFT_FPGA this points to the same memory as PHY_vars->tx_vars[a].TX_DMA_BUFFER.
......@@ -810,6 +815,7 @@ typedef struct {
NR_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_PUSCH *pusch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_PUCCH *pucch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_DLSCH_t *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX][NR_MAX_NB_CODEWORDS]; // two RxTx Threads
NR_UE_ULSCH_t *ulsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX][NR_MAX_NB_CODEWORDS]; // two code words
NR_UE_DLSCH_t *dlsch_SI[NUMBER_OF_CONNECTED_gNB_MAX];
......@@ -957,9 +963,6 @@ typedef struct {
/// PUSCH contention-based access vars
PUSCH_CA_CONFIG_DEDICATED pusch_ca_config_dedicated[NUMBER_OF_eNB_MAX]; // lola
/// PUCCH variables
PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_gNB_MAX];
//#if defined(UPGRADE_RAT_NR)
#if 1
......@@ -970,9 +973,6 @@ typedef struct {
PDSCH_ServingCellConfig_t PDSCH_ServingCellConfig;
PDSCH_Config_t PDSCH_Config;
PUCCH_ConfigCommon_nr_t pucch_config_common_nr[NUMBER_OF_CONNECTED_gNB_MAX];
PUCCH_Config_t pucch_config_dedicated_nr[NUMBER_OF_CONNECTED_gNB_MAX];
PUSCH_Config_t pusch_config;
SRS_NR srs;
......
......@@ -681,23 +681,10 @@ uci_onPusch_t uci_onPusch;
*
************************************************************************/
#define MAX_NR_OF_PUCCH_P0_PER_SET (8)
#define NUMBER_PUCCH_FORMAT_NR (5)
typedef int8_t power_level_t; /* INTEGER (-16..15) */
typedef struct {
uint8_t p0_PUCCH_Id; /* INTEGER (1..8) */
power_level_t p0_PUCCH_Value;
} P0_PUCCH_t;
typedef struct {
power_level_t deltaF_PUCCH_f[NUMBER_PUCCH_FORMAT_NR];
P0_PUCCH_t *p0_Set[MAX_NR_OF_PUCCH_P0_PER_SET];
// pathlossReferenceRSs SEQUENCE (SIZE (1..maxNrofPUCCH-PathlossReferenceRSs)) OF PUCCH-PathlossReferenceRS OPTIONAL, -- Need M
int8_t twoPUCCH_PC_AdjustmentStates;
} PUCCH_PowerControl_t;
/***********************************************************************
*
......@@ -887,9 +874,10 @@ typedef struct {
PUCCH_FormatConfig_t *formatConfig[NUMBER_PUCCH_FORMAT_NR-1]; /* format 0 is not there */
uint8_t dl_DataToUL_ACK[NB_DL_DATA_TO_UL_ACK]; /* table TS 38.213 Table 9.2.3-1: Mapping of PSDCH-to-HARQ_feedback timing indicator field values to numbers of slots */
void *spatial_Relation_Info[MAX_NR_OF_SPATIAL_RELATION_INFOS];
PUCCH_PowerControl_t pucch_PowerControl;
} PUCCH_Config_t;
/***********************************************************************
*
* FUNCTIONALITY : PhysicalCellGroupConfig
......
......@@ -417,6 +417,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
uint8_t gNB_id,
PHY_VARS_NR_UE *ue,
NR_UE_DLSCH_t *dlsch0,
NR_UE_DLSCH_t *dlsch1,
uint16_t n_pdus);
......
......@@ -47,6 +47,7 @@ const char *ul_pdu_type[]={"PRACH", "PUCCH", "PUSCH", "SRS"};
int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
bool found = false;
if(scheduled_response != NULL){
module_id_t module_id = scheduled_response->module_id;
......@@ -59,7 +60,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
NR_UE_DLSCH_t *dlsch0 = NULL;
NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0];
NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0][0];
NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms;
NR_UE_PUCCH *pucch_vars = PHY_vars_UE_g[module_id][cc_id]->pucch_vars[thread_id][0];
if(scheduled_response->dl_config != NULL){
fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
......@@ -119,19 +120,13 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
dlsch0_harq->mcs = dlsch_config_pdu->mcs;
dlsch0_harq->rvidx = dlsch_config_pdu->rv;
dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id;
dlsch0_harq->harq_ack.slot_for_feedback_ack = (slot+dlsch_config_pdu->pdsch_to_harq_feedback_time_ind)%frame_parms.slots_per_frame;
dlsch0_harq->Nl=1;
dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table;
dlsch0_harq->harq_ack.rx_status = downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type);
if (dlsch0_harq->status != ACTIVE) {
// dlsch0_harq->status not ACTIVE may be due to false retransmission. Reset the
// following flag to skip PDSCH procedures in that case.
dlsch0->active = 0;
dlsch0_harq->harq_ack.ack = 1;
dlsch0_harq->harq_ack.send_harq_status = 1;
}
dlsch0_harq->harq_ack.vDAI_DL = dlsch_config_pdu->dai;
/* PTRS */
dlsch0_harq->PTRSFreqDensity = dlsch_config_pdu->PTRSFreqDensity;
dlsch0_harq->PTRSTimeDensity = dlsch_config_pdu->PTRSTimeDensity;
......@@ -139,7 +134,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
dlsch0_harq->nEpreRatioOfPDSCHToPTRS = dlsch_config_pdu->nEpreRatioOfPDSCHToPTRS;
dlsch0_harq->PTRSReOffset = dlsch_config_pdu->PTRSReOffset;
dlsch0_harq->pduBitmap = dlsch_config_pdu->pduBitmap;
LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\tpdsch_to_harq_feedback_time_ind = %d\tslot_for_feedback_ack = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs, dlsch_config_pdu->pdsch_to_harq_feedback_time_ind, dlsch0_harq->harq_ack.slot_for_feedback_ack);
LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs);
}
}
}
......@@ -163,9 +158,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu;
/* PUCCH */
fapi_nr_ul_config_pucch_pdu *pucch_config_pdu;
PUCCH_ConfigCommon_nr_t *pucch_config_common_nr;
PUCCH_Config_t *pucch_config_dedicated_nr;
PUCCH_format_t *format_params;
switch (pdu_type){
......@@ -203,47 +195,16 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
break;
case (FAPI_NR_UL_CONFIG_TYPE_PUCCH):
// pucch config pdu
found = false;
pucch_config_pdu = &ul_config->ul_config_list[i].pucch_config_pdu;
pucch_resource_id = 0; //FIXME!!!
format = 1; // FIXME!!!
pucch_config_common_nr = &PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0];
pucch_config_dedicated_nr = &PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0];
format_params = &pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->format_parameters;
format_params->initialCyclicShift = pucch_config_pdu->initialCyclicShift;
format_params->nrofSymbols = pucch_config_pdu->nrofSymbols;
format_params->startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
format_params->nrofPRBs = pucch_config_pdu->nrofPRBs;
format_params->timeDomainOCC = pucch_config_pdu->timeDomainOCC;
format_params->occ_length = pucch_config_pdu->occ_length;
format_params->occ_Index = pucch_config_pdu->occ_Index;
pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB;
pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping;
pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used
pucch_config_dedicated_nr->formatConfig[format - 1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used
pucch_config_dedicated_nr->formatConfig[format - 1]->pi2PBSK = pucch_config_pdu->pi2PBSK;
pucch_config_common_nr->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
pucch_config_common_nr->hoppingId = pucch_config_pdu->hoppingId;
pucch_config_common_nr->p0_nominal = pucch_config_pdu->p0_nominal;
/* pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift;
pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols;
pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs;
pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB;
pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC;
pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length;
pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index;
pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping;
pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used
pucch_config_dedicated->formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used
pucch_config_dedicated->formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK;
pucch_config_common->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
pucch_config_common->hoppingId = pucch_config_pdu->hoppingId;
pucch_config_common->p0_nominal = pucch_config_pdu->p0_nominal;*/
for(int j=0; j<2; j++) {
if(pucch_vars->active[j] == false) {
memcpy((void*)&(pucch_vars->pucch_pdu[j]), (void*)pucch_config_pdu, sizeof(fapi_nr_ul_config_pucch_pdu));
found = true;
}
}
if (!found)
LOG_E(PHY, "Couldn't find allocation for PUCCH PDU in PUCCH VARS\n");
break;
case (FAPI_NR_UL_CONFIG_TYPE_PRACH):
......
......@@ -98,43 +98,6 @@
#define DL_DCI (1)
#define UL_DCI (0)
/*******************************************************************
*
* NAME : get_dci_info_for_harq
*
* PARAMETERS : pointer to ue context
* id of current gNB
* number of uplink processes
* maximum number of uplink retransmissions
* RETURN : none
*
* DESCRIPTION : update HARQ entity with information from DCI
* TS 38.212 7.3.1.2 DCI formats for scheduling PDSCH
*
*********************************************************************/
void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted,
NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t slot, uint8_t tx_offset)
{
if (nr_dci_info_extracted->identifier_dci_formats == DL_DCI) {
dlsch[0]->current_harq_pid = nr_dci_info_extracted->harq_process_number;
NR_DL_UE_HARQ_t *dl_harq = dlsch[0]->harq_processes[dlsch[0]->current_harq_pid];
dl_harq->harq_ack.vDAI_DL = nr_dci_info_extracted->dai+1;
dl_harq->harq_ack.pucch_resource_indicator = nr_dci_info_extracted->pucch_resource_ind;
dl_harq->harq_ack.slot_for_feedback_ack = (slot + nr_dci_info_extracted->pdsch_to_harq_feedback_time_ind)%ue->frame_parms.slots_per_subframe;
dl_harq->harq_ack.harq_id = nr_dci_info_extracted->harq_process_number;
dl_harq->harq_ack.rx_status = downlink_harq_process(dl_harq, dlsch[0]->current_harq_pid, nr_dci_info_extracted->ndi, dlsch[0]->rnti_type);
}
else if (nr_dci_info_extracted->identifier_dci_formats == UL_DCI) {
/* store harq id for which pusch should be transmitted at rx_slot + tx_offset */
set_tx_harq_id(ulsch, nr_dci_info_extracted->harq_process_number, (slot + tx_offset)%ue->frame_parms.slots_per_subframe);
ulsch->harq_processes[nr_dci_info_extracted->harq_process_number]->tx_status = uplink_harq_process(ulsch, nr_dci_info_extracted->harq_process_number, nr_dci_info_extracted->ndi, ulsch->rnti_type);
}
}
/*******************************************************************
*
......@@ -345,158 +308,4 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq)
dl_harq->status = SCH_IDLE;
dl_harq->first_tx = 1;
dl_harq->round = 0;
dl_harq->harq_ack.ack = DL_ACKNACK_NO_SET;
dl_harq->harq_ack.send_harq_status = 0;
dl_harq->harq_ack.vDAI_UL = UL_DAI_NO_SET;
dl_harq->harq_ack.vDAI_DL = DL_DAI_NO_SET;
dl_harq->harq_ack.slot_for_feedback_ack = NR_MAX_SLOTS_PER_FRAME;
dl_harq->harq_ack.pucch_resource_indicator = MAX_PUCCH_RESOURCE_INDICATOR;
dl_harq->harq_ack.n_CCE = 0;
dl_harq->harq_ack.N_CCE = 0;;
}
/*******************************************************************
*
* NAME : config_downlink_harq_process
*
* PARAMETERS : pointer to ue context
* id of current gNB
* number of downlink processes
*
* RETURN : none
*
* DESCRIPTION : configuration of downlink HARQ entity
*
*********************************************************************/
void config_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, int execution_thread_number, uint8_t number_harq_processes_for_pdsch)
{
NR_UE_DLSCH_t *dlsch;
dlsch = (NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t));
if (dlsch != NULL) {
memset(dlsch,0,sizeof(NR_UE_DLSCH_t));
ue->dlsch[execution_thread_number][gNB_id][TB_id] = dlsch;
}
else {
LOG_E(PHY, "Fatal memory allocation problem at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__);
assert(0);
}
dlsch->Mdlharq = number_harq_processes_for_pdsch; /* an additional HARQ is reserved for PBCCH */
dlsch->number_harq_processes_for_pdsch = number_harq_processes_for_pdsch;
/* allocation of HARQ process context */
for (int harq_pid = 0; harq_pid < number_harq_processes_for_pdsch; harq_pid++) {
//dlsch->harq_processes[harq_pid] = (NR_DL_UE_HARQ_t *)malloc16(sizeof(NR_DL_UE_HARQ_t));
/*if (dlsch->harq_processes[harq_pid] == NULL) {
LOG_E(PHY, "Fatal memory allocation problem at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__);
assert(0);
}*/
memset(&dlsch->harq_processes[harq_pid],0,sizeof(NR_DL_UE_HARQ_t));
NR_DL_UE_HARQ_t *dl_harq = dlsch->harq_processes[harq_pid];
init_downlink_harq_status(dl_harq);
}
}
/*******************************************************************
*
* NAME : release_downlink_harq_process
*
* PARAMETERS : pointer to ue context
* id of current gNB
* TB_id transport block identity 0 or 1
* execution_thread_number thread number for current downlink processing
* RETURN : none
*
* DESCRIPTION : release of HARQ downlink entity
*
*********************************************************************/
void release_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, int execution_thread_number)
{
NR_UE_DLSCH_t *dlsch = ue->dlsch[execution_thread_number][gNB_id][TB_id];
/*for (int process_id = 0; process_id < dlsch->Mdlharq; process_id++) {
free16(dlsch->harq_processes[process_id],sizeof(NR_DL_UE_HARQ_t));
dlsch->harq_processes[process_id] = NULL;
}*/
free16(dlsch,sizeof(NR_UE_DLSCH_t));
ue->dlsch[execution_thread_number][gNB_id][TB_id] = NULL;
}
/*******************************************************************
*
* NAME : downlink_harq_process
*
* PARAMETERS : downlink harq context
* harq identifier
* ndi (new data indicator) from DCI
* rnti_type from DCI
*
* RETURN : none
*
* DESCRIPTION : manage downlink information from DCI for downlink transmissions/retransmissions
* TS 38.321 5.3.1 DL Assignment reception
* TS 38.321 5.3.2 HARQ operation
*
*********************************************************************/
harq_result_t downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, uint8_t rnti_type)
{
harq_result_t result_harq = RETRANSMISSION_HARQ;
if (rnti_type == _CS_RNTI_)
{
LOG_E(PHY, "Fatal error in HARQ entity due to not supported CS_RNTI at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__);
return(NEW_TRANSMISSION_HARQ);
}
else if ((rnti_type != _C_RNTI_) && (rnti_type != _TC_RNTI_)) {
/* harq mechanism is not relevant for other rnti */
return(NEW_TRANSMISSION_HARQ);
}
if (dl_harq->first_tx == 1) {
dl_harq->round = 0;
dl_harq->status = ACTIVE;
dl_harq->DCINdi = ndi;
dl_harq->first_tx = 0;
result_harq = NEW_TRANSMISSION_HARQ;
LOG_D(PHY, "[HARQ-DL-PDSCH harqId : %d] first new reception \n", harq_pid);
}
else if (dl_harq->DCINdi != ndi) {
dl_harq->round = 0;
dl_harq->status = ACTIVE;
dl_harq->DCINdi = ndi;
result_harq = NEW_TRANSMISSION_HARQ;
LOG_D(PHY, "[HARQ-DL-PDSCH harqId : %d] new reception due to toogle of ndi \n", harq_pid);
}
else {
dl_harq->round++;
if (dl_harq->harq_ack.ack) dl_harq->status = SCH_IDLE;
result_harq = RETRANSMISSION_HARQ;
LOG_D(PHY, "[HARQ-DL-PDSCH harqId : %d] reception of a retransmission \n", harq_pid);
}
return (result_harq);
}
......@@ -46,8 +46,6 @@
#define NR_DEFAULT_DLSCH_HARQ_PROCESSES (8) /* TS 38.214 5.1 */
#define NR_DL_MAX_DAI (4) /* TS 38.213 table 9.1.3-1 Value of counter DAI for DCI format 1_0 and 1_1 */
#define NR_DL_MAX_NB_CW (2) /* number of downlink code word */
#define DL_ACKNACK_NO_SET (2)
#define DL_NACK (0)
#define DL_ACK (1)
......@@ -68,18 +66,6 @@
/*************** FUNCTIONS ****************************************/
/** \brief This function updates HARQ context according to dci
@param PHY_VARS_NR_UE ue context
@param nr_dci_info_extracted extracted information from dci
@param dlsch downlink context
@param ulsch uplink context
@param nr_slot_rx rx slot
@param tx_offset slot offset for tx
@returns none */
void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted,
NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t nr_slot_rx, uint8_t tx_offset);
/** \brief This function configures uplink HARQ context
@param PHY_VARS_NR_UE ue context
@param gNB_id gNodeB identifier
......@@ -127,24 +113,6 @@ harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, int ndi, u
void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq);
/** \brief This function configures downlink HARQ context
@param PHY_VARS_NR_UE ue context
@param gNB_id gNodeB identifier
@param TB_id transport block identifier
@param execution_thread_number thread_number
@param number_harq_processes maximum number of downlink HARQ processes
@returns none */
void config_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, int execution_thread_number, uint8_t number_harq_processes);
/** \brief This function releases downlink HARQ context
@param PHY_VARS_NR_UE ue context
@param gNB_id gNodeB identifier
@param TB_id transport block identifier
@param execution_thread_number thread_number
@returns none */
void release_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, int execution_thread_number);
/** \brief This function update downlink harq context and return reception type (new transmission or retransmission)
@param dlsch downlink harq context
......
......@@ -122,9 +122,10 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
uint8_t gNB_id,
PHY_VARS_NR_UE *ue,
NR_UE_DLSCH_t *dlsch0,
NR_UE_DLSCH_t *dlsch1,
uint16_t n_pdus){
int harq_pid;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
if (n_pdus > 1){
......@@ -133,11 +134,27 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
switch (pdu_type){
case FAPI_NR_RX_PDU_TYPE_SIB:
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.harq_pid = dlsch0->current_harq_pid;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.ack_nack = dlsch0->harq_processes[dlsch0->current_harq_pid]->ack;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dlsch0->harq_processes[dlsch0->current_harq_pid]->b;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS / 8;
break;
case FAPI_NR_RX_PDU_TYPE_DLSCH:
if(dlsch0) {
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.harq_pid = dlsch0->current_harq_pid;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.ack_nack = dlsch0->harq_processes[dlsch0->current_harq_pid]->ack;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dlsch0->harq_processes[dlsch0->current_harq_pid]->b;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS / 8;
}
if(dlsch1) {
AssertFatal(1==0,"Second codeword currently not supported\n");
}
break;
case FAPI_NR_RX_PDU_TYPE_RAR:
harq_pid = dlsch0->current_harq_pid;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS / 8;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.harq_pid = dlsch0->current_harq_pid;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.ack_nack = dlsch0->harq_processes[dlsch0->current_harq_pid]->ack;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dlsch0->harq_processes[dlsch0->current_harq_pid]->b;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS / 8;
break;
case FAPI_NR_RX_PDU_TYPE_SSB:
rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.pdu = ue->pbch_vars[gNB_id]->decoded_output;
......@@ -1018,6 +1035,28 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
}
switch (pdsch) {
case RA_PDSCH:
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, NULL, number_pdus);
ue->UE_mode[gNB_id] = RA_RESPONSE;
break;
case PDSCH:
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, NULL, number_pdus);
break;
case SI_PDSCH:
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, NULL, number_pdus);
break;
default:
break;
}
LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch0->harq_processes[harq_pid]->TBS, dlsch0->harq_processes[harq_pid]->TBS / 8);
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
#if DISABLE_LOG_X
......@@ -1115,42 +1154,18 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
#endif
#endif
LOG_I(PHY,"AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
LOG_D(PHY,"AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch1->harq_processes[harq_pid]->TBS);
}
LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ decoded in %d \n", frame_rx, nr_slot_rx, ret);
LOG_D(PHY, "harq_pid: %d, TBS expected dlsch0: %d \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS);
if(ret<dlsch0->max_ldpc_iterations+1){
switch (pdsch) {
case RA_PDSCH:
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, number_pdus);
ue->UE_mode[gNB_id] = RA_RESPONSE;
break;
case PDSCH:
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, number_pdus);
break;
case SI_PDSCH:
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, number_pdus);
break;
default:
break;
}
LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch0->harq_processes[harq_pid]->TBS, dlsch0->harq_processes[harq_pid]->TBS / 8);
// send to mac
if (ue->if_inst && ue->if_inst->dl_indication) {
ue->if_inst->dl_indication(&dl_indication, ul_time_alignment);
// send to mac
if (ue->if_inst && ue->if_inst->dl_indication) {
ue->if_inst->dl_indication(&dl_indication, ul_time_alignment);
}
}
if (ue->mac_enabled == 1) {
......
/*
* 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.1 (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
*/
/************************************************************************
*
* MODULE : PUCCH power control for UE NR
*
* DESCRIPTION : functions related to PUCCH Transmit power
* TS 38.213 7.2.1 UE behaviour
*
**************************************************************************/
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
#include "PHY/defs_nr_UE.h"
#include "SCHED_NR_UE/pucch_uci_ue_nr.h"
#include "SCHED_NR_UE/pucch_power_control_ue_nr.h"
#include <openair1/PHY/LTE_ESTIMATION/lte_estimation.h>
#include <openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h>
/**************** defines **************************************/
/**************** variables **************************************/
/**************** functions **************************************/
/*******************************************************************
*
* NAME : get_pucch_tx_power_ue
*
* PARAMETERS : ue context
* gNB_id identity
* slots for rx and tx
* pucch_format_nr_t pucch format
* nb_of_prbs number of prb allocated to pucch
* N_sc_ctrl_RB subcarrier control rb related to current pucch format
* N_symb_PUCCH number of pucch symbols excluding those reserved for dmrs
* O_UCI number of bits for UCI Uplink Control Information
* O_SR number of bits for SR scheduling Request
* O_UCI number of bits for CSI Channel State Information
* O_ACK number of bits for HARQ-ACK
* O_CRC number of bits for CRC
* n_HARQ_ACK use for obtaining a PUCCH transmission power
*
* RETURN : pucch power level in dBm
*
* DESCRIPTION : determines pucch transmission power in dBm
* TS 38.213 7.2.1 UE behaviour
*
*********************************************************************/
int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue,
uint8_t gNB_id,
UE_nr_rxtx_proc_t *proc,
pucch_format_nr_t pucch_format,
int nb_of_prbs,
int N_sc_ctrl_RB,
int N_symb_PUCCH,
int O_UCI,
int O_SR,
int O_CSI,
int O_ACK,
int O_CRC,
int n_HARQ_ACK) {
int16_t P_O_NOMINAL_PUCCH = ue->pucch_config_common_nr[gNB_id].p0_nominal;
PUCCH_PowerControl_t *power_config = &ue->pucch_config_dedicated_nr[gNB_id].pucch_PowerControl;
int16_t P_O_UE_PUCCH;
int16_t G_b_f_c = 0;
if (ue->pucch_config_dedicated_nr[gNB_id].spatial_Relation_Info[0] != NULL) { /* FFS TODO NR */
LOG_E(PHY,"PUCCH Spatial relation infos are not yet implemented : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
return (PUCCH_POWER_DEFAULT);
}
if (power_config->p0_Set[0] != NULL) {
P_O_UE_PUCCH = power_config->p0_Set[0]->p0_PUCCH_Value; /* get from index 0 if no spatial relation set */
G_b_f_c = 0;
}
else {
G_b_f_c = ue->dlsch[proc->thread_id][gNB_id][0]->g_pucch;
LOG_D(PHY,"PUCCH Transmit power control command not yet implemented for NR : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
return (PUCCH_POWER_DEFAULT);
}
int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH;
int16_t PL = get_nr_PL(ue->Mod_id, ue->CC_id, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */
int16_t delta_F_PUCCH = power_config->deltaF_PUCCH_f[pucch_format];
int DELTA_TF;
uint16_t N_ref_PUCCH;
/* computing of pucch transmission power adjustment */
switch (pucch_format) {
case pucch_format0_nr:
{
N_ref_PUCCH = 2;
DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH);
break;
}
case pucch_format1_nr:
{
N_ref_PUCCH = N_SYMB_SLOT;
DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH);
break;
}
case pucch_format2_nr:
case pucch_format3_nr:
case pucch_format4_nr:
{
float N_RE = nb_of_prbs * N_sc_ctrl_RB * N_symb_PUCCH;
float K1 = 6;
/* initial phase so no higher layer parameters */
if (ue->UE_mode[gNB_id] != PUSCH) {
if (O_ACK == 0) {
n_HARQ_ACK = 0;
}
else {
n_HARQ_ACK = 1;
}
}
if (O_UCI < 12) {
DELTA_TF = 10 * log10((double)(((K1 * (n_HARQ_ACK + O_SR + O_CSI))/N_RE)));
}
else {
float K2 = 2.4;
float BPRE = (O_ACK + O_SR + O_CSI + O_CRC)/N_RE;
DELTA_TF = 10 * log10((double)(pow(2,(K2*BPRE)) - 1));
}
break;
}
default:
{
LOG_E(PHY,"PUCCH unknown pucch format : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
return (0);
}
}
int k2;
if (power_config->twoPUCCH_PC_AdjustmentStates > 1) {
LOG_E(PHY,"PUCCH power control adjustment states with 2 states not yet implemented : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
return (PUCCH_POWER_DEFAULT);
}
/* response to a detection by the UE of a DCI format 1_0 or DCI format 1_1 */
//int K_PUCCH = 0;
if (O_ACK != 0) {
/* it assumes that PDCCH is in the first symbol of receive slot FFS TDDO NR */
//int slots_gap = (proc->nr_slot_tx > proc->nr_slot_rx ? (proc->nr_slot_tx - proc->nr_slot_rx - 1) : ((proc->nr_slot_tx + ue->frame_parms.slots_per_subframe) - proc->nr_slot_rx - 1));
//K_PUCCH = (slots_gap * (ue->frame_parms.symbols_per_tti)) - 1;
}
else {
/* field k2 is not present - to check k2 of pucch from upper layer FFS TDDO NR */
if (ue->pusch_config.pusch_TimeDomainResourceAllocation[0] == NULL) {
if (ue->frame_parms.numerology_index == 0) {
k2 = 1;
}
else {
k2 = ue->frame_parms.numerology_index;
}
}
else
{
/* get minimum value of k2 */
int i = 0;
int k2_min = 32; /* max value of k2 */
do {
k2 = ue->pusch_config.pusch_TimeDomainResourceAllocation[i]->k2;
if (k2 < k2_min) {
k2_min = k2;
}
i++;
if (i >= MAX_NR_OF_UL_ALLOCATIONS) {
break;
}
} while(ue->pusch_config.pusch_TimeDomainResourceAllocation[i] != NULL);
k2 = k2_min;
}
//K_PUCCH = N_SYMB_SLOT * k2; /* the product of a number of symbols per slot and the minimum of the values provided by higher layer parameter k2 */
}
int contributor = (10 * log10((double)(pow(2,(ue->frame_parms.numerology_index)) * nb_of_prbs)));
int16_t pucch_power = P_O_PUCCH + contributor + PL + delta_F_PUCCH + DELTA_TF + G_b_f_c;
if (pucch_power > ue->tx_power_max_dBm) {
pucch_power = ue->tx_power_max_dBm;
}
NR_TST_PHY_PRINTF("PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n",
pucch_power, contributor, PL, delta_F_PUCCH, DELTA_TF, G_b_f_c);
return (pucch_power);
}
/*
* 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.1 (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
*/
/************************************************************************
*
* MODULE : PUCCH power control for UE NR
*
* DESCRIPTION : functions related to PUCCH Transmit power
* TS 38.213 7.2.1 UE behaviour
*
**************************************************************************/
#ifndef PUCCH_POWER_CONTROL_H
#define PUCCH_POWER_CONTROL_H
/*************** INCLUDE *******************************************/
/*************** DEFINE ********************************************/
#define PUCCH_POWER_DEFAULT (0) /* in dBm */
/*************** VARIABLES *****************************************/
/*************** FUNCTIONS *****************************************/
/** \brief This function returns pucch power level in dBm
@param ue context
@param gNB_id identity
@param slots for rx and tx
@param pucch_format_nr_t pucch format
@param nb_of_prbs number of prb allocated to pucch
@param N_sc_ctrl_RB subcarrier control rb related to current pucch format
@param N_symb_PUCCH number of pucch symbols excluding those reserved for dmrs
@param O_UCI number of bits for UCI Uplink Control Information
@param O_SR number of bits for SR scheduling Request
@param int O_UCI number of bits for CSI Channel State Information
@param O_ACK number of bits for HARQ-ACK
@param O_CRC number of bits for CRC
@param n_HARQ_ACK use for obtaining a PUCCH transmission power
@returns pucch power level in dBm */
int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, pucch_format_nr_t pucch_format,
int nb_of_prbs, int N_sc_ctrl_RB, int N_symb_PUCCH, int O_UCI, int O_SR, int O_CSI, int O_ACK,
int O_CRC, int n_HARQ_ACK);
#endif /* PUCCH_POWER_CONTROL_H */
This diff is collapsed.
......@@ -58,51 +58,12 @@
#define BITS_PER_SYMBOL_BPSK (1) /* 1 bit per symbol for bpsk modulation */
#define BITS_PER_SYMBOL_QPSK (2) /* 2 bits per symbol for bpsk modulation */
/************** VARIABLES *****************************************/
#define NB_SYMBOL_MINUS_FOUR (11)
#define I_PUCCH_NO_ADDITIONAL_DMRS (0)
#define I_PUCCH_ADDITIONAL_DMRS (1)
#define I_PUCCH_NO_HOPPING (0)
#define I_PUCCH_HOPING (1)
/*************** FUNCTIONS ****************************************/
bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, bool reset_harq);
/** \brief This function return number of downlink acknowledgement and its bitmap
@param ue context
@param gNB_id identity
@param slots for rx and tx
@param o_ACK HARQ-ACK information bits
@param n_HARQ_ACK use for obtaining a PUCCH transmission power
@param do_reset reset downlink HARQ context
@returns number of bits of o_ACK */
uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, uint32_t *o_ACK,
int *n_HARQ_ACK, bool do_reset);
/** \brief This function selects a pucch resource
@param ue context
@param gNB_id identity
@param uci size number of uci bits
@param pucch_resource_indicator is from downlink DCI
@param initial_pucch_id pucch resource id for initial phase
@param resource_set_id pucch resource set if any
@param resource_id pucch resource id if any
@returns TRUE a pucch resource has been found FALSE no valid pucch resource */
boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size, int pucch_resource_indicator,
int *initial_pucch_id, int *resource_set_id, int *resource_id, NR_UE_HARQ_STATUS_t *harq_status);
/** \brief This function select a pucch resource set
@param ue context
@param gNB_id identity
@param uci size number of uci bits
@returns number of the pucch resource set */
int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size);
void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue,
uint8_t gNB_id,
UE_nr_rxtx_proc_t *proc);
/** \brief This function check pucch format
@param ue context
......
......@@ -996,12 +996,12 @@ int main(int argc, char **argv)
NR_gNB_DLSCH_t *gNB_dlsch = gNB->dlsch[0][0];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
UE_harq_process->harq_ack.ack = 0;
UE_harq_process->ack = 0;
round = 0;
UE_harq_process->round = round;
UE_harq_process->first_tx = 1;
while ((round<num_rounds) && (UE_harq_process->harq_ack.ack==0)) {
while ((round<num_rounds) && (UE_harq_process->ack==0)) {
memset(RC.nrmac[0]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int));
memset(RC.nrmac[0]->cce_list[1][1],0,MAX_NUM_CCE*sizeof(int));
clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
......@@ -1230,7 +1230,7 @@ int main(int argc, char **argv)
printf("errors_bit = %u (trial %d)\n", errors_bit, trial);
}
roundStats[snrRun]+=((float)round);
if (UE_harq_process->harq_ack.ack==1) effRate += ((float)TBS)/round;
if (UE_harq_process->ack==1) effRate += ((float)TBS)/round;
} // noise trials
blerStats[snrRun] = (float) n_errors / (float) n_trials;
......
......@@ -25,4 +25,5 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
uint8_t gNB_id,
PHY_VARS_NR_UE *ue,
NR_UE_DLSCH_t *dlsch0,
NR_UE_DLSCH_t *dlsch1,
uint16_t n_pdus) {}
......@@ -456,32 +456,8 @@ int main(int argc, char **argv)
bzero(rxdataF[i],14*frame_parms->ofdm_symbol_size*sizeof(int));
}
//configure UE
UE = malloc(sizeof(PHY_VARS_NR_UE));
memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
UE->pucch_config_common_nr->hoppingId = Nid_cell;
//phy_init_nr_top(UE); //called from init_nr_ue_signal
UE->perfect_ce = 0;
if(eps!=0.0)
UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation
if (init_nr_ue_signal(UE, 1, 0) != 0)
{
printf("Error at UE NR initialisation\n");
exit(-1);
}
uint8_t mcs=0;
startingPRB_intraSlotHopping=N_RB_DL-1;
pucch_GroupHopping_t PUCCH_GroupHopping=UE->pucch_config_common_nr->pucch_GroupHopping;
uint32_t hopping_id=UE->pucch_config_common_nr->hoppingId;
uint32_t dmrs_scrambling_id = 0, data_scrambling_id=0;
//t_nrPolar_params *currentPtr;
int shift = 0;
if(format==0){
if (sr_flag)
shift = 1<<nr_bit;
......@@ -495,6 +471,62 @@ int main(int argc, char **argv)
}
else if (format == 2 && nr_bit > 11) gNB->uci_polarParams = nr_polar_params(2, nr_bit, nrofPRB, 1, NULL);
startingPRB_intraSlotHopping=N_RB_DL-1;
uint32_t hopping_id=Nid_cell;
uint32_t dmrs_scrambling_id = 0, data_scrambling_id=0;
//configure UE
UE = malloc(sizeof(PHY_VARS_NR_UE));
memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
fapi_nr_ul_config_pucch_pdu pucch_tx_pdu;
if (format==0) {
pucch_tx_pdu.format_type = 0;
pucch_tx_pdu.nr_of_symbols = nrofSymbols;
pucch_tx_pdu.start_symbol_index = startingSymbolIndex;
pucch_tx_pdu.bwp_start = 0;
pucch_tx_pdu.prb_start = startingPRB;
pucch_tx_pdu.hopping_id = hopping_id;
pucch_tx_pdu.group_hop_flag = 0;
pucch_tx_pdu.sequence_hop_flag = 0;
pucch_tx_pdu.freq_hop_flag = 0;
pucch_tx_pdu.mcs = mcs;
pucch_tx_pdu.initial_cyclic_shift = 0;
pucch_tx_pdu.second_hop_prb = startingPRB_intraSlotHopping;
}
if (format==2) {
pucch_tx_pdu.format_type = 2;
pucch_tx_pdu.rnti = 0x1234;
pucch_tx_pdu.n_bit = nr_bit;
pucch_tx_pdu.payload = actual_payload;
pucch_tx_pdu.nr_of_symbols = nrofSymbols;
pucch_tx_pdu.start_symbol_index = startingSymbolIndex;
pucch_tx_pdu.bwp_start = 0;
pucch_tx_pdu.prb_start = startingPRB;
pucch_tx_pdu.hopping_id = hopping_id;
pucch_tx_pdu.group_hop_flag = 0;
pucch_tx_pdu.sequence_hop_flag = 0;
pucch_tx_pdu.freq_hop_flag = 0;
pucch_tx_pdu.dmrs_scrambling_id = dmrs_scrambling_id;
pucch_tx_pdu.data_scrambling_id = data_scrambling_id;
pucch_tx_pdu.second_hop_prb = startingPRB_intraSlotHopping;
}
UE->perfect_ce = 0;
if(eps!=0.0)
UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation
if (init_nr_ue_signal(UE, 1, 0) != 0)
{
printf("Error at UE NR initialisation\n");
exit(-1);
}
pucch_GroupHopping_t PUCCH_GroupHopping = pucch_tx_pdu.group_hop_flag + (pucch_tx_pdu.sequence_hop_flag<<1);
//t_nrPolar_params *currentPtr;
for(SNR=snr0;SNR<=snr1;SNR=SNR+1){
ack_nack_errors=0;
sr_errors=0;
......@@ -502,13 +534,28 @@ int main(int argc, char **argv)
for (trial=0; trial<n_trials; trial++) {
bzero(txdataF[aa],frame_parms->ofdm_symbol_size*sizeof(int));
if(format==0){
nr_generate_pucch0(UE,txdataF,frame_parms,PUCCH_GroupHopping,hopping_id,amp,nr_slot_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB, 0);
nr_generate_pucch0(UE,
txdataF,
frame_parms,
amp,
nr_slot_tx,
&pucch_tx_pdu);
}
else if (format == 1){
nr_generate_pucch1(UE,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_slot_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit);
nr_generate_pucch1(UE,
txdataF,
frame_parms,
amp,
nr_slot_tx,
&pucch_tx_pdu);
}
else {
nr_generate_pucch2(UE,0x1234,dmrs_scrambling_id,data_scrambling_id,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_slot_tx,nrofSymbols,startingSymbolIndex,nrofPRB,startingPRB,nr_bit);
nr_generate_pucch2(UE,
txdataF,
frame_parms,
amp,
nr_slot_tx,
&pucch_tx_pdu);
}
int txlev = signal_energy(&txdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size],
......
......@@ -3537,6 +3537,83 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
}
uint16_t compute_pucch_prb_size(uint8_t format,
uint8_t nr_prbs,
uint16_t O_tot,
uint16_t O_csi,
NR_PUCCH_MaxCodeRate_t *maxCodeRate,
uint8_t Qm,
uint8_t n_symb,
uint8_t n_re_ctrl) {
uint16_t O_crc;
if (O_tot<12)
O_crc = 0;
else{
if (O_tot<20)
O_crc = 6;
else {
if (O_tot<360)
O_crc = 11;
else
AssertFatal(1==0,"Case for segmented PUCCH not yet implemented");
}
}
int rtimes100;
switch(*maxCodeRate){
case NR_PUCCH_MaxCodeRate_zeroDot08 :
rtimes100 = 8;
break;
case NR_PUCCH_MaxCodeRate_zeroDot15 :
rtimes100 = 15;
break;
case NR_PUCCH_MaxCodeRate_zeroDot25 :
rtimes100 = 25;
break;
case NR_PUCCH_MaxCodeRate_zeroDot35 :
rtimes100 = 35;
break;
case NR_PUCCH_MaxCodeRate_zeroDot45 :
rtimes100 = 45;
break;
case NR_PUCCH_MaxCodeRate_zeroDot60 :
rtimes100 = 60;
break;
case NR_PUCCH_MaxCodeRate_zeroDot80 :
rtimes100 = 80;
break;
default :
AssertFatal(1==0,"Invalid MaxCodeRate");
}
float r = (float)rtimes100/100;
if (O_csi == O_tot) {
if ((O_tot+O_csi)>(nr_prbs*n_re_ctrl*n_symb*Qm*r))
AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with %d PRBs",
r,O_tot,O_crc,nr_prbs);
else
return nr_prbs;
}
if (format==2){
// TODO fix this for multiple CSI reports
for (int i=1; i<=nr_prbs; i++){
if((O_tot+O_crc)<=(i*n_symb*Qm*n_re_ctrl*r) &&
(O_tot+O_crc)>((i-1)*n_symb*Qm*n_re_ctrl*r))
return i;
}
AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with at most %d PRBs",
r,O_tot,O_crc,nr_prbs);
}
else{
AssertFatal(1==0,"Not yet implemented");
}
}
/* extract UL PTRS values from RRC and validate it based upon 38.214 6.2.3 */
bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config,
uint16_t rbSize,uint8_t mcsIndex, uint8_t mcsTable,
......
......@@ -139,6 +139,15 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb);
uint16_t compute_pucch_prb_size(uint8_t format,
uint8_t nr_prbs,
uint16_t O_tot,
uint16_t O_csi,
NR_PUCCH_MaxCodeRate_t *maxCodeRate,
uint8_t Qm,
uint8_t n_symb,
uint8_t n_re_ctrl);
int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH);
bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
......
......@@ -302,6 +302,20 @@ typedef struct {
} RA_config_t;
typedef struct {
bool active;
bool ack_received;
uint8_t pucch_resource_indicator;
uint16_t feedback_to_ul;
frame_t dl_frame;
int dl_slot;
uint8_t ack;
uint8_t dai;
int n_CCE;
int N_CCE;
int8_t delta_pucch;
} NR_UE_HARQ_STATUS_t;
typedef struct {
uint8_t freq_hopping;
......@@ -311,11 +325,27 @@ typedef struct {
} RAR_grant_t;
typedef struct {
int n_HARQ_ACK;
uint32_t ack_payload;
uint8_t sr_payload;
uint32_t csi_part1_payload;
uint32_t csi_part2_payload;
int resource_indicator;
int resource_set_id;
int initial_pucch_id;
NR_PUCCH_Resource_t *pucch_resource;
int n_CCE;
int N_CCE;
int8_t delta_pucch;
} PUCCH_sched_t;
/*!\brief Top level UE MAC structure */
typedef struct {
NR_ServingCellConfigCommon_t *scc;
NR_ServingCellConfigCommonSIB_t *scc_SIB;
NR_ServingCellConfigCommonSIB_t *scc_SIB;
NR_CellGroupConfig_t *cg;
int servCellIndex;
NR_CSI_ReportConfig_t *csirc;
......@@ -391,6 +421,8 @@ typedef struct {
dci_pdu_rel15_t def_dci_pdu_rel15[8];
NR_UE_HARQ_STATUS_t dl_harq_info[16];
} NR_UE_MAC_INST_t;
typedef enum seach_space_mask_e {
......
......@@ -37,6 +37,9 @@
#include "PHY/defs_nr_UE.h"
#include "RRC/NR_UE/rrc_defs.h"
#define NR_DL_MAX_DAI (4) /* TS 38.213 table 9.1.3-1 Value of counter DAI for DCI format 1_0 and 1_1 */
#define NR_DL_MAX_NB_CW (2) /* number of downlink code word */
/**\brief decode mib pdu in NR_UE, from if_module ul_ind with P7 tx_ind message
\param module_id module id
\param cc_id component carrier id
......@@ -135,7 +138,7 @@ uint32_t ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP,
int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe);
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, uint16_t rnti, uint8_t dci_format);
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind);
int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
uint32_t get_ssb_frame(uint32_t test);
......@@ -197,6 +200,58 @@ int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, int mu,
int nrofDownlinkSlots, int nrofDownlinkSymbols,
int nrofUplinkSlots, int nrofUplinkSymbols);
void set_harq_status(NR_UE_MAC_INST_t *mac,
uint8_t pucch_id,
uint8_t harq_id,
int8_t delta_pucch,
uint8_t data_toul_fb,
uint8_t dai,
int n_CCE,
int N_CCE,
frame_t frame,
int slot);
void update_harq_status(nr_downlink_indication_t *dl_info,
int pdu_id);
uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac,
frame_t frame,
int slot,
PUCCH_sched_t *pucch);
int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, int uci_size);
void select_pucch_resource(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t *pucch);
int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
NR_PUCCH_Config_t *pucch_Config,
PUCCH_sched_t *pucch,
uint8_t format_type,
uint16_t nb_of_prbs,
uint8_t freq_hop_flag,
uint8_t add_dmrs_flag,
uint8_t N_symb_PUCCH,
int subframe_number,
int O_ACK, int O_SR,
int O_CSI, int O_CRC);
int get_deltatf(uint16_t nb_of_prbs,
uint8_t N_symb_PUCCH,
uint8_t freq_hop_flag,
uint8_t add_dmrs_flag,
int N_sc_ctrl_RB,
int n_HARQ_ACK,
int O_ACK, int O_SR,
int O_CSI, int O_CRC);
void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
int slot,
uint16_t rnti,
PUCCH_sched_t *pucch,
fapi_nr_ul_config_pucch_pdu *pucch_pdu,
int O_SR, int O_ACK, int O_CSI);
/** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure.
@param Mod_id Module id of UE
@returns Po_NOMINAL_PUSCH (PREAMBLE_RECEIVED_TARGET_POWER+DELTA_PREAMBLE
......@@ -226,6 +281,7 @@ and fills the PRACH PDU per each FD occasion.
@returns void
*/
void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, int thread_id);
void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, int thread_id);
/* \brief This function schedules the Msg3 transmission
@param
......
......@@ -1794,6 +1794,77 @@ void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac) {
LOG_D(NR_MAC,"Map SSB to RO done\n");
}
void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, int thread_id) {
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
int O_SR = 0;
int O_ACK = 0;
int O_CSI = 0;
int N_UCI = 0;
PUCCH_sched_t *pucch = calloc(1,sizeof(*pucch));
pucch->resource_indicator = -1;
pucch->initial_pucch_id = -1;
uint16_t rnti = mac->crnti; //FIXME not sure this is valid for all pucch instances
// SR
// CSI
// ACKNACK
O_ACK = get_downlink_ack(mac, frameP, slotP, pucch);
NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
NR_PUCCH_Config_t *pucch_Config;
if (bwp_id>0 &&
mac->ULbwp[bwp_id-1] &&
mac->ULbwp[bwp_id-1]->bwp_Dedicated &&
mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config &&
mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup) {
pucch_Config = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup;
}
else if (bwp_id==0 &&
mac->cg &&
mac->cg->spCellConfig &&
mac->cg->spCellConfig->spCellConfigDedicated &&
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config &&
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
pucch_Config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
}
else AssertFatal(1==0,"no pucch_Config\n");
// if multiplexing of HARQ and CSI is not possible, transmit only HARQ bits
if ((O_ACK != 0) && (O_ACK != 0) && (pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI == NULL)) {
O_CSI = 0;
pucch->csi_part1_payload = 0;
pucch->csi_part2_payload = 0;
}
N_UCI = O_SR + O_ACK + O_CSI;
if (N_UCI > 0) {
pucch->resource_set_id = find_pucch_resource_set(mac, N_UCI);
select_pucch_resource(mac, pucch);
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu;
nr_ue_configure_pucch(mac,
slotP,
rnti,
pucch,
pucch_pdu,
O_SR, O_ACK, O_CSI);
fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
}
}
// This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x
// PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3.
// - todo:
......
......@@ -1101,7 +1101,7 @@ bool nr_acknack_scheduling(int mod_id,
int UE_id,
frame_t frame,
sub_frame_t slot,
int r_pucch)
int r_pucch)
{
const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
......@@ -1355,81 +1355,6 @@ void csi_period_offset(const NR_CSI_ReportConfig_t *csirep,
}
}
uint16_t compute_pucch_prb_size(uint8_t format,
uint8_t nr_prbs,
uint16_t O_tot,
uint16_t O_csi,
NR_PUCCH_MaxCodeRate_t *maxCodeRate,
uint8_t Qm,
uint8_t n_symb,
uint8_t n_re_ctrl) {
uint16_t O_crc;
if (O_tot<12)
O_crc = 0;
else{
if (O_tot<20)
O_crc = 6;
else {
if (O_tot<360)
O_crc = 11;
else
AssertFatal(1==0,"Case for segmented PUCCH not yet implemented");
}
}
int rtimes100;
switch(*maxCodeRate){
case NR_PUCCH_MaxCodeRate_zeroDot08 :
rtimes100 = 8;
break;
case NR_PUCCH_MaxCodeRate_zeroDot15 :
rtimes100 = 15;
break;
case NR_PUCCH_MaxCodeRate_zeroDot25 :
rtimes100 = 25;
break;
case NR_PUCCH_MaxCodeRate_zeroDot35 :
rtimes100 = 35;
break;
case NR_PUCCH_MaxCodeRate_zeroDot45 :
rtimes100 = 45;
break;
case NR_PUCCH_MaxCodeRate_zeroDot60 :
rtimes100 = 60;
break;
case NR_PUCCH_MaxCodeRate_zeroDot80 :
rtimes100 = 80;
break;
default :
AssertFatal(1==0,"Invalid MaxCodeRate");
}
float r = (float)rtimes100/100;
if (O_csi == O_tot) {
if ((O_tot+O_csi)>(nr_prbs*n_re_ctrl*n_symb*Qm*r))
AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with %d PRBs",
r,O_tot,O_crc,nr_prbs);
else
return nr_prbs;
}
if (format==2){
// TODO fix this for multiple CSI reports
for (int i=1; i<=nr_prbs; i++){
if((O_tot+O_crc)<=(i*n_symb*Qm*n_re_ctrl*r) &&
(O_tot+O_crc)>((i-1)*n_symb*Qm*n_re_ctrl*r))
return i;
}
AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with at most %d PRBs",
r,O_tot,O_crc,nr_prbs);
}
else{
AssertFatal(1==0,"Not yet implemented");
}
}
void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
{
......
......@@ -327,15 +327,6 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
int m,
int nr_of_candidates);
uint16_t compute_pucch_prb_size(uint8_t format,
uint8_t nr_prbs,
uint16_t O_tot,
uint16_t O_csi,
NR_PUCCH_MaxCodeRate_t *maxCodeRate,
uint8_t Qm,
uint8_t n_symb,
uint8_t n_re_ctrl);
int nr_get_default_pucch_res(int pucch_ResourceCommon);
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_info, int UE_id, module_id_t Mod_idP);
......
......@@ -81,6 +81,7 @@ int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t
// Note: sdu should always be processed because data and timing advance updates are transmitted by the UE
int8_t handle_dlsch (nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){
update_harq_status(dl_info, pdu_id);
nr_ue_send_sdu(dl_info, ul_time_alignment, pdu_id);
return 0;
......@@ -98,9 +99,12 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon = mac->scc != NULL ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon;
if (is_nr_UL_slot(tdd_UL_DL_ConfigurationCommon, ul_info->slot_tx, mac->frame_type) /*&& get_softmodem_params()->do_ra*/)
if (is_nr_UL_slot(tdd_UL_DL_ConfigurationCommon, ul_info->slot_tx, mac->frame_type) && !get_softmodem_params()->phy_test)
nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->thread_id);
if (is_nr_UL_slot(tdd_UL_DL_ConfigurationCommon, ul_info->slot_tx, mac->frame_type))
nr_ue_pucch_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->thread_id);
switch(ret){
case UE_CONNECTION_OK:
break;
......@@ -178,10 +182,10 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
case FAPI_NR_RX_PDU_TYPE_SIB:
ret_mask |= (handle_bcch_dlsch(dl_info->module_id,
dl_info->cc_id, dl_info->gNB_index,
(dl_info->rx_ind->rx_indication_body+i)->sib_pdu.sibs_mask,
(dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu,
(dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB;
dl_info->cc_id, dl_info->gNB_index,
(dl_info->rx_ind->rx_indication_body+i)->sib_pdu.sibs_mask,
(dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu,
(dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB;
break;
......
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