PUSCH power control state
This commit is contained in:
@@ -359,7 +359,6 @@ typedef struct
|
||||
//beamforming
|
||||
nfapi_nr_ue_ul_beamforming_t beamforming;
|
||||
//OAI specific
|
||||
int8_t absolute_delta_PUSCH;
|
||||
int16_t tx_power;
|
||||
fapi_nr_tx_request_body_t tx_request_body;
|
||||
} 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->nrOfLayers = precod_nbr_layers;
|
||||
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->tbslbrm = tbslbrm;
|
||||
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
|
||||
int G_b_f_c;
|
||||
bool pucch_power_control_initialized;
|
||||
int f_b_f_c;
|
||||
bool pusch_power_control_initialized;
|
||||
} 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]));
|
||||
|
||||
mac->pucch_power_control_initialized = false;
|
||||
mac->pusch_power_control_initialized = false;
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
if (has_pusch_power_control_config && pusch_Config->pusch_PowerControl->tpc_Accumulation) {
|
||||
f_b_f_c = delta_pusch;
|
||||
} 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,
|
||||
"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;
|
||||
/* HARQ_PROCESS_NUMBER */
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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_;
|
||||
|
||||
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->pusch_uci.beta_offset_csi1,
|
||||
pusch_config_pdu->pusch_data.tb_size << 3,
|
||||
pusch_config_pdu->absolute_delta_PUSCH,
|
||||
delta_pusch,
|
||||
is_rar_tx_retx,
|
||||
pusch_config_pdu->transform_precoding);
|
||||
|
||||
|
||||
@@ -198,6 +198,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
|
||||
NR_PUSCH_PowerControl pusch_PowerControl = {0};
|
||||
pusch_Config.pusch_PowerControl = &pusch_PowerControl;
|
||||
pusch_PowerControl.tpc_Accumulation = (long*)1;
|
||||
mac.pusch_power_control_initialized = true;
|
||||
mac.frame_type = TDD;
|
||||
|
||||
// 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";
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
logInit();
|
||||
|
||||
Reference in New Issue
Block a user