|
|
|
@@ -63,6 +63,32 @@ const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon
|
|
|
|
|
return 0; // if FDD or not mixed slot in TDD, for now use default TDA (TODO handle CSI-RS slots)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int compute_bw_factor(int mu, int rb) {
|
|
|
|
|
// 38.213 7.1.1
|
|
|
|
|
return (10 * log10(rb << mu));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int compute_delta_tf(int tbs_bits,
|
|
|
|
|
int rb,
|
|
|
|
|
int n_layers,
|
|
|
|
|
int n_symbols,
|
|
|
|
|
int n_dmrs,
|
|
|
|
|
long *deltaMCS) {
|
|
|
|
|
|
|
|
|
|
// 38.213 7.1.1
|
|
|
|
|
// if the PUSCH transmission is over more than one layer delta_tf = 0
|
|
|
|
|
if(deltaMCS == NULL || n_layers>1)
|
|
|
|
|
return 0;
|
|
|
|
|
else
|
|
|
|
|
AssertFatal(1==0,"Compute DeltaTF not yet fully supported\n");
|
|
|
|
|
|
|
|
|
|
const int n_re = (NR_NB_SC_PER_RB * n_symbols - n_dmrs) * rb;
|
|
|
|
|
const int BPRE = tbs_bits/n_re; //TODO change for PUSCH with CSI
|
|
|
|
|
const float f = pow(2, (float) BPRE * 1.25);
|
|
|
|
|
const float beta = 1.0f; //TODO change for PUSCH with CSI
|
|
|
|
|
return(10 * log10((f - 1) * beta));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For both UL-SCH except:
|
|
|
|
|
// - UL-SCH: fixed-size MAC CE(known by LCID)
|
|
|
|
|
// - UL-SCH: padding
|
|
|
|
@@ -93,14 +119,15 @@ int nr_process_mac_pdu(instance_t module_idP,
|
|
|
|
|
frame_t frameP,
|
|
|
|
|
sub_frame_t slot,
|
|
|
|
|
uint8_t *pduP,
|
|
|
|
|
int pdu_len)
|
|
|
|
|
int pdu_len,
|
|
|
|
|
const int8_t harq_pid)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
uint8_t done = 0;
|
|
|
|
|
|
|
|
|
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
|
|
|
|
|
|
|
|
|
if ( pduP[0] != UL_SCH_LCID_PADDING )
|
|
|
|
|
if (pduP[0] != UL_SCH_LCID_PADDING)
|
|
|
|
|
trace_NRpdu(DIRECTION_UPLINK, pduP, pdu_len, WS_C_RNTI, UE->rnti, frameP, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
|
|
|
@@ -209,6 +236,8 @@ int nr_process_mac_pdu(instance_t module_idP,
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case UL_SCH_LCID_SINGLE_ENTRY_PHR:
|
|
|
|
|
AssertFatal(harq_pid>-1,"Invalid HARQ PID %d\n",harq_pid);
|
|
|
|
|
NR_sched_pusch_t *sched_pusch = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch;;
|
|
|
|
|
//38.321 section 6.1.3.8
|
|
|
|
|
//fixed length
|
|
|
|
|
mac_len = 2;
|
|
|
|
@@ -216,13 +245,23 @@ int nr_process_mac_pdu(instance_t module_idP,
|
|
|
|
|
ce_ptr = &pduP[mac_subheader_len];
|
|
|
|
|
NR_SINGLE_ENTRY_PHR_MAC_CE *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr;
|
|
|
|
|
/* Save the phr info */
|
|
|
|
|
const int PH = phr->PH;
|
|
|
|
|
int PH;
|
|
|
|
|
const int PCMAX = phr->PCMAX;
|
|
|
|
|
/* 38.133 Table10.1.17.1-1 */
|
|
|
|
|
if (PH < 55)
|
|
|
|
|
sched_ctrl->ph = PH - 32;
|
|
|
|
|
if (phr->PH < 55)
|
|
|
|
|
PH = phr->PH - 32;
|
|
|
|
|
else
|
|
|
|
|
sched_ctrl->ph = PH - 32 + (PH - 54);
|
|
|
|
|
PH = phr->PH - 32 + (phr->PH - 54);
|
|
|
|
|
// in sched_ctrl we set normalized PH wrt MCS and PRBs
|
|
|
|
|
long* deltaMCS = sched_ctrl->pusch_semi_static.pusch_Config->pusch_PowerControl->deltaMCS;
|
|
|
|
|
sched_ctrl->ph = PH +
|
|
|
|
|
compute_bw_factor(sched_pusch->mu, sched_pusch->rbSize) +
|
|
|
|
|
compute_delta_tf(sched_pusch->tb_size<<3,
|
|
|
|
|
sched_pusch->rbSize,
|
|
|
|
|
0, //n_layers
|
|
|
|
|
0, //n_symbols
|
|
|
|
|
0, //n_dmrs
|
|
|
|
|
deltaMCS);
|
|
|
|
|
/* 38.133 Table10.1.18.1-1 */
|
|
|
|
|
sched_ctrl->pcmax = PCMAX - 29;
|
|
|
|
|
LOG_D(NR_MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n",
|
|
|
|
@@ -564,7 +603,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
|
|
|
|
if (UE_scheduling_control->sched_ul_bytes < 0)
|
|
|
|
|
UE_scheduling_control->sched_ul_bytes = 0;
|
|
|
|
|
|
|
|
|
|
nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP);
|
|
|
|
|
nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP, harq_pid);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid];
|
|
|
|
@@ -691,7 +730,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
|
|
|
|
// First byte corresponds to R/LCID MAC sub-header
|
|
|
|
|
memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6);
|
|
|
|
|
|
|
|
|
|
if (nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP) == 0) {
|
|
|
|
|
if (nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP, -1) == 0) {
|
|
|
|
|
ra->state = Msg4;
|
|
|
|
|
ra->Msg4_frame = (frameP + 2) % 1024;
|
|
|
|
|
ra->Msg4_slot = 1;
|
|
|
|
@@ -875,34 +914,6 @@ static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc,
|
|
|
|
|
return has_data || sched_ctrl->SR || high_inactivity;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int estimate_nr_ue_tx_power(int mu, uint32_t tbs_bits, int code_rate, int rb, int n_symbols)
|
|
|
|
|
{
|
|
|
|
|
/* see TS 38.213 Sec 7.1.1 */
|
|
|
|
|
|
|
|
|
|
const unsigned int CRC = (tbs_bits >> 3) > 3824 ? 24 : 16; /* from nr_dlsch_encoding(): 24 or 16 bits CRC */
|
|
|
|
|
const unsigned int B = tbs_bits + CRC;
|
|
|
|
|
unsigned int C; /* number of code blocks */
|
|
|
|
|
unsigned int K; /* total code block size */
|
|
|
|
|
unsigned int Zout; /* unused */
|
|
|
|
|
unsigned int F; /* unused */
|
|
|
|
|
/* to scale MCS 20 and 26 in 214 Tab 5.1.3.1-2 (decimal and input 2* in * nr_target_code_rate_table2) */
|
|
|
|
|
const float targetCodeRate = code_rate < 1000 ? (float) code_rate / 1024.0f : (float) code_rate / 2048.0f;
|
|
|
|
|
const unsigned int BG = get_BG(tbs_bits, targetCodeRate);
|
|
|
|
|
const int32_t Kb = nr_segmentation(NULL, NULL, B, &C, &K, &Zout, &F, BG);
|
|
|
|
|
AssertFatal(Kb >= 0, "problem with segmentation for B %d BG %d\n", B, BG);
|
|
|
|
|
|
|
|
|
|
const unsigned int Nre = 12 * rb * n_symbols;
|
|
|
|
|
const unsigned int BPRE = C * K / Nre;
|
|
|
|
|
const float f = pow(2, (float) BPRE * 1.25);
|
|
|
|
|
const float beta = 1.0f;
|
|
|
|
|
const int delta_tf = 10 * log10((f - 1) * beta);
|
|
|
|
|
|
|
|
|
|
const int bw_factor = 10 * log10(rb << mu);
|
|
|
|
|
LOG_D(NR_MAC, "estimated UE TX power %d (Nre %d C %d K %d Nre %d BPRE %d delta_tf %d rb %d bw_factor %d)\n",
|
|
|
|
|
bw_factor + delta_tf, Nre, C, K, Nre, BPRE, delta_tf, rb, bw_factor);
|
|
|
|
|
return bw_factor + delta_tf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void update_ul_ue_R_Qm(int mcs, const NR_pusch_semi_static_t *ps, uint16_t *R, uint8_t *Qm)
|
|
|
|
|
{
|
|
|
|
|
*R = nr_get_code_rate_ul(mcs, ps->mcs_table);
|
|
|
|
@@ -914,31 +925,49 @@ void update_ul_ue_R_Qm(int mcs, const NR_pusch_semi_static_t *ps, uint16_t *R, u
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int nr_ue_max_mcs_min_rb(int mu, int ph, NR_pusch_semi_static_t *ps, uint16_t minRb, int tbs, uint16_t *maxRb, uint8_t *mcs)
|
|
|
|
|
void nr_ue_max_mcs_min_rb(int mu, int ph, NR_pusch_semi_static_t *ps, long* deltaMCS, uint16_t minRb, uint32_t tbs, uint16_t *Rb, uint8_t *mcs)
|
|
|
|
|
{
|
|
|
|
|
AssertFatal(*maxRb >= minRb, "illegal maxRb %d < minRb %d\n", *maxRb, minRb);
|
|
|
|
|
AssertFatal(*Rb >= minRb, "illegal Rb %d < minRb %d\n", *Rb, minRb);
|
|
|
|
|
AssertFatal(*mcs >= 0 && *mcs <= 28, "illegal MCS %d\n", *mcs);
|
|
|
|
|
|
|
|
|
|
const int tbs_bits = tbs << 3;
|
|
|
|
|
int tbs_bits = tbs << 3;
|
|
|
|
|
uint16_t R;
|
|
|
|
|
uint8_t Qm;
|
|
|
|
|
update_ul_ue_R_Qm(*mcs, ps, &R, &Qm);
|
|
|
|
|
|
|
|
|
|
int tx_power = estimate_nr_ue_tx_power(mu, tbs_bits, R, *maxRb, ps->nrOfSymbols);
|
|
|
|
|
while (ph < tx_power && *maxRb >= minRb) {
|
|
|
|
|
(*maxRb)--;
|
|
|
|
|
tx_power = estimate_nr_ue_tx_power(mu, tbs_bits, R, *maxRb, ps->nrOfSymbols);
|
|
|
|
|
int tx_power = compute_bw_factor(mu, *Rb) +
|
|
|
|
|
compute_delta_tf(tbs_bits,
|
|
|
|
|
*Rb,
|
|
|
|
|
ps->nrOfLayers,
|
|
|
|
|
ps->nrOfSymbols,
|
|
|
|
|
ps->N_PRB_DMRS*ps->num_dmrs_symb,
|
|
|
|
|
deltaMCS);
|
|
|
|
|
|
|
|
|
|
while (ph < tx_power && *Rb >= minRb) {
|
|
|
|
|
(*Rb)--;
|
|
|
|
|
tx_power = compute_bw_factor(mu, *Rb) +
|
|
|
|
|
compute_delta_tf(tbs_bits,
|
|
|
|
|
*Rb,
|
|
|
|
|
ps->nrOfLayers,
|
|
|
|
|
ps->nrOfSymbols,
|
|
|
|
|
ps->N_PRB_DMRS*ps->num_dmrs_symb,
|
|
|
|
|
deltaMCS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (ph < tx_power && *mcs > 6) {
|
|
|
|
|
(*mcs)--;
|
|
|
|
|
update_ul_ue_R_Qm(*mcs, ps, &R, &Qm);
|
|
|
|
|
tx_power = estimate_nr_ue_tx_power(mu, tbs_bits, R, *maxRb, ps->nrOfSymbols);
|
|
|
|
|
tx_power = compute_bw_factor(mu, *Rb) +
|
|
|
|
|
compute_delta_tf(tbs_bits,
|
|
|
|
|
*Rb,
|
|
|
|
|
ps->nrOfLayers,
|
|
|
|
|
ps->nrOfSymbols,
|
|
|
|
|
ps->N_PRB_DMRS*ps->num_dmrs_symb,
|
|
|
|
|
deltaMCS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ph < tx_power)
|
|
|
|
|
LOG_W(NR_MAC, "PH %d < tx_power %d (RBs %d, MCS %d)\n", ph, tx_power, *maxRb, *mcs);
|
|
|
|
|
return tx_power;
|
|
|
|
|
LOG_W(NR_MAC, "PH %d < tx_power %d (RBs %d, MCS %d)\n", ph, tx_power, *Rb, *mcs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
|
|
|
@@ -1398,10 +1427,10 @@ void pf_ul(module_id_t module_id,
|
|
|
|
|
|
|
|
|
|
/* Calculate the current scheduling bytes */
|
|
|
|
|
const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0);
|
|
|
|
|
/* adjust rbSize and MCS according to PHR and BPRE */
|
|
|
|
|
sched_pusch->mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
|
|
|
|
nr_ue_max_mcs_min_rb(sched_pusch->mu, sched_ctrl->ph, ps, ps->pusch_Config->pusch_PowerControl->deltaMCS, min_rbSize, B, &max_rbSize, &sched_pusch->mcs);
|
|
|
|
|
|
|
|
|
|
/* reduce max_rbSize according to PHR and BPRE */
|
|
|
|
|
const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
|
|
|
|
nr_ue_max_mcs_min_rb(mu, sched_ctrl->ph, ps, min_rbSize, B, &max_rbSize, &sched_pusch->mcs);
|
|
|
|
|
if (sched_pusch->mcs < sched_ctrl->ul_bler_stats.mcs)
|
|
|
|
|
sched_ctrl->ul_bler_stats.mcs = sched_pusch->mcs; /* force estimated MCS down */
|
|
|
|
|
|
|
|
|
@@ -1418,6 +1447,7 @@ void pf_ul(module_id_t module_id,
|
|
|
|
|
max_rbSize,
|
|
|
|
|
&TBS,
|
|
|
|
|
&rbSize);
|
|
|
|
|
|
|
|
|
|
sched_pusch->rbSize = rbSize;
|
|
|
|
|
sched_pusch->tb_size = TBS;
|
|
|
|
|
LOG_D(NR_MAC,"rbSize %d (max_rbSize %d), TBS %d, est buf %d, sched_ul %d, B %d, CCE %d, num_dmrs_symb %d, N_PRB_DMRS %d\n",
|
|
|
|
|