PUSCH power control state
This commit is contained in:
@@ -359,7 +359,6 @@ typedef struct
|
|||||||
//beamforming
|
//beamforming
|
||||||
nfapi_nr_ue_ul_beamforming_t beamforming;
|
nfapi_nr_ue_ul_beamforming_t beamforming;
|
||||||
//OAI specific
|
//OAI specific
|
||||||
int8_t absolute_delta_PUSCH;
|
|
||||||
int16_t tx_power;
|
int16_t tx_power;
|
||||||
fapi_nr_tx_request_body_t tx_request_body;
|
fapi_nr_tx_request_body_t tx_request_body;
|
||||||
} nfapi_nr_ue_pusch_pdu_t;
|
} nfapi_nr_ue_pusch_pdu_t;
|
||||||
|
|||||||
@@ -1119,7 +1119,6 @@ int main(int argc, char *argv[])
|
|||||||
pusch_config_pdu->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
|
pusch_config_pdu->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
|
||||||
pusch_config_pdu->nrOfLayers = precod_nbr_layers;
|
pusch_config_pdu->nrOfLayers = precod_nbr_layers;
|
||||||
pusch_config_pdu->dmrs_ports = ((1 << precod_nbr_layers) - 1);
|
pusch_config_pdu->dmrs_ports = ((1 << precod_nbr_layers) - 1);
|
||||||
pusch_config_pdu->absolute_delta_PUSCH = 0;
|
|
||||||
pusch_config_pdu->target_code_rate = code_rate;
|
pusch_config_pdu->target_code_rate = code_rate;
|
||||||
pusch_config_pdu->tbslbrm = tbslbrm;
|
pusch_config_pdu->tbslbrm = tbslbrm;
|
||||||
pusch_config_pdu->ldpcBaseGraph = get_BG(TBS, code_rate);
|
pusch_config_pdu->ldpcBaseGraph = get_BG(TBS, code_rate);
|
||||||
|
|||||||
@@ -593,6 +593,8 @@ typedef struct NR_UE_MAC_INST_s {
|
|||||||
// PUCCH closed loop power control state
|
// PUCCH closed loop power control state
|
||||||
int G_b_f_c;
|
int G_b_f_c;
|
||||||
bool pucch_power_control_initialized;
|
bool pucch_power_control_initialized;
|
||||||
|
int f_b_f_c;
|
||||||
|
bool pusch_power_control_initialized;
|
||||||
} NR_UE_MAC_INST_t;
|
} NR_UE_MAC_INST_t;
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
|
|||||||
memset(&mac->scheduling_info.sr_info[i], 0, sizeof(mac->scheduling_info.sr_info[i]));
|
memset(&mac->scheduling_info.sr_info[i], 0, sizeof(mac->scheduling_info.sr_info[i]));
|
||||||
|
|
||||||
mac->pucch_power_control_initialized = false;
|
mac->pucch_power_control_initialized = false;
|
||||||
|
mac->pusch_power_control_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
|
void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
|
||||||
|
|||||||
@@ -553,12 +553,28 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
|||||||
|
|
||||||
// TODO: compute pathoss using correct reference
|
// TODO: compute pathoss using correct reference
|
||||||
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
||||||
|
int P_CMIN = nr_get_Pcmin(mac->current_UL_BWP->scs, mac->nr_band, mac->current_UL_BWP->BWPSize);
|
||||||
|
|
||||||
|
float pusch_power_without_f_b_f_c = P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF;
|
||||||
|
|
||||||
int f_b_f_c = 0;
|
int f_b_f_c = 0;
|
||||||
if (has_pusch_power_control_config && pusch_Config->pusch_PowerControl->tpc_Accumulation) {
|
if (has_pusch_power_control_config && pusch_Config->pusch_PowerControl->tpc_Accumulation) {
|
||||||
f_b_f_c = delta_pusch;
|
f_b_f_c = delta_pusch;
|
||||||
} else {
|
} else {
|
||||||
// TODO: PUSCH power control state
|
if (!mac->pusch_power_control_initialized && is_rar_tx_retx) {
|
||||||
|
NR_PRACH_RESOURCES_t* prach_resources = &mac->ra.prach_resources;
|
||||||
|
float DELTA_P_rampup_requested = (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP;
|
||||||
|
float DELTA_P_rampup = P_CMAX - (P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF + delta_pusch);
|
||||||
|
DELTA_P_rampup = min(DELTA_P_rampup_requested, max(0, DELTA_P_rampup));
|
||||||
|
mac->f_b_f_c = DELTA_P_rampup + delta_pusch;
|
||||||
|
mac->pusch_power_control_initialized = true;
|
||||||
|
} else {
|
||||||
|
if (!((pusch_power_without_f_b_f_c + mac->f_b_f_c >= P_CMAX && delta_pusch > 0) ||
|
||||||
|
(pusch_power_without_f_b_f_c + mac->f_b_f_c <= P_CMIN && delta_pusch < 0))) {
|
||||||
|
mac->f_b_f_c += delta_pusch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f_b_f_c = mac->f_b_f_c;
|
||||||
}
|
}
|
||||||
LOG_D(NR_MAC,
|
LOG_D(NR_MAC,
|
||||||
"PUSCH tx power components P_O_PUSCH=%d, M_pusch_component=%d, alpha*pathloss=%f, delta_TF=%f, f_b_f_c=%d\n",
|
"PUSCH tx power components P_O_PUSCH=%d, M_pusch_component=%d, alpha*pathloss=%f, delta_TF=%f, f_b_f_c=%d\n",
|
||||||
|
|||||||
@@ -793,20 +793,6 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
|||||||
pusch_config_pdu->pusch_data.rv_index = dci->rv;
|
pusch_config_pdu->pusch_data.rv_index = dci->rv;
|
||||||
/* HARQ_PROCESS_NUMBER */
|
/* HARQ_PROCESS_NUMBER */
|
||||||
pusch_config_pdu->pusch_data.harq_process_id = dci->harq_pid;
|
pusch_config_pdu->pusch_data.harq_process_id = dci->harq_pid;
|
||||||
/* TPC_PUSCH */
|
|
||||||
// according to TS 38.213 Table Table 7.1.1-1
|
|
||||||
if (dci->tpc == 0) {
|
|
||||||
pusch_config_pdu->absolute_delta_PUSCH = -4;
|
|
||||||
}
|
|
||||||
if (dci->tpc == 1) {
|
|
||||||
pusch_config_pdu->absolute_delta_PUSCH = -1;
|
|
||||||
}
|
|
||||||
if (dci->tpc == 2) {
|
|
||||||
pusch_config_pdu->absolute_delta_PUSCH = 1;
|
|
||||||
}
|
|
||||||
if (dci->tpc == 3) {
|
|
||||||
pusch_config_pdu->absolute_delta_PUSCH = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NR_DMRS_ulconfig != NULL)
|
if (NR_DMRS_ulconfig != NULL)
|
||||||
add_pos = (NR_DMRS_ulconfig->dmrs_AdditionalPosition == NULL) ? 2 : *NR_DMRS_ulconfig->dmrs_AdditionalPosition;
|
add_pos = (NR_DMRS_ulconfig->dmrs_AdditionalPosition == NULL) ? 2 : *NR_DMRS_ulconfig->dmrs_AdditionalPosition;
|
||||||
@@ -913,6 +899,22 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
|||||||
pusch_config_pdu->pusch_data.tb_size = mac->ul_harq_info[pid].TBS;
|
pusch_config_pdu->pusch_data.tb_size = mac->ul_harq_info[pid].TBS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TPC_PUSCH */
|
||||||
|
int delta_pusch = 0;
|
||||||
|
if (dci) {
|
||||||
|
bool stateless_pusch_power_control = mac->current_UL_BWP->pusch_Config != NULL
|
||||||
|
&& mac->current_UL_BWP->pusch_Config->pusch_PowerControl != NULL
|
||||||
|
&& mac->current_UL_BWP->pusch_Config->pusch_PowerControl->tpc_Accumulation != NULL;
|
||||||
|
int table_38_213_7_1_1_1[2][4] = {{-1, 0, 1, 3}, {-4, -1, 1, 4}};
|
||||||
|
if (stateless_pusch_power_control) {
|
||||||
|
delta_pusch = table_38_213_7_1_1_1[1][dci->tpc];
|
||||||
|
} else {
|
||||||
|
// TODO: This is not entirely correct. In case there is a prevously scheduled PUSCH for a future slot
|
||||||
|
// we should apply its TPC now.
|
||||||
|
delta_pusch = table_38_213_7_1_1_1[0][dci->tpc];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool is_rar_tx_retx = rnti_type == TYPE_TC_RNTI_;
|
bool is_rar_tx_retx = rnti_type == TYPE_TC_RNTI_;
|
||||||
|
|
||||||
pusch_config_pdu->tx_power = get_pusch_tx_power_ue(mac,
|
pusch_config_pdu->tx_power = get_pusch_tx_power_ue(mac,
|
||||||
@@ -925,7 +927,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
|||||||
pusch_config_pdu->target_code_rate,
|
pusch_config_pdu->target_code_rate,
|
||||||
pusch_config_pdu->pusch_uci.beta_offset_csi1,
|
pusch_config_pdu->pusch_uci.beta_offset_csi1,
|
||||||
pusch_config_pdu->pusch_data.tb_size << 3,
|
pusch_config_pdu->pusch_data.tb_size << 3,
|
||||||
pusch_config_pdu->absolute_delta_PUSCH,
|
delta_pusch,
|
||||||
is_rar_tx_retx,
|
is_rar_tx_retx,
|
||||||
pusch_config_pdu->transform_precoding);
|
pusch_config_pdu->transform_precoding);
|
||||||
|
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
|
|||||||
NR_PUSCH_PowerControl pusch_PowerControl = {0};
|
NR_PUSCH_PowerControl pusch_PowerControl = {0};
|
||||||
pusch_Config.pusch_PowerControl = &pusch_PowerControl;
|
pusch_Config.pusch_PowerControl = &pusch_PowerControl;
|
||||||
pusch_PowerControl.tpc_Accumulation = (long*)1;
|
pusch_PowerControl.tpc_Accumulation = (long*)1;
|
||||||
|
mac.pusch_power_control_initialized = true;
|
||||||
mac.frame_type = TDD;
|
mac.frame_type = TDD;
|
||||||
|
|
||||||
// msg3 cofiguration as in 5g_rfsimulator testcase
|
// msg3 cofiguration as in 5g_rfsimulator testcase
|
||||||
@@ -358,6 +359,143 @@ TEST(pusch_power_control, pusch_power_data)
|
|||||||
EXPECT_EQ(power, P_CMAX) << "Expecting max tx power because of deltaMCS with CSI-only";
|
EXPECT_EQ(power, P_CMAX) << "Expecting max tx power because of deltaMCS with CSI-only";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(pusch_power_control, pusch_power_control_state_initialization)
|
||||||
|
{
|
||||||
|
NR_UE_MAC_INST_t mac = {0};
|
||||||
|
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
||||||
|
current_UL_BWP.scs = 1;
|
||||||
|
current_UL_BWP.BWPSize = 106;
|
||||||
|
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||||
|
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
||||||
|
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
||||||
|
mac.nr_band = 78;
|
||||||
|
NR_PUSCH_Config_t pusch_Config = {0};
|
||||||
|
current_UL_BWP.pusch_Config = &pusch_Config;
|
||||||
|
NR_PUSCH_PowerControl pusch_PowerControl = {0};
|
||||||
|
pusch_Config.pusch_PowerControl = &pusch_PowerControl;
|
||||||
|
mac.pusch_power_control_initialized = false;
|
||||||
|
|
||||||
|
// msg3 cofiguration as in 5g_rfsimulator testcase
|
||||||
|
int num_rb = 8;
|
||||||
|
int start_prb = 0;
|
||||||
|
uint16_t nb_symb_sch = 3;
|
||||||
|
uint16_t nb_dmrs_prb = 12;
|
||||||
|
uint16_t nb_ptrs_prb = 0;
|
||||||
|
uint16_t Qm = 2;
|
||||||
|
uint16_t R = 1570;
|
||||||
|
uint16_t beta_offset_csi1 = 0;
|
||||||
|
uint32_t sum_bits_in_codeblocks = 56;
|
||||||
|
int delta_pusch = 0;
|
||||||
|
bool is_rar_tx_retx = true;
|
||||||
|
long preambleReceivedTargetPower = -96;
|
||||||
|
nr_rach_ConfigCommon.rach_ConfigGeneric.preambleReceivedTargetPower = preambleReceivedTargetPower;
|
||||||
|
|
||||||
|
get_pusch_tx_power_ue(&mac,
|
||||||
|
num_rb,
|
||||||
|
start_prb,
|
||||||
|
nb_symb_sch,
|
||||||
|
nb_dmrs_prb,
|
||||||
|
nb_ptrs_prb,
|
||||||
|
Qm,
|
||||||
|
R,
|
||||||
|
beta_offset_csi1,
|
||||||
|
sum_bits_in_codeblocks,
|
||||||
|
delta_pusch,
|
||||||
|
is_rar_tx_retx,
|
||||||
|
false);
|
||||||
|
EXPECT_EQ(mac.pusch_power_control_initialized, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(pusch_power_control, pusch_power_control_state)
|
||||||
|
{
|
||||||
|
NR_UE_MAC_INST_t mac = {0};
|
||||||
|
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
||||||
|
current_UL_BWP.scs = 1;
|
||||||
|
current_UL_BWP.BWPSize = 106;
|
||||||
|
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||||
|
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
||||||
|
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
||||||
|
mac.nr_band = 78;
|
||||||
|
mac.f_b_f_c = 0;
|
||||||
|
mac.pusch_power_control_initialized = true;
|
||||||
|
|
||||||
|
bool is_rar_tx_retx = false;
|
||||||
|
int num_rb = 5;
|
||||||
|
int start_prb = 0;
|
||||||
|
uint16_t nb_symb_sch = 3;
|
||||||
|
uint16_t nb_dmrs_prb = 6;
|
||||||
|
uint16_t nb_ptrs_prb = 0;
|
||||||
|
uint16_t Qm = 2;
|
||||||
|
uint16_t R = 6790;
|
||||||
|
uint16_t beta_offset_csi1 = 0;
|
||||||
|
uint32_t sum_bits_in_codeblocks = 192;
|
||||||
|
int delta_pusch = 1;
|
||||||
|
bool transform_precoding = false;
|
||||||
|
NR_PUSCH_Config_t pusch_Config = {0};
|
||||||
|
current_UL_BWP.pusch_Config = &pusch_Config;
|
||||||
|
NR_PUSCH_PowerControl pusch_PowerControl = {0};
|
||||||
|
pusch_Config.pusch_PowerControl = &pusch_PowerControl;
|
||||||
|
long p0_NominalWithGrant = 0;
|
||||||
|
current_UL_BWP.p0_NominalWithGrant = &p0_NominalWithGrant;
|
||||||
|
mac.frame_type = TDD;
|
||||||
|
|
||||||
|
int P_CMAX = nr_get_Pcmax(23, mac.nr_band, mac.frame_type, FR1, Qm, false, current_UL_BWP.scs, current_UL_BWP.BWPSize, transform_precoding, num_rb, start_prb);
|
||||||
|
|
||||||
|
int power = get_pusch_tx_power_ue(&mac,
|
||||||
|
num_rb,
|
||||||
|
start_prb,
|
||||||
|
nb_symb_sch,
|
||||||
|
nb_dmrs_prb,
|
||||||
|
nb_ptrs_prb,
|
||||||
|
Qm,
|
||||||
|
R,
|
||||||
|
beta_offset_csi1,
|
||||||
|
sum_bits_in_codeblocks,
|
||||||
|
delta_pusch,
|
||||||
|
is_rar_tx_retx,
|
||||||
|
transform_precoding);
|
||||||
|
EXPECT_LE(power, P_CMAX);
|
||||||
|
EXPECT_EQ(power, 11);
|
||||||
|
for (int i = 0; i < 20; i++) {
|
||||||
|
int increased_power = get_pusch_tx_power_ue(&mac,
|
||||||
|
num_rb,
|
||||||
|
start_prb,
|
||||||
|
nb_symb_sch,
|
||||||
|
nb_dmrs_prb,
|
||||||
|
nb_ptrs_prb,
|
||||||
|
Qm,
|
||||||
|
R,
|
||||||
|
beta_offset_csi1,
|
||||||
|
sum_bits_in_codeblocks,
|
||||||
|
delta_pusch,
|
||||||
|
is_rar_tx_retx,
|
||||||
|
transform_precoding);
|
||||||
|
EXPECT_GE(increased_power, power);
|
||||||
|
EXPECT_LE(increased_power, P_CMAX);
|
||||||
|
power = increased_power;
|
||||||
|
}
|
||||||
|
|
||||||
|
delta_pusch = -1;
|
||||||
|
for (int i = 0; i < 20; i++) {
|
||||||
|
int reduced_power = get_pusch_tx_power_ue(&mac,
|
||||||
|
num_rb,
|
||||||
|
start_prb,
|
||||||
|
nb_symb_sch,
|
||||||
|
nb_dmrs_prb,
|
||||||
|
nb_ptrs_prb,
|
||||||
|
Qm,
|
||||||
|
R,
|
||||||
|
beta_offset_csi1,
|
||||||
|
sum_bits_in_codeblocks,
|
||||||
|
delta_pusch,
|
||||||
|
is_rar_tx_retx,
|
||||||
|
transform_precoding);
|
||||||
|
EXPECT_LE(reduced_power, power);
|
||||||
|
EXPECT_LE(reduced_power, P_CMAX);
|
||||||
|
power = reduced_power;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
logInit();
|
logInit();
|
||||||
|
|||||||
Reference in New Issue
Block a user